diff --git a/.github/scripts/bump-version.cjs b/.github/scripts/bump-version.cjs new file mode 100644 index 000000000..7b4349177 --- /dev/null +++ b/.github/scripts/bump-version.cjs @@ -0,0 +1,78 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +const { execFileSync } = require('node:child_process'); +const fs = require('node:fs'); + +function readVersion() { + const manifest = JSON.parse(fs.readFileSync('package.json', 'utf8')); + const lock = JSON.parse(fs.readFileSync('package-lock.json', 'utf8')); + if ( + typeof manifest.version !== 'string' || + lock.version !== manifest.version || + lock.packages?.['']?.version !== manifest.version + ) { + throw new Error('package.json and both root package-lock.json versions must match before and after the bump.'); + } + return manifest.version; +} + +function report(outputs, message) { + console.log(message); + if (process.env.GITHUB_OUTPUT) { + fs.appendFileSync( + process.env.GITHUB_OUTPUT, + Object.entries(outputs) + .map(([key, value]) => `${key}=${value}\n`) + .join(''), + ); + } + if (process.env.GITHUB_STEP_SUMMARY) { + fs.appendFileSync(process.env.GITHUB_STEP_SUMMARY, `## Development version bump\n\n${message}\n`); + } +} + +function main() { + const oldVersion = readVersion(); + const releaseTag = process.env.RELEASE_TAG; + if (releaseTag && releaseTag !== oldVersion && releaseTag !== `v${oldVersion}`) { + report( + { changed: false }, + `Skipped: release ${releaseTag} does not match the current main version ${oldVersion}.`, + ); + return; + } + if (/^\d+\.\d+\.\d+-/.test(oldVersion)) { + report({ changed: false }, `Skipped: main is already on development version ${oldVersion}.`); + return; + } + if (!/^\d+\.\d+\.\d+$/.test(oldVersion)) { + throw new Error(`Expected a numeric release version, received ${oldVersion}.`); + } + + execFileSync( + 'npm', + [ + 'version', + 'prerelease', + '--preid=alpha', + '--no-git-tag-version', + '--ignore-scripts', + '--workspaces=false', + '--package-lock=true', + ], + { stdio: 'inherit' }, + ); + const newVersion = readVersion(); + if (!/^\d+\.\d+\.\d+-alpha\.0$/.test(newVersion)) { + throw new Error(`Expected the first alpha of the next patch version, received ${newVersion}.`); + } + report( + { changed: true, 'old-version': oldVersion, 'new-version': newVersion }, + `Updated package.json and both root package-lock.json versions: **${oldVersion} -> ${newVersion}**.`, + ); +} + +main(); diff --git a/.github/scripts/bump-version.test.cjs b/.github/scripts/bump-version.test.cjs new file mode 100644 index 000000000..f0158c6f7 --- /dev/null +++ b/.github/scripts/bump-version.test.cjs @@ -0,0 +1,165 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +const assert = require('node:assert/strict'); +const { execFileSync, spawnSync } = require('node:child_process'); +const fs = require('node:fs'); +const os = require('node:os'); +const path = require('node:path'); +const { test } = require('node:test'); + +const script = path.join(__dirname, 'bump-version.cjs'); + +function fixture(t, version = '1.0.1') { + const directory = fs.mkdtempSync(path.join(os.tmpdir(), 'documentdb-version-bump-')); + t.after(() => fs.rmSync(directory, { recursive: true, force: true })); + const lifecycle = 'node -e "throw new Error(\'Version lifecycle scripts must not run\')"'; + const manifest = { + name: 'version-bump-fixture', + version, + private: true, + workspaces: ['packages/*'], + dependencies: { 'fixture-dependency': '7.8.9' }, + scripts: { preversion: lifecycle, version: lifecycle, postversion: lifecycle }, + }; + const lock = { + name: manifest.name, + version, + lockfileVersion: 3, + requires: true, + packages: { + '': { + name: manifest.name, + version, + workspaces: manifest.workspaces, + dependencies: manifest.dependencies, + }, + 'packages/example': { name: 'fixture-workspace', version: '4.5.6' }, + 'node_modules/fixture-workspace': { resolved: 'packages/example', link: true }, + 'node_modules/fixture-dependency': { version: '7.8.9' }, + }, + }; + fs.mkdirSync(path.join(directory, 'packages/example'), { recursive: true }); + fs.writeFileSync(path.join(directory, 'package.json'), `${JSON.stringify(manifest, null, 2)}\n`); + fs.writeFileSync(path.join(directory, 'package-lock.json'), `${JSON.stringify(lock, null, 2)}\n`); + fs.writeFileSync( + path.join(directory, 'packages/example/package.json'), + `${JSON.stringify({ name: 'fixture-workspace', version: '4.5.6' }, null, 2)}\n`, + ); + return { directory, manifest, lock }; +} + +function run(directory, releaseTag = '') { + return spawnSync(process.execPath, [script], { + cwd: directory, + encoding: 'utf8', + env: { + ...process.env, + RELEASE_TAG: releaseTag, + GITHUB_OUTPUT: path.join(directory, 'outputs'), + GITHUB_STEP_SUMMARY: path.join(directory, 'summary'), + npm_config_update_notifier: 'false', + }, + }); +} + +function read(directory, file) { + return JSON.parse(fs.readFileSync(path.join(directory, file), 'utf8')); +} + +for (const releaseTag of ['', 'v1.0.1', '1.0.1']) { + test(`Bumps only the root manifest and lockfile to alpha.0 (${releaseTag || 'manual'})`, (t) => { + const { directory, manifest, lock } = fixture(t); + const workspace = fs.readFileSync(path.join(directory, 'packages/example/package.json'), 'utf8'); + execFileSync('git', ['init', '--quiet'], { cwd: directory }); + + const result = run(directory, releaseTag); + + assert.equal(result.status, 0, result.stderr); + assert.deepEqual(read(directory, 'package.json'), { ...manifest, version: '1.0.2-alpha.0' }); + assert.deepEqual(read(directory, 'package-lock.json'), { + ...lock, + version: '1.0.2-alpha.0', + packages: { ...lock.packages, '': { ...lock.packages[''], version: '1.0.2-alpha.0' } }, + }); + assert.equal(fs.readFileSync(path.join(directory, 'packages/example/package.json'), 'utf8'), workspace); + assert.equal( + fs.readFileSync(path.join(directory, 'outputs'), 'utf8'), + 'changed=true\nold-version=1.0.1\nnew-version=1.0.2-alpha.0\n', + ); + assert.match(fs.readFileSync(path.join(directory, 'summary'), 'utf8'), /1\.0\.1 -> 1\.0\.2-alpha\.0/); + assert.equal(execFileSync('git', ['tag', '--list'], { cwd: directory, encoding: 'utf8' }), ''); + assert.notEqual(spawnSync('git', ['rev-parse', '--verify', 'HEAD'], { cwd: directory }).status, 0); + }); +} + +for (const version of ['1.0.2-alpha.0', '1.0.2-alpha.1', '1.1.0-beta.0']) { + test(`Does not advance an existing development version (${version})`, (t) => { + const { directory, manifest, lock } = fixture(t, version); + + const result = run(directory); + + assert.equal(result.status, 0, result.stderr); + assert.deepEqual(read(directory, 'package.json'), manifest); + assert.deepEqual(read(directory, 'package-lock.json'), lock); + assert.equal(fs.readFileSync(path.join(directory, 'outputs'), 'utf8'), 'changed=false\n'); + assert.match(result.stdout, /already on development version/); + }); +} + +for (const releaseTag of ['v0.11.2', 'v1.1.0', 'unrelated-package-v1.0.1']) { + test(`Skips a release that does not match main (${releaseTag})`, (t) => { + const { directory, manifest, lock } = fixture(t); + + const result = run(directory, releaseTag); + + assert.equal(result.status, 0, result.stderr); + assert.deepEqual(read(directory, 'package.json'), manifest); + assert.deepEqual(read(directory, 'package-lock.json'), lock); + assert.equal(fs.readFileSync(path.join(directory, 'outputs'), 'utf8'), 'changed=false\n'); + assert.match(result.stdout, /does not match the current main version/); + }); +} + +test('A repeated manual run does not produce alpha.1', (t) => { + const { directory } = fixture(t); + assert.equal(run(directory).status, 0); + fs.writeFileSync(path.join(directory, 'outputs'), ''); + + const result = run(directory); + + assert.equal(result.status, 0, result.stderr); + assert.equal(read(directory, 'package.json').version, '1.0.2-alpha.0'); + assert.equal(fs.readFileSync(path.join(directory, 'outputs'), 'utf8'), 'changed=false\n'); +}); + +for (const field of ['version', 'root-package']) { + test(`Fails before modifying files if the lockfile is out of sync (${field})`, (t) => { + const { directory, manifest, lock } = fixture(t); + if (field === 'version') { + lock.version = '1.0.0'; + } else { + lock.packages[''].version = '1.0.0'; + } + fs.writeFileSync(path.join(directory, 'package-lock.json'), JSON.stringify(lock)); + + const result = run(directory); + + assert.notEqual(result.status, 0); + assert.match(result.stderr, /both root package-lock.json versions must match/); + assert.deepEqual(read(directory, 'package.json'), manifest); + assert.deepEqual(read(directory, 'package-lock.json'), lock); + assert.equal(fs.existsSync(path.join(directory, 'outputs')), false); + }); +} + +test('Fails explicitly for an unsupported version', (t) => { + const { directory } = fixture(t, 'not-a-version'); + + const result = run(directory); + + assert.notEqual(result.status, 0); + assert.match(result.stderr, /Expected a numeric release version/); +}); diff --git a/.github/workflows/bump-version-pr.yaml b/.github/workflows/bump-version-pr.yaml index f1d679e2b..7f086fb52 100644 --- a/.github/workflows/bump-version-pr.yaml +++ b/.github/workflows/bump-version-pr.yaml @@ -1,30 +1,98 @@ name: Bump version after release -# Disabled for now โ€” comment out the trigger block to prevent execution on: - # release: - # types: [published] + release: + types: [published] workflow_dispatch: +permissions: + actions: write + contents: write + pull-requests: write + +concurrency: + group: bump-version-after-release + cancel-in-progress: false + jobs: bump: + if: github.event_name == 'workflow_dispatch' || !github.event.release.prerelease runs-on: ubuntu-latest + timeout-minutes: 5 steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + ref: main + + - uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v7.1.0 + with: + node-version-file: .nvmrc - name: Bump version id: bump - uses: alexweininger/bump-prerelease-version@91183ecfa908d49e9e7c1c62e9c781a49aa7c307 # v0.1.1 + run: node .github/scripts/bump-version.cjs + env: + RELEASE_TAG: ${{ github.event.release.tag_name }} - name: Create pull request + id: pr + if: steps.bump.outputs.changed == 'true' uses: peter-evans/create-pull-request@5f6978faf089d4d20b00c7766989d076bb2fc7f1 # v8.1.1 with: - title: ${{ env.MESSAGE }} - body: Automatically created by ${{ env.RUN_LINK }} - commit-message: ${{ env.MESSAGE }} + title: 'chore: prepare ${{ steps.bump.outputs.new-version }} development' + body: | + ## Why this PR exists + + Move `main` to the next development version after a release, so ongoing + development is no longer labelled with an already released version. + The published release and its tag are unchanged. + + ## Version change + + | File | Old version | New version | + | --- | --- | --- | + | `package.json` | `${{ steps.bump.outputs.old-version }}` | **`${{ steps.bump.outputs.new-version }}`** | + | `package-lock.json` (both root version entries) | `${{ steps.bump.outputs.old-version }}` | **`${{ steps.bump.outputs.new-version }}`** | + + `alpha.0` means the **first alpha of the next patch version**. The `.0` + is the prerelease counter, not an additional patch number. Re-running + this workflow does not advance it to `alpha.1`. + + Only the root extension version is updated; workspace package versions + and dependency versions are unchanged. This PR does **not** publish an + extension, create a release, or change release notes. Before publishing + the next release, replace the alpha version with its intended numeric + release version. + + ## Review and merge + + This PR is **ready for review**, not a draft. The workflow explicitly + starts **full CI** on this branch, so no separate token secret or manual + CI dispatch is needed. Review the changes and merge after the required + checks pass. + + GitHub may also request approval for PR-triggered workflows because + this PR was created with `GITHUB_TOKEN`. If shown, select + **Approve workflows to run** for those additional runs. + + ## Source + + - Trigger: ${{ github.event_name == 'release' && format('[Release {0}]({1})', github.event.release.tag_name, github.event.release.html_url) || 'Manual workflow run' }} + - [Workflow run](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}) + commit-message: 'chore: prepare ${{ steps.bump.outputs.new-version }} development' branch: bot/bump-${{ steps.bump.outputs.new-version }} base: main + draft: false + delete-branch: true + add-paths: | + package.json + package-lock.json author: GitHub + + - name: Start full CI for the pull request + if: steps.pr.outputs.pull-request-number != '' + run: gh workflow run main.yml --ref "$PR_BRANCH" -f enforce_full_run=true env: - RUN_LINK: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} - MESSAGE: Bump version after release + GH_TOKEN: ${{ github.token }} + GH_REPO: ${{ github.repository }} + PR_BRANCH: ${{ steps.pr.outputs.pull-request-branch }} diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 0a5a03f05..e5fec20fa 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -242,6 +242,9 @@ jobs: - name: ๐Ÿงช Run Unit Tests (Vitest) run: npm test + - name: Test release automation + run: node --test .github/scripts/*.test.cjs + package-checks: name: 'npm packages: verify tarballs' needs: [plan] diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index e8f9bec79..705f88a25 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -423,6 +423,29 @@ Always ship the signed artifact from the pipeline. A locally packaged `.vsix` is 3. Attach the **signed** `.vsix` downloaded in the previous step. 4. Save the release. +Publishing a stable GitHub release also starts [Bump version after release](.github/workflows/bump-version-pr.yaml). +When its tag matches the version on `main`, the workflow opens a ready-for-review PR for the next patch's +first development version, for example `1.0.1` โ†’ `1.0.2-alpha.0`. It updates `package.json` and +both root version entries in `package-lock.json`, leaving workspace package versions unchanged. +The workflow explicitly starts full CI on the PR's branch. Review and merge it once the required +checks pass. If GitHub requests approval for additional PR-triggered workflows, select +**Approve workflows to run**. The published release and tag are not modified. +The alpha suffix is for development only; use the intended numeric release +version at [ยง7.4](#74-bump-the-version) before the next publication. + +To catch up after a release, select **Actions โ†’ Bump version after release โ†’ Run workflow** on +`main`, or run: + +```bash +gh workflow run bump-version-pr.yaml --ref main +``` + +The workflow always operates on `main`. Re-running it reuses the same version-specific PR while +`main` is still on the released version; after the bump is merged, it leaves the existing alpha +version alone. GitHub prereleases are ignored, as are releases whose tags do not match the version +on `main` (for example, a patch release from an older release branch). The repository's +**Settings โ†’ Actions โ†’ General โ†’ Workflow permissions** must allow Actions to create pull requests. + ### 7.9 Publish to the Marketplace Run the second internal Azure DevOps pipeline, the **release** pipeline, which publishes to the Visual Studio Marketplace from whichever branch holds the release commit โ€” `main` for a normal release, or the `release/` branch when a patch was cut off a tag ([ยง1.3](#13-releases)). This is a separate pipeline from the build in ยง7.7: one produces and signs the artifact, the other ships it. diff --git a/docs/ai-and-plans/features/build-and-test-stack/README.md b/docs/ai-and-plans/features/build-and-test-stack/README.md index 82144c333..7fd7f7ada 100644 --- a/docs/ai-and-plans/features/build-and-test-stack/README.md +++ b/docs/ai-and-plans/features/build-and-test-stack/README.md @@ -127,6 +127,16 @@ coverage into installed-workbench E2E; see the 5. Tests for verification tooling belong beside that tool and run through `npm run test:verification`, not the main Vitest project unless the local config says otherwise. +## Post-release version automation + +[`bump-version-pr.yaml`](../../../../.github/workflows/bump-version-pr.yaml) runs after stable +GitHub releases and on manual dispatch. It always operates on `main`, requires release tags to +match its current version, and proposes the next patch's first alpha in a ready-for-review PR. The root +manifest and both lockfile version entries stay synchronized; workspace versions are not bumped. +Reruns reuse the same PR or skip an existing development version. The workflow explicitly +dispatches full CI on the PR branch without a separate token secret. +See [the release process](../../../../CONTRIBUTING.md#78-create-the-github-release). + ## Durable documents - [Design and invariants](./design.md) @@ -134,5 +144,6 @@ coverage into installed-workbench E2E; see the - [Pipeline guide](./pipelines.md) - [Deferred work](./future-work.md) - [Modernization iteration](./iterations/01-modernization/build-and-test-stack.md) and its reviews +- [Post-release version automation review](./iterations/02-post-release-version-review.md) - [E2E strategy](../e2e-testing/strategy.md) - [Data-grid replacement plan](../data-grid/slickgrid-removal.md) diff --git a/docs/ai-and-plans/features/build-and-test-stack/design.md b/docs/ai-and-plans/features/build-and-test-stack/design.md index 70b87b996..04aca81b2 100644 --- a/docs/ai-and-plans/features/build-and-test-stack/design.md +++ b/docs/ai-and-plans/features/build-and-test-stack/design.md @@ -161,6 +161,21 @@ representative calls through every public entry point. The real-VS-Code unbundle CommonJS `await import()` and ESM loading to pass, and records synchronous CommonJS `require()` as the known unsupported case. +### Post-release version bumps are root-only, idempotent, and reviewed + +The release-bump workflow checks out `main`, not the release tag or the manually selected ref. +Automatic runs ignore GitHub prereleases and tags that do not match `main`'s package version. +Both automatic and manual runs propose only the next patch's `alpha.0`; they never increment an +existing development version to `alpha.1`. The root manifest and both root lockfile versions must +agree before and after npm runs. Workspace package and dependency versions stay unchanged. + +The workflow creates or updates a version-specific, ready-for-review PR using `GITHUB_TOKEN`, +with explicit actions, contents and pull-request write permissions. It dispatches `main.yml` on +the PR branch with `enforce_full_run=true`, so the complete CI suite and required `Merge gate` +run without a separate token secret or approval. Additional PR-triggered workflows may require +a maintainer's approval under GitHub's token-event rules. No release is published or tag modified. +The development alpha must be replaced with a numeric release version before publication. + ## Change discipline Change a config and the relevant rationale together. Package before claiming a bundle change works, diff --git a/docs/ai-and-plans/features/build-and-test-stack/iterations/02-post-release-version-review.md b/docs/ai-and-plans/features/build-and-test-stack/iterations/02-post-release-version-review.md new file mode 100644 index 000000000..1a05ffea9 --- /dev/null +++ b/docs/ai-and-plans/features/build-and-test-stack/iterations/02-post-release-version-review.md @@ -0,0 +1,104 @@ +--- +feature: build-and-test-stack +kind: review +status: active +prs: [1042] +created: 2026-10-21 +--- + +# Post-release version automation review + +- **PR:** [#1042](https://github.com/microsoft/vscode-documentdb/pull/1042). +- **Reviewed commit:** `37df67839a25bbf503c4faddf517eaabe3bcc82c`. +- **Scope:** release filtering, the root-only version bump and its integration tests, rerun behavior, + pull-request action inputs and outputs, explicit full-CI dispatch, merge requirements, and related + contributor and feature documentation. +- **Method:** direct diff and code review; checked the pinned pull-request action's declared outputs, + the repository's required checks, CI logs, and GitHub's token-trigger rules. The local build and all + 13 release-automation integration tests passed during the review. +- **Author instruction:** after receiving the review, the operator requested: "good, document and fix + fixable issues according to the contributing md file." + +## F01: pipeline inventory formatting fails the required merge gate + +- **Severity:** low; merge-blocking CI failure, not a release-automation logic defect. +- **Where:** the GitHub Actions inventory table in [pipelines.md](../pipelines.md#github-actions-githubworkflows). +- **Evidence:** [CI run 39589761800](https://github.com/microsoft/vscode-documentdb/actions/runs/39589761800), + [static-check job](https://github.com/microsoft/vscode-documentdb/actions/runs/39589761800/job/119187582908). + Prettier reports only `docs/ai-and-plans/features/build-and-test-stack/pipelines.md`. + The final quality check reports `l10n=success, lint=success, prettier=failure`, causing both + `Static checks` and the required `Merge gate` to fail. +- **Recommended fix:** format the affected Markdown document with the repository's existing Prettier + configuration. This repairs the required check without changing workflow behavior. +- **Author decision:** fix under the operator's instruction above. The confirmed formatting failure + is the fixable issue from the review; no new product or workflow design decision is required. +- **Implementation:** F01 fixed in + [d9dc4d09](https://github.com/microsoft/vscode-documentdb/commit/d9dc4d09): + formatted the pipeline inventory table to restore the required Prettier check, without changing + release-automation behavior. Targeted formatting, the Case 1 build, and all 13 release-automation + integration tests passed. The fix was committed and pushed separately under CONTRIBUTING section 6.3. +- **Validation:** `npm run build` passed; `node --test .github/scripts/bump-version.test.cjs` + passed all 13 tests. The focused Prettier check passed for the affected guide, this review record, + and the feature README; `git diff --check` passed. The repository-wide `prettier-fix` command + was not run because the PR remains a draft. + +## C01: bot pull-request creation remains an operational check + +- **Classification:** verification limitation, not a confirmed code defect. +- **Evidence:** the workflow-permissions endpoint returned HTTP 403 with the available credentials. + No live bump run was performed, so actual bot PR creation and the subsequent CI dispatch have not + been exercised together. +- **Disposition:** leave repository settings and live automation unchanged. The operator authorized + fixing confirmed issues, not publishing a release or creating a test bump PR. Existing + [release instructions](../../../../../CONTRIBUTING.md#78-create-the-github-release) already describe + the required Actions PR-creation permission and the catch-up command. +- **Remaining check:** a maintainer must confirm Actions may create pull requests and observe the + first intended bump run after merge. + +## Review stages and handoff + +- The initial direct review found no blocking logic defects. +- The active PR had no inline review threads or GitHub Copilot reviewer findings to merge when + checked on 2026-10-21. Its only timeline feedback was the CI report. +- This record does not claim completion of the different-vendor validation gate or independent + sweep in [CONTRIBUTING.md section 6.1](../../../../../CONTRIBUTING.md#61-stage-1-ai-review-pass-run-by-the-contributor). + Those stages remain prerequisites before requesting human review. +- At the initial follow-up, PR #1042 remained in draft under **Case 1**. The full Case 2 + checks, including repository-wide `prettier-fix`, were deferred until the handoff below. + +## Outcome + +The confirmed formatting failure is fixed, validated locally, and pushed without changing the +automation implementation. F01 records the implementation commit and verification inline. +The review record and its feature-index link accompany the fix, and implementation comments are +posted on the PR. Live bot permissions and end-to-end operation remain explicitly unverified. +The initial follow-up did not claim that the full pre-review or Case 2 checks had run. + +## Ready-for-review handoff checks, 2026-10-21 + +The operator requested: "review completed, move forward to marking it as ready for review." +The full **Case 2** suite ran on the branch at `c99ebd82`, even though the review-stage +evidence described above remains incomplete. + +| Check | Result | +| --------------------------------------------------- | ----------------------------------------------- | +| `npm run prettier-fix` | Passed; no tracked changes | +| `npm run lint` | Passed | +| `npx vitest run` | 314 files passed; 5,184 tests passed, 1 skipped | +| `npm run build` | Passed | +| `npm run package` | Passed; VSIX produced | +| `node --test .github/scripts/bump-version.test.cjs` | All 13 tests passed | +| `npm run l10n` | Not applicable; no localized strings changed | + +The PR was assigned to milestone **1.0.2**. Packaging emitted non-failing CSS warnings; no +unrelated source changes were made. + +**Remaining handoff blocker:** this committed record explicitly leaves the cross-vendor +validation gate and independent sweep incomplete. The operator's review-completed statement +does not identify those stages or their results. A follow-up request for confirmation was +unanswered; no completion evidence or author decisions have been invented. The PR remains a +draft until those stages are confirmed and recorded. The successful Case 2 checks are no +longer deferred. + +The separate operational limitation in C01 remains: Actions PR-creation permission and a live +bot-PR/CI-dispatch run still require observation after merge. diff --git a/docs/ai-and-plans/features/build-and-test-stack/pipelines.md b/docs/ai-and-plans/features/build-and-test-stack/pipelines.md index 129118062..4b54cd5e6 100644 --- a/docs/ai-and-plans/features/build-and-test-stack/pipelines.md +++ b/docs/ai-and-plans/features/build-and-test-stack/pipelines.md @@ -42,11 +42,14 @@ the operator-run ADO build and the G0 manual checklist passed on 2026-10-02 (G0) | `api-extractor.yaml` | Push to `main` and `release/**`; PRs | Extracts the public API typings | | `api-publish.yaml` | Manual | Publishes the API typings package to npm | | `npm-publish-documentdb-js.yml` | Manual; `dry_run` defaults to `true`, one checkbox per package | Builds, type-checks package tests, tests and verifies packages, and dry-runs publication; explicit real publication to npmjs with provenance requires successful verification and environment approval | -| `bump-version-pr.yaml` | Manual | Opens the version bump PR after a release | +| `bump-version-pr.yaml` | Stable GitHub release published; manual | Opens or updates a ready-for-review PR into `main` for the next patch's `alpha.0`, updating the root manifest and lockfile, then explicitly dispatches full CI on its branch. Release tags must match `main`; existing development versions are left alone. | | `deploy-documentation-production.yml` | Push to `main` touching `docs/**`; manual | Deploys the documentation site | | `seed-build-cache.yml` | Manual (`seed` / `verify`) | Build-size cache | -All of them install from **public npmjs**: there is no `.npmrc` at the repository root. +Workflows that install dependencies use **public npmjs**: there is no `.npmrc` at the repository +root. The version-bump workflow needs no dependency installation; it runs the repository's +`.github/scripts/bump-version.cjs` with Node from `.nvmrc` and npm. Its integration tests run in +the CI unit-tests job. All checkouts in `main.yml` use `actions/checkout`'s default ref: GitHub's synthetic **merge ref for PRs**, and `github.sha` for push/manual runs. Stage 6 restores this policy