Skip to content

Commit d3ee437

Browse files
ci: Attach Vercel build logs to Slack post on failures (#1956)
Fixing the GitHub action's filter to find the Vercel post in Slack, to attach the build logs in Slack instead of PRs on a public repo, just in case anything sensitive makes it way into the build, and out of the logs. Follow-up to #1946, found by re-triggering the build on #1948 after merging #1946 ## Tested - Build failure logs posted in [Slack](https://sourcegraph.slack.com/archives/C0C25K5RHRN/p1789188631974869?thread_ts=1789185584.403469&cid=C0C25K5RHRN) - Build failure PR comment #1948 (comment) links to the Slack post, instead of posting build logs publicly ## Amp thread - [Vercel build report security review](https://ampcode.com/threads/T-01a093c3-a827-71ba-af20-c13e851c9a77) --------- Co-authored-by: Amp <amp@ampcode.com>
1 parent ab14b15 commit d3ee437

3 files changed

Lines changed: 182 additions & 188 deletions

File tree

Lines changed: 27 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,24 @@
11
name: Vercel build report
22

33
# Vercel only shows build logs to members of its team. When a PR's Vercel
4-
# build fails, this comments the end of the build log on the PR, with the
5-
# full log as a workflow artifact when the comment cannot hold it all; when a
6-
# later revision builds, the comment is updated to say so and the artifact
7-
# is deleted. The full log is also attached to the Vercel Slack app's "failed
8-
# to deploy" post when the SLACK_BOT_TOKEN secret and SLACK_CHANNEL_ID
9-
# variable are set (see dev/slack-app-vercel-build-report.json).
4+
# build fails, this attaches the build log to the Vercel Slack app's "failed
5+
# to deploy" post (SLACK_BOT_TOKEN secret and SLACK_CHANNEL_ID variable; see
6+
# dev/slack-app-vercel-build-report.json) and comments a link to it on the
7+
# PR; when a later revision builds, the comment is updated to say so. The log
8+
# never goes on the PR itself, so anything sensitive a build prints stays in
9+
# Slack instead of a public repository.
1010
#
1111
# GitHub only delivers repository_dispatch (and finds workflow_dispatch
1212
# workflows) once the workflow file is on the default branch, so before merge
1313
# run dev/report-vercel-build.mjs locally instead. After merge, re-run on a PR
1414
# by hand with the same payload fields as inputs:
1515
# gh workflow run vercel-build-report.yml \
16-
# -f id=dpl_... -f state=error -f sha=<pr head sha>
16+
# -f id=dpl_... -f state=failed -f sha=<pr head sha>
1717
on:
1818
repository_dispatch:
19-
types: [vercel.deployment.error, vercel.deployment.success]
19+
# A build that exits non-zero is `failed`; `error` is only sent for
20+
# deleted deployments, which have no log
21+
types: [vercel.deployment.failed, vercel.deployment.success]
2022
workflow_dispatch:
2123
inputs:
2224
id:
@@ -26,16 +28,14 @@ on:
2628
description: Deployment state (client_payload.state.type)
2729
required: true
2830
type: choice
29-
options: [error, success]
31+
options: [failed, success]
3032
sha:
3133
description: Full commit SHA of the PR head (client_payload.git.sha)
3234
required: true
3335

3436
permissions:
3537
contents: read
3638
pull-requests: write
37-
# To delete the full-log artifact once the build passes
38-
actions: write
3939

4040
env:
4141
DEPLOYMENT_ID: ${{ github.event.client_payload.id || inputs.id }}
@@ -46,7 +46,12 @@ env:
4646

4747
jobs:
4848
report:
49-
if: github.event.client_payload.environment != 'production'
49+
# `failed` is also sent for checks_failed, aliasing_failed and account
50+
# problems, where the build log shows a build that passed
51+
if: >-
52+
github.event.client_payload.environment != 'production'
53+
&& (github.event.client_payload.state.type != 'failed'
54+
|| github.event.client_payload.state.detail == 'deployment_failed')
5055
runs-on: ubuntu-latest
5156
steps:
5257
- name: Check out dev/report-vercel-build.mjs
@@ -57,35 +62,26 @@ jobs:
5762

5863
- name: Fetch the build log from Vercel
5964
# Vercel is only contacted when the build failed
60-
if: env.DEPLOYMENT_STATE == 'error'
65+
if: env.DEPLOYMENT_STATE == 'failed'
6166
id: log
6267
env:
6368
# Scoped to the sourcegraph-docs project, so it needs no team ID
6469
VERCEL_TOKEN: ${{ secrets.VERCEL_TOKEN }}
6570
run: node dev/report-vercel-build.mjs fetch-log "$LOG_FILE"
6671

67-
- name: Attach the full log when the comment cannot hold it all
68-
if: steps.log.outputs.truncated == 'true'
69-
id: artifact
70-
uses: actions/upload-artifact@v4
71-
with:
72-
name: vercel-build-log-${{ env.COMMIT_SHA }}
73-
path: ${{ env.LOG_FILE }}
74-
retention-days: 30
75-
76-
- name: Comment on the pull request
77-
env:
78-
PR_NUMBER: ${{ steps.log.outputs.pull_request }}
79-
ARTIFACT_ID: ${{ steps.artifact.outputs.artifact-id }}
80-
ARTIFACT_URL: ${{ steps.artifact.outputs.artifact-url }}
81-
run: node dev/report-vercel-build.mjs comment "$LOG_FILE"
82-
8372
- name: Attach the log to the Vercel app's Slack post
84-
if: env.DEPLOYMENT_STATE == 'error'
85-
# The PR comment is the record; a Slack problem must not fail it
73+
if: env.DEPLOYMENT_STATE == 'failed'
74+
id: slack
75+
# The PR should still hear about the failure when Slack is down
8676
continue-on-error: true
8777
env:
8878
PR_NUMBER: ${{ steps.log.outputs.pull_request }}
8979
SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }}
9080
SLACK_CHANNEL_ID: ${{ vars.SLACK_CHANNEL_ID }}
9181
run: node dev/report-vercel-build.mjs slack "$LOG_FILE"
82+
83+
- name: Comment on the pull request
84+
env:
85+
PR_NUMBER: ${{ steps.log.outputs.pull_request }}
86+
SLACK_PERMALINK: ${{ steps.slack.outputs.permalink }}
87+
run: node dev/report-vercel-build.mjs comment

‎AGENTS.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
- **Checks**: `npm run check` runs every `dev/check-*.mjs` (links, filenames, images); `npm run build` runs them first, so any finding fails a deploy
1010
- **Check links**: `npm run check -- links --check-anchors --check-self-links` (CI comments on PRs that break links; see `dev/check-links.mjs`; the build runs it without flags, so only dead page links fail a deploy). When moving a page or renaming a heading, update every link to it; a redirect in `src/data/redirects.ts` does not satisfy the check. Link to this site with relative paths (`/admin/config/site-config`), never `https://sourcegraph.com/docs/…` or `https://docs.sourcegraph.com/…`. To also probe the external links you added: `npm run check -- links --check-anchors --check-self-links --check-external --diff <(git diff -U0 origin/main)`
1111
- **Prove changed links resolve on a deploy**: `node dev/verify-links-live.mjs --site <vercel-preview-url>` prints a Markdown table for the PR description
12-
- **Vercel build failures**: Vercel shows build logs only to its team members, so `.github/workflows/vercel-build-report.yml` comments the log tail on the PR (see `dev/report-vercel-build.mjs`). It reads Vercel with the `VERCEL_TOKEN` repo secret, a token scoped to the `sourcegraph-docs` project that expires 2026-12-10; mint a new one with `POST /v3/user/tokens?teamId=<team>` and `projectId` in the body. It also attaches the full log to the Vercel Slack app's "failed to deploy" post in `#alerts-vercel-doc-site`, using the `SLACK_BOT_TOKEN` repo secret and `SLACK_CHANNEL_ID` repo variable. The bot is the Slack app in `dev/slack-app-vercel-build-report.json`; to recreate it, paste that manifest at <https://api.slack.com/apps?new_app=1> (From a manifest), install it, copy its Bot User OAuth Token into the secret, and `/invite @Vercel build log` to the channel
12+
- **Vercel build failures**: Vercel shows build logs only to its team members, so `.github/workflows/vercel-build-report.yml` attaches the log to the Vercel Slack app's "failed to deploy" post in `#alerts-vercel-doc-site` and comments a link to it on the PR (see `dev/report-vercel-build.mjs`). The log itself never goes on the PR, since the repository is public. It reads Vercel with the `VERCEL_TOKEN` repo secret, a token scoped to the `sourcegraph-docs` project that expires 2026-12-10; mint a new one with `POST /v3/user/tokens?teamId=<team>` and `projectId` in the body. Slack needs the `SLACK_BOT_TOKEN` repo secret and `SLACK_CHANNEL_ID` repo variable. The bot is the Slack app in `dev/slack-app-vercel-build-report.json`; to recreate it, paste that manifest at <https://api.slack.com/apps?new_app=1> (From a manifest), install it, copy its Bot User OAuth Token into the secret, and `/invite @Vercel build log` to the channel
1313

1414
## AI Chat Integration
1515

0 commit comments

Comments
 (0)