ci: cross-platform test matrix with git version testing #3584
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| on: | |
| push: | |
| branches: | |
| - main | |
| pull_request: | |
| workflow_dispatch: | |
| name: CI | |
| jobs: | |
| init: | |
| runs-on: ubuntu-latest | |
| outputs: | |
| runners: ${{ steps.matrix.outputs.runners }} | |
| git-versions: ${{ steps.matrix.outputs.git-versions }} | |
| ctags-versions: ${{ steps.matrix.outputs.ctags-versions }} | |
| steps: | |
| - name: Define matrix | |
| id: matrix | |
| run: | | |
| echo 'runners=["ubuntu-24.04","ubuntu-22.04","ubuntu-24.04-arm","ubuntu-22.04-arm","macos-15","macos-26","macos-15-intel","macos-26-intel"]' >> "$GITHUB_OUTPUT" | |
| # Git versions to test against: | |
| # 2.34.1 — Ubuntu 22.04 LTS (Jammy), oldest supported LTS, ships 1:2.34.1-1ubuntu1 | |
| # 2.39.5 — Debian 12 (Bookworm), ships 1:2.39.5-0+deb12u3, reported failing in #1029 | |
| # 2.47.3 — Debian 13 (Trixie) + Alpine 3.21, ships 1:2.47.3-0+deb13u1, also failing in #1029 | |
| # 2.53.0 — Latest stable (2026-02-02), first version with cat-file --batch --filter= (added in 2.50.0) | |
| echo 'git-versions=["2.34.1","2.39.5","2.47.3","2.53.0"]' >> "$GITHUB_OUTPUT" | |
| # Universal-ctags versions to test against: | |
| # p5.9.20210829.0 — Ubuntu 22.04/24.04 LTS, ships 5.9.20210829.0-1 (2021-08-29 snapshot) | |
| # v6.2.1 — Latest stable, matches Homebrew and Alpine Edge | |
| echo 'ctags-versions=["p5.9.20210829.0","v6.2.1"]' >> "$GITHUB_OUTPUT" | |
| build-git: | |
| needs: init | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| runner: ${{ fromJSON(needs.init.outputs.runners) }} | |
| git-version: ${{ fromJSON(needs.init.outputs.git-versions) }} | |
| runs-on: ${{ matrix.runner }} | |
| name: build-git (${{ matrix.runner }}, git ${{ matrix.git-version }}) | |
| steps: | |
| - name: Cache git build | |
| id: cache-git | |
| uses: actions/cache@v5.0.4 | |
| with: | |
| path: ~/git-install | |
| key: git-${{ matrix.git-version }}-${{ matrix.runner }} | |
| - name: Install dependencies (Linux) | |
| if: runner.os == 'Linux' | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y make libssl-dev libcurl4-gnutls-dev libexpat1-dev libz-dev gettext | |
| - name: Install dependencies (macOS) | |
| if: runner.os == 'macOS' | |
| run: brew install openssl curl expat gettext | |
| - name: Build git from source | |
| if: steps.cache-git.outputs.cache-hit != 'true' | |
| run: | | |
| curl -fsSL "https://www.kernel.org/pub/software/scm/git/git-${{ matrix.git-version }}.tar.gz" | tar xz | |
| cd "git-${{ matrix.git-version }}" | |
| NPROC=$(nproc 2>/dev/null || sysctl -n hw.ncpu) | |
| # On macOS, Homebrew keg-only packages (openssl, curl, gettext) are | |
| # not linked into the default search paths. Git's config.mak.uname | |
| # gained Homebrew auto-detection around v2.47, but older versions | |
| # (2.34.1, 2.39.5) lack it. Git's Makefile auto-includes config.mak, | |
| # so we write the paths there to avoid shell quoting issues with | |
| # make command-line variables. | |
| if [ "$RUNNER_OS" = "macOS" ]; then | |
| BREW_PREFIX=$(brew --prefix) | |
| cat > config.mak <<CFGEOF | |
| CPPFLAGS += -I${BREW_PREFIX}/opt/openssl/include -I${BREW_PREFIX}/opt/curl/include -I${BREW_PREFIX}/opt/expat/include -I${BREW_PREFIX}/opt/gettext/include | |
| LDFLAGS += -L${BREW_PREFIX}/opt/openssl/lib -L${BREW_PREFIX}/opt/curl/lib -L${BREW_PREFIX}/opt/expat/lib -L${BREW_PREFIX}/opt/gettext/lib | |
| CFGEOF | |
| fi | |
| make prefix="$HOME/git-install" -j"$NPROC" all | |
| make prefix="$HOME/git-install" install | |
| - name: Verify git build | |
| run: | | |
| "$HOME/git-install/bin/git" --version | |
| "$HOME/git-install/bin/git" --version | grep -q "${{ matrix.git-version }}" | |
| - name: Upload git binaries | |
| uses: actions/upload-artifact@v7.0.0 | |
| with: | |
| name: git-${{ matrix.git-version }}-${{ matrix.runner }} | |
| path: ~/git-install | |
| retention-days: 1 | |
| build-ctags: | |
| needs: init | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| runner: ${{ fromJSON(needs.init.outputs.runners) }} | |
| ctags-version: ${{ fromJSON(needs.init.outputs.ctags-versions) }} | |
| runs-on: ${{ matrix.runner }} | |
| name: build-ctags (${{ matrix.runner }}, ctags ${{ matrix.ctags-version }}) | |
| steps: | |
| - name: Cache ctags build | |
| id: cache-ctags | |
| uses: actions/cache@v5.0.4 | |
| with: | |
| path: ~/ctags-install | |
| key: ctags-${{ matrix.ctags-version }}-${{ matrix.runner }} | |
| - name: Install dependencies (Linux) | |
| if: runner.os == 'Linux' | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y gcc make pkg-config autoconf automake libjansson-dev libyaml-dev libxml2-dev | |
| - name: Install dependencies (macOS) | |
| if: runner.os == 'macOS' | |
| run: brew install autoconf automake pkg-config jansson libyaml pcre2 | |
| - name: Build universal-ctags from source | |
| if: steps.cache-ctags.outputs.cache-hit != 'true' | |
| run: | | |
| curl -fsSL "https://github.com/universal-ctags/ctags/archive/refs/tags/${{ matrix.ctags-version }}.tar.gz" | tar xz | |
| cd ctags-*/ | |
| NPROC=$(nproc 2>/dev/null || sysctl -n hw.ncpu) | |
| ./autogen.sh | |
| ./configure --prefix="$HOME/ctags-install" --program-prefix=universal- --enable-json | |
| make -j"$NPROC" | |
| make install | |
| - name: Verify ctags build | |
| run: | | |
| "$HOME/ctags-install/bin/universal-ctags" --version | |
| "$HOME/ctags-install/bin/universal-ctags" --version | grep -q "Universal Ctags" | |
| - name: Upload ctags binaries | |
| uses: actions/upload-artifact@v7.0.0 | |
| with: | |
| name: ctags-${{ matrix.ctags-version }}-${{ matrix.runner }} | |
| path: ~/ctags-install | |
| retention-days: 1 | |
| test: | |
| needs: [init, build-git, build-ctags] | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| runner: ${{ fromJSON(needs.init.outputs.runners) }} | |
| git-version: ${{ fromJSON(needs.init.outputs.git-versions) }} | |
| ctags-version: ${{ fromJSON(needs.init.outputs.ctags-versions) }} | |
| runs-on: ${{ matrix.runner }} | |
| name: test (${{ matrix.runner }}, git ${{ matrix.git-version }}, ctags ${{ matrix.ctags-version }}) | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v6.0.2 | |
| - name: Set up Go | |
| uses: actions/setup-go@v6.4.0 | |
| with: | |
| go-version-file: go.mod | |
| - name: Download git binaries | |
| uses: actions/download-artifact@v8.0.1 | |
| with: | |
| name: git-${{ matrix.git-version }}-${{ matrix.runner }} | |
| path: ~/git-install | |
| - name: Add git to PATH | |
| run: | | |
| chmod -R +x "$HOME/git-install/bin" "$HOME/git-install/libexec" | |
| echo "$HOME/git-install/bin" >> "$GITHUB_PATH" | |
| - name: Download ctags binaries | |
| uses: actions/download-artifact@v8.0.1 | |
| with: | |
| name: ctags-${{ matrix.ctags-version }}-${{ matrix.runner }} | |
| path: ~/ctags-install | |
| - name: Add ctags to PATH | |
| run: | | |
| chmod -R +x "$HOME/ctags-install/bin" | |
| echo "$HOME/ctags-install/bin" >> "$GITHUB_PATH" | |
| - name: Install ctags runtime dependencies (Linux) | |
| if: runner.os == 'Linux' | |
| run: sudo apt-get update && sudo apt-get install -y libjansson4 libyaml-0-2 libxml2 | |
| - name: Install ctags runtime dependencies (macOS) | |
| if: runner.os == 'macOS' | |
| run: brew install jansson libyaml pcre2 | |
| - name: Print versions | |
| run: | | |
| go version | |
| git --version | |
| git --version | grep -q "${{ matrix.git-version }}" | |
| universal-ctags --version | |
| - name: Test | |
| run: go test ./... | |
| fuzz-test: | |
| name: fuzz test | |
| runs-on: ubuntu-latest | |
| container: alpine:edge | |
| steps: | |
| - name: add dependencies | |
| run: apk add bash go | |
| - uses: jidicula/go-fuzz-action@2d8b802597c47a79764d83dabc27fb672f2fb8d9 | |
| with: | |
| packages: 'github.com/sourcegraph/zoekt' # This is the package where the Protobuf round trip tests are defined | |
| fuzz-time: 30s | |
| fuzz-minimize-time: 1m | |
| go-version: '1.23' | |
| shellcheck: | |
| name: shellcheck | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v3 | |
| - name: Run ShellCheck | |
| uses: ludeeus/action-shellcheck@1.1.0 | |
| shfmt: | |
| name: shfmt | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v3 | |
| - uses: reviewdog/action-shfmt@v1.0.2 | |
| with: | |
| filter_mode: "nofilter" | |
| fail_on_error: "true" | |
| shfmt_flags: "-i 2 -ci -bn" | |
| lint-protos: | |
| name: "buf lint" | |
| runs-on: ubuntu-latest | |
| steps: | |
| # Run `git checkout` | |
| - uses: actions/checkout@v2 | |
| # Install the `buf` CLI | |
| - uses: bufbuild/buf-setup-action@v1 | |
| with: | |
| github_token: ${{ secrets.GH_TOKEN }} | |
| # Lint your Protobuf sources | |
| - run: .github/workflows/buf-lint-check.sh | |
| format-protos: | |
| name: "buf format" | |
| runs-on: ubuntu-latest | |
| steps: | |
| # Run `git checkout` | |
| - uses: actions/checkout@v2 | |
| # Install the `buf` CLI | |
| - uses: bufbuild/buf-setup-action@v1 | |
| with: | |
| github_token: ${{ secrets.GH_TOKEN }} | |
| # Check to see if the Protobuf sources are formatted | |
| - run: .github/workflows/buf-format-check.sh | |
| generate-protos: | |
| name: "buf generate" | |
| runs-on: ubuntu-latest | |
| steps: | |
| # Run `git checkout` | |
| - uses: actions/checkout@v2 | |
| # Install the `buf` CLI | |
| - uses: bufbuild/buf-setup-action@v1 | |
| with: | |
| github_token: ${{ secrets.GH_TOKEN }} | |
| # Check if the generated code is up-to-date | |
| - run: .github/workflows/buf-generate-check.sh | |