name: KTX Release on: workflow_dispatch: inputs: release_kind: description: "Release kind: rc publishes to next, stable publishes to latest" required: true type: choice default: "stable" options: - stable - rc force_release: description: "Force a patch release even if semantic-release finds no releasable commits" required: false type: boolean default: false publish_live: description: "Create the release and publish @kaelio/ktx to npm instead of running a dry-run" required: true type: boolean default: true permissions: contents: write id-token: write concurrency: group: ktx-release-${{ github.ref }} cancel-in-progress: false jobs: npm-public-release: runs-on: ubuntu-latest steps: - name: Checkout repository uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 0 - name: Setup pnpm uses: pnpm/action-setup@0e279bb959325dab635dd2c09392533439d90093 # v6.0.8 with: run_install: false - name: Setup Node.js uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 with: node-version: "24" cache: "pnpm" cache-dependency-path: "pnpm-lock.yaml" registry-url: "https://registry.npmjs.org" - name: Install TypeScript dependencies run: pnpm install --frozen-lockfile - name: Setup Python uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 with: python-version: "3.13" - name: Setup uv uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0 with: enable-cache: true cache-dependency-glob: "uv.lock" - name: Install Python dependencies run: uv sync --all-packages - name: Prepare next prerelease branch if: ${{ inputs.release_kind == 'rc' }} run: | set -euo pipefail source_sha="$(git rev-parse HEAD)" git config user.name "github-actions[bot]" git config user.email "41898282+github-actions[bot]@users.noreply.github.com" if git ls-remote --exit-code --heads origin "${KTX_PRERELEASE_BRANCH}" >/dev/null 2>&1; then git fetch origin "${KTX_PRERELEASE_BRANCH}" git checkout -B "${KTX_PRERELEASE_BRANCH}" "origin/${KTX_PRERELEASE_BRANCH}" git merge --no-edit "${source_sha}" else git checkout -B "${KTX_PRERELEASE_BRANCH}" "${source_sha}" fi git push --set-upstream origin "HEAD:${KTX_PRERELEASE_BRANCH}" env: KTX_PRERELEASE_BRANCH: next - name: Prepare npm package root for release verification run: | set -euo pipefail mkdir -p dist/public-npm-package node --input-type=module <<'EOF' import { writeFile } from 'node:fs/promises'; const packageJson = { name: '@kaelio/ktx', version: '0.0.0', private: false }; await writeFile( 'dist/public-npm-package/package.json', `${JSON.stringify(packageJson, null, 2)}\n` ); EOF - name: Dry-run semantic release if: ${{ !inputs.publish_live }} run: | set -euo pipefail if [ "${KTX_RELEASE_KIND}" = "rc" ]; then export GITHUB_REF="refs/heads/${KTX_PRERELEASE_BRANCH}" export GITHUB_REF_NAME="${KTX_PRERELEASE_BRANCH}" export GITHUB_SHA="$(git rev-parse HEAD)" fi pnpm run semantic-release:dry-run env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} KTX_RELEASE_KIND: ${{ inputs.release_kind }} KTX_PRERELEASE_BRANCH: next FORCE_RELEASE: ${{ inputs.force_release }} - name: Create semantic release if: ${{ inputs.publish_live }} run: | set -euo pipefail if [ "${KTX_RELEASE_KIND}" = "rc" ]; then export GITHUB_REF="refs/heads/${KTX_PRERELEASE_BRANCH}" export GITHUB_REF_NAME="${KTX_PRERELEASE_BRANCH}" export GITHUB_SHA="$(git rev-parse HEAD)" fi pnpm run semantic-release env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} KTX_RELEASE_KIND: ${{ inputs.release_kind }} KTX_PRERELEASE_BRANCH: next FORCE_RELEASE: ${{ inputs.force_release }}