Skip to content

chore: take over release automation and remove Stainless dependencies#70

Merged
MingruiZhang merged 9 commits into
mainfrom
chore/stainless-exit
Jul 7, 2026
Merged

chore: take over release automation and remove Stainless dependencies#70
MingruiZhang merged 9 commits into
mainfrom
chore/stainless-exit

Conversation

@MingruiZhang

@MingruiZhang MingruiZhang commented Jul 7, 2026

Copy link
Copy Markdown
Member

Context

Stainless sunsets its platform for our account on 2026-09-01. This PR implements Problem 1 (Getting off Stainless) of the approved design doc (see docs/design/stainless-exit-and-v2.md in landing-ai/ade-python#100) for the TypeScript SDK. Companion to that Python PR.

Changes

  • New .github/workflows/release.yml — one-shot, dispatch-only releases. A maintainer runs the workflow and picks patch / minor / major. The workflow computes the next version from the latest tag, stamps package.json, src/version.ts, and the mcp-server package.json + manifest.json, prepends the changelog section (owned script, existing CHANGELOG style), lands the release: x.y.z commit directly on main, tags it, and creates the GitHub Release → publish-npm.yml (root + mcp-server + DXT asset). No release PR; dispatching is the release decision. Ordinary merges never trigger any of this. release-please fully removed.
  • build: replace the Stainless-hosted tsc-multi tarball with @stainless-api/[email protected] from npm (root + mcp-server; same bin name). Verified: full build, mcpb pack, and sign pass locally, and CI is green.
  • Cherry-picked fix/npm-oidc-auth (06b8ba6, original authorship preserved) — registry-url on setup-node, modern npm, npm publish --provenance --access public.
  • ci.yml — main + PRs triggers; stainless-sdks/* conditionals and both pkg.stainless.com uploads removed; setup-node bumped (Node 20 action runtimes leave runners 2026-09-16).
  • publish-npm.yml — DXT upload guarded with if: github.event_name == 'release' (manual re-runs used to fail on an empty tag).
  • Removed .stats.yml, scripts/utils/upload-artifact.sh; rewrote CONTRIBUTING.md + SECURITY.md (confirm [email protected] as security contact); README drops "generated with Stainless" and the vscode.stainless.com badge.

Why every publish-npm run since April is red (and what this PR does/doesn't fix)

Root cause (v2.7.0 run logs): npm error code ENEEDAUTH on the landingai-ade-mcp publish. No NPM_TOKEN is passed, so publishing rides on npm Trusted Publishing (OIDC) — configured for landingai-ade (root publishes fine; npm is current at 2.7.0) but impossible for landingai-ade-mcp, which has never existed on npm: trusted publishers can only be configured on existing packages.

Still required, npm-side (owner action): first-publish landingai-ade-mcp once with a token, then configure a Trusted Publisher for it (repo landing-ai/ade-typescript, workflow publish-npm.yml).

Required before releases work end-to-end

  1. RELEASE_TOKEN repo secret — fine-grained PAT (or GitHub App token) with Contents: write, whose owner can bypass the main ruleset (main requires PRs; this repo's ruleset grants "always" bypass to the repository Admin role). The default GITHUB_TOKEN can't be used: releases it creates don't trigger publish-npm.yml.
  2. Close the stale bot release PR release: 2.8.0 #67 — nothing replaces it; releases happen on dispatch.
  3. npm-side steps above; on the first dispatch, review the produced release commit + Release before considering the exit criterion met.

Note: local lockfile regeneration used --ignore-engines (this machine runs node 25; an mcp dev dependency pins 20 || 22 || 24, CI uses 20/22 — no CI impact).

🤖 Generated with Claude Code

MingruiZhang and others added 5 commits July 7, 2026 11:59
The previous approach installed [email protected] in a ../oidc/ prefix directory
and ran it directly, which didn't properly trigger the OIDC token exchange
for Trusted Publishing authentication.

Changes:
- Upgrade setup-node to v4 with registry-url to configure .npmrc
- Install [email protected] globally instead of in a prefix directory
- Add --provenance and --access public flags to trigger OIDC auth

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
package.json pinned tsc-multi to a tarball on the stainless-api GitHub
org's release assets, which goes away when that org is archived after
the Stainless sunset (2026-09-01). @stainless-api/tsc-multi is published
on npm (persists regardless); the bin name is unchanged, so scripts/build
works as before. Verified: full root + mcp-server build, pack, and sign
pass with 1.1.12.

Co-Authored-By: Claude Fable 5 <[email protected]>
Stainless sunsets its platform for our account on 2026-09-01. This
implements Problem 1 of the design doc (landing-ai/ade-python#100):

- Add self-hosted release-please workflow (replaces the Stainless app,
  which opened release PRs and created tags/GitHub Releases externally)
- Point release-please-config.json $schema at upstream googleapis and
  drop the README.md / mcp yarn.lock extra-files (no version strings in
  either; upstream's generic updater would no-op on them)
- Simplify CI triggers to main + PRs; drop stainless-sdks runner
  conditionals and both pkg.stainless.com artifact uploads
- Bump deprecated actions/setup-node (Node 20 action runtimes leave
  GitHub runners 2026-09-16)
- Guard the DXT release-asset upload so manual workflow_dispatch runs
  don't fail on an empty release tag
- Remove .stats.yml and scripts/utils/upload-artifact.sh
- Rewrite CONTRIBUTING.md and SECURITY.md for owned, hand-maintained code
- Drop "generated with Stainless" phrasing and the vscode.stainless.com
  MCP badge from README

Co-Authored-By: Claude Fable 5 <[email protected]>
Per review: ordinary merges to main must never create release PRs.
Releases now start with a maintainer running the Release workflow and
choosing patch/minor/major; the release-please CLI opens a release PR
pinned to exactly that version (changelog and multi-file version
stamping still come from the existing config/manifest). Merging that PR
triggers the finalize job, which creates the tag + GitHub Release and
thereby the npm publish. Config drops the now-bypassed prerelease
versioning keys.

Co-Authored-By: Claude Fable 5 <[email protected]>
@MingruiZhang

Copy link
Copy Markdown
Member Author

Release model revised per Mingrui's feedback: releases are now dispatch-only — a maintainer runs the Release workflow and explicitly picks patch/minor/major; ordinary merges to main never open release PRs. See the updated release.yml and PR description.

🤖 Claude Code

Per review: dispatching the Release workflow IS the release decision, so
the intermediate release PR is gone. The workflow now stamps the version
(package.json, src/version.ts, mcp-server package.json + manifest.json),
prepends the changelog section, lands the release commit directly on
main (requires the RELEASE_TOKEN owner to have ruleset bypass), tags it,
and creates the GitHub Release that triggers the npm publish.
release-please is fully removed (config, manifest, version annotations)
in favor of a small owned script.

Co-Authored-By: Claude Fable 5 <[email protected]>
@MingruiZhang

Copy link
Copy Markdown
Member Author

Revised again per feedback: the release PR is gone entirely. Dispatching Release (explicit patch/minor/major choice) stamps all four version locations + changelog, lands the release commit directly on main via ruleset bypass, tags, and publishes — one human action total. release-please fully removed. Secret renamed RELEASE_TOKEN; its owner needs ruleset bypass (repo Admin role).

🤖 Claude Code

MingruiZhang and others added 3 commits July 7, 2026 15:12
Keep the shared script byte-identical across both SDK repos.

Co-Authored-By: Claude Fable 5 <[email protected]>
- Add a concurrency group to the Release workflow so concurrent
  dispatches queue instead of racing the version computation
- Sync the notes-script SECTION_KEYS hoist from ade-python
- Simplify release-doctor to dispatch-only (its PR trigger gated on
  release-please branch names that no longer exist)

Co-Authored-By: Claude Fable 5 <[email protected]>
Mirror of the ade-python change: bootstrap + build + tests run on the
stamped tree, aborting the release before any commit or tag exists if
anything is red.

Co-Authored-By: Claude Fable 5 <[email protected]>
@MingruiZhang MingruiZhang merged commit 140047b into main Jul 7, 2026
3 checks passed
MingruiZhang added a commit that referenced this pull request Jul 7, 2026
The SDK is hand-maintained since the Stainless exit (#70); the
"File generated from our OpenAPI spec by Stainless" headers gave
contributors guidance that contradicts CONTRIBUTING.md. Mechanical
sweep of 45 source files plus the two .keep placeholders.

Co-Authored-By: Claude Fable 5 <[email protected]>
MingruiZhang added a commit that referenced this pull request Jul 8, 2026
The SDK is hand-maintained since the Stainless exit (#70); the
"File generated from our OpenAPI spec by Stainless" headers gave
contributors guidance that contradicts CONTRIBUTING.md. Mechanical
sweep of 45 source files plus the two .keep placeholders.

Co-authored-by: Claude Fable 5 <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants