Skip to content

Add merge-queue skill and document label-driven merge workflow #811

Add merge-queue skill and document label-driven merge workflow

Add merge-queue skill and document label-driven merge workflow #811

Workflow file for this run

name: CI
on:
push:
branches: [main]
pull_request:
branches: [main]
merge_group:
branches: [main]
workflow_dispatch:
permissions:
contents: read
jobs:
zizmor:
runs-on: ubuntu-latest
permissions:
contents: read
security-events: write
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- name: Install zizmor
run: pip install zizmor==1.6.0
- name: Run zizmor
run: zizmor --format sarif . > results.sarif
- name: Upload SARIF
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository
uses: github/codeql-action/upload-sarif@5c8a8a642e79153f5d047b10ec1cba1d1cc65699 # v3
with:
sarif_file: results.sarif
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6.2.0
with:
go-version-file: go.mod
- run: go tool golangci-lint run
mdsmith:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6.2.0
with:
go-version-file: go.mod
- run: go build -o mdsmith ./cmd/mdsmith
- run: ./mdsmith check .
demo:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6.2.0
with:
go-version-file: go.mod
- name: Build mdsmith
run: go build -o mdsmith ./cmd/mdsmith
- name: Cache VHS + ttyd binaries
id: vhs-cache
uses: actions/cache@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4
with:
path: |
~/vhs-bin
key: vhs-0.10.0-ttyd-1.7.7-${{ runner.os }}-${{ runner.arch }}
- name: Install VHS runtime dependencies
run: |
# Google Chrome is pre-installed on GitHub runners and
# go-rod (used by VHS) finds it via launcher.LookPath().
# Installing chromium via apt on Ubuntu 24.04 triggers a
# slow snap install (~500 MB of dependencies), so we skip
# it and only install ffmpeg.
sudo apt-get update -qq
sudo apt-get install -y -qq ffmpeg
if [ -f ~/vhs-bin/ttyd ]; then
sudo install ~/vhs-bin/ttyd /usr/local/bin/ttyd
else
curl -fsSL -o /tmp/ttyd \
"https://github.com/tsl0922/ttyd/releases/download/1.7.7/ttyd.x86_64"
sudo install /tmp/ttyd /usr/local/bin/ttyd
fi
- name: Install VHS
run: |
if [ -f ~/vhs-bin/vhs ]; then
sudo install ~/vhs-bin/vhs /usr/local/bin/vhs
else
go install github.com/charmbracelet/vhs@v0.10.0
fi
echo "$(go env GOPATH)/bin" >> "$GITHUB_PATH"
- name: Populate VHS cache
if: steps.vhs-cache.outputs.cache-hit != 'true'
run: |
mkdir -p ~/vhs-bin
cp /usr/local/bin/ttyd ~/vhs-bin/
cp "$(go env GOPATH)/bin/vhs" ~/vhs-bin/ 2>/dev/null || cp /usr/local/bin/vhs ~/vhs-bin/ 2>/dev/null || true
- name: Record demo
run: vhs demo.tape
- name: Validate GIF
run: |
file="assets/demo.gif"
if [ ! -f "$file" ]; then
echo "ERROR: $file not produced" >&2
exit 1
fi
header=$(head -c 6 "$file")
if [ "$header" != "GIF89a" ] && [ "$header" != "GIF87a" ]; then
echo "ERROR: $file is not a valid GIF (header: $header)" >&2
exit 1
fi
size=$(stat -c%s "$file")
if [ "$size" -lt 10240 ]; then
echo "ERROR: $file too small (${size} bytes < 10 KB)" >&2
exit 1
fi
if [ "$size" -gt 5242880 ]; then
echo "ERROR: $file too large (${size} bytes > 5 MB)" >&2
exit 1
fi
echo "assets/demo.gif OK — ${size} bytes, header: $header"
test:
runs-on: ubuntu-latest
permissions:
contents: read
id-token: write
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6.2.0
with:
go-version-file: go.mod
- name: Run tests with coverage
run: |
mkdir -p "$GITHUB_WORKSPACE/e2e-cover"
E2E_COVERDIR="$GITHUB_WORKSPACE/e2e-cover" go test -covermode=atomic -coverprofile=unit.cov ./...
- name: Merge coverage profiles
run: |
head -1 unit.cov > merged.cov
# Exclude cmd/mdsmith from unit profile — those functions
# are only exercised via the subprocess binary, so the
# test-process counters are always zero.
tail -n +2 unit.cov | grep -v 'cmd/mdsmith/' >> merged.cov || true
e2e_profile="$GITHUB_WORKSPACE/e2e-cover/e2e_coverage.txt"
if [ ! -f "$e2e_profile" ]; then
echo "e2e_coverage.txt not found — cmd/mdsmith coverage will be missing" >&2
exit 1
fi
unit_mode_line=$(head -1 unit.cov)
e2e_mode_line=$(head -1 "$e2e_profile")
if [ "$unit_mode_line" != "$e2e_mode_line" ]; then
echo "Coverage mode mismatch: unit='$unit_mode_line' e2e='$e2e_mode_line'" >&2
exit 1
fi
e2e_lines=$(tail -n +2 "$e2e_profile" | grep -c 'cmd/mdsmith/' || true)
if [ "$e2e_lines" -eq 0 ]; then
echo "e2e profile contains no cmd/mdsmith/ coverage lines" >&2
exit 1
fi
tail -n +2 "$e2e_profile" | grep 'cmd/mdsmith/' >> merged.cov
- name: Coverage summary
run: |
total=$(go tool cover -func=merged.cov | tail -1)
{
echo '## Test Coverage'
echo '```'
echo "$total"
echo '```'
echo ''
echo '<details><summary>Per-package breakdown</summary>'
echo ''
echo '```'
go tool cover -func=merged.cov
echo '```'
echo '</details>'
} >> "$GITHUB_STEP_SUMMARY"
- name: Upload coverage to Codecov
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository
uses: codecov/codecov-action@57e3a136b779b570ffcdbf80b3bdc90e7fab3de2 # v6.0.0
with:
use_oidc: true
files: merged.cov
fail_ci_if_error: false