Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 83 additions & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,26 @@ permissions:
contents: read

jobs:
# A real release may only be dispatched from `main`: `gh workflow run --ref`
# accepts any branch or tag, and publishing plus tagging from anywhere else
# would permanently release the wrong commit. Dry runs are allowed from any
# ref so a branch can rehearse the packaging matrix. Failing here (instead
# of silently skipping the publish steps) makes the mistake visible.
preflight:
name: Preflight
if: github.repository == 'rstackjs/rstack-editor'
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- name: Require main for a real release
if: ${{ !inputs.dry_run && github.ref != 'refs/heads/main' }}
run: |
echo "::error::A real release must be dispatched from main (got ${GITHUB_REF}). Re-run with dry run enabled, or dispatch from main."
exit 1

release_vscode_extension:
name: Release VS Code Extension (${{ matrix.vsce-target }})
if: github.repository == 'rstackjs/rstack-editor' && github.event_name == 'workflow_dispatch'
needs: preflight
runs-on: ${{ matrix.runner }}
environment: vscode-marketplace
timeout-minutes: 30
Expand Down Expand Up @@ -100,3 +117,68 @@ jobs:
env:
OVSX_PAT: ${{ secrets.OVSX_PAT }}
run: pnpm exec ovsx publish --target ${{ matrix.vsce-target }} --skip-duplicate

# Runs only for a real release: a dry run must leave no tag behind. The tag
# points at the commit that was actually published (github.sha), the release
# notes come from the conventional commits since the previous tag, and the
# VSIX of every matrix target is attached as an asset so a release can be
# installed by hand (`code --install-extension`) without either marketplace.
github_release:
name: Tag and GitHub Release
needs: release_vscode_extension
if: ${{ !inputs.dry_run }}
Comment thread
fi3ework marked this conversation as resolved.
runs-on: ubuntu-latest
timeout-minutes: 10
permissions:
contents: write
steps:
- name: Checkout
uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0
with:
# changelogithub needs the tags and history to find the previous
# release and list the commits since it; the tag step compares an
# existing tag's target against this commit.
fetch-depth: 0

- name: Setup Node.js
uses: actions/setup-node@249970729cb0ef3589644e2896645e5dc5ba9c38 # v6.5.0
with:
node-version: 22

- name: Download VSIX Artifacts
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
pattern: rstack-*
path: vsix
merge-multiple: true

- name: Read Version
id: version
run: echo "tag=v$(node -p "require('./packages/vscode/package.json').version")" >> "$GITHUB_OUTPUT"

# Idempotent for a re-run of the same commit (e.g. after one marketplace
# publish flaked and `--skip-duplicate` covered the rest), but a tag that
# already points at a *different* commit means the version was never
# bumped after the last release: fail instead of attaching VSIX files
# built from this commit to a release tagged at another one.
- name: Push Tag
env:
TAG: ${{ steps.version.outputs.tag }}
run: |
existing=$(git rev-parse --verify --quiet "refs/tags/$TAG^{commit}" || true)
if [ -z "$existing" ]; then
git tag "$TAG" "$GITHUB_SHA"
git push origin "refs/tags/$TAG"
elif [ "$existing" = "$GITHUB_SHA" ]; then
echo "tag $TAG already points at $GITHUB_SHA, leaving it as is"
else
echo "::error::tag $TAG already exists at $existing but this run is at $GITHUB_SHA — bump the version (pnpm bump) before releasing again."
exit 1
fi

- name: GitHub Release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
TAG: ${{ steps.version.outputs.tag }}
run: |
npx changelogithub@15.0.4 --to "$TAG" --assets 'vsix/*.vsix'
3 changes: 2 additions & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ Unified editor support for the [Rstack](https://rstack.rs) toolchain. pnpm works
## Conventions

- All code, comments, commit messages, PRs and docs are in English, regardless of the conversation language.
- Root scripts are thin `pnpm -r run` fan-outs. Never make a root script reach into a package's internals — add the script to the package instead.
- Root scripts either fan out (`pnpm -r run`) or act on the whole workspace at once (`pnpm bump`). Never make a root script reach into one named package's internals — add the script to that package instead.
- READMEs are user-facing only. Contributor/agent material goes in AGENTS.md files, not READMEs.
- Sibling checkouts of rslint / rstest / rstack-cli (`../rslint` etc.) are read-only references. Their working trees may be stale: `git fetch origin` and read via `git show origin/main:<path>`.
- Verify claims about upstream behavior or published packages against the actual source or registry — do not answer from memory.
Expand All @@ -16,6 +16,7 @@ Unified editor support for the [Rstack](https://rstack.rs) toolchain. pnpm works
- If extension source changed, also run the E2E slice covering the change (see `packages/vscode/AGENTS.md`). E2E launches a real VS Code and is the ground truth for editor behavior — unit tests are not a substitute.
- Never delete `packages/vscode/.vscode-test/` — it caches the VS Code download the E2E suites reuse.
- Report real command results only; never claim green without running.
- Releases: never tag or publish by hand — the **Release** workflow does both. See CONTRIBUTING.md → Releasing.

## Agent skills

Expand Down
10 changes: 10 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,13 @@ To try the extension: press F5 in VS Code at the repo root — the playground la
- The pre-commit hook formats and lints staged files (`rs staged`).
- CI runs build, lint, format check, unit tests and the E2E suites on Linux and Windows — please run `pnpm lint && pnpm test:unit` locally before pushing.
- Keep PRs focused; fill in the PR template.

## Releasing

All packages share one version and are bumped in lockstep. Today the VS Code extension (`packages/vscode`) is the only published artifact.

1. On a branch, run `pnpm bump` (interactive; or `pnpm bump --release minor`) — [bumpp](https://github.com/antfu-collective/bumpp) bumps every `packages/*/package.json` and commits `vX.Y.Z`. It does not tag or push.
2. Open a PR with that commit and merge it into `main`.
3. Run the **Release** workflow (`Actions → Release → Run workflow`, branch `main`; `gh workflow run release.yml`). Tick **dry run** to only build the VSIX artifacts (one per platform target). A real run publishes every platform target to the VS Code Marketplace and Open VSX, then tags `main` as `vX.Y.Z` and creates the GitHub Release with notes generated from the conventional commits since the previous tag and the VSIX files attached.

Re-running a release for the same commit is safe: both marketplaces skip an already-published version and the tag step leaves a tag that already points at that commit alone. A real (non-dry) run is rejected unless dispatched from `main`, and fails if the version's tag already exists on a different commit — bump first.
12 changes: 12 additions & 0 deletions bump.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { defineConfig } from 'bumpp';

// All packages share one version; see CONTRIBUTING.md → Releasing.
export default defineConfig({
files: ['packages/*/package.json'],
commit: 'v%s',
// Tagging and pushing belong to the release workflow, which tags the commit
// it actually published from. `pnpm bump` only prepares the release commit
// for a PR.
tag: false,
push: false,
});
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
"type": "module",
"scripts": {
"build": "pnpm -r run build",
"bump": "bumpp",
"fmt": "rs fmt",
"fmt:check": "rs fmt --check",
"lint": "rs lint --type-check",
Expand All @@ -14,6 +15,7 @@
"test:unit": "pnpm -r run test:unit"
},
"devDependencies": {
"bumpp": "^11.1.0",
"rstack": "^0.3.2"
},
"packageManager": "pnpm@11.20.0",
Expand Down
2 changes: 1 addition & 1 deletion packages/vscode/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "rstack",
"displayName": "Rstack",
"version": "0.1.0",
"version": "0.0.1",
"private": true,
"description": "All Rstack tool integrations for VS Code.",
"categories": [
Expand Down
Loading