Skip to content

chore(ci): automate migration apply and type sync on schema change#225

Open
glassBead-tc wants to merge 2 commits intomainfrom
feat/schema-sync
Open

chore(ci): automate migration apply and type sync on schema change#225
glassBead-tc wants to merge 2 commits intomainfrom
feat/schema-sync

Conversation

@glassBead-tc
Copy link
Copy Markdown
Member

On any push to main that touches supabase/migrations/:

  1. Applies pending migrations to remote Supabase via supabase db push
  2. Regenerates src/database.types.ts
  3. Commits updated types back to main ([skip ci] prevents retrigger)
  4. Fires repository_dispatch to thoughtbox-web-two with the types URL

Secrets required in repo settings before this does anything useful:

  • SUPABASE_ACCESS_TOKEN — Supabase dashboard → Account → Access tokens
  • SUPABASE_DB_PASSWORD — database password for the project
  • GH_PAT — PAT with repo scope on Kastalien-Research/thoughtbox-web-two

Web app side: needs a workflow that handles the schema-updated dispatch event.

@supabase
Copy link
Copy Markdown

supabase bot commented Apr 2, 2026

This pull request has been ignored for the connected project akjccuoncxlvrrtkvtno because there are no changes detected in supabase directory. You can change this behaviour in Project Integrations Settings ↗︎.


Preview Branches by Supabase.
Learn more about Supabase Branching ↗︎.

@chatgpt-codex-connector
Copy link
Copy Markdown

Codex usage limits have been reached for code reviews. Please check with the admins of this repo to increase the limits by adding credits.
Credits must be used to enable repository wide code reviews.

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps bot commented Apr 2, 2026

Greptile Summary

This PR adds a new schema-sync.yml workflow that applies pending Supabase migrations to the remote project, regenerates src/database.types.ts, commits the result back to main, and fires a repository_dispatch to thoughtbox-web-two.

  • P1 — stale types_url: ${{ github.sha }} is captured at workflow start and never updated after the bot commit. When types change, the bot pushes a new commit, but the downstream types_url still points to the pre-update SHA — so thoughtbox-web-two fetches the old types. Capture $(git rev-parse HEAD) after the push and propagate that SHA instead.

Confidence Score: 4/5

Not safe to merge until the types_url SHA bug is fixed — the downstream web app will receive a URL pointing to stale types whenever schema changes.

One P1 logic defect: the types_url delivered in the repository_dispatch always references the triggering commit SHA, not the new bot-commit SHA that actually contains the regenerated types. The two P2 findings (unpinned action, unconditional notify) are non-blocking quality improvements.

.github/workflows/schema-sync.yml — specifically the Notify step's client_payload and the Commit step's output handling.

Important Files Changed

Filename Overview
.github/workflows/schema-sync.yml New CI workflow that applies Supabase migrations, regenerates TypeScript types, and notifies a downstream repo — contains a P1 bug where types_url always references the triggering commit SHA rather than the new bot-commit SHA, delivering stale types to the web app.

Sequence Diagram

sequenceDiagram
    participant Dev as Developer
    participant GH as GitHub (main)
    participant Runner as GH Actions Runner
    participant Supa as Supabase Remote
    participant Web as thoughtbox-web-two

    Dev->>GH: push (supabase/migrations/**)
    GH->>Runner: trigger schema-sync workflow
    Runner->>Supa: supabase db push (apply migrations)
    Supa-->>Runner: ok
    Runner->>Supa: supabase gen types typescript
    Supa-->>Runner: updated database.types.ts
    Runner->>Runner: git diff --cached
    alt types changed
        Runner->>GH: git push (new bot commit @ HEAD+1)
    else types unchanged
        Runner->>Runner: skip commit
    end
    Runner->>Web: POST /repos/.../dispatches event_type=schema-updated types_url=raw.github.com/.../github.sha
    Note over Runner,Web: BUG: github.sha = original push SHA, not the new bot-commit SHA
Loading
Prompt To Fix All With AI
This is a comment left during a code review.
Path: .github/workflows/schema-sync.yml
Line: 68-69

Comment:
**`types_url` SHA points to the pre-update commit**

`${{ github.sha }}` is the SHA of the push that triggered the workflow — set before the bot commit in step 4 runs. When types change, the bot creates a *new* commit with the updated `src/database.types.ts`, but `github.sha` never updates. The raw.githubusercontent.com URL therefore resolves to the file at the *old* commit, returning stale types to `thoughtbox-web-two`.

Fix by capturing the new HEAD SHA after the push and using it in the payload:

```
      - name: Commit updated types
        id: commit-types
        run: |
          git config user.name  "github-actions[bot]"
          git config user.email "github-actions[bot]@users.noreply.github.com"
          git add src/database.types.ts
          if git diff --cached --quiet; then
            echo "Types unchanged — nothing to commit"
            echo "types_sha=${{ github.sha }}" >> "$GITHUB_OUTPUT"
          else
            git commit -m "chore(schema): regenerate database.types.ts [skip ci]"
            git push
            echo "types_sha=$(git rev-parse HEAD)" >> "$GITHUB_OUTPUT"
          fi
```

Then reference `${{ steps.commit-types.outputs.types_sha }}` in the `types_url` and `thoughtbox_sha` fields.

How can I resolve this? If you propose a fix, please make it concise.

---

This is a comment left during a code review.
Path: .github/workflows/schema-sync.yml
Line: 23

Comment:
**`supabase/setup-cli` not pinned to a commit SHA**

`actions/checkout` is correctly pinned to a full commit SHA, but `supabase/setup-cli@v1` uses a floating tag. A tag can be force-pushed to a different commit, creating a supply-chain attack surface. Pin it to a SHA for the same level of protection:

```suggestion
        uses: supabase/setup-cli@78e29c45fddf9e8b11a59854c30cbc2e2b87d0c6 # v1
```

(Verify the current SHA for the `v1` tag in the [supabase/setup-cli releases](https://github.com/supabase/setup-cli/releases) before committing.)

How can I resolve this? If you propose a fix, please make it concise.

---

This is a comment left during a code review.
Path: .github/workflows/schema-sync.yml
Line: 58-71

Comment:
**Notify fires unconditionally, even when types are unchanged**

When migrations apply cleanly but produce no schema diff, the "Commit updated types" step logs "Types unchanged — nothing to commit" and skips the push, but the `repository_dispatch` to `thoughtbox-web-two` fires regardless. This will trigger unnecessary downstream builds/deploys on every migration-only push where types don't change.

Export a flag from the commit step (e.g. `echo "changed=false" >> "$GITHUB_OUTPUT"`) and add `if: steps.commit-types.outputs.changed == 'true'` to the Notify step.

How can I resolve this? If you propose a fix, please make it concise.

Reviews (1): Last reviewed commit: "chore(ci): automate migration apply and ..." | Re-trigger Greptile

Comment on lines +68 to +69
"thoughtbox_sha": "${{ github.sha }}",
"types_url": "https://raw.githubusercontent.com/Kastalien-Research/thoughtbox/${{ github.sha }}/src/database.types.ts"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 types_url SHA points to the pre-update commit

${{ github.sha }} is the SHA of the push that triggered the workflow — set before the bot commit in step 4 runs. When types change, the bot creates a new commit with the updated src/database.types.ts, but github.sha never updates. The raw.githubusercontent.com URL therefore resolves to the file at the old commit, returning stale types to thoughtbox-web-two.

Fix by capturing the new HEAD SHA after the push and using it in the payload:

      - name: Commit updated types
        id: commit-types
        run: |
          git config user.name  "github-actions[bot]"
          git config user.email "github-actions[bot]@users.noreply.github.com"
          git add src/database.types.ts
          if git diff --cached --quiet; then
            echo "Types unchanged — nothing to commit"
            echo "types_sha=${{ github.sha }}" >> "$GITHUB_OUTPUT"
          else
            git commit -m "chore(schema): regenerate database.types.ts [skip ci]"
            git push
            echo "types_sha=$(git rev-parse HEAD)" >> "$GITHUB_OUTPUT"
          fi

Then reference ${{ steps.commit-types.outputs.types_sha }} in the types_url and thoughtbox_sha fields.

Prompt To Fix With AI
This is a comment left during a code review.
Path: .github/workflows/schema-sync.yml
Line: 68-69

Comment:
**`types_url` SHA points to the pre-update commit**

`${{ github.sha }}` is the SHA of the push that triggered the workflow — set before the bot commit in step 4 runs. When types change, the bot creates a *new* commit with the updated `src/database.types.ts`, but `github.sha` never updates. The raw.githubusercontent.com URL therefore resolves to the file at the *old* commit, returning stale types to `thoughtbox-web-two`.

Fix by capturing the new HEAD SHA after the push and using it in the payload:

```
      - name: Commit updated types
        id: commit-types
        run: |
          git config user.name  "github-actions[bot]"
          git config user.email "github-actions[bot]@users.noreply.github.com"
          git add src/database.types.ts
          if git diff --cached --quiet; then
            echo "Types unchanged — nothing to commit"
            echo "types_sha=${{ github.sha }}" >> "$GITHUB_OUTPUT"
          else
            git commit -m "chore(schema): regenerate database.types.ts [skip ci]"
            git push
            echo "types_sha=$(git rev-parse HEAD)" >> "$GITHUB_OUTPUT"
          fi
```

Then reference `${{ steps.commit-types.outputs.types_sha }}` in the `types_url` and `thoughtbox_sha` fields.

How can I resolve this? If you propose a fix, please make it concise.

token: ${{ secrets.GITHUB_TOKEN }}

- name: Setup Supabase CLI
uses: supabase/setup-cli@v1
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 supabase/setup-cli not pinned to a commit SHA

actions/checkout is correctly pinned to a full commit SHA, but supabase/setup-cli@v1 uses a floating tag. A tag can be force-pushed to a different commit, creating a supply-chain attack surface. Pin it to a SHA for the same level of protection:

Suggested change
uses: supabase/setup-cli@v1
uses: supabase/setup-cli@78e29c45fddf9e8b11a59854c30cbc2e2b87d0c6 # v1

(Verify the current SHA for the v1 tag in the supabase/setup-cli releases before committing.)

Prompt To Fix With AI
This is a comment left during a code review.
Path: .github/workflows/schema-sync.yml
Line: 23

Comment:
**`supabase/setup-cli` not pinned to a commit SHA**

`actions/checkout` is correctly pinned to a full commit SHA, but `supabase/setup-cli@v1` uses a floating tag. A tag can be force-pushed to a different commit, creating a supply-chain attack surface. Pin it to a SHA for the same level of protection:

```suggestion
        uses: supabase/setup-cli@78e29c45fddf9e8b11a59854c30cbc2e2b87d0c6 # v1
```

(Verify the current SHA for the `v1` tag in the [supabase/setup-cli releases](https://github.com/supabase/setup-cli/releases) before committing.)

How can I resolve this? If you propose a fix, please make it concise.

Comment on lines +58 to +71
- name: Notify web app
run: |
curl -s -X POST \
-H "Authorization: Bearer ${{ secrets.GH_PAT }}" \
-H "Accept: application/vnd.github+json" \
-H "X-GitHub-Api-Version: 2022-11-28" \
https://api.github.com/repos/Kastalien-Research/thoughtbox-web-two/dispatches \
-d '{
"event_type": "schema-updated",
"client_payload": {
"thoughtbox_sha": "${{ github.sha }}",
"types_url": "https://raw.githubusercontent.com/Kastalien-Research/thoughtbox/${{ github.sha }}/src/database.types.ts"
}
}'
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Notify fires unconditionally, even when types are unchanged

When migrations apply cleanly but produce no schema diff, the "Commit updated types" step logs "Types unchanged — nothing to commit" and skips the push, but the repository_dispatch to thoughtbox-web-two fires regardless. This will trigger unnecessary downstream builds/deploys on every migration-only push where types don't change.

Export a flag from the commit step (e.g. echo "changed=false" >> "$GITHUB_OUTPUT") and add if: steps.commit-types.outputs.changed == 'true' to the Notify step.

Prompt To Fix With AI
This is a comment left during a code review.
Path: .github/workflows/schema-sync.yml
Line: 58-71

Comment:
**Notify fires unconditionally, even when types are unchanged**

When migrations apply cleanly but produce no schema diff, the "Commit updated types" step logs "Types unchanged — nothing to commit" and skips the push, but the `repository_dispatch` to `thoughtbox-web-two` fires regardless. This will trigger unnecessary downstream builds/deploys on every migration-only push where types don't change.

Export a flag from the commit step (e.g. `echo "changed=false" >> "$GITHUB_OUTPUT"`) and add `if: steps.commit-types.outputs.changed == 'true'` to the Notify step.

How can I resolve this? If you propose a fix, please make it concise.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant