chore: OSS scaffolding for the initial public release#18
Conversation
Adds the standard community files + repo hygiene that an OSS Go project is expected to ship before its first public tag, and adopts the hop-top conventions where they apply. Community files (mirror kit's content, license attribution and security-contact email are deliberately kept identical): - LICENSE — MIT, copyright Idea Crafters LLC + jadb - SECURITY.md — coordinated disclosure to opensec@ideacrafters.com, 48h ack - CODE_OF_CONDUCT.md — Contributor Covenant 2.1 - CONTRIBUTING.md — intent-driven (bug → PR → dev-env) rather than mirroring kit's top-down section list README polish (in place, no restructure — existing 'Jobs this solves' arc already reads as intent-driven): - Release/CI/License badges at the top (three badges only, no wall) - Status section now points at CHANGELOG + releases - Trailing License section links the four community files Release-flow alignment with hop-top conventions: - .github/release-please-config.json: add + (status:release-pending / status:release-tagged) so the standing PR is visually distinct from feature PRs and the merged tag PR gets its own state — matches kit's setup. - .github/CODEOWNERS: gate release-please-config + manifest to @hop-top/release (sidesteps accidental edits to the bump shape). Repo hygiene: - .gitattributes: LF normalization + binary marking + linguist hints for docs/cassettes/.tlc/go.sum. Mirrors kit. - .golangci.yml: copy of kit's lint config (errcheck/govet/ staticcheck/unused/ineffassign/misspell + gofmt/goimports). - ci.yml: lint job added, marked continue-on-error until the existing 26-finding baseline is cleared in a follow-up. - Makefile: 'lint' target now runs golangci-lint when installed, falls back to vet otherwise. What's NOT in this PR (intentional follow-ups): - GoReleaser cross-platform binaries + Homebrew tap publish: needs a reusable workflow in hop-top/.github first, since release-please's '<component>/v<version>' tag shape collides with GoReleaser OSS (the monorepo tag-prefix stripping is Pro-only). Tracked separately — the hop-top/homebrew-tap repo is already created and waiting. - Clearing the 26 golangci-lint findings on main: separate PR.
There was a problem hiding this comment.
Pull request overview
This PR prepares usp for an initial public OSS release by adding community governance files, release/lint scaffolding, and README polish.
Changes:
- Adds OSS community files: license, security policy, code of conduct, and contributing guide.
- Adds lint configuration and advisory CI lint job.
- Adds release-please labels, CODEOWNERS release ownership, and Git attributes hygiene.
Reviewed changes
Copilot reviewed 11 out of 11 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
SECURITY.md |
Adds vulnerability reporting and disclosure policy. |
README.md |
Adds badges, status update, and license/community links. |
Makefile |
Extends make lint to run golangci-lint when installed. |
LICENSE |
Adds MIT license attribution. |
CONTRIBUTING.md |
Adds contributor workflow and development setup guidance. |
CODE_OF_CONDUCT.md |
Adds project conduct policy. |
.golangci.yml |
Adds golangci-lint v2 configuration. |
.github/workflows/ci.yml |
Adds advisory lint job. |
.github/release-please-config.json |
Adds custom release-please pending/tagged labels. |
.github/CODEOWNERS |
Adds release config ownership rules. |
.gitattributes |
Adds line-ending, binary, and Linguist attributes. |
Comments suppressed due to low confidence (3)
CONTRIBUTING.md:56
- This table says
make lintruns golangci-lint unconditionally, but the Makefile now skips that step when the binary is not installed. Please document that golangci-lint is optional/required to get the full lint pass so contributors do not thinkmake checkhas run the same linting as CI when it was skipped locally.
| `make lint` | `go vet` + `golangci-lint` |
.github/CODEOWNERS:3
- The release ownership gate omits the release workflows themselves.
.github/workflows/release-please.ymlmints the release-bot token and invokes release-please, andpublish.ymlruns on release tags, so changes to those files can alter the release path without@hop-top/releasereview. Add the release workflow paths to this CODEOWNERS block if the intent is to restrict release configuration to the release team.
# Release configuration — admin or release team only
.github/release-please-config.json @hop-top/release
.github/.release-please-manifest.json @hop-top/release
Makefile:57
- With the current 26-finding baseline, this command exits non-zero whenever golangci-lint is installed, and
lintis still part ofmake check. That makes a clean checkout fail the documented setup command for contributors who have the linter installed, while CI treats the same baseline as advisory; make the local lint pass advisory or keep it out ofcheckuntil the baseline is cleared.
GOFLAGS=-buildvcs=false golangci-lint run $(PKG); \
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| lint: vet ## Run lint checks | ||
| lint: vet ## Run lint checks (vet + golangci-lint if installed) | ||
| @if command -v golangci-lint >/dev/null 2>&1; then \ | ||
| GOFLAGS=-buildvcs=false golangci-lint run $(PKG); \ |
There was a problem hiding this comment.
Fixed in 43397d3 — make lint now wraps the golangci-lint invocation in $(GOENV) GOFLAGS="-buildvcs=false $(GOFLAGS)" so any contributor-set GOFLAGS/GOCACHE flows through alongside the buildvcs override.
| @@ -0,0 +1,3 @@ | |||
| # Release configuration — admin or release team only | |||
There was a problem hiding this comment.
Fixed in 43397d3 — CODEOWNERS now gates itself plus release-please.yml and publish.yml, not just the manifest + config. Comment in the file documents why.
| "label": "status:release-pending", | ||
| "release-label": "status:release-tagged", |
There was a problem hiding this comment.
Real concern. Verified: PR #17 currently carries the release-please default autorelease: pending label, and this PR switches to custom status:release-pending / status:release-tagged. Mitigation plan: relabel #17 manually at merge time before the next release-please run, so the bot recognizes its existing standing PR rather than opening a duplicate. Adding the migration step to the PR body. Not fixing in code (the label-name change is intentional, matching kit's convention).
| # `.golangci.yml` ships with this repo, but the CI lint job is | ||
| # advisory until the existing baseline of 26 findings (errcheck, | ||
| # misspell, staticcheck, gofmt, ineffassign) is cleared in a | ||
| # follow-up. Run `make lint` locally to surface them. |
There was a problem hiding this comment.
Fixed in 43397d3 — the ci.yml comment now spells out the install link, and the same caveat is in CONTRIBUTING.md's targets table. Plus the underlying job-status issue (job-level continue-on-error reports FAILURE in the rollup) is fixed by moving continue-on-error to the golangci-lint step.
| ```sh | ||
| git clone https://github.com/hop-top/usp.git | ||
| cd usp | ||
| make check # build + test + lint |
There was a problem hiding this comment.
- Makefile lint target: wrap golangci-lint via $(GOENV) so contributor-set GOFLAGS/GOCACHE flow through, instead of hard-coding GOFLAGS=-buildvcs=false in isolation. - .github/CODEOWNERS: gate the file itself plus release-please.yml and publish.yml — without this, the release gate could be weakened without release-team review. - .github/workflows/ci.yml: move continue-on-error from the lint job to the golangci-lint step so the job conclusion stays SUCCESS (job-level continue-on-error still reports FAILURE in the rollup, which trips branch protection). Also expanded the comment to spell out the golangci-lint install requirement. - CONTRIBUTING.md: replace `make check` in the quick-start with `make build test` (check fails today against the 26-finding lint baseline), and clarify in the targets table that golangci-lint is optional. Document the baseline + the recommended local command. Not addressed in this commit (handled at merge time): - release-please label migration: PR #17 still carries the default `autorelease: pending` label, while this PR adds custom `status:release-pending` / `status:release-tagged` labels. Plan: relabel PR #17 manually at merge time, before the next release-please run.
Summary
OSS scaffolding for usp's first public release. Adds the community files an OSS Go project is expected to ship before its first public tag, plus the hop-top conventions that apply.
What's in
Community files (mirror
hop-top/kit's wording where it's the point — license attribution, security contact, code of conduct):LICENSE— MIT, copyright Idea Crafters LLC + jadbSECURITY.md— coordinated disclosure to opensec@ideacrafters.com, 48h ackCODE_OF_CONDUCT.md— Contributor Covenant 2.1CONTRIBUTING.md— intent-driven (bug → PR → dev-env) rather than mirroring kit's top-down listREADME polish (in place, no restructure — the existing "Jobs this solves" arc already reads as intent-driven):
Release-flow alignment with hop-top conventions:
.github/release-please-config.json— addslabel+release-label(status:release-pending/status:release-tagged), matching kit.github/CODEOWNERS— gates release-please config + manifest to `@hop-top/release`Repo hygiene:
.gitattributes— LF normalization + binary marking + linguist hints (docs/,e2e/cassettes/,.tlc/,go.sum).golangci.yml— copy of kit's lint config (errcheck/govet/staticcheck/unused/ineffassign/misspell + gofmt/goimports)ci.yml— lint job added, marked `continue-on-error: true` until the existing 26-finding baseline is cleared in a follow-up (tracked)Makefile— `make lint` now runs golangci-lint when installed, falls back to vet otherwiseWhat's NOT in this PR (intentional follow-ups)
hop-top/.githubfirst. release-please's `/v` tag shape collides with GoReleaser OSS (the monorepo tag-prefix stripping is Pro-only). Tracked separately. The `hop-top/homebrew-tap` repo is already created and waiting.Test plan
Sequencing
After this lands, the planned order is:
Merge-time migration (release-please labels)
This PR changes
.github/release-please-config.jsonfrom release-please's default labels (autorelease: pending/autorelease: tagged) to custom ones (status:release-pending/status:release-tagged), matching the kit convention.Standing release PR #17 still carries the old
autorelease: pendinglabel. On the next release-please run, the bot looks up its standing PR by label and would not find #17 — potentially opening a duplicate.Action at merge time:
autorelease: pending, addstatus:release-pending.gh workflow run release-please.yml --repo hop-top/usp --ref mainto confirm it recognizes chore(release): usp 0.1.0-alpha.1 #17.After that, all future standing PRs use the new labels.