Skip to content

Commit fb73579

Browse files
committed
build(ci): harden release workflow + add issue/PR templates
- release.yml: add a validate gate (go test + golangci-lint + goreleaser check) that the release job depends on, so a broken tag never publishes. Add workflow_dispatch that runs a snapshot dry-run (build everything, publish nothing) to rehearse a release. Scope write/id-token permissions to the release job only; the gate runs read-only. - Add .github/ISSUE_TEMPLATE: a structured bug report (version, engine, OS, exit code) and feature request (problem/proposal/area), plus a config.yml routing questions to Discussions and security reports to the security policy. - Add a PR template with a verification checklist matching the project's discipline (test, lint, integration, docs/CHANGELOG, web build).
1 parent c086ad5 commit fb73579

5 files changed

Lines changed: 175 additions & 7 deletions

File tree

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
name: Bug report
2+
description: Something siphon did wrong — a crash, wrong output, or a failed operation.
3+
labels: ["bug"]
4+
body:
5+
- type: markdown
6+
attributes:
7+
value: |
8+
Thanks for the report. Please include enough to reproduce — siphon shells
9+
out to native dump/restore tools, so the exact command and engine matter.
10+
- type: textarea
11+
id: what-happened
12+
attributes:
13+
label: What happened
14+
description: What you ran and what went wrong. Paste the command and the error.
15+
placeholder: |
16+
$ siphon backup prod
17+
✗ ...
18+
validations:
19+
required: true
20+
- type: textarea
21+
id: expected
22+
attributes:
23+
label: What you expected
24+
validations:
25+
required: true
26+
- type: input
27+
id: version
28+
attributes:
29+
label: siphon version
30+
description: Output of `siphon --version`.
31+
placeholder: "v1.0.0"
32+
validations:
33+
required: true
34+
- type: dropdown
35+
id: engine
36+
attributes:
37+
label: Database engine
38+
options:
39+
- PostgreSQL
40+
- MySQL
41+
- MariaDB
42+
- Cross-engine (specify in details)
43+
- Not engine-specific
44+
validations:
45+
required: true
46+
- type: dropdown
47+
id: os
48+
attributes:
49+
label: OS
50+
options: [Linux, macOS, Windows]
51+
validations:
52+
required: true
53+
- type: input
54+
id: exit-code
55+
attributes:
56+
label: Exit code
57+
description: siphon uses a POSIX exit-code taxonomy; the number helps classify the failure.
58+
placeholder: "e.g. 1 (user), 70 (system), 65 (integrity)"
59+
- type: textarea
60+
id: details
61+
attributes:
62+
label: Anything else
63+
description: Profile config (redact secrets), storage backend, logs, repro steps.

.github/ISSUE_TEMPLATE/config.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
blank_issues_enabled: false
2+
contact_links:
3+
- name: Question or discussion
4+
url: https://github.com/nixrajput/siphon/discussions
5+
about: For usage questions and ideas, start a discussion instead of an issue.
6+
- name: Security vulnerability
7+
url: https://github.com/nixrajput/siphon/security/policy
8+
about: Please report security issues privately, not as a public issue.
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
name: Feature request
2+
description: Suggest a capability or improvement.
3+
labels: ["enhancement"]
4+
body:
5+
- type: textarea
6+
id: problem
7+
attributes:
8+
label: The problem
9+
description: What are you trying to do that siphon makes hard or impossible today?
10+
validations:
11+
required: true
12+
- type: textarea
13+
id: proposal
14+
attributes:
15+
label: Proposed solution
16+
description: What you'd like siphon to do. A command sketch helps.
17+
validations:
18+
required: true
19+
- type: textarea
20+
id: alternatives
21+
attributes:
22+
label: Alternatives considered
23+
- type: dropdown
24+
id: area
25+
attributes:
26+
label: Area
27+
options:
28+
- Backup / restore
29+
- Sync / CDC / cross-engine
30+
- Storage backends
31+
- Retention
32+
- Secrets / auth / audit
33+
- TUI
34+
- Drivers (new engine)
35+
- Other
36+
validations:
37+
required: true

.github/pull_request_template.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
## What & why
2+
3+
<!-- What this changes and the reason. Link any issue: Closes #123. -->
4+
5+
## How it was verified
6+
7+
<!-- Commands run and their outcome — evidence, not assertions. -->
8+
9+
- [ ] `make test` passes
10+
- [ ] `make lint` passes (0 issues)
11+
- [ ] `make test-integration` (if the change touches a live DB / storage path)
12+
- [ ] Docs updated (README / `docs/*.md` / CHANGELOG) for any user-facing change
13+
- [ ] `web/` builds (`npm run build`) — only if the site changed
14+
15+
## Notes for reviewers
16+
17+
<!-- Anything non-obvious: a deliberate scope decision, a deferred follow-up,
18+
a tradeoff, or a place you'd especially like eyes. -->

.github/workflows/release.yml

Lines changed: 49 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,53 @@
11
name: Release
22

3-
# Fires on a version tag (e.g. v1.0.0). GoReleaser builds the cross-platform
4-
# binaries, checksums, and cosign-keyless signatures, publishes a GitHub
5-
# Release, and — when the tap repos + tokens exist — pushes the Homebrew
6-
# formula and Scoop manifest.
3+
# Auto-releases when a version tag (vX.Y.Z) is pushed. GoReleaser builds the
4+
# cross-platform binaries, SHA-256 checksums, and cosign-keyless signatures,
5+
# publishes a GitHub Release, and — when the tap repos + tokens exist — pushes
6+
# the Homebrew formula and Scoop manifest.
7+
#
8+
# A validation gate (test + lint + config check) runs first, so a broken tag
9+
# never publishes. workflow_dispatch runs a snapshot dry-run (no publish) to
10+
# rehearse a release without tagging.
711
on:
812
push:
913
tags:
1014
- "v*"
15+
workflow_dispatch: {}
1116

1217
permissions:
13-
contents: write # create the GitHub Release
14-
id-token: write # cosign keyless signing via GitHub OIDC
18+
contents: read
1519

1620
jobs:
21+
# Gate: the same checks CI runs, plus goreleaser config validation. The
22+
# release job depends on this, so a failing test/lint aborts before publish.
23+
validate:
24+
name: Validate
25+
runs-on: ubuntu-latest
26+
steps:
27+
- uses: actions/checkout@v6
28+
with:
29+
fetch-depth: 0
30+
- uses: actions/setup-go@v6
31+
with:
32+
go-version: stable
33+
cache: true
34+
- name: Test
35+
run: go test ./... github.com/nixrajput/siphon/internal/driver/_mysqlcommon
36+
- name: Lint
37+
uses: golangci/golangci-lint-action@v6
38+
- name: GoReleaser check
39+
uses: goreleaser/goreleaser-action@v6
40+
with:
41+
version: "~> v2"
42+
args: check
43+
1744
release:
1845
name: Release
46+
needs: validate
1947
runs-on: ubuntu-latest
48+
permissions:
49+
contents: write # create the GitHub Release
50+
id-token: write # cosign keyless signing via GitHub OIDC
2051
steps:
2152
- uses: actions/checkout@v6
2253
with:
@@ -30,11 +61,22 @@ jobs:
3061
- name: Install cosign
3162
uses: sigstore/cosign-installer@v3
3263

64+
# On a tag push: full release. On manual dispatch: snapshot dry-run that
65+
# builds everything locally and publishes nothing (rehearsal).
66+
- name: Set release args
67+
id: args
68+
run: |
69+
if [ "${{ github.ref_type }}" = "tag" ]; then
70+
echo "args=release --clean" >> "$GITHUB_OUTPUT"
71+
else
72+
echo "args=release --clean --snapshot" >> "$GITHUB_OUTPUT"
73+
fi
74+
3375
- name: Run GoReleaser
3476
uses: goreleaser/goreleaser-action@v6
3577
with:
3678
version: "~> v2"
37-
args: release --clean
79+
args: ${{ steps.args.outputs.args }}
3880
env:
3981
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
4082
# Tap-push tokens. These secrets may be unset on early releases; a

0 commit comments

Comments
 (0)