-
Notifications
You must be signed in to change notification settings - Fork 1
Enrich spec-changes manifest + changelog preview for dashboard #39
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weβll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
3 commits
Select commit
Hold shift + click to select a range
c311fe8
feat: enrich spec-changes manifest + changelog preview for the dashboard
gjtorikian fb71f55
fix: resolve staged scopes via mountRules + report the rendered base SHA
gjtorikian ac55642
fix: include mountOn-remounted scopes in changelog preview
gjtorikian File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,96 @@ | ||
| name: Changelog preview | ||
|
|
||
| # Dispatched on-demand by the SDK bot when an operator clicks "Generate staged". | ||
| # Renders the changelog (with the canonical sdk-release-metadata logic) scoped to | ||
| # the staged service set, then POSTs it back to the bot keyed by preview_id. The | ||
| # bot polls its changelog_previews table and shows the editable result. No PRs, | ||
| # no SDK checkout β pure analysis. | ||
|
|
||
| on: | ||
| workflow_dispatch: | ||
| inputs: | ||
| services: | ||
| description: 'Comma-separated post-mount service names to scope the changelog to' | ||
| required: false | ||
| type: string | ||
| preview_id: | ||
| description: 'Id the bot keys the result on' | ||
| required: true | ||
| type: string | ||
| base_ref: | ||
| description: 'Spec ref to render the changelog for' | ||
| required: false | ||
| default: main | ||
| type: string | ||
|
|
||
| concurrency: | ||
| # A re-dispatch of the same preview supersedes the prior one. | ||
| group: changelog-preview-${{ github.event.inputs.preview_id }} | ||
| cancel-in-progress: true | ||
|
|
||
| env: | ||
| SDK_BOT_URL: https://sdk-automation-bot.workos.tools | ||
|
|
||
| jobs: | ||
| preview: | ||
| runs-on: ubuntu-latest | ||
| permissions: | ||
| contents: read | ||
| steps: | ||
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | ||
| with: | ||
| fetch-depth: 0 | ||
|
|
||
| - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 | ||
| with: | ||
| node-version: '24' | ||
| cache: 'npm' | ||
| cache-dependency-path: package-lock.json | ||
|
|
||
| - name: Install dependencies | ||
| run: npm ci | ||
|
|
||
| - name: Build policy module | ||
| # render-changelog-preview.mjs reads mountRules from dist/policy.mjs to | ||
| # resolve staged post-mount service names to changelog scopes (e.g. | ||
| # ClientApi -> client). dist/ is git-ignored and not produced by npm ci. | ||
| run: npm run build:policy | ||
|
|
||
| - name: Render + push the changelog preview | ||
| env: | ||
| SPEC_CHANGES_SECRET: ${{ secrets.SPEC_CHANGES_SECRET }} | ||
| PREVIEW_ID: ${{ inputs.preview_id }} | ||
| SERVICES: ${{ inputs.services }} | ||
| BASE_REF: ${{ inputs.base_ref }} | ||
| run: | | ||
| set -uo pipefail | ||
| # Report the SHA of the ref we actually render the changelog for, so the | ||
| # bot's "spec advanced since preview" check compares like-for-like. | ||
| BASE_SHA=$(git rev-parse "$BASE_REF") | ||
|
|
||
| post() { # $1 = json file | ||
| SIG="sha256=$(openssl dgst -sha256 -hmac "$SPEC_CHANGES_SECRET" "$1" | sed 's/^.*= //')" | ||
| for attempt in 1 2 3; do | ||
| if curl -sS -X POST "$SDK_BOT_URL/internal/changelog-preview" \ | ||
| -H "Content-Type: application/json" \ | ||
| -H "X-Spec-Changes-Signature: $SIG" \ | ||
| --data-binary @"$1" \ | ||
| --fail-with-body; then | ||
| echo ""; return 0 | ||
| fi | ||
| echo "push attempt ${attempt} failed; retrying in 5s..."; sleep 5 | ||
| done | ||
| echo "::error::could not push changelog preview after 3 attempts"; return 1 | ||
| } | ||
|
|
||
| # sdk-release-metadata --spec-commit runs oagen parse/diff internally | ||
| # (this spec commit vs the previous spec-changing commit) and emits the | ||
| # changelog entries; render-changelog-preview scopes + renders them. | ||
| if node scripts/sdk-release-metadata.mjs --spec-commit "$BASE_REF" --format json --output /tmp/entries.json \ | ||
| && node scripts/render-changelog-preview.mjs --entries /tmp/entries.json --services "$SERVICES" > /tmp/changelog.md; then | ||
| jq -Rs --arg id "$PREVIEW_ID" --arg sha "$BASE_SHA" \ | ||
| '{previewId:$id, status:"ready", markdown:., baseSha:$sha}' /tmp/changelog.md > /tmp/preview.json | ||
| else | ||
| jq -n --arg id "$PREVIEW_ID" '{previewId:$id, status:"failed", error:"changelog analysis failed"}' > /tmp/preview.json | ||
| fi | ||
| post /tmp/preview.json | ||
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
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
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
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,61 @@ | ||
| import assert from 'node:assert/strict'; | ||
| import test from 'node:test'; | ||
|
|
||
| import { scopesForStaged } from '../render-changelog-preview.mjs'; | ||
|
|
||
| // Representative slice of the real mount-rules (Client mounts to ClientApi). | ||
| const MOUNT_RULES = { | ||
| Client: 'ClientApi', | ||
| Permissions: 'Authorization', | ||
| Connections: 'SSO', | ||
| UserManagementUsers: 'UserManagement', | ||
| UserManagementDataProviders: 'Pipes', | ||
| }; | ||
|
|
||
| // Regression: staging the post-mount ClientApi must include the `client` scope | ||
| // the changelog entries actually use β publicScopeFromService('ClientApi') is | ||
| // 'client_api', so without the mount-aware union a ClientApi-only preview would | ||
| // filter out every (client-scoped) entry and render blank. | ||
| test('staged ClientApi resolves to the client scope, not just client_api', () => { | ||
| const scopes = scopesForStaged(['ClientApi'], MOUNT_RULES); | ||
| assert.ok(scopes.has('client'), 'includes client (from the Client -> ClientApi mount)'); | ||
| }); | ||
|
|
||
| test('a directly-named service resolves to its own scope', () => { | ||
| const scopes = scopesForStaged(['SSO'], MOUNT_RULES); | ||
| assert.ok(scopes.has('sso')); | ||
| }); | ||
|
|
||
| test('a post-mount parent picks up the scopes of its mounted sub-services', () => { | ||
| // UserManagementUsers + UserManagementDataProviders mount to UserManagement / | ||
| // Pipes; staging UserManagement should at least include user_management. | ||
| const scopes = scopesForStaged(['UserManagement'], MOUNT_RULES); | ||
| assert.ok(scopes.has('user_management')); | ||
| }); | ||
|
|
||
| test('no mountRules β still resolves the post-mount name to its own scope', () => { | ||
| const scopes = scopesForStaged(['Vault'], {}); | ||
| assert.ok(scopes.has('vault')); | ||
| }); | ||
|
|
||
| // Representative slice of the real operation hints: the audit-log-retention ops | ||
| // live under /organizations (changelog scope `organizations`) but mount on | ||
| // AuditLogs via per-operation `mountOn`. | ||
| const OPERATION_HINTS = { | ||
| 'GET /organizations/{id}/audit_logs_retention': { name: 'get_organization_audit_logs_retention', mountOn: 'AuditLogs' }, | ||
| 'PUT /organizations/{id}/audit_logs_retention': { mountOn: 'AuditLogs' }, | ||
| }; | ||
|
|
||
| // Regression: staging AuditLogs must include the `organizations` scope of the | ||
| // retention ops mounted onto it via `mountOn` β without the hint-aware union an | ||
| // AuditLogs-only preview would drop those staged entries and render blank. | ||
| test('staged AuditLogs picks up the organizations scope of mountOn-remounted ops', () => { | ||
| const scopes = scopesForStaged(['AuditLogs'], MOUNT_RULES, OPERATION_HINTS); | ||
| assert.ok(scopes.has('audit_logs'), 'includes its own scope'); | ||
| assert.ok(scopes.has('organizations'), 'includes the source scope of the remounted ops'); | ||
| }); | ||
|
|
||
| test('mountOn hints for non-staged targets do not leak scopes', () => { | ||
| const scopes = scopesForStaged(['SSO'], MOUNT_RULES, OPERATION_HINTS); | ||
| assert.ok(!scopes.has('organizations'), 'AuditLogs not staged β no organizations scope'); | ||
| }); |
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
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.