docs(schema): document shows.legacy_dj_name DJ_HANDLE invariant #73
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Schema shape report | |
| # When a PR touches schema.ts or a migration SQL file, generate a markdown | |
| # summary of the new constraints (UNIQUE / NOT NULL / CHECK / FK), probe the | |
| # staging Postgres clone for rows that would violate them, and post / update | |
| # a single PR comment with the result. | |
| # | |
| # Non-blocking: this workflow always exits 0. The comment is informational. | |
| on: | |
| pull_request: | |
| branches: | |
| - main | |
| paths: | |
| - 'shared/database/src/schema.ts' | |
| - 'shared/database/src/migrations/*.sql' | |
| permissions: | |
| contents: read | |
| pull-requests: write | |
| concurrency: | |
| group: schema-shape-report-${{ github.event.pull_request.number }} | |
| cancel-in-progress: true | |
| jobs: | |
| shape-report: | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 10 | |
| steps: | |
| - name: Checkout PR head with merge-base history | |
| uses: actions/checkout@v6 | |
| with: | |
| fetch-depth: 0 | |
| ref: ${{ github.event.pull_request.head.sha }} | |
| - name: Fetch base branch | |
| run: git fetch --no-tags --depth=1 origin ${{ github.event.pull_request.base.ref }} | |
| - name: Set up Node | |
| uses: actions/setup-node@v6 | |
| with: | |
| node-version: '24' | |
| cache: 'npm' | |
| - name: Install postgres client (isolated from workspace) | |
| # We don't need the full workspace install for this script — the | |
| # `postgres` client is the only runtime dep. We install into a | |
| # throwaway dir OUTSIDE the workspace root so npm has no | |
| # `package.json`/`.npmrc` context to walk — otherwise npm hits | |
| # GitHub Packages for `@wxyc/shared` metadata and 401s since | |
| # this step intentionally doesn't expose NPM_TOKEN. The previous | |
| # `--no-package-lock` workaround (PR #1377) didn't suffice | |
| # because npm still consults the root manifest. Observed on PR | |
| # #1348 / runs 27185185058 + 27222288445. | |
| run: | | |
| mkdir -p .cache/pg-client | |
| cd .cache/pg-client | |
| npm init -y > /dev/null | |
| npm install --no-audit --no-fund postgres@^3.4.9 | |
| - name: Compute diff | |
| id: diff | |
| run: | | |
| set -euo pipefail | |
| BASE_REF="origin/${{ github.event.pull_request.base.ref }}" | |
| mkdir -p .cache | |
| git diff "$BASE_REF"...HEAD -- \ | |
| 'shared/database/src/schema.ts' \ | |
| 'shared/database/src/migrations/*.sql' \ | |
| > .cache/pr.diff || true | |
| echo "diff_bytes=$(wc -c < .cache/pr.diff)" >> "$GITHUB_OUTPUT" | |
| - name: Generate comment body | |
| id: report | |
| env: | |
| STAGING_DATABASE_URL_RO: ${{ secrets.STAGING_DATABASE_URL_RO }} | |
| STAGING_SCHEMA_NAME: ${{ vars.STAGING_SCHEMA_NAME }} | |
| STAGING_SNAPSHOT_LABEL: ${{ vars.STAGING_SNAPSHOT_LABEL }} | |
| # `postgres` is installed in the isolated dir above; the script | |
| # does a bare `import postgres from 'postgres'` and resolves it | |
| # via NODE_PATH. | |
| NODE_PATH: .cache/pg-client/node_modules | |
| run: | | |
| set -uo pipefail | |
| # The script itself never throws — it always emits a comment-shaped | |
| # markdown blob to stdout, even on internal failures. | |
| if ! node scripts/schema-shape-report.mjs --diff .cache/pr.diff > .cache/comment.md 2> .cache/script.err; then | |
| EXIT_CODE=$? | |
| ERR_TEXT=$(tr '\n' ' ' < .cache/script.err | sed 's/[][`*_]//g' | head -c 300) | |
| cat > .cache/comment.md <<EOF | |
| <!-- wxyc-schema-shape-report --> | |
| ## Schema constraint shape report | |
| _data-shape report errored (exit $EXIT_CODE): ${ERR_TEXT:-no stderr captured}; manual check required_ | |
| EOF | |
| fi | |
| # Always succeed — the comment carries the failure mode in its text. | |
| exit 0 | |
| - name: Find existing comment | |
| id: find-comment | |
| uses: actions/github-script@v9 | |
| with: | |
| script: | | |
| const marker = '<!-- wxyc-schema-shape-report -->'; | |
| const { data: comments } = await github.rest.issues.listComments({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| issue_number: context.issue.number, | |
| per_page: 100, | |
| }); | |
| const existing = comments.find( | |
| (c) => c.user?.type === 'Bot' && c.body && c.body.includes(marker), | |
| ) || comments.find((c) => c.body && c.body.includes(marker)); | |
| return existing ? existing.id : ''; | |
| - name: Post or update comment | |
| uses: actions/github-script@v9 | |
| with: | |
| script: | | |
| const fs = require('fs'); | |
| const body = fs.readFileSync('.cache/comment.md', 'utf8'); | |
| const existingId = ${{ steps.find-comment.outputs.result || 'null' }}; | |
| if (existingId) { | |
| await github.rest.issues.updateComment({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| comment_id: existingId, | |
| body, | |
| }); | |
| } else { | |
| await github.rest.issues.createComment({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| issue_number: context.issue.number, | |
| body, | |
| }); | |
| } |