diff --git a/.github/workflows/published-action-smoke.yml b/.github/workflows/published-action-smoke.yml index f6d843e..172c3a6 100644 --- a/.github/workflows/published-action-smoke.yml +++ b/.github/workflows/published-action-smoke.yml @@ -143,13 +143,13 @@ jobs: env: FIXTURE: ${{ github.workspace }}/fixtures/stdio-server.mjs run: | - set -uo pipefail + set -euo pipefail + status=0 npx --yes --registry=https://registry.npmjs.org/ @stackql/mcp-wringer@latest run \ --spec 2025-11-25 --profile quick --seed 20261118 --fail-on high \ --env MCP_WRINGER_DEFECTS=exit-on-decode-error \ --report-dir "$RUNNER_TEMP/npm-defective" \ - -- node "$FIXTURE" --revision 2025-11-25 - status=$? + -- node "$FIXTURE" --revision 2025-11-25 || status=$? if [ "$status" -ne 1 ]; then echo "expected exit code 1 for a high-severity finding, got ${status}" >&2 exit 1 diff --git a/README.md b/README.md index e878e3e..8478d2e 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,9 @@ +[![Marketplace](https://img.shields.io/badge/Marketplace-mcp--wringer-blue?logo=github)](https://github.com/marketplace/actions/mcp-wringer) +[![GitHub Release](https://img.shields.io/github/v/release/stackql/mcp-wringer?color=8250df)](https://github.com/stackql/mcp-wringer/releases) +[![NPM Version](https://img.shields.io/npm/v/%40stackql%2Fmcp-wringer)](https://www.npmjs.com/package/@stackql/mcp-wringer) +[![CI](https://github.com/stackql/mcp-wringer/actions/workflows/ci.yml/badge.svg)](https://github.com/stackql/mcp-wringer/actions/workflows/ci.yml) +[![License](https://img.shields.io/github/license/stackql/mcp-wringer)](LICENSE) + # mcp-wringer `@stackql/mcp-wringer` is a protocol robustness fuzzer for Model Context Protocol (MCP) servers over stdio and Streamable HTTP, with a focus on deterministic, replayable findings. @@ -92,63 +98,3 @@ After the first release and its moving `v0` tag are published, use the following fail_on: high report_directory: .mcp-wringer/reports ``` - -## Publishing releases - -Both publication steps are performed by a maintainer. npm publication is manual and uses interactive 2FA. Publishing a GitHub release does not publish the npm package: the [release workflow](./.github/workflows/release.yml) only validates the tagged artifacts. StackQL CI integration is a separate follow-up. - -### Prepare the release - -Use Node 24 and a current npm CLI. Start from a reviewed checkout with dependencies installed using `npm ci`. Run each command below separately, and stop if any command fails: - -```sh -npm run check -npm run test:matrix -npm run build -npm run check:action -npm run test:action -npm run check:plugin-api -npm run check:package -npm run docs:config:check -``` - -`check:action` rebuilds the committed Action bundle and checks for drift. If the bundle needs updating, review and commit the generated changes before rerunning the checks. `check:package` previews the npm tarball and checks its file allowlist and required entry points. Review that listing for credentials or unwanted files as well. - -The initial package version is `0.1.0`, with release tag `v0.1.0`. For later releases, update the package and lockfile together with `npm version patch --no-git-tag-version` (or `minor` / `major` as appropriate), then repeat the checks. Commit and merge the release changes, and confirm a clean working tree. npm and the Action must be released from the same commit. Published npm versions and `vX.Y.Z` tags must never be overwritten. - -### Publish to npmjs - -The maintainer's npm account must have 2FA enabled and permission to publish under the `@stackql` organization. Check that the intended version has not already been published. From the validated release checkout, run these commands separately and stop on any error: - -```sh -npm login --registry=https://registry.npmjs.org/ -npm whoami --registry=https://registry.npmjs.org/ -npm publish --access public --registry=https://registry.npmjs.org/ -``` - -Complete the browser login and any 2FA prompts. `--access public` is required for this scoped public package; the package also sets public access in `publishConfig`. Do not put an OTP or npm token into source, scripts, or GitHub secrets. Local publication does not provide GitHub Actions OIDC provenance; do not add `--provenance` to this manual procedure. - -Verify the published version (substitute the release version for later releases). Run the `npx` command from a directory outside the repository checkout: inside it, `npx` matches the checkout's own package name and fails with `'mcp-wringer' is not recognized` or `command not found`, because the package's bin is not linked into its own `node_modules/.bin`. - -```sh -npm view @stackql/mcp-wringer@0.1.0 version dist.integrity --registry=https://registry.npmjs.org/ -cd "$(mktemp -d)" && npx --yes --registry=https://registry.npmjs.org/ @stackql/mcp-wringer@0.1.0 --help -``` - -Confirm the package is public on [npmjs](https://www.npmjs.com/package/@stackql/mcp-wringer). The [npm scoped-package guide](https://docs.npmjs.com/creating-and-publishing-scoped-public-packages) describes account and publication requirements. - -### Publish the GitHub Marketplace Action - -The repository is public and has one root [action.yml](./action.yml), with display name `MCP Wringer` and entry point `dist-action/index.cjs`. Marketplace publication uses a GitHub release, not `npm publish`, and must be completed in the GitHub UI by a maintainer with release permissions. - -1. Confirm npm publication succeeded and the release commit passed CI, including the committed Action bundle check. -2. Open [action.yml on GitHub](https://github.com/stackql/mcp-wringer/blob/main/action.yml) and select **Draft a release** from the Marketplace banner, or open the repository's [new release form](https://github.com/stackql/mcp-wringer/releases/new). -3. Select **Publish this Action to the GitHub Marketplace**. If disabled, a StackQL organization owner must accept the GitHub Marketplace Developer Agreement using the link in the release form. -4. Check GitHub's metadata validation, including the uniqueness of `MCP Wringer`. Resolve any error before proceeding; name availability is not guaranteed until GitHub validates it. -5. Choose **Testing** as the primary category, and optionally **Security** as the secondary category. -6. Create tag `v0.1.0` at the exact validated release commit (use the matching `vX.Y.Z` for later releases), title the release `v0.1.0`, and include release notes. Do not select a prerelease for the stable release. -7. Click **Publish release** and complete GitHub's authentication prompts. Confirm the Marketplace listing is visible and the **Validate release** workflow succeeds. This workflow does not publish to npm. -8. After validation, create or update the moving `v0` major tag to the same commit. Keep `v0.1.0` immutable. The workflow examples use `@v0` to receive updates within that major version. -9. Run the [Published Action smoke](./.github/workflows/published-action-smoke.yml) workflow from the Actions tab. It pulls the Action from `@v0` and the package from the npm registry, runs both against the fixture server at that tag on Linux (x64 and arm64), macOS and Windows, and checks that the npm `latest` version matches the tag. It also runs weekly as a canary. - -Test the published Action against an isolated authorized server before integrating it into another project's CI. The StackQL repository runs it as a pull request gate in its `mcp-wringer` workflow, which builds the server from the pull request and fuzzes stdio and Streamable HTTP in both protocol revisions on each platform it ships. Record the Marketplace URL and release commit SHA. See [GitHub's Marketplace publication guide](https://docs.github.com/en/actions/how-tos/create-and-publish-actions/publish-in-github-marketplace) and the [maintainer release checklist](./docs/dev/release-checklist.md). diff --git a/docs/dev/release-checklist.md b/docs/dev/release-checklist.md index 43b616b..6ca0af9 100644 --- a/docs/dev/release-checklist.md +++ b/docs/dev/release-checklist.md @@ -1,6 +1,6 @@ # Release checklist -The maintainer publishes npm releases manually with interactive 2FA and lists the Action through the GitHub release form. Agents do not create tags or releases, publish packages, or change repository settings. The current procedure is documented in the [README](../../README.md#publishing-releases); it supersedes the trusted-publishing setup in Work order 001 and the historical M6 report. +The maintainer publishes npm releases manually with interactive 2FA and lists the Action through the GitHub release form. Agents do not create tags or releases, publish packages, or change repository settings. The current procedure is documented in the [publishing guide](../publishing.md); it supersedes the trusted-publishing setup in Work order 001 and the historical M6 report. ## npm account setup @@ -11,9 +11,9 @@ The release job has only `contents: read`. It verifies the tag against the packa ## Prepare a release 1. Confirm the working tree and intended release commit are clean and reviewed. -2. Update `package.json` version and the lockfile with the package manager when needed, then run `npm ci` and all preparation checks listed in the README, including Action self-tests. +2. Update `package.json` version and the lockfile with the package manager when needed, then run `npm ci` and all preparation checks listed in the [publishing guide](../publishing.md), including Action self-tests. 3. Review `git diff`, confirm `dist-action/` matches the Action source, and ensure no credentials or generated reports are included. -4. Merge the release commit to the default branch and confirm CI passes. Publish from a clean checkout of that commit using the README's npm login and publish commands, completing interactive 2FA. +4. Merge the release commit to the default branch and confirm CI passes. Publish from a clean checkout of that commit using the npm login and publish commands in the [publishing guide](../publishing.md), completing interactive 2FA. 5. Verify the exact published npm version and CLI before proceeding to Marketplace publication. 6. The maintainer creates the immutable `vX.Y.Z` tag and GitHub release through the Marketplace release form. The tag must match `package.json` exactly; publishing the release triggers the validation-only `.github/workflows/release.yml`. 7. Confirm the validation workflow succeeds, verify the Marketplace listing, and then create or update the moving `vX` tag. Do not overwrite or move a published npm version or immutable tag. @@ -21,4 +21,4 @@ The release job has only `contents: read`. It verifies the tag against the packa ## GitHub Marketplace -Follow the README's Marketplace steps, including the Developer Agreement, metadata/name validation, categories, and exact release commit selection. Marketplace publication must be explicitly approved and performed by the maintainer; the release validation workflow does not list the Action. The published Action is consumed as a pull request gate by the StackQL repository's `mcp-wringer` workflow. +Follow the [publishing guide's Marketplace steps](../publishing.md#publish-the-github-marketplace-action), including the Developer Agreement, metadata/name validation, categories, and exact release commit selection. Marketplace publication must be explicitly approved and performed by the maintainer; the release validation workflow does not list the Action. The published Action is consumed as a pull request gate by the StackQL repository's `mcp-wringer` workflow. diff --git a/docs/publishing.md b/docs/publishing.md new file mode 100644 index 0000000..a416bf0 --- /dev/null +++ b/docs/publishing.md @@ -0,0 +1,59 @@ +# Publishing releases + +Both publication steps are performed by a maintainer. npm publication is manual and uses interactive 2FA. Publishing a GitHub release does not publish the npm package: the [release workflow](../.github/workflows/release.yml) only validates the tagged artifacts. StackQL CI integration is a separate follow-up. + +## Prepare the release + +Use Node 24 and a current npm CLI. Start from a reviewed checkout with dependencies installed using `npm ci`. Run each command below separately, and stop if any command fails: + +```sh +npm run check +npm run test:matrix +npm run build +npm run check:action +npm run test:action +npm run check:plugin-api +npm run check:package +npm run docs:config:check +``` + +`check:action` rebuilds the committed Action bundle and checks for drift. If the bundle needs updating, review and commit the generated changes before rerunning the checks. `check:package` previews the npm tarball and checks its file allowlist and required entry points. Review that listing for credentials or unwanted files as well. + +The initial package version is `0.1.0`, with release tag `v0.1.0`. For later releases, update the package and lockfile together with `npm version patch --no-git-tag-version` (or `minor` / `major` as appropriate), then repeat the checks. Commit and merge the release changes, and confirm a clean working tree. npm and the Action must be released from the same commit. Published npm versions and `vX.Y.Z` tags must never be overwritten. + +## Publish to npmjs + +The maintainer's npm account must have 2FA enabled and permission to publish under the `@stackql` organization. Check that the intended version has not already been published. From the validated release checkout, run these commands separately and stop on any error: + +```sh +npm login --registry=https://registry.npmjs.org/ +npm whoami --registry=https://registry.npmjs.org/ +npm publish --access public --registry=https://registry.npmjs.org/ +``` + +Complete the browser login and any 2FA prompts. `--access public` is required for this scoped public package; the package also sets public access in `publishConfig`. Do not put an OTP or npm token into source, scripts, or GitHub secrets. Local publication does not provide GitHub Actions OIDC provenance; do not add `--provenance` to this manual procedure. + +Verify the published version (substitute the release version for later releases). Run the `npx` command from a directory outside the repository checkout: inside it, `npx` matches the checkout's own package name and fails with `'mcp-wringer' is not recognized` or `command not found`, because the package's bin is not linked into its own `node_modules/.bin`. + +```sh +npm view @stackql/mcp-wringer@0.1.0 version dist.integrity --registry=https://registry.npmjs.org/ +cd "$(mktemp -d)" && npx --yes --registry=https://registry.npmjs.org/ @stackql/mcp-wringer@0.1.0 --help +``` + +Confirm the package is public on [npmjs](https://www.npmjs.com/package/@stackql/mcp-wringer). The [npm scoped-package guide](https://docs.npmjs.com/creating-and-publishing-scoped-public-packages) describes account and publication requirements. + +## Publish the GitHub Marketplace Action + +The repository is public and has one root [action.yml](../action.yml), with display name `MCP Wringer` and entry point `dist-action/index.cjs`. Marketplace publication uses a GitHub release, not `npm publish`, and must be completed in the GitHub UI by a maintainer with release permissions. + +1. Confirm npm publication succeeded and the release commit passed CI, including the committed Action bundle check. +2. Open [action.yml on GitHub](https://github.com/stackql/mcp-wringer/blob/main/action.yml) and select **Draft a release** from the Marketplace banner, or open the repository's [new release form](https://github.com/stackql/mcp-wringer/releases/new). +3. Select **Publish this Action to the GitHub Marketplace**. If disabled, a StackQL organization owner must accept the GitHub Marketplace Developer Agreement using the link in the release form. +4. Check GitHub's metadata validation, including the uniqueness of `MCP Wringer`. Resolve any error before proceeding; name availability is not guaranteed until GitHub validates it. +5. Choose **Testing** as the primary category, and optionally **Security** as the secondary category. +6. Create tag `v0.1.0` at the exact validated release commit (use the matching `vX.Y.Z` for later releases), title the release `v0.1.0`, and include release notes. Do not select a prerelease for the stable release. +7. Click **Publish release** and complete GitHub's authentication prompts. Confirm the Marketplace listing is visible and the **Validate release** workflow succeeds. This workflow does not publish to npm. +8. After validation, create or update the moving `v0` major tag to the same commit. Keep `v0.1.0` immutable. The workflow examples use `@v0` to receive updates within that major version. +9. Run the [Published Action smoke](../.github/workflows/published-action-smoke.yml) workflow from the Actions tab. It pulls the Action from `@v0` and the package from the npm registry, runs both against the fixture server at that tag on Linux (x64 and arm64), macOS and Windows, and checks that the npm `latest` version matches the tag. It also runs weekly as a canary. + +Test the published Action against an isolated authorized server before integrating it into another project's CI. The StackQL repository runs it as a pull request gate in its `mcp-wringer` workflow, which builds the server from the pull request and fuzzes stdio and Streamable HTTP in both protocol revisions on each platform it ships. Record the Marketplace URL and release commit SHA. See [GitHub's Marketplace publication guide](https://docs.github.com/en/actions/how-tos/create-and-publish-actions/publish-in-github-marketplace) and the [maintainer release checklist](./dev/release-checklist.md).