Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
| if: ${{ github.event.inputs.action == 'deploy' }} | ||
| runs-on: ubuntu-latest | ||
| timeout-minutes: 15 | ||
| outputs: | ||
| url: ${{ steps.deploy.outputs.url }} | ||
| # Only run one deployment at a time per PR. | ||
| concurrency: | ||
| group: pr-${{ github.event.number }} | ||
|
|
||
| # Deploying apps with this "review" environment allows the URL for the app to be displayed in the PR UI. | ||
| # Feel free to change the name of this environment. | ||
| group: workflows-preview-${{ github.ref_name }} | ||
| environment: | ||
| name: pr-${{ github.event.number }} # The script in the `deploy` sets the URL output for each review app. | ||
| url: ${{ steps.deploy.outputs.url }} | ||
| name: workflows-preview-${{ github.ref_name }} | ||
| url: https://${{ env.APP_NAME }}.fly.dev | ||
| steps: | ||
| - name: Get code | ||
| uses: actions/checkout@v4 | ||
|
|
||
| - name: Deploy PR app to Fly.io | ||
| id: deploy | ||
| uses: superfly/fly-pr-review-apps@1.2.1 | ||
| with: | ||
| config: apps/workflows/fly.toml | ||
| vmsize: shared-cpu-1x | ||
| name: openstatus-workflows-pr-${{ github.event.number }} | ||
| secrets: | | ||
| DATABASE_URL=${{ secrets.STAGING_DB_URL }} | ||
| DATABASE_AUTH_TOKEN=${{ env.STAGING_DB_AUTH_TOKEN }} | ||
| RESEND_API_KEY=${{ secrets.STAGING_RESEND_API_KEY }} | ||
| UPSTASH_REDIS_REST_URL=test | ||
| UPSTASH_REDIS_REST_TOKEN=test | ||
| GCP_PROJECT_ID=test | ||
| - name: Setup Fly.io CLI | ||
| uses: superfly/flyctl-actions/setup-flyctl@master | ||
|
|
||
| - name: Create app if not exists | ||
| run: flyctl apps create ${{ env.APP_NAME }} --org ${{ env.FLY_ORG }} || true | ||
|
|
||
| - name: Set secrets | ||
| run: | | ||
| flyctl secrets set \ | ||
| DATABASE_URL="${{ secrets.STAGING_DB_URL }}" \ | ||
| DATABASE_AUTH_TOKEN="${{ secrets.STAGING_DB_AUTH_TOKEN }}" \ | ||
| RESEND_API_KEY="${{ secrets.STAGING_RESEND_API_KEY }}" \ | ||
| UPSTASH_REDIS_REST_URL=test \ | ||
| UPSTASH_REDIS_REST_TOKEN=test \ | ||
| GCP_PROJECT_ID=test \ | ||
| --app ${{ env.APP_NAME }} | ||
|
|
||
| - name: Deploy to Fly.io | ||
| run: | | ||
| flyctl deploy \ | ||
| --config apps/workflows/fly.toml \ | ||
| --app ${{ env.APP_NAME }} \ | ||
| --region ${{ env.FLY_REGION }} \ | ||
| --vm-size shared-cpu-1x \ | ||
| --yes | ||
|
|
||
| destroy: |
Check warning
Code scanning / CodeQL
Workflow does not contain permissions Medium
This autofix suggestion was applied.
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 5 days ago
In general, the fix is to explicitly declare a permissions block for the workflow or per job so that the GITHUB_TOKEN is restricted to the minimal set of scopes required. For this workflow, the deploy job needs to read repository contents for actions/checkout@v4, and the destroy job needs to clean up a GitHub environment using strumwolf/delete-deployment-environment@v2, which typically requires deployments: write but not broader write access.
The best fix, without changing existing functionality, is to add a top‑level permissions block that applies to the whole workflow with:
contents: readto allow checkout,deployments: writeto allow deleting the deployment environment,
and nothing else. This documents the needed permissions and prevents the token from having unnecessary write scopes likecontents: write,issues: write, orpull-requests: write. Concretely, in.github/workflows/workflow-preview.yml, insert apermissionsblock after theon:section (after line 11/12) so it applies to all jobs. No additional imports or methods are needed since this is just YAML configuration.
| @@ -10,6 +10,10 @@ | ||
| - deploy | ||
| - destroy | ||
|
|
||
| permissions: | ||
| contents: read | ||
| deployments: write | ||
|
|
||
| env: | ||
| FLY_API_TOKEN: ${{ secrets.FLY_API_TOKEN }} | ||
| FLY_REGION: ams |
| if: ${{ github.event.inputs.action == 'destroy' }} | ||
| runs-on: ubuntu-latest | ||
| timeout-minutes: 5 | ||
| steps: | ||
| - name: Setup Fly.io CLI | ||
| uses: superfly/flyctl-actions/setup-flyctl@master | ||
|
|
||
| - name: Destroy app | ||
| run: flyctl apps destroy ${{ env.APP_NAME }} --yes || true | ||
|
|
||
| - name: Clean up GitHub environment | ||
| uses: strumwolf/delete-deployment-environment@v2 | ||
| if: ${{ github.event.action == 'closed' }} | ||
| with: | ||
| # ⚠️ The provided token needs permission for admin write:org | ||
| token: ${{ secrets.GITHUB_TOKEN }} | ||
| environment: pr-${{ github.event.number }} | ||
| environment: workflows-preview-${{ github.ref_name }} |
Check warning
Code scanning / CodeQL
Workflow does not contain permissions Medium
Copilot Autofix
AI 5 days ago
Copilot could not generate an autofix suggestion
Copilot could not generate an autofix suggestion for this alert. Try pushing a new commit or if the problem persists contact support.
…in permissions Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
…in permissions Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
This PR refactors the Fly preview GitHub Actions workflows to use manual workflow_dispatch deploy/destroy flows and direct flyctl commands, instead of the fly-pr-review-apps action and PR lifecycle triggers.
Changes:
- Replace
pull_requesttriggers (including path filters and PR close cleanup) withworkflow_dispatchinputs (deploy/destroy). - Implement preview app creation, secrets provisioning, deploy, and destroy via
flyctl. - Rename concurrency/environment grouping to be based on
github.ref_nameand set a predictable preview URL.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 10 comments.
| File | Description |
|---|---|
| .github/workflows/workflow-preview.yml | Converts workflows preview deployment to manual flyctl-based deploy/destroy with per-ref app/environment naming. |
| .github/workflows/api-preview.yml | Converts API preview deployment to manual flyctl-based deploy/destroy with per-ref app/environment naming. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| - name: Setup Fly.io CLI | ||
| uses: superfly/flyctl-actions/setup-flyctl@master | ||
|
|
There was a problem hiding this comment.
Using superfly/flyctl-actions/setup-flyctl@master pins to a moving branch, which is a supply-chain risk and can cause unexpected breaks if master changes. Prefer pinning to a tagged release or a specific commit SHA.
| - name: Create app if not exists | ||
| run: flyctl apps create ${{ env.APP_NAME }} --org ${{ env.FLY_ORG }} || true | ||
|
|
There was a problem hiding this comment.
flyctl apps create ... || true will also ignore real failures (e.g., invalid app name, auth/org issues), making the root cause harder to diagnose and potentially continuing to later steps with a misconfigured app. Consider handling only the "already exists" case explicitly (or checking existence first) and failing on other errors.
| on: | ||
| pull_request: | ||
| types: [opened, reopened, synchronize, closed] | ||
| paths: | ||
| - "apps/server/**" | ||
| - "packages/db/**" | ||
| - "packages/emails/**" | ||
| - "packages/regions/**" | ||
| - "packages/tsconfig/**" | ||
| - "packages/utils/**" | ||
| - "packages/upstash/**" | ||
| - "packages/proto/**" | ||
| workflow_dispatch: | ||
| inputs: | ||
| action: | ||
| description: "Action to perform" | ||
| required: true | ||
| type: choice | ||
| options: | ||
| - deploy | ||
| - destroy | ||
|
|
There was a problem hiding this comment.
Switching the trigger from pull_request to workflow_dispatch means preview apps will no longer deploy/destroy automatically on PR open/sync/close (and path filters no longer apply). If the goal is still PR previews, consider keeping pull_request (optionally alongside workflow_dispatch) so PR lifecycle events continue to manage the preview environment.
| - name: Setup Fly.io CLI | ||
| uses: superfly/flyctl-actions/setup-flyctl@master | ||
|
|
There was a problem hiding this comment.
Using superfly/flyctl-actions/setup-flyctl@master pins to a moving branch, which is a supply-chain risk and can cause unexpected breaks if master changes. Prefer pinning to a tagged release or a specific commit SHA.
| on: | ||
| pull_request: | ||
| types: [opened, reopened, synchronize, closed] | ||
| paths: | ||
| - "apps/workflows/**" | ||
| - "packages/db/**" | ||
| - "packages/emails/**" | ||
| - "packages/utils/**" | ||
| - "packages/notifications/**" | ||
| - "packages/tsconfig/**" | ||
| workflow_dispatch: | ||
| inputs: | ||
| action: | ||
| description: "Action to perform" | ||
| required: true | ||
| type: choice | ||
| options: | ||
| - deploy | ||
| - destroy |
There was a problem hiding this comment.
Switching the trigger from pull_request to workflow_dispatch means preview apps will no longer deploy/destroy automatically on PR open/sync/close (and path filters no longer apply). If the goal is still PR previews, consider keeping pull_request (optionally alongside workflow_dispatch) so PR lifecycle events continue to manage the preview environment.
| env: | ||
| FLY_API_TOKEN: ${{ secrets.FLY_API_TOKEN }} | ||
| # Set these to your Fly.io organization and preferred region. | ||
| FLY_REGION: ams | ||
| FLY_ORG: openstatus | ||
| APP_NAME: openstatus-workflows-preview-${{ github.ref_name }} | ||
|
|
There was a problem hiding this comment.
APP_NAME is derived from github.ref_name, which can contain characters Fly app names don't allow (e.g., /, ., uppercase) and can also exceed length limits. This can cause flyctl apps create/deploy to fail for common branch names like feature/foo. Consider generating a sanitized, lowercased, length-limited app name in a step (writing to $GITHUB_ENV) or accepting an explicit app_name input.
| - name: Destroy app | ||
| run: flyctl apps destroy ${{ env.APP_NAME }} --yes || true | ||
|
|
||
| - name: Clean up GitHub environment | ||
| uses: strumwolf/delete-deployment-environment@v2 | ||
| if: ${{ github.event.action == 'closed' }} | ||
| with: | ||
| # ⚠️ The provided token needs permission for admin write:org | ||
| token: ${{ secrets.GITHUB_TOKEN }} | ||
| environment: pr-${{ github.event.number }} | ||
| environment: workflows-preview-${{ github.ref_name }} |
There was a problem hiding this comment.
flyctl apps destroy ... || true masks failures (e.g., permission issues), and the workflow will still delete the GitHub environment afterwards, which can leave orphaned Fly apps while removing the tracking environment. Consider removing || true, or at least conditionally running the environment cleanup only when the destroy succeeded.
| # Set these to your Fly.io organization and preferred region. | ||
| FLY_REGION: ams | ||
| FLY_ORG: openstatus | ||
| APP_NAME: openstatus-api-preview-${{ github.ref_name }} |
There was a problem hiding this comment.
APP_NAME is derived from github.ref_name, which can contain characters Fly app names don't allow (e.g., /, ., uppercase) and can also exceed length limits. This can cause flyctl apps create/deploy to fail for common branch names like feature/foo. Consider generating a sanitized, lowercased, length-limited app name in a step (writing to $GITHUB_ENV) or accepting an explicit app_name input.
| APP_NAME: openstatus-api-preview-${{ github.ref_name }} | |
| APP_NAME: ${{ format('openstatus-api-preview-{0}', substr(toLower(replace(replace(github.ref_name, '/', '-'), '.', '-')), 0, 40)) }} |
| uses: superfly/flyctl-actions/setup-flyctl@master | ||
|
|
||
| - name: Create app if not exists | ||
| run: flyctl apps create ${{ env.APP_NAME }} --org ${{ env.FLY_ORG }} || true |
There was a problem hiding this comment.
flyctl apps create ... || true will also ignore real failures (e.g., invalid app name, auth/org issues), making the root cause harder to diagnose and potentially continuing to later steps with a misconfigured app. Consider handling only the "already exists" case explicitly (or checking existence first) and failing on other errors.
| run: flyctl apps create ${{ env.APP_NAME }} --org ${{ env.FLY_ORG }} || true | |
| run: | | |
| if ! flyctl apps show "$APP_NAME" >/dev/null 2>&1; then | |
| flyctl apps create "$APP_NAME" --org "$FLY_ORG" | |
| fi |
| - name: Destroy app | ||
| run: flyctl apps destroy ${{ env.APP_NAME }} --yes || true | ||
|
|
||
| - name: Clean up GitHub environment | ||
| uses: strumwolf/delete-deployment-environment@v2 | ||
| if: ${{ github.event.action == 'closed' }} | ||
| with: | ||
| # ⚠️ The provided token needs permission for admin write:org | ||
| token: ${{ secrets.GITHUB_TOKEN }} | ||
| environment: pr-${{ github.event.number }} | ||
| environment: api-preview-${{ github.ref_name }} |
There was a problem hiding this comment.
flyctl apps destroy ... || true masks failures (e.g., permission issues), and the workflow will still delete the GitHub environment afterwards, which can leave orphaned Fly apps while removing the tracking environment. Consider removing || true, or at least conditionally running the environment cleanup only when the destroy succeeded.
No description provided.