diff --git a/.github/workflows/preview-env-dispatch.yaml b/.github/workflows/preview-env-dispatch.yaml index d7554b31ae..344030dc75 100644 --- a/.github/workflows/preview-env-dispatch.yaml +++ b/.github/workflows/preview-env-dispatch.yaml @@ -1,7 +1,6 @@ name: 'Preview Environment Dispatch' -permissions: - contents: write +permissions: {} on: pull_request_target: @@ -11,7 +10,6 @@ on: - packages/twenty-server/** - packages/twenty-front/** - .github/workflows/preview-env-dispatch.yaml - - .github/workflows/preview-env-keepalive.yaml concurrency: group: ${{ github.workflow }}-${{ github.ref }} @@ -35,28 +33,15 @@ jobs: timeout-minutes: 5 runs-on: ubuntu-latest steps: - - name: Trigger preview environment workflow + - name: Dispatch preview-env to ci-privileged env: GH_TOKEN: ${{ secrets.CI_PRIVILEGED_DISPATCH_TOKEN }} PR_NUMBER: ${{ github.event.pull_request.number }} PR_HEAD_SHA: ${{ github.event.pull_request.head.sha }} REPOSITORY: ${{ github.repository }} run: | - gh api repos/"$REPOSITORY"/dispatches \ + gh api repos/twentyhq/ci-privileged/dispatches \ -f event_type=preview-environment \ -f "client_payload[pr_number]=$PR_NUMBER" \ -f "client_payload[pr_head_sha]=$PR_HEAD_SHA" \ - -f "client_payload[repo_full_name]=$REPOSITORY" - - - name: Dispatch to ci-privileged for PR comment - env: - GH_TOKEN: ${{ secrets.CI_PRIVILEGED_DISPATCH_TOKEN }} - PR_NUMBER: ${{ github.event.pull_request.number }} - KEEPALIVE_DISPATCH_TIME: ${{ github.event.pull_request.updated_at }} - REPOSITORY: ${{ github.repository }} - run: | - gh api repos/twentyhq/ci-privileged/dispatches \ - -f event_type=preview-env-url \ - -f "client_payload[pr_number]=$PR_NUMBER" \ - -f "client_payload[keepalive_dispatch_time]=$KEEPALIVE_DISPATCH_TIME" \ -f "client_payload[repo]=$REPOSITORY" diff --git a/.github/workflows/preview-env-keepalive.yaml b/.github/workflows/preview-env-keepalive.yaml deleted file mode 100644 index 1e73f14ece..0000000000 --- a/.github/workflows/preview-env-keepalive.yaml +++ /dev/null @@ -1,186 +0,0 @@ -name: 'Preview Environment Keep Alive' - -permissions: - contents: read - -on: - repository_dispatch: - types: [preview-environment] - -jobs: - preview-environment: - timeout-minutes: 310 - runs-on: ubuntu-latest - steps: - - name: Checkout PR - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 - with: - ref: ${{ github.event.client_payload.pr_head_sha }} - - - name: Login to Docker Hub - uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3.7.0 - with: - username: ${{ vars.DOCKERHUB_USERNAME }} - password: ${{ secrets.DOCKERHUB_PASSWORD }} - - - name: Run compose setup - run: | - echo "Patching docker-compose.yml..." - # change image to localbuild using yq - yq eval 'del(.services.server.image)' -i packages/twenty-docker/docker-compose.yml - yq eval '.services.server.build.context = "../../"' -i packages/twenty-docker/docker-compose.yml - yq eval '.services.server.build.dockerfile = "./packages/twenty-docker/twenty/Dockerfile"' -i packages/twenty-docker/docker-compose.yml - yq eval '.services.server.build.target = "twenty"' -i packages/twenty-docker/docker-compose.yml - - yq eval 'del(.services.worker.image)' -i packages/twenty-docker/docker-compose.yml - yq eval '.services.worker.build.context = "../../"' -i packages/twenty-docker/docker-compose.yml - yq eval '.services.worker.build.dockerfile = "./packages/twenty-docker/twenty/Dockerfile"' -i packages/twenty-docker/docker-compose.yml - yq eval '.services.worker.build.target = "twenty"' -i packages/twenty-docker/docker-compose.yml - - echo "Adding SIGN_IN_PREFILLED environment variable to server service..." - yq eval '.services.server.environment.SIGN_IN_PREFILLED = "${SIGN_IN_PREFILLED}"' -i packages/twenty-docker/docker-compose.yml - - echo "Setting up .env file..." - cp packages/twenty-docker/.env.example packages/twenty-docker/.env - - echo "Generating secrets..." - echo "" >> packages/twenty-docker/.env - echo "# === Randomly generated secrets ===" >> packages/twenty-docker/.env - echo "APP_SECRET=$(openssl rand -base64 32)" >> packages/twenty-docker/.env - echo "PG_DATABASE_PASSWORD=$(openssl rand -hex 16)" >> packages/twenty-docker/.env - echo "SIGN_IN_PREFILLED=true" >> packages/twenty-docker/.env - echo "Docker compose build..." - cd packages/twenty-docker/ - docker compose build - working-directory: ./ - - - name: Create Tunnel - id: expose-tunnel - env: - CLOUDFLARED_VERSION: '2026.3.0' - run: | - set -euo pipefail - - # Install cloudflared (pinned for reproducibility) - sudo curl -fsSL -o /usr/local/bin/cloudflared \ - "https://github.com/cloudflare/cloudflared/releases/download/${CLOUDFLARED_VERSION}/cloudflared-linux-amd64" - sudo chmod +x /usr/local/bin/cloudflared - cloudflared --version - - # Start an account-less "quick tunnel" pointing at the server container. - # Cloudflare prints the assigned https://*.trycloudflare.com URL into the log. - log_file="$RUNNER_TEMP/cloudflared.log" - : > "$log_file" - - cloudflared tunnel \ - --url http://localhost:3000 \ - --no-autoupdate \ - --logfile "$log_file" \ - --loglevel info \ - > "$RUNNER_TEMP/cloudflared.stdout" 2>&1 & - - pid=$! - echo "$pid" > "$RUNNER_TEMP/cloudflared.pid" - echo "cloudflared PID: $pid" - - # Wait up to 2 minutes for the URL to appear; fail fast if cloudflared exits. - url='' - for _ in $(seq 1 60); do - url=$(grep -oE 'https://[a-zA-Z0-9-]+\.trycloudflare\.com' "$log_file" 2>/dev/null | head -n1 || true) - [ -n "$url" ] && break - if ! kill -0 "$pid" 2>/dev/null; then - echo "cloudflared exited before producing a URL" - cat "$log_file" || true - exit 1 - fi - sleep 2 - done - - if [ -z "$url" ]; then - echo "Timed out waiting for tunnel URL" - cat "$log_file" || true - exit 1 - fi - - echo "Tunnel URL: $url" - echo "tunnel-url=$url" >> "$GITHUB_OUTPUT" - - - name: Start services with correct SERVER_URL - env: - TUNNEL_URL: ${{ steps.expose-tunnel.outputs.tunnel-url }} - run: | - cd packages/twenty-docker/ - - echo "Setting SERVER_URL to $TUNNEL_URL" - sed -i '/SERVER_URL=/d' .env - echo "" >> .env - echo "SERVER_URL=$TUNNEL_URL" >> .env - - # Start the services - echo "Docker compose up..." - docker compose up -d || { - echo "Docker compose failed to start" - docker compose logs - exit 1 - } - - echo "Waiting for services to be ready..." - count=0 - while [ ! $(docker inspect --format='{{.State.Health.Status}}' twenty-db-1) = "healthy" ] || [ ! $(docker inspect --format='{{.State.Health.Status}}' twenty-server-1) = "healthy" ]; do - sleep 5 - count=$((count+1)) - if [ $count -gt 60 ]; then - echo "Timeout waiting for services to be ready" - docker compose logs - exit 1 - fi - echo "Still waiting for services... ($count/60)" - done - - echo "All services are up and running!" - working-directory: ./ - - - name: Seed Dev Workspace - run: | - cd packages/twenty-docker/ - echo "Seeding light dev workspace (Apple only)..." - if ! docker compose exec -T server yarn command:prod workspace:seed:dev --light; then - echo "❌ Seeding light dev workspace failed. Dumping server logs..." - docker compose logs server - exit 1 - fi - working-directory: ./ - - - name: Output tunnel URL - env: - TUNNEL_URL: ${{ steps.expose-tunnel.outputs.tunnel-url }} - run: | - echo "✅ Preview Environment Ready!" - echo "🔗 Preview URL: $TUNNEL_URL" - echo "⏱️ This environment will be available for 5 hours" - echo "## 🚀 Preview Environment Ready!" >> "$GITHUB_STEP_SUMMARY" - echo "" >> "$GITHUB_STEP_SUMMARY" - echo "Preview URL: $TUNNEL_URL" >> "$GITHUB_STEP_SUMMARY" - echo "" >> "$GITHUB_STEP_SUMMARY" - echo "This environment will automatically shut down after 5 hours." >> "$GITHUB_STEP_SUMMARY" - echo "$TUNNEL_URL" > tunnel-url.txt - - - name: Upload tunnel URL artifact - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 - with: - name: tunnel-url - path: tunnel-url.txt - retention-days: 1 - - - name: Keep tunnel alive for 5 hours - run: timeout 300m sleep 18000 # Stop on whichever we reach first (300m or 5hour sleep) - - - name: Cleanup - if: always() - run: | - if [ -f "$RUNNER_TEMP/cloudflared.pid" ]; then - kill "$(cat "$RUNNER_TEMP/cloudflared.pid")" 2>/dev/null || true - fi - cd packages/twenty-docker/ - docker compose down -v - working-directory: ./