Skip to content

feat(ci)!: resolve the spec and scripts from the pinned workflow revision - #85

Closed
spydon wants to merge 1 commit into
mainfrom
fix/sync-compliance-stale-spec-ref
Closed

feat(ci)!: resolve the spec and scripts from the pinned workflow revision#85
spydon wants to merge 1 commit into
mainfrom
fix/sync-compliance-stale-spec-ref

Conversation

@spydon

@spydon spydon commented Aug 17, 2026

Copy link
Copy Markdown
Contributor

Callers pin the reusable workflow by SHA, and then the workflow went back out to a branch for everything that actually matters. This makes the pin mean what it looks like it means.

The bug

supabase/sdk was resolved twice per run, and the two resolutions disagreed:

Workflow spec + scripts composite actions
validate-sdk-compliance-{dart,javascript,python,swift}.yml sdk-ref: main @main
sync-sdk-compliance.yml sdk-ref: faba359a (20 July) n/a, inlined

faba359a is the commit that introduced the sync workflow in #65. It reads like a pre-merge testing value that was never switched back.

Consequence one, the visible outage. The sync reads capabilities/ to find IDs an SDK's sdk-compliance.yaml does not mention yet, so a July snapshot resurrects everything renamed since. #74 renamed or split exactly five:

  • auth.sign_in.reset_passwordauth.sign_in.send_password_reset_email
  • realtime.channel.sendrealtime.channel.broadcast
  • storage.file_buckets.list_files_paginated → merged into list_files
  • storage.analytics.iceberg_namespacecreate_namespace / list_namespaces / delete_namespace
  • storage.analytics.iceberg_tablecreate_table / list_tables / load_table / update_table / rename_table / delete_table

This morning's scheduled run added all five back as not_implemented in all three repos that call the workflow, and the validate job in each of those very pull requests rejected them:

Repo Pull request Validate compliance file
supabase-flutter #1726 fail, 5 × unknown feature id
supabase-js #2617 fail, same five
supabase-swift #1234 fail, same five

Unmergeable by construction: each compliance file already carried the new names.

Consequence two, the supply chain hole. The four validate workflows loaded executable code from a branch (sdk-compliance-validate, sdk-compliance-check-setup, sdk-compliance-check-symbols, sdk-compliance-check-drift, all @main), and read the spec and scripts from main as well. Anything landing here reached every SDK's CI on the next run, with no pin to review and nothing to roll back to. It also means a rename in this repo breaks other repos' CI retroactively, which is the same defect as consequence one pointed the other way.

The fix

Resolve everything from github.job_workflow_sha, the commit SHA of the reusable workflow file itself. The caller's existing pin then governs the spec, the scripts and the actions alike, so there is exactly one ref in the system and it cannot skew. No branch is referenced anywhere. sdk-ref survives as an explicit override for pre-merge testing, now defaulting to "" and coalescing at the step, since input defaults are evaluated before the job context is populated.

uses: accepts no expressions, so the composite actions cannot be referenced at that SHA directly. The spec is checked out first and they are loaded from it by path:

- name: Checkout capability spec
  uses: actions/checkout@df4cb1c... # v6.0.3
  with:
    repository: supabase/sdk
    ref: ${{ inputs.sdk-ref || github.job_workflow_sha }}
    path: _sdk-spec

- uses: ./_sdk-spec/.github/actions/sdk-compliance-validate

Which is the pattern the docs describe for a reusable workflow that needs files co-located with its own definition.

That hoists the checkouts up out of sdk-compliance-validate and sdk-compliance-check-setup, which lose their duplicated spec checkout and their now-unused sdk-ref input. Nothing outside the four reusable workflows references these actions, so their contract change is contained.

Ordering became load-bearing in the process. actions/checkout cleans the directory it manages, so where the calling repo occupies the workspace root it has to be checked out before _sdk-spec or it deletes it; in the check jobs nothing takes the root, so the spec goes first because the actions are loaded from it. Both call sites carry a comment saying so.

The base-branch: main default in the sync workflow is untouched. That one is the caller's own branch to open a pull request against, not a ref anything is loaded from.

Consumer impact

The spec becomes pinned rather than live, which is the point, but it is a behavior change worth stating plainly:

  • A rename in this repo can no longer break another repo's CI retroactively. It surfaces when the pin is bumped, in that pull request, atomically with the compliance file update it requires.
  • New capability IDs arrive when the pin is bumped rather than the moment they merge here. supabase-flutter, supabase-js and supabase-swift all already run Dependabot on github-actions, so the bump arrives as a reviewable pull request without anyone doing anything.
  • The sync therefore proposes IDs up to the pinned release, not up to main. Bump, then sync.

Marked feat! rather than fix so the changelog signals to the other SDK teams that the pinning semantics changed, and so the minor bump is a deliberate thing to read about.

Verification

Still to do before merge, since none of the above exercises a real cross-repo call: point a throwaway supabase-flutter branch at this branch and confirm both jobs go green with _sdk-spec resolved from job_workflow_sha.

…iles

The sync workflow's sdk-ref input defaulted to faba359, the commit that
introduced the workflow back in #65. That looks like a pre-merge testing
value that was never switched back, and it left the sync reading a July
snapshot of capabilities/ while every validate workflow reads main.

Any capability ID renamed since then therefore came back from the dead.
#74 renamed or split five of them, so the last sync run opened
supabase/supabase-flutter#1726 adding auth.sign_in.reset_password,
realtime.channel.send, storage.file_buckets.list_files_paginated,
storage.analytics.iceberg_namespace and storage.analytics.iceberg_table
as not_implemented, and the validate job in the same pull request
rejected all five as unknown feature IDs. Every SDK repo calling this
workflow gets that same unmergeable pull request.

Default to main and reuse the wording the validate workflows already
have, so the two halves of the system agree on which spec is canonical.
@spydon
spydon requested review from a team as code owners August 17, 2026 09:04
@coderabbitai

coderabbitai Bot commented Aug 17, 2026

Copy link
Copy Markdown

Important

Review available on request

  • 🔍 Trigger review

Reviews should be triggered manually for repositories with fewer than 10 stars. Select Trigger review above or comment @coderabbitai review to review the latest changes. For a full review, comment @coderabbitai full review.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 3f7d2d78-8569-4908-8a85-faf02e21a8d8


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@spydon spydon closed this Aug 17, 2026
@spydon spydon changed the title fix(ci): read the capability spec from main when syncing compliance files feat(ci)!: resolve the spec and scripts from the pinned workflow revision Aug 17, 2026
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