Skip to content

config: add JSON path output (#369) #526

config: add JSON path output (#369)

config: add JSON path output (#369) #526

Workflow file for this run

name: CI
on:
push:
branches: [main]
paths-ignore:
- '**.md'
- 'docs/**'
- 'LICENSE'
- '.github/*.md'
pull_request:
paths-ignore:
- '**.md'
- 'docs/**'
- 'LICENSE'
- '.github/*.md'
workflow_call:
# Cancel in-progress runs for the same branch/PR to avoid wasted resources.
concurrency:
group: ci-${{ github.ref }}
cancel-in-progress: true
permissions:
contents: read
jobs:
test:
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
runs-on: ${{ matrix.os }}
continue-on-error: ${{ matrix.os == 'macos-latest' }}
# Skip push-triggered runs from automated release commits. The release
# workflow already calls ci.yml via workflow_call — an independent
# push-triggered run is a duplicate that races the release's concurrency
# group and can cancel or conflict with the in-flight release CI step.
if: >-
github.event_name != 'push' ||
github.actor != 'github-actions[bot]'
env:
CGO_ENABLED: "0" # Match release build settings
steps:
# Pin actions to full SHA for supply-chain security.
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0
with:
go-version: "1.26.5"
- name: Check formatting (gofmt)
if: runner.os == 'Linux'
run: |
unformatted=$(gofmt -l .)
if [ -n "$unformatted" ]; then
echo "::error::Files need formatting:"
echo "$unformatted"
exit 1
fi
- name: Check modules tidy
if: runner.os == 'Linux'
run: |
go mod tidy
git diff --exit-code go.mod go.sum
- name: Verify module integrity
if: runner.os == 'Linux'
run: go mod verify
- name: Check strict formatting (gofumpt)
if: runner.os == 'Linux'
run: |
go install mvdan.cc/gofumpt@v0.10.0 || { echo "gofumpt install failed, skipping"; exit 0; }
unformatted=$(gofumpt -l .)
if [ -n "$unformatted" ]; then
echo "::error::Files need strict formatting (gofumpt):"
echo "$unformatted"
exit 1
fi
- name: Check dead code
if: runner.os == 'Linux'
run: |
go install golang.org/x/tools/cmd/deadcode@v0.47.0
go install github.com/magefile/mage@v1.17.2
mage deadcode
- run: go build ./...
- run: go vet ./...
- name: golangci-lint
if: runner.os == 'Linux'
uses: golangci/golangci-lint-action@ba0d7d2ec06a0ea1cb5fa41b2e4a3ab91d21278a # v9.3.0
with:
version: v2.12.2
install-mode: goinstall
- name: Test with coverage
if: runner.os == 'Linux'
run: go test -coverprofile=coverage.out -covermode=atomic ./...
- name: Test
if: runner.os != 'Linux'
run: go test ./...
- name: Coverage summary
if: runner.os == 'Linux'
run: go tool cover -func=coverage.out | tail -1
- name: Coverage threshold check
if: runner.os == 'Linux'
run: |
coverage=$(go tool cover -func=coverage.out | tail -1 | awk '{print $NF}' | tr -d '%')
echo "Total coverage: ${coverage}%"
threshold=75
if [ "$(echo "$coverage < $threshold" | bc -l)" -eq 1 ]; then
echo "::error::Coverage ${coverage}% is below minimum threshold ${threshold}%"
exit 1
fi
- name: Upload coverage artifact
if: runner.os == 'Linux'
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: coverage-${{ github.sha }}
path: coverage.out
retention-days: 30
- name: Test (race detector)
if: runner.os == 'Linux'
env:
CGO_ENABLED: "1"
run: go test -race ./... -count=1
- name: govulncheck
if: runner.os == 'Linux'
run: |
go install golang.org/x/vuln/cmd/govulncheck@v1.5.0
govulncheck ./...
# Verify the binary compiles for all release platforms.
# CGO_ENABLED=0 means cross-compilation is pure Go — no native runners needed.
cross-compile:
runs-on: ubuntu-latest
if: github.event_name == 'pull_request' && !github.event.pull_request.draft
env:
CGO_ENABLED: "0"
steps:
# Pin actions to full SHA for supply-chain security.
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0
with:
go-version: "1.26.5"
- name: Cross-compile
run: |
for platform in linux/amd64 linux/arm64 darwin/amd64 darwin/arm64 windows/amd64 windows/arm64; do
os=$(echo $platform | cut -d/ -f1)
arch=$(echo $platform | cut -d/ -f2)
ext=""
if [ "$os" = "windows" ]; then ext=".exe"; fi
echo "Building $os/$arch..."
GOOS=$os GOARCH=$arch CGO_ENABLED=0 go build \
-ldflags "-X github.com/jongio/grut/internal/config.AppVersion=pr-${{ github.event.pull_request.number }}" \
-o "dist/grut_${os}_${arch}${ext}" .
done
- name: Upload artifacts
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: grut-pr-${{ github.event.pull_request.number }}
path: dist/
retention-days: 7