chore(sdk): track dxos/main@0132aab (#34) #37
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: Release | |
| # Changesets-driven release, trunk-based on `main` — there is no long-lived release branch, matching | |
| # dxos/dxos. Every push to `main`: | |
| # - with changesets pending, opens/updates a "Version Packages" PR (bumps each changed plugin's | |
| # version + CHANGELOG). Merging that PR is the human gate; | |
| # - with none left, publishes the bumped plugins to npm (which also tags each version) and then to | |
| # the AT Protocol registry via `dx registry publish`. | |
| # | |
| # Dispatching with `registry_only` skips npm and republishes the current versions to the registry, so | |
| # a registry failure can be retried without a version bump — npm is append-only, so a plain re-run | |
| # would find its half already done and never reach the registry. | |
| # | |
| # Plugins carry independent version lines (`fixed: []`), but share one Version Packages PR, so a | |
| # release ships whatever accumulated since the last one — independent numbers, coupled timing. | |
| # | |
| # npm auth is a trusted publisher (OIDC), not a token: this filename is load-bearing, because each | |
| # plugin's trusted publisher on npmjs.com names `release.yml`, and publishing from a workflow with any | |
| # other filename fails OIDC. A plugin npm has never seen has no trusted publisher yet, so it stays | |
| # `private: true` until someone publishes it once by hand and configures one — enforced in CI by | |
| # `scripts/check-packages-published.mjs`. | |
| on: | |
| push: | |
| branches: [main] | |
| workflow_dispatch: | |
| inputs: | |
| registry_only: | |
| description: 'Republish current versions to the registry only, skipping npm. Retries a failed registry publish.' | |
| type: boolean | |
| default: false | |
| cli_package: | |
| description: 'npm spec for the dx CLI, overriding the pinned default — e.g. a pkg.pr.new URL for a branch build.' | |
| required: false | |
| permissions: | |
| contents: write | |
| pull-requests: write | |
| id-token: write # npm trusted-publisher OIDC + provenance. | |
| jobs: | |
| release: | |
| runs-on: ubuntu-latest | |
| env: | |
| # Exposed so a step condition can branch on token presence: secrets are not allowed in `if:`. | |
| GH_DXOS_BOT_PAT: ${{ secrets.GH_DXOS_BOT_PAT }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| # changesets/action pushes over a `~/.netrc` it writes from `github-token`, and a persisted | |
| # checkout credential outranks netrc (`http.extraheader` is an explicit Authorization | |
| # header), which would silently put the Version PR's commits back on GITHUB_TOKEN. | |
| persist-credentials: false | |
| - name: Release guard — never publish against an unreleased SDK | |
| # Matches quoted @dxos/* entry values only, so the guard neither trips on the explanatory | |
| # pkg.pr.new mentions in the file header nor on a prerelease pin in the external catalog, | |
| # and does not go blind once the catalog outgrows a fixed line window. | |
| run: | | |
| if grep -qE "^[[:space:]]+'@dxos/[^']+':[[:space:]]*'[^']*pkg\.pr\.new" pnpm-workspace.yaml; then | |
| echo "::error::Refusing to release: the dxos catalog points at a pkg.pr.new pin. Run the SDK npm release workflow first (see RELEASING.md)." | |
| exit 1 | |
| fi | |
| if grep -qE "^[[:space:]]+'@dxos/[^']+':[[:space:]]*'[^']*[0-9]+\.[0-9]+\.[0-9]+-" pnpm-workspace.yaml; then | |
| echo "::error::Refusing to release: the dxos catalog points at a prerelease version. Run the SDK npm release workflow first (see RELEASING.md)." | |
| exit 1 | |
| fi | |
| - uses: ./.github/actions/setup | |
| # `files` ships dist/, so the library has to exist before changesets packs the tarball. The | |
| # registry bundle is not built here — `dx registry publish` runs the `buildCommand` declared | |
| # in each plugin's dx.config.ts itself. | |
| - run: moon run :build | |
| - name: Warn when the bot PAT is missing | |
| if: ${{ env.GH_DXOS_BOT_PAT == '' }} | |
| run: | | |
| echo "::warning::GH_DXOS_BOT_PAT is not set; the Version Packages PR is owned by" \ | |
| "github-actions[bot], so its checks are parked in action_required until approved by hand." \ | |
| "See RELEASING.md." | |
| # `changeset publish` pushes to npm and tags each released version; `publishedPackages` then | |
| # reports exactly what this run released, which drives the registry publish below. | |
| - id: changesets | |
| if: ${{ !inputs.registry_only }} | |
| uses: changesets/action@v1 | |
| with: | |
| # dxos-bot's PAT, not GITHUB_TOKEN: GitHub's recursion guard parks every `pull_request` run | |
| # a GITHUB_TOKEN update triggers in `action_required`, so a GITHUB_TOKEN-owned Version PR | |
| # reports zero check runs until a human approves each one by hand. The action reads | |
| # `process.env.GITHUB_TOKEN` ahead of this input, so that env var must stay unset here. | |
| github-token: ${{ secrets.GH_DXOS_BOT_PAT || secrets.GITHUB_TOKEN }} | |
| version: pnpm version-packages | |
| publish: pnpm exec changeset publish | |
| env: | |
| NPM_CONFIG_PROVENANCE: 'true' # provenance via OIDC; trusted publisher means no NPM_TOKEN. | |
| # npm is the library channel; the registry is what Composer installs from. Both ship the same | |
| # version, from different build outputs — dist/ for npm, out/ for the registry. | |
| # Runs on a `registry_only` dispatch even though nothing was published in that run: npm is | |
| # append-only, so once a version is up the release cannot be replayed to reach the registry | |
| # half, and this is the half that talks to two external services. | |
| - name: Publish released plugins to the registry | |
| if: ${{ inputs.registry_only || steps.changesets.outputs.published == 'true' }} | |
| env: | |
| ALL: ${{ inputs.registry_only }} | |
| # Pinned to a pkg.pr.new preview: npm's @dxos/cli@0.10.0 cannot read a dx.config.ts from a | |
| # plugin directory (fixed in dxos/dxos#12514) and lacks DX_HUB_API_KEY upload auth | |
| # (dxos/dxos#12528). Override with the DX_CLI_PACKAGE repo variable, and drop the default | |
| # once a working CLI is on npm. Installing the single linux-x64 package rather than the | |
| # launcher avoids fetching all five platforms. | |
| DX_CLI_PACKAGE: ${{ inputs.cli_package || vars.DX_CLI_PACKAGE || 'https://pkg.pr.new/dxos/dxos/@dxos/cli-linux-x64@d7b0a3b' }} | |
| PUBLISHED: ${{ steps.changesets.outputs.publishedPackages }} | |
| ATPROTO_HANDLE: ${{ secrets.ATPROTO_HANDLE }} | |
| ATPROTO_APP_PASSWORD: ${{ secrets.ATPROTO_APP_PASSWORD }} | |
| # Authenticates the edge upload in place of a hub-identity VP — CI holds no HALO identity. | |
| DX_HUB_API_KEY: ${{ secrets.DX_HUB_API_KEY }} | |
| run: | | |
| # node comes from proto, whose global bin is not on PATH, so a `-g` install lands somewhere | |
| # the shell will not find. npm reports the prefix it is about to install into, so ask it. | |
| export PATH="$(npm prefix -g)/bin:${PATH}" | |
| npm install -g "${DX_CLI_PACKAGE}" | |
| # Fail fast on a broken CLI rather than part-way through publishing. | |
| dx --version | |
| # pnpm resolves the workspace glob and reports `private`, so the publishable set never has | |
| # to be re-derived here. A `registry_only` retry takes all of them, since `publishedPackages` | |
| # is empty in a run that published nothing. | |
| pnpm list --recursive --depth=-1 --json \ | |
| | jq -r --argjson all "${ALL:-false}" --argjson published "${PUBLISHED:-[]}" ' | |
| ($published | map(.name)) as $names | |
| | .[] | |
| | select(.name and (.private | not)) | |
| | select($all or (.name as $name | $names | any(. == $name))) | |
| | .path | |
| ' > released-dirs.txt | |
| echo "Publishing $(grep -c . released-dirs.txt || true) plugin(s) to the registry." | |
| while read -r dir; do | |
| [ -n "${dir}" ] || continue | |
| echo "::group::Publishing ${dir}" | |
| dx registry publish --dir "${dir}" | |
| echo "::endgroup::" | |
| done < released-dirs.txt |