From c3ab70cc988f7ec5fd462b2713abe9834ab8a8e9 Mon Sep 17 00:00:00 2001 From: dundargoc Date: Tue, 6 Feb 2024 00:16:27 +0100 Subject: [PATCH] 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. --- .github/workflows/CICD.yml | 66 ------------------- .github/workflows/build.yml | 23 +++---- .github/workflows/ci.yml | 23 +++++++ .github/workflows/publish.yml | 63 ------------------ .github/workflows/release.yml | 121 +++++++++++++++------------------- 5 files changed, 85 insertions(+), 211 deletions(-) delete mode 100644 .github/workflows/CICD.yml create mode 100644 .github/workflows/ci.yml delete mode 100644 .github/workflows/publish.yml diff --git a/.github/workflows/CICD.yml b/.github/workflows/CICD.yml deleted file mode 100644 index d8cc7f96..00000000 --- a/.github/workflows/CICD.yml +++ /dev/null @@ -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 diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index f288dd6c..f9fb8f7a 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -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 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 00000000..67f62bad --- /dev/null +++ b/.github/workflows/ci.yml @@ -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 diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml deleted file mode 100644 index b4e54d33..00000000 --- a/.github/workflows/publish.yml +++ /dev/null @@ -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 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index e6ee9e1c..eadbab6e 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -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