From d16c55f5838845a4888f5c1a29ab2fe316935710 Mon Sep 17 00:00:00 2001 From: Adam Hall Date: Fri, 19 Jun 2026 09:36:23 +0930 Subject: [PATCH 1/3] FEAT: Create workflow for deploying preview environments to vercel on each PR --- .github/workflows/vercel-preview.yml | 99 ++++++++++++++++++++++++++++ docs/vercel-preview.md | 36 ++++++++++ 2 files changed, 135 insertions(+) create mode 100644 .github/workflows/vercel-preview.yml create mode 100644 docs/vercel-preview.md diff --git a/.github/workflows/vercel-preview.yml b/.github/workflows/vercel-preview.yml new file mode 100644 index 0000000..a9dc9ad --- /dev/null +++ b/.github/workflows/vercel-preview.yml @@ -0,0 +1,99 @@ +name: Vercel Preview Deployment + +on: + workflow_call: + inputs: + vercel-org-id: + description: "Vercel organisation ID" + type: string + required: true + vercel-project-id: + description: "Vercel project ID" + type: string + required: true + working-directory: + description: "Directory to run the Vercel deploy from" + type: string + required: false + default: "." + environment-name: + description: "GitHub Environment to deploy to" + type: string + required: false + default: "Preview" + secrets: + vercel-token: + description: "Vercel deployment token" + required: true + +concurrency: + group: vercel-preview-${{ github.event.pull_request.number }} + cancel-in-progress: true + +permissions: + contents: read + deployments: write + pull-requests: write + +jobs: + deploy-preview: + name: Deploy Preview to Vercel + runs-on: ubuntu-latest + environment: + name: ${{ inputs.environment-name }} + url: ${{ steps.deploy.outputs.url }} + env: + VERCEL_ORG_ID: ${{ inputs.vercel-org-id }} + VERCEL_PROJECT_ID: ${{ inputs.vercel-project-id }} + VERCEL_TELEMETRY_DISABLED: 1 + steps: + - name: Checkout + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2 + with: + persist-credentials: false + + - name: Install Vercel CLI + run: npm install --global vercel@latest + + - name: Deploy to Vercel (preview) + id: deploy + working-directory: ${{ inputs.working-directory }} + env: + VERCEL_TOKEN: ${{ secrets.vercel-token }} + run: | + vercel deploy --yes --no-wait --token="$VERCEL_TOKEN" \ + > deployment-url.txt 2> >(tee vercel-output.log >&2) + url="$(cat deployment-url.txt)" + inspect_url="$(grep -m1 -o 'https://vercel.com/[^[:space:]]*' vercel-output.log || true)" + echo "url=$url" >> "$GITHUB_OUTPUT" + echo "inspect_url=$inspect_url" >> "$GITHUB_OUTPUT" + + # Posts (or updates in place) a single comment on the PR with the preview URL. + - name: Comment preview URL on PR + env: + GH_TOKEN: ${{ github.token }} + PR_NUMBER: ${{ github.event.pull_request.number }} + REPO: ${{ github.repository }} + DEPLOY_URL: ${{ steps.deploy.outputs.url }} + INSPECT_URL: ${{ steps.deploy.outputs.inspect_url }} + COMMIT_SHA: ${{ github.event.pull_request.head.sha }} + run: | + marker='' + body="$marker + ### ⚡ Preview environment is deploying + + Wait ~5 minutes for completion, or monitor progress using the Inspect URL. + + **Preview URL:** ${DEPLOY_URL} + **Inspect:** ${INSPECT_URL} + + _Deployed commit ${COMMIT_SHA}_" + + comment_id="$(gh api "repos/${REPO}/issues/${PR_NUMBER}/comments" \ + --jq "[.[] | select(.body | startswith(\"${marker}\"))][0].id")" + + if [ -n "$comment_id" ] && [ "$comment_id" != "null" ]; then + gh api -X PATCH "repos/${REPO}/issues/comments/${comment_id}" -f body="$body" + else + gh api -X POST "repos/${REPO}/issues/${PR_NUMBER}/comments" -f body="$body" + fi diff --git a/docs/vercel-preview.md b/docs/vercel-preview.md new file mode 100644 index 0000000..63a9ae2 --- /dev/null +++ b/docs/vercel-preview.md @@ -0,0 +1,36 @@ +# Vercel Preview Deployment + +Deploys a preview build to Vercel and posts (or updates) a single comment on the +pull request with the preview and inspect URLs. Intended to be called from a +`pull_request` triggered workflow. + +#### **Inputs** +| Name | Required | Type | Default | Description | +|--------------------|----------|--------|----------|----------------------------------------| +| vercel-org-id | ✅ | string | | Vercel organisation ID | +| vercel-project-id | ✅ | string | | Vercel project ID | +| working-directory | ❌ | string | . | Directory to run the Vercel deploy from | +| environment-name | ❌ | string | Preview | GitHub Environment to deploy to | + +#### **Secrets** +| Name | Required | Description | +|---------------|----------|--------------------------| +| vercel-token | ✅ | Vercel deployment token | + +#### Example Usage + +```yaml +on: + pull_request: + branches: + - main + +jobs: + deploy-preview: + uses: aligent/workflows/.github/workflows/vercel-preview.yml@main + with: + vercel-org-id: ${{ vars.VERCEL_ORG_ID }} + vercel-project-id: ${{ vars.VERCEL_PROJECT_ID }} + secrets: + vercel-token: ${{ secrets.VERCEL_TOKEN }} +``` From af5dd6afe6cd3b2ddc4297b846257f90ff878fb4 Mon Sep 17 00:00:00 2001 From: Adam Hall Date: Fri, 19 Jun 2026 09:36:44 +0930 Subject: [PATCH 2/3] FEAT: Create a workflow for deploying to vercel production --- .github/workflows/vercel-production.yml | 64 +++++++++++++++++++++++++ docs/vercel-production.md | 36 ++++++++++++++ 2 files changed, 100 insertions(+) create mode 100644 .github/workflows/vercel-production.yml create mode 100644 docs/vercel-production.md diff --git a/.github/workflows/vercel-production.yml b/.github/workflows/vercel-production.yml new file mode 100644 index 0000000..82d82a8 --- /dev/null +++ b/.github/workflows/vercel-production.yml @@ -0,0 +1,64 @@ +name: Vercel Production Deployment + +on: + workflow_call: + inputs: + vercel-org-id: + description: "Vercel organisation ID" + type: string + required: true + vercel-project-id: + description: "Vercel project ID" + type: string + required: true + working-directory: + description: "Directory to run the Vercel deploy from" + type: string + required: false + default: "." + environment-name: + description: "GitHub Environment to deploy to" + type: string + required: false + default: "Production" + secrets: + vercel-token: + description: "Vercel deployment token" + required: true + +concurrency: + group: vercel-production-${{ github.ref }} + cancel-in-progress: false + +permissions: + contents: read + deployments: write + +jobs: + deploy-production: + name: Deploy Production to Vercel + runs-on: ubuntu-latest + environment: + name: ${{ inputs.environment-name }} + url: ${{ steps.deploy.outputs.url }} + env: + VERCEL_ORG_ID: ${{ inputs.vercel-org-id }} + VERCEL_PROJECT_ID: ${{ inputs.vercel-project-id }} + VERCEL_TELEMETRY_DISABLED: 1 + steps: + - name: Checkout + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2 + with: + persist-credentials: false + + - name: Install Vercel CLI + run: npm install --global vercel@latest + + - name: Deploy to Vercel (production) + id: deploy + working-directory: ${{ inputs.working-directory }} + env: + VERCEL_TOKEN: ${{ secrets.vercel-token }} + run: | + url="$(vercel deploy --prod --yes --no-wait --token="$VERCEL_TOKEN")" + echo "url=$url" >> "$GITHUB_OUTPUT" diff --git a/docs/vercel-production.md b/docs/vercel-production.md new file mode 100644 index 0000000..908513d --- /dev/null +++ b/docs/vercel-production.md @@ -0,0 +1,36 @@ +# Vercel Production Deployment + +Deploys a production build to Vercel. Intended to be called from a `push` (or +`workflow_dispatch`) triggered workflow. + +#### **Inputs** +| Name | Required | Type | Default | Description | +|--------------------|----------|--------|------------|----------------------------------------| +| vercel-org-id | ✅ | string | | Vercel organisation ID | +| vercel-project-id | ✅ | string | | Vercel project ID | +| working-directory | ❌ | string | . | Directory to run the Vercel deploy from | +| environment-name | ❌ | string | Production | GitHub Environment to deploy to | + +#### **Secrets** +| Name | Required | Description | +|---------------|----------|--------------------------| +| vercel-token | ✅ | Vercel deployment token | + +#### Example Usage + +```yaml +on: + push: + branches: + - main + workflow_dispatch: + +jobs: + deploy-production: + uses: aligent/workflows/.github/workflows/vercel-production.yml@main + with: + vercel-org-id: ${{ vars.VERCEL_ORG_ID }} + vercel-project-id: ${{ vars.VERCEL_PROJECT_ID }} + secrets: + vercel-token: ${{ secrets.VERCEL_TOKEN }} +``` From 7a560e9b931db2fd5f3dc83897d9a94cb814c3e7 Mon Sep 17 00:00:00 2001 From: Adam Hall Date: Fri, 19 Jun 2026 09:55:29 +0930 Subject: [PATCH 3/3] FEAT: Move permissions to the job block --- .github/workflows/vercel-preview.yml | 9 ++++----- .github/workflows/vercel-production.yml | 7 +++---- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/.github/workflows/vercel-preview.yml b/.github/workflows/vercel-preview.yml index a9dc9ad..9144662 100644 --- a/.github/workflows/vercel-preview.yml +++ b/.github/workflows/vercel-preview.yml @@ -30,15 +30,14 @@ concurrency: group: vercel-preview-${{ github.event.pull_request.number }} cancel-in-progress: true -permissions: - contents: read - deployments: write - pull-requests: write - jobs: deploy-preview: name: Deploy Preview to Vercel runs-on: ubuntu-latest + permissions: + contents: read + deployments: write + pull-requests: write environment: name: ${{ inputs.environment-name }} url: ${{ steps.deploy.outputs.url }} diff --git a/.github/workflows/vercel-production.yml b/.github/workflows/vercel-production.yml index 82d82a8..ed66fdd 100644 --- a/.github/workflows/vercel-production.yml +++ b/.github/workflows/vercel-production.yml @@ -30,14 +30,13 @@ concurrency: group: vercel-production-${{ github.ref }} cancel-in-progress: false -permissions: - contents: read - deployments: write - jobs: deploy-production: name: Deploy Production to Vercel runs-on: ubuntu-latest + permissions: + contents: read + deployments: write environment: name: ${{ inputs.environment-name }} url: ${{ steps.deploy.outputs.url }}