Workflows
Skill AndriyKalashnykov/flight-path/.claude/skills/workflows
Project-specific development workflows for the flight-path Go project: adding endpoints, benchmarking, releasing, Docker builds, and CI pipelines. Use when following a development process, preparing a release, running CI locally, or understanding the build pipeline. Do NOT use for environment setup, troubleshooting errors, or debugging specific failures.From its SKILL.md
npx -y skills add AndriyKalashnykov/flight-path --skill workflowsAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
2 things to look at
- 1 stars1 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
- runs commandsInstructs the agent to run 8 commands, including `make api-docs` and 7 more.
SKILL.md
8.3 KB, ~2.2k tokens by cl100k_base, as published. Nobody here has run it
Development Workflows
Adding a New Endpoint
- Create handler method on
Handlerstruct ininternal/handlers/with Swagger annotations - Register route in
internal/routes/(receives*handlers.Handler) - Wire route in
main.go - Run
make api-docs - Write table-driven tests
- Add Postman test case to
test/FlightPath.postman_collection.json - Run:
make test && make build
Performance Optimization
make bench-save(baseline — saved tobenchmarks/bench_YYYYMMDD_HHMMSS.txt)- Implement optimization
make bench-save(after)make bench-compare(auto-picks latest two files, or specifyOLD=file1 NEW=file2)make test(verify correctness)
Benchmarks run: go test ./internal/handlers/ -bench=. -benchmem -benchtime=3s
Pre-commit Checklist
Quick way:
make check # Alias for `make ci` — runs the full local pipeline (see "Local CI" below)
Or individual steps:
make lint # golangci-lint (60+ linters)
make sec # gosec security scanner
make vulncheck # govulncheck dependency check
make secrets # gitleaks secrets detection
make test # Unit tests
make api-docs # Regenerate Swagger docs
make build # Compile binary (depends on api-docs)
Local CI
make ci # full pipeline: deps + static-check + test + integration-test + coverage + coverage-check + build + fuzz + deps-prune-check
make ci-run # run the GitHub Actions workflow locally via act
make check is an alias for make ci.
Release
- Ensure a clean
mainbranch with an upstream set make release— runs the fullcipipeline first, then validates the semver tag (vN.N.N), updatespkg/api/version.txt, commits, tags, and pushes- On the tag push, the tag-gated
goreleaseranddockerjobs in.github/workflows/ci.ymlrun (there is no separaterelease.yml): GoReleaser builds binaries/archives/checksums + the GitHub Release, anddockerpushes the cosign-signed multi-arch image to GHCR. They are serialized vianeeds:so a tag produces both artifacts or neither.
make release depends on ci (the full local pipeline).
Docker
make image-build # Build image locally (single platform, buildx)
make image-run # Build + run container (binds a free host port, --env-file .env.example)
make image-test # Build + smoke-test + structure-test
make image-push # Build + push to GHCR (requires GH_ACCESS_TOKEN)
- Image: multi-stage build (
golang:1.26-alpine->alpine:3.23.4) - Non-root user:
srvuser:srvgroup(uid/gid 1000),CGO_ENABLED=0 - Platforms:
linux/amd64,linux/arm64,linux/arm/v7 - Registry: GHCR —
make image-pushtagsghcr.io/<user>/flight-path:<git-tag>. The release-grade multi-arch build + cosign signing is done by thedockerjob in ci.yml on tag pushes, not by the local target.
CI Pipeline (GitHub Actions)
Pipeline in .github/workflows/ci.yml, runs on push to main, tags v*, and PRs. A changes job (dorny/paths-filter) emits a code output; heavy jobs gate on needs.changes.outputs.code == 'true', so doc-only changes run only changes + ci-pass. (Uses a changes filter, NOT trigger-level paths-ignore — this avoids the Repository-Ruleset deadlock where a skipped workflow never reports the required ci-pass check.)
| Job | Needs | What it runs |
|---|---|---|
changes | — | dorny/paths-filter — emits the code gate output |
static-check | changes | make static-check (incl. check-go-alignment, check-docs-go-version, lint, sec, vulncheck, secrets, trivy-fs, mermaid-lint, diagrams-check, release-check) |
build | changes, static-check | make build + upload binary artifact |
test | changes, static-check | make coverage + make coverage-check (80%) + make fuzz |
integration-test | changes, static-check | make integration-test (full HTTP stack via httptest) |
e2e | changes, build, test | Download binary (fallback rebuild), start server, make e2e-quick (Newman) |
dast | changes, static-check, test | OWASP ZAP API scan (skipped under act) |
goreleaser | changes, static-check, build, test, integration-test, e2e, dast | tag-only — GoReleaser binaries/archives/checksums + GitHub Release |
docker | changes, static-check, build, test, integration-test, goreleaser | Build + Trivy image scan + smoke/structure test every push; on tags also push + cosign-sign multi-arch to GHCR |
ci-pass | all of the above | Aggregator (if: always()); single required check for branch protection (skipped jobs count as success) |
- Go + Node + the whole quality toolchain are installed by
jdx/mise-actionreading.mise.toml(which mirrorsgo.modand.nvmrc) — notactions/setup-go/setup-node. - There is no
release.yml; the release phase lives inci.ymlas the tag-gatedgoreleaser+dockerjobs, soci-passaggregates CI and release into one green check. - Run the whole workflow locally with
make ci-run(usesact).
Dependency Updates
- Automated: Renovate auto-creates and auto-merges PRs (config:
renovate.json, viaplatformAutomerge) - Manual:
make update(runsgo get -u && go mod tidy)
Auto-merge (applies to your own PRs too)
auto-merge.yml runs gh pr merge --auto --squash on every non-draft PR authored by the repo owner (AndriyKalashnykov) — not just Renovate PRs. So any PR you open here merges (squash) the instant ci-pass goes green, with no manual merge step.
Practical consequence: treat an open PR as immutable. Don't push extra commits to an in-flight PR's branch expecting it to wait — native auto-merge will land it on green CI and strand the new commits on an orphaned branch. Put follow-up work on a fresh branch from origin/main (after the prior PR merges: git fetch origin --prune && git reset --hard origin/main). If commits do get stranded, git cherry-pick them onto a fresh branch and open a new PR.
Bumping the Go version
A Go patch bump is ONE PR that updates the source-of-truth pins and every live-state doc — never split the doc sweep into a follow-up PR (doing so is how stale version strings ship).
- Get the target patch and the new base-image digest, and confirm it:
docker buildx imagetools inspect golang:1.26-alpine --format '{{.Manifest.Digest}}' docker run --rm golang:1.26-alpine@<digest> go version # MUST show goX.Y.Z - Bump the three pins:
go.mod(go X.Y.Z),.mise.toml(go = "X.Y.Z"),Dockerfile(golang:1.26-alpine@sha256:<digest>— so the docker job's Trivy scan doesn't ship a binary built against the old stdlib). go mod tidy; verify the bump cleared what prompted it:mise install [email protected] && mise exec -- govulncheck ./... # "No vulnerabilities found"- Sweep every live-state doc in the SAME commit. Do NOT grep one exact
version string — grep the broad pattern across the whole tree and inspect
every hit, then prove zero stale remain:
Update the patch number AND any version-implied staleness (toolchain manager names likegit ls-files | xargs grep -nE 'go ?1\.26|gvm' 2>/dev/null # check each hitgvm→mise, framework versions). Leave dated history (docs/plan/,docs/research/) unchanged — append, don't rewrite. - Prove it before declaring done:
make check-go-alignment && make check-docs-go-version && make static-check
check-docs-go-version is wired into static-check, so a forgotten doc sweep
reds CI and cannot merge — it is the mechanical backstop for step 4. See the
project troubleshooting skill for the govulncheck-fired-the-bump runbook.
Quick Test Commands
make test-case-one # Single flight: [["SFO", "EWR"]]
make test-case-two # Two flights: [["ATL", "EWR"], ["SFO", "ATL"]]
make test-case-three # Four flights: [["IND", "EWR"], ["SFO", "ATL"], ["GSO", "IND"], ["ATL", "GSO"]]
make open-swagger # Open Swagger UI in browser
What ships with it
Read from the repository
Just SKILL.md. No reference files, no scripts.