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
4 changes: 4 additions & 0 deletions .changeset/central-release-contract.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
---

Adopt the shared Changesets policy and hardened independent-package release contract.
11 changes: 11 additions & 0 deletions .changeset/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"$schema": "https://unpkg.com/@changesets/config@3.1.4/schema.json",
"changelog": ["@changesets/changelog-github", { "repo": "stella/tooling" }],
"commit": false,
"fixed": [],
"linked": [],
"access": "public",
"baseBranch": "main",
"updateInternalDependencies": "patch",
"ignore": []
}
34 changes: 34 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,43 @@ permissions:
contents: read

jobs:
changeset:
name: Changeset present for published package changes
if: github.event_name == 'pull_request'
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7
with:
fetch-depth: 0
persist-credentials: false

- name: Enforce release intent
# The repository owner publishes this versioned shared contract.
uses: stella/.github/.github/actions/changeset-policy@v1.2.0 # zizmor: ignore[unpinned-uses]
with:
release-paths: |
packages/typescript-config/**
packages/oxlint-config/**
generated-paths: |
bun.lock
packages/typescript-config/CHANGELOG.md
packages/typescript-config/package.json
packages/oxlint-config/CHANGELOG.md
packages/oxlint-config/package.json
package-files: |
packages/typescript-config/package.json
packages/oxlint-config/package.json
version-file: bun.lock

checks:
runs-on: ubuntu-latest
steps:
- name: Check out repository
uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1
with:
persist-credentials: false

- name: Set up Node
uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5.0.0
Expand Down Expand Up @@ -49,6 +81,8 @@ jobs:
steps:
- name: Check out repository
uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1
with:
persist-credentials: false

- name: Install Rust lint toolchain
run: |
Expand Down
217 changes: 55 additions & 162 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,199 +2,92 @@ name: Publish

on:
push:
branches:
- main
branches: [main]
paths:
- VERSION
- packages/typescript-config/package.json
- packages/oxlint-config/package.json
workflow_dispatch:
inputs:
publish_to_npm:
description: Publish the current VERSION to npm after verification
description: Publish missing package versions after verification
required: true
default: false
type: boolean

permissions:
contents: write
id-token: write
concurrency:
group: publish-${{ github.ref }}
cancel-in-progress: false

permissions: {}

env:
NODE_VERSION: "22"
NPM_VERSION: "11.11.1"
BUN_VERSION: "1.3.14"

jobs:
npm:
pack:
name: Build and pack ${{ matrix.package }}
runs-on: ubuntu-latest
strategy:
matrix:
package: [typescript-config, oxlint-config]
permissions:
contents: read
steps:
- name: Check out repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
with:
fetch-depth: 0

- name: Read version
id: version
shell: bash
run: |
set -euo pipefail
version="$(cat VERSION)"
echo "version=${version}" >> "$GITHUB_OUTPUT"
echo "tag=v${version}" >> "$GITHUB_OUTPUT"
persist-credentials: false

- name: Set up Node
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6
with:
node-version: ${{ env.NODE_VERSION }}
registry-url: https://registry.npmjs.org

- name: Set up Bun
uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0
- uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2
with:
bun-version: ${{ env.BUN_VERSION }}

- name: Set up npm
run: npm install --global "npm@${{ env.NPM_VERSION }}"

- name: Install dependencies
run: bun install --frozen-lockfile

- name: Sync package versions
uses: stella/.github/.github/actions/sync-package-versions@00ae4b134881be790b3631a3131f3ba2ee541520
with:
package-files: |
packages/typescript-config/package.json
packages/oxlint-config/package.json

- name: Typecheck
run: bun run typecheck

- name: Lint
run: bun run lint

- name: Publint
run: bun run publint

- name: Pack dry run
run: bun run pack:dry-run

- name: Pack release tarballs
id: pack
shell: bash
run: |
set -euo pipefail
mkdir -p release-artifacts

ts_json="$(
cd packages/typescript-config
npm pack --json --ignore-scripts --pack-destination "$GITHUB_WORKSPACE/release-artifacts"
)"
ts_file="$(node -e 'const pack = JSON.parse(process.argv[1]); console.log(pack[0].filename);' "$ts_json")"

oxlint_json="$(
cd packages/oxlint-config
npm pack --json --ignore-scripts --pack-destination "$GITHUB_WORKSPACE/release-artifacts"
)"
oxlint_file="$(node -e 'const pack = JSON.parse(process.argv[1]); console.log(pack[0].filename);' "$oxlint_json")"

(cd release-artifacts && sha256sum "$ts_file" "$oxlint_file" > SHA256SUMS)

{
echo "tarballs<<EOF"
printf 'release-artifacts/%s\n' "$ts_file" "$oxlint_file"
echo "EOF"
} >> "$GITHUB_OUTPUT"

echo "ts_tarball=release-artifacts/${ts_file}" >> "$GITHUB_OUTPUT"
echo "oxlint_tarball=release-artifacts/${oxlint_file}" >> "$GITHUB_OUTPUT"
run: npm install --global --ignore-scripts "npm@${{ env.NPM_VERSION }}"

- name: Publish to npm
if: github.event_name == 'push' || inputs.publish_to_npm == true
uses: stella/.github/.github/actions/npm-publish-hardened@d11bdc933dec609e291f6685f470b039d8342b6a
with:
tarballs: ${{ steps.pack.outputs.tarballs }}
- run: bun install --frozen-lockfile

- name: Create git tag
if: github.event_name == 'push' || inputs.publish_to_npm == true
- name: Build and pack
env:
TAG: ${{ steps.version.outputs.tag }}
run: |
set -euo pipefail
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"

if git rev-parse -q --verify "refs/tags/$TAG" >/dev/null; then
tag_commit="$(git rev-parse "$TAG^{commit}")"
head_commit="$(git rev-parse HEAD)"
if [[ "$tag_commit" != "$head_commit" ]]; then
echo "::error::Tag $TAG already points to $tag_commit, not $head_commit"
exit 1
fi
exit 0
fi

git tag -a "$TAG" -m "$TAG"
git push origin "$TAG"

- name: Resolve release notes range
if: github.event_name == 'push' || inputs.publish_to_npm == true
id: release-notes-range
env:
RELEASE_TAG: ${{ steps.version.outputs.tag }}
PACKAGE: ${{ matrix.package }}
shell: bash
run: |
set -euo pipefail
previous_stable="$(
git tag --list 'v[0-9]*.[0-9]*.[0-9]*' \
--sort=-v:refname \
| awk -v release_tag="$RELEASE_TAG" '
/^v[0-9]+\.[0-9]+\.[0-9]+$/ && $0 != release_tag {
print
exit
}
'
)"
if [[ -z "$previous_stable" ]]; then
first_commit="$(git rev-list --max-parents=0 HEAD | tail -n 1)"
echo "args=--tag ${RELEASE_TAG} --strip header ${first_commit}..HEAD" >> "$GITHUB_OUTPUT"
else
echo "args=--tag ${RELEASE_TAG} --strip header ${previous_stable}..HEAD" >> "$GITHUB_OUTPUT"
if [[ "$PACKAGE" == "oxlint-config" ]]; then
bun --filter @stll/oxlint-config build
fi

- name: Generate release notes from Conventional Commits
if: github.event_name == 'push' || inputs.publish_to_npm == true
uses: orhun/git-cliff-action@f50e11560dce63f7c33227798f90b924471a88b5 # v4.8.0
with:
config: cliff.toml
args: ${{ steps.release-notes-range.outputs.args }}
env:
OUTPUT: NOTES.md

- name: Create or update GitHub release
if: github.event_name == 'push' || inputs.publish_to_npm == true
env:
GH_TOKEN: ${{ github.token }}
RELEASE_TAG: ${{ steps.version.outputs.tag }}
TS_TARBALL: ${{ steps.pack.outputs.ts_tarball }}
OXLINT_TARBALL: ${{ steps.pack.outputs.oxlint_tarball }}
run: |
set -euo pipefail

assets=(
"$TS_TARBALL"
"$OXLINT_TARBALL"
release-artifacts/SHA256SUMS
mkdir -p release-artifacts
(
cd "packages/${PACKAGE}"
npm pack --ignore-scripts --pack-destination "$GITHUB_WORKSPACE/release-artifacts"
)

prerelease_flag=()
if [[ "$RELEASE_TAG" == *-* ]]; then
prerelease_flag+=(--prerelease)
fi

if gh release view "$RELEASE_TAG" >/dev/null 2>&1; then
gh release upload "$RELEASE_TAG" "${assets[@]}" --clobber
gh release edit "$RELEASE_TAG" --notes-file NOTES.md
else
gh release create "$RELEASE_TAG" "${assets[@]}" \
"${prerelease_flag[@]}" \
--title "$RELEASE_TAG" \
--notes-file NOTES.md
fi
- name: Upload tarball
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
with:
name: npm-tarball-${{ matrix.package }}
path: release-artifacts/*.tgz
retention-days: 1
if-no-files-found: error

release:
name: Publish packages
needs: pack
if: >-
github.ref == 'refs/heads/main'
&& (github.event_name == 'push' || inputs.publish_to_npm)
permissions:
contents: write
id-token: write
# Keep this caller filename stable: npm trusted publishing authorizes it.
uses: stella/.github/.github/workflows/npm-independent-release.yml@v1.2.0 # zizmor: ignore[unpinned-uses]
with:
artifact-pattern: npm-tarball-*
package-files: |
packages/typescript-config/package.json
packages/oxlint-config/package.json
24 changes: 24 additions & 0 deletions .github/workflows/release-pr.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
name: Release PR

on:
push:
branches: [main]

concurrency:
group: release-pr-${{ github.ref }}
cancel-in-progress: true

permissions: {}

jobs:
version:
name: Maintain Version Packages PR
permissions:
contents: read
# The repository owner publishes this versioned shared contract.
uses: stella/.github/.github/workflows/changeset-release-pr.yml@v1.2.0 # zizmor: ignore[unpinned-uses]
with:
bun-version-file: package.json
secrets:
CHANGELOG_APP_ID: ${{ secrets.CHANGELOG_APP_ID }}
CHANGELOG_APP_PRIVATE_KEY: ${{ secrets.CHANGELOG_APP_PRIVATE_KEY }}
13 changes: 13 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -133,3 +133,16 @@ run Clippy first and Dylint second:
cargo clippy --workspace --all-targets --all-features -- -D warnings
cargo dylint --workspace --all -- --all-targets --all-features -- -D warnings
```

## Releasing packages

Add a Changeset for every pull request that changes a published package. Choose
the affected package and semantic bump with `bun run changeset`; use an empty
Changeset when a release is intentionally unnecessary.

After the change lands on `main`, the shared release workflow maintains one
Version Packages pull request. Merging that pull request updates package
versions and changelogs, then `.github/workflows/publish.yml` builds the
tarballs and delegates the hardened npm and GitHub release transaction to the
versioned `stella/.github` contract. Package tags use the immutable
`<name>@<version>` form.
1 change: 0 additions & 1 deletion VERSION

This file was deleted.

Loading
Loading