diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 318aba6..883e809 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -190,6 +190,30 @@ jobs: if: ${{ steps.release.outputs.release_created }} run: npm publish --access public --ignore-scripts --tag ${{ steps.release-target.outputs.npm_tag }} + - name: Sync quantex alias package + if: ${{ steps.release.outputs.release_created }} + env: + QUANTEX_SYNC_TOKEN: ${{ secrets.QUANTEX_SYNC_TOKEN }} + RELEASE_TAG: ${{ steps.release.outputs.tag_name }} + run: | + version="${RELEASE_TAG#v}" + + if [[ ! "${version}" =~ ^[0-9]+\.[0-9]+\.[0-9]+(-[0-9A-Za-z.-]+)?(\+[0-9A-Za-z.-]+)?$ ]]; then + echo "Release tag '${RELEASE_TAG}' did not resolve to a semver version without a leading v." >&2 + exit 1 + fi + + npm_tag="latest" + if [[ "${version}" == *-* ]]; then + npm_tag="next" + fi + + curl --fail-with-body -X POST \ + -H "Authorization: Bearer ${QUANTEX_SYNC_TOKEN}" \ + -H "Accept: application/vnd.github+json" \ + https://api.github.com/repos/Drswith/quantex/dispatches \ + -d "{\"event_type\":\"sync-quantex-cli-release\",\"client_payload\":{\"version\":\"${version}\",\"npm_tag\":\"${npm_tag}\"}}" + - name: Upload release artifacts if: ${{ steps.release.outputs.release_created }} env: diff --git a/openspec/changes/sync-alias-package-after-release/.openspec.yaml b/openspec/changes/sync-alias-package-after-release/.openspec.yaml new file mode 100644 index 0000000..40cc12f --- /dev/null +++ b/openspec/changes/sync-alias-package-after-release/.openspec.yaml @@ -0,0 +1,2 @@ +schema: spec-driven +created: 2026-05-12 diff --git a/openspec/changes/sync-alias-package-after-release/design.md b/openspec/changes/sync-alias-package-after-release/design.md new file mode 100644 index 0000000..02dc14f --- /dev/null +++ b/openspec/changes/sync-alias-package-after-release/design.md @@ -0,0 +1,30 @@ +## Context + +The `Release` workflow publishes `quantex-cli` to npm from protected-branch release commits after release-please creates the GitHub Release, builds artifacts, and validates the package. The `quantex` alias package is maintained in `Drswith/quantex` and exposes its own `repository_dispatch` entry point for synchronized publishing. + +## Goals / Non-Goals + +**Goals:** + +- Notify `Drswith/quantex` only after the `quantex-cli` npm publish step succeeds. +- Send the released `quantex-cli` version without a leading `v`. +- Send `latest` for stable alias publishes and `next` for prerelease alias publishes. +- Fail the release workflow if the dispatch API call is rejected, so maintainers see alias synchronization problems. + +**Non-Goals:** + +- Do not publish the `quantex` alias package from this repository. +- Do not add a repository-local workflow wrapper for dispatching. +- Do not change the existing `quantex-cli` npm publish tag behavior. + +## Decisions + +- Place the dispatch step immediately after `Publish npm package`. GitHub Actions step ordering already guarantees it only runs when prior release validation and npm publish succeeded. +- Derive `version` from `steps.release.outputs.tag_name` by removing a leading `v`, matching the tag created by release-please while satisfying the alias repository payload contract. +- Derive the alias payload tag from the semver version: versions containing `-` are prereleases and dispatch `npm_tag=next`; all others dispatch `npm_tag=latest`. +- Use `curl --fail-with-body` with `QUANTEX_SYNC_TOKEN` so API failures stop the release job with visible response details. + +## Risks / Trade-offs + +- Missing or under-permissioned `QUANTEX_SYNC_TOKEN` -> the primary `quantex-cli` package will already be published, but the workflow will fail before artifact upload and require maintainer intervention. +- GitHub API outage after npm publish -> the alias sync notification can fail independently of primary publish; rerunning the release workflow should retry the dispatch for the same release target. diff --git a/openspec/changes/sync-alias-package-after-release/proposal.md b/openspec/changes/sync-alias-package-after-release/proposal.md new file mode 100644 index 0000000..384c247 --- /dev/null +++ b/openspec/changes/sync-alias-package-after-release/proposal.md @@ -0,0 +1,27 @@ +## Why + +Quantex publishes `quantex-cli` as the primary npm package while `quantex` is an alias package maintained in a separate repository. The release workflow needs a durable handoff so a successful `quantex-cli` publish can trigger the alias repository to publish the same version. + +## What Changes + +- Add a post-npm-publish release workflow step that sends `repository_dispatch` to `Drswith/quantex`. +- Include the published `quantex-cli` semver version without a leading `v` in the dispatch payload. +- Send `npm_tag=latest` for stable releases and `npm_tag=next` for prereleases. +- Keep alias package publishing owned by the `quantex` repository; `quantex-cli` only sends the notification. +- Use the `QUANTEX_SYNC_TOKEN` secret for the GitHub API call. + +## Capabilities + +### New Capabilities + +None. + +### Modified Capabilities + +- `release-workflow`: the publish phase must notify the alias package repository after `quantex-cli` npm publishing succeeds. + +## Impact + +- Affected workflow: `.github/workflows/release.yml`. +- Affected docs/specs: `openspec/specs/release-workflow/spec.md` via this change delta. +- External dependency: repository secret `QUANTEX_SYNC_TOKEN` with sufficient permission to dispatch events to `Drswith/quantex`. diff --git a/openspec/changes/sync-alias-package-after-release/specs/release-workflow/spec.md b/openspec/changes/sync-alias-package-after-release/specs/release-workflow/spec.md new file mode 100644 index 0000000..2792ce7 --- /dev/null +++ b/openspec/changes/sync-alias-package-after-release/specs/release-workflow/spec.md @@ -0,0 +1,25 @@ +## ADDED Requirements + +### Requirement: Release Workflow Dispatches Alias Package Sync After Npm Publish + +The Release workflow SHALL notify the `Drswith/quantex` alias package repository after `quantex-cli` is successfully published to npm, and it MUST NOT publish the alias package directly from the `quantex-cli` repository. + +#### Scenario: Stable release dispatches latest alias sync + +- **WHEN** the Release workflow successfully publishes `quantex-cli` version `0.18.0` to npm +- **THEN** it MUST send a `repository_dispatch` event to `Drswith/quantex` +- **AND** the event type MUST be `sync-quantex-cli-release` +- **AND** the client payload version MUST be `0.18.0` +- **AND** the client payload `npm_tag` MUST be `latest` + +#### Scenario: Prerelease dispatches next alias sync + +- **WHEN** the Release workflow successfully publishes `quantex-cli` version `0.18.0-beta.1` to npm +- **THEN** it MUST send a `repository_dispatch` event to `Drswith/quantex` +- **AND** the client payload version MUST be `0.18.0-beta.1` +- **AND** the client payload `npm_tag` MUST be `next` + +#### Scenario: Npm publish does not succeed + +- **WHEN** the Release workflow does not successfully publish `quantex-cli` to npm +- **THEN** it MUST NOT send the alias package synchronization dispatch diff --git a/openspec/changes/sync-alias-package-after-release/tasks.md b/openspec/changes/sync-alias-package-after-release/tasks.md new file mode 100644 index 0000000..b10e677 --- /dev/null +++ b/openspec/changes/sync-alias-package-after-release/tasks.md @@ -0,0 +1,10 @@ +## 1. Release Workflow + +- [x] 1.1 Add a post-npm-publish `repository_dispatch` step in `.github/workflows/release.yml`. +- [x] 1.2 Derive the alias dispatch payload version without a leading `v` and map prerelease versions to `npm_tag=next`. + +## 2. Validation + +- [x] 2.1 Run `bun run lint`, `bun run format:check`, `bun run typecheck`, and `bun run test`. +- [x] 2.2 Run `bun run openspec:validate`. +- [x] 2.3 Confirm git and OpenSpec closure state for handoff.