Skip to content

Commit cd114a4

Browse files
committed
ci: adopt storage-go's GitHub Actions setup
Mirror the CI/release pipeline used by tigrisdata/storage-go so objgit gets the same test matrix, supply-chain checks, and automated releases. Workflows (.github/workflows), all with SHA-pinned actions: - go.yml: matrix build/test across ubuntu/windows/macos + arm variants, running `go vet`, `go test`, and staticcheck on every push and PR. The full OS matrix matters here because objgit shells out to git/ssh/ ssh-keygen for its protocol tests, so cross-platform regressions are real. A trailing `autorelease` job dispatches release.yaml on main so a green build can cut a release without manual steps. - zizmor.yml: scans the workflow files themselves for CI misconfig and uploads SARIF; runs only when a workflow changes. - lint-pr-titles.yaml: enforces conventional-commit PR titles, which is what semantic-release reads to decide the version bump. - dco_check.yaml: requires Signed-off-by on every PR (DCO). - pull_request_template.md: standard summary/details/test-plan checklist. Release tooling: - package.json carries the semantic-release config (commit-analyzer release rules, changelog, GitHub release, git asset commit), plus commitlint, lint-staged, and prettier so local commits match CI expectations. npmPublish is off; this is a Go binary, semantic-release is used purely for tagging/changelog/GitHub releases. - release.yaml runs semantic-release on a throwaway release-* branch and opens a release PR (needs the WRITE_GH_TOKEN secret), matching storage-go's "release via PR" flow. - .husky/{commit-msg,pre-commit} wire commitlint + npm test and lint-staged into git hooks; package-lock.json is committed so `npm ci` in release.yaml is reproducible. - .prettierignore excludes CLAUDE.md; .gitignore now ignores node_modules. Build/tooling: - Add goimports and staticcheck as `go tool` directives so the format hook (`go tool goimports`) and local linting work without global installs, matching storage-go. `go mod tidy` also dropped a stale self-referential require on the old tangled.org module path left over from the org move. - Drop the unused embedded s3Client from optRecorder in resilient_test.go: it overrides all nine interface methods directly, so the embed was dead and tripped staticcheck (U1000), which would have made the new pipeline red on its first run. Docs: - Consolidate agent guidance into AGENTS.md and point CLAUDE.md at it, matching storage-go's layout. Assisted-by: Claude Opus 4.8 via Claude Code Signed-off-by: Xe Iaso <xe@tigrisdata.com>
1 parent ca4f6d6 commit cd114a4

17 files changed

Lines changed: 7959 additions & 201 deletions

.github/pull_request_template.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
## Summary
2+
3+
-
4+
-
5+
6+
## Details
7+
8+
## Test plan
9+
10+
- [ ] Code compiles with `go build ./...`
11+
- [ ] Code formatted with `npm run format`
12+
- [ ] Manual testing

.github/workflows/dco_check.yaml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
name: DCO Check
2+
3+
on: [pull_request]
4+
5+
jobs:
6+
check:
7+
runs-on: ubuntu-latest
8+
steps:
9+
- uses: tisonkun/actions-dco@f1024cd563550b5632e754df11b7d30b73be54a5 # v1.1

.github/workflows/go.yml

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
name: Go
2+
3+
on:
4+
push:
5+
branches: ["main"]
6+
pull_request:
7+
branches: ["main"]
8+
9+
permissions:
10+
contents: read
11+
actions: write
12+
13+
jobs:
14+
go_tests:
15+
strategy:
16+
matrix:
17+
os:
18+
- ubuntu-24.04
19+
- windows-2025
20+
- macos-15
21+
- ubuntu-24.04-arm
22+
- windows-11-arm
23+
runs-on: ${{ matrix.os }}
24+
steps:
25+
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
26+
with:
27+
persist-credentials: false
28+
fetch-tags: true
29+
30+
- uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0
31+
with:
32+
node-version: latest
33+
34+
- uses: actions/setup-go@44694675825211faa026b3c33043df3e48a5fa00 # v6.0.0
35+
with:
36+
go-version: stable
37+
38+
- name: Test
39+
run: |
40+
go vet ./...
41+
go test ./...
42+
43+
- uses: dominikh/staticcheck-action@024238d2898c874f26d723e7d0ff4308c35589a2 # v1.4.0
44+
with:
45+
version: "latest"
46+
install-go: false
47+
48+
autorelease:
49+
runs-on: ubuntu-latest
50+
needs: [go_tests]
51+
steps:
52+
- name: "Cut release if CI passes"
53+
if: "${{ github.ref == 'refs/heads/main' }}"
54+
uses: benc-uk/workflow-dispatch@e2e5e9a103e331dad343f381a29e654aea3cf8fc # v1.2.4
55+
with:
56+
workflow: "release.yaml"
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
name: "Lint PR"
2+
3+
on:
4+
pull_request_target:
5+
types:
6+
- opened
7+
- edited
8+
- synchronize
9+
- reopened
10+
11+
jobs:
12+
main:
13+
name: Validate PR title
14+
runs-on: ubuntu-latest
15+
permissions:
16+
pull-requests: read
17+
steps:
18+
- uses: amannn/action-semantic-pull-request@0723387faaf9b38adef4775cd42cfd5155ed6017 # v5.5.3
19+
env:
20+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

.github/workflows/release.yaml

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
name: Cut Release
2+
on:
3+
workflow_dispatch: {}
4+
5+
permissions:
6+
contents: write
7+
pull-requests: write
8+
9+
jobs:
10+
release:
11+
runs-on: ubuntu-latest
12+
steps:
13+
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
14+
with:
15+
persist-credentials: true
16+
fetch-tags: true
17+
fetch-depth: 0
18+
token: ${{ secrets.WRITE_GH_TOKEN }}
19+
20+
- uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6.1.0
21+
with:
22+
node-version: "latest" # does not matter for our needs
23+
24+
- uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0
25+
with:
26+
go-version: "stable"
27+
28+
- name: Setup Git
29+
run: |
30+
git config user.name "github-actions[bot]"
31+
git config user.email "github-actions[bot]@users.noreply.github.com"
32+
33+
- name: Create release branch and run semantic-release
34+
env:
35+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
36+
run: |
37+
npm ci
38+
39+
# Create a unique release branch
40+
TIMESTAMP=$(date +%s)
41+
BRANCH_NAME="release-${TIMESTAMP}"
42+
43+
# Create and checkout release branch
44+
git checkout -b "${BRANCH_NAME}"
45+
46+
# Run semantic-release on the release branch
47+
npx semantic-release --debug
48+
49+
# Check if semantic-release made changes
50+
if git diff --quiet origin/main HEAD 2>/dev/null || [ $(git rev-list --count HEAD ^origin/main) -eq 0 ]; then
51+
echo "No release created"
52+
exit 0
53+
fi
54+
55+
# Push the release branch
56+
git push origin "${BRANCH_NAME}"
57+
58+
# Get the version from the commit message or package.json
59+
VERSION=$(node -p "require('./package.json').version" 2>/dev/null || echo "unknown")
60+
61+
# Create pull request
62+
gh pr create \
63+
--title "chore(release): ${VERSION}" \
64+
--body "Automated release PR for version ${VERSION}. This PR includes updates to CHANGELOG.md and package.json. Once this PR is merged to main, the GitHub release will be created automatically." \
65+
--base main \
66+
--head "${BRANCH_NAME}" \
67+
--label "release"
68+
69+
- name: Clean up old release branches
70+
if: always()
71+
env:
72+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
73+
run: |
74+
# Get all release branches except the current one
75+
for branch in $(git ls-remote --heads origin "release-*" | awk '{print $2}' | sed 's|refs/heads/||' | grep -v "^${BRANCH_NAME}$"); do
76+
echo "Deleting old release branch: ${branch}"
77+
git push origin --delete "${branch}" || true
78+
done

.github/workflows/zizmor.yml

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
name: zizmor
2+
3+
on:
4+
push:
5+
paths:
6+
- ".github/workflows/*.ya?ml"
7+
pull_request:
8+
paths:
9+
- ".github/workflows/*.ya?ml"
10+
11+
jobs:
12+
zizmor:
13+
name: zizmor latest via PyPI
14+
runs-on: ubuntu-24.04
15+
permissions:
16+
security-events: write
17+
steps:
18+
- name: Checkout repository
19+
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
20+
with:
21+
persist-credentials: false
22+
23+
- name: Install the latest version of uv
24+
uses: astral-sh/setup-uv@681c641aba71e4a1c380be3ab5e12ad51f415867 # v7.1.6
25+
26+
- name: Run zizmor 🌈
27+
run: uvx zizmor --format sarif . > results.sarif
28+
env:
29+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
30+
31+
- name: Upload SARIF file
32+
uses: github/codeql-action/upload-sarif@5d4e8d1aca955e8d8589aabd499c5cae939e33c7 # v4.31.9
33+
with:
34+
sarif_file: results.sarif
35+
category: zizmor

.gitignore

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,4 @@
11
.env
2-
/objgitd
2+
/objgitd
3+
4+
node_modules

.husky/commit-msg

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
npx --no-install commitlint --edit "$1"
2+
3+
case "$(cat $1)" in
4+
*"[skip ci]"*)
5+
exit 0
6+
;;
7+
*)
8+
npm test
9+
;;
10+
esac

.husky/pre-commit

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
npx lint-staged

.prettierignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
/CLAUDE.md

0 commit comments

Comments
 (0)