ci: rework release strategy

Switch the release trigger from PR to a git tag. In practice this would
mean tagging a commit in master branch and pushing it with
`git push --tags`.

The benefit of this is that tagging is already an event that is reserved
for maintainers, so we can remove the need for verifying whether the
event was done by a maintainer.

We also no longer need to keep track of the tag. Previously the trigger
was a PR which has a different ref from the tag, so manual bookkeeping
was required to ensure github used the tag reference instead of the PR
reference. Having the tagging itself be the trigger removes this need
entirely as the default checkout will already use the tag as reference.
This commit is contained in:
dundargoc 2024-02-06 00:16:27 +01:00
parent 7147c72737
commit c3ab70cc98
5 changed files with 85 additions and 211 deletions

View file

@ -1,66 +0,0 @@
name: CICD
on:
workflow_dispatch:
pull_request:
types:
- opened
- reopened
- synchronize
- ready_for_review
push:
branches:
- 'master'
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
init:
name: Init
runs-on: ubuntu-latest
steps:
- name: Get PR head ref
if: ${{ github.event_name == 'pull_request' }}
id: pr_head_ref
run: |
echo "ref=refs/pull/${{ github.event.pull_request.number }}/head" >> $GITHUB_OUTPUT
outputs:
ref: >-
${{
(github.event_name == 'pull_request' && startsWith(github.head_ref, 'release/v'))
&& steps.pr_head_ref.outputs.ref
|| github.ref
}}
checks:
uses: ./.github/workflows/checks.yml
sanitize:
name: Sanitize
needs: [init, checks]
uses: ./.github/workflows/sanitize.yml
build:
name: Build & Test
needs: [init, checks]
uses: ./.github/workflows/build.yml
with:
ref: ${{ needs.init.outputs.ref }}
release:
name: Release
needs: [init, checks, build, sanitize]
if: >
github.event_name == 'pull_request' &&
startsWith(github.head_ref, 'release/v') &&
!github.event.pull_request.draft
uses: ./.github/workflows/release.yml
with:
ref: ${{ needs.init.outputs.ref }}
publish:
name: Publish
needs: release
uses: ./.github/workflows/publish.yml

View file

@ -8,9 +8,9 @@ env:
on:
workflow_call:
inputs:
ref:
default: ${{ github.ref }}
type: string
run_test:
default: true
type: boolean
jobs:
build:
@ -71,10 +71,7 @@ jobs:
shell: bash
steps:
- name: Checkout source code
uses: actions/checkout@v4
with:
ref: ${{ inputs.ref }}
- uses: actions/checkout@v4
- name: Read Emscripten version
run: |
@ -167,27 +164,27 @@ jobs:
echo "🔗 Minimal **glibc** version required for CLI: ${min_glibc}">> $GITHUB_STEP_SUMMARY
- name: Fetch fixtures
if: ${{ !matrix.cli-only }} # Don't fetch fixtures for only CLI building targets
if: ${{ !matrix.cli-only && inputs.run_test }} # Don't fetch fixtures for only CLI building targets
run: script/fetch-fixtures
- name: Generate fixtures
if: ${{ !matrix.cli-only }} # Can't natively run CLI on Github runner's host
if: ${{ !matrix.cli-only && inputs.run_test }} # Can't natively run CLI on Github runner's host
run: script/generate-fixtures
- name: Generate WASM fixtures
if: ${{ !matrix.cli-only && !matrix.use-cross }} # See comment for the "Build wasm library" step
if: ${{ !matrix.cli-only && !matrix.use-cross && inputs.run_test }} # See comment for the "Build wasm library" step
run: script/generate-fixtures-wasm
- name: Run main tests
if: ${{ !matrix.cli-only }} # Can't natively run CLI on Github runner's host
if: ${{ !matrix.cli-only && inputs.run_test }} # Can't natively run CLI on Github runner's host
run: $BUILD_CMD test --target=${{ matrix.target }} --features=${CLI_FEATURES}
- name: Run wasm tests
if: ${{ !matrix.cli-only && !matrix.use-cross }} # See comment for the "Build wasm library" step
if: ${{ !matrix.cli-only && !matrix.use-cross && inputs.run_test }} # See comment for the "Build wasm library" step
run: script/test-wasm
- name: Run benchmarks
if: ${{ !matrix.cli-only && !matrix.use-cross }} # Cross-compiled benchmarks make no sense
if: ${{ !matrix.cli-only && !matrix.use-cross && inputs.run_test }} # Cross-compiled benchmarks make no sense
run: $BUILD_CMD bench benchmark -p tree-sitter-cli --target=${{ matrix.target }}
- name: Upload CLI artifact

23
.github/workflows/ci.yml vendored Normal file
View file

@ -0,0 +1,23 @@
name: CI
on:
pull_request:
push:
branches:
- 'master'
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
checks:
uses: ./.github/workflows/checks.yml
sanitize:
needs: checks
uses: ./.github/workflows/sanitize.yml
build:
needs: checks
uses: ./.github/workflows/build.yml

View file

@ -1,63 +0,0 @@
name: Publish to registries
on:
workflow_call:
workflow_dispatch:
jobs:
crates_io:
name: Publish CLI to Crates.io
runs-on: ubuntu-latest
steps:
- name: Get latest tag
id: latest_tag
run: |
echo "tag=$(git describe --tags `git rev-list --tags --max-count=1`)" >> $GITHUB_OUTPUT
- name: Check out latest tag
uses: actions/checkout@v4
with:
ref: ${{ steps.latest_tag.outputs.tag }}
- name: Setup Rust
uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: stable
override: true
- name: Publish CLI to Crates.io
uses: katyo/publish-crates@v2
with:
registry-token: ${{ secrets.CARGO_REGISTRY_TOKEN }}
npm:
name: Publish lib to npmjs.com
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
directory: ["cli/npm", "lib/binding_web"]
steps:
- name: Get latest tag
id: latest_tag
run: |
echo "tag=$(git describe --tags `git rev-list --tags --max-count=1`)" >> $GITHUB_OUTPUT
- name: Check out latest tag
uses: actions/checkout@v4
with:
ref: ${{ steps.latest_tag.outputs.tag }}
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: 18
registry-url: "https://registry.npmjs.org"
- name: Publish lib to npmjs.com
env:
NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}}
run: |
cd ${{ matrix.directory }}
npm publish

View file

@ -1,61 +1,24 @@
name: Release
on:
workflow_call:
inputs:
ref:
default: ${{ github.ref }}
type: string
workflow_dispatch:
push:
tags:
- v*
jobs:
permissions:
name: Check permissions
runs-on: ubuntu-latest
outputs:
release_allowed: >
${{
github.repository_owner == 'tree-sitter' &&
steps.maintainer.outputs.is_maintainer == 'true' &&
steps.local_branch.outputs.is_local == 'true'
}}
steps:
- name: Initated by a maintainer
id: maintainer
env:
GH_TOKEN: ${{ github.token }}
repo: ${{ github.repository }}
actor: ${{ github.actor }}
run: |
maintainer=$(
gh api "/repos/${repo}/collaborators" |
jq ".[] | {login, maintainer: .permissions | .maintain} | select(.login == \"${actor}\") | .maintainer"
);
if [ "$maintainer" == "true" ]; then
echo "@${actor} has maintainer level permissions :rocket:" >> $GITHUB_STEP_SUMMARY;
echo "is_maintainer=true" >> $GITHUB_OUTPUT
fi
- name: The ref branch is local
id: local_branch
env:
is_local: ${{ github.event.pull_request.head.repo.full_name == github.repository }}
run: |
echo "is_local=${is_local}" >> $GITHUB_OUTPUT
build:
uses: ./.github/workflows/build.yml
with:
run_test: false
release:
name: Release
needs: permissions
if: needs.permissions.outputs.release_allowed
runs-on: ubuntu-latest
needs: build
permissions:
contents: write
steps:
- name: Checkout source code
uses: actions/checkout@v4
with:
ref: ${{ inputs.ref }}
- uses: actions/checkout@v4
- name: Download build artifacts
uses: actions/download-artifact@v4
@ -78,36 +41,56 @@ jobs:
rm -rf artifacts
ls -l target/
- name: Get tag name from a release/v* branch name
id: tag_name
env:
tag: ${{ github.head_ref }}
run: echo "tag=${tag#release/}" >> $GITHUB_OUTPUT
- name: Add a release tag
env:
ref: ${{ inputs.ref }}
tag: ${{ steps.tag_name.outputs.tag }}
message: "Release ${{ steps.tag_name.outputs.tag }}"
run: |
git config user.name "$(git log -1 --pretty='%cn')"
git config user.email "$(git log -1 --pretty='%ce')"
git tag -a "$tag" HEAD -m "$message"
git push origin "$tag"
- name: Create release
uses: softprops/action-gh-release@v1
with:
name: ${{ steps.tag_name.outputs.tag }}
tag_name: ${{ steps.tag_name.outputs.tag }}
name: ${{ github.ref_name }}
tag_name: ${{ github.ref_name }}
fail_on_unmatched_files: true
files: |
target/tree-sitter-*.gz
target/tree-sitter.wasm
target/tree-sitter.js
- name: Merge release PR
crates_io:
name: Publish CLI to Crates.io
runs-on: ubuntu-latest
needs: release
steps:
- uses: actions/checkout@v4
- name: Setup Rust
uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: stable
override: true
- name: Publish CLI to Crates.io
uses: katyo/publish-crates@v2
with:
registry-token: ${{ secrets.CARGO_REGISTRY_TOKEN }}
npm:
name: Publish lib to npmjs.com
runs-on: ubuntu-latest
needs: release
strategy:
fail-fast: false
matrix:
directory: ["cli/npm", "lib/binding_web"]
steps:
- uses: actions/checkout@v4
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: 18
registry-url: "https://registry.npmjs.org"
- name: Publish lib to npmjs.com
env:
GH_TOKEN: ${{ github.token }}
NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}}
run: |
gh pr merge ${{ github.event.pull_request.html_url }} --match-head-commit $(git rev-parse HEAD) --merge --delete-branch
cd ${{ matrix.directory }}
npm publish