Skip to content

chore: OSS scaffolding for the initial public release#18

Merged
jadb merged 2 commits into
mainfrom
chore/initial-release-prep
May 18, 2026
Merged

chore: OSS scaffolding for the initial public release#18
jadb merged 2 commits into
mainfrom
chore/initial-release-prep

Conversation

@jadb
Copy link
Copy Markdown
Contributor

@jadb jadb commented May 18, 2026

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 + 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 list

README polish (in place, no restructure — the existing "Jobs this solves" arc already reads as intent-driven):

  • Release / CI / License badges at the top (three, 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 — adds label + 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 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. 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.
  • Clear the 26 golangci-lint baseline findings on main (errcheck, misspell, staticcheck, gofmt, ineffassign) — separate PR after this one merges.

Test plan

  • `go build ./...` clean
  • `go vet ./...` clean
  • `go test -short ./...` green
  • `golangci-lint run ./...` finishes (26 pre-existing findings, gated by `continue-on-error`)
  • CI green on PR (build matrix + advisory lint)

Sequencing

After this lands, the planned order is:

  1. Open dotgithub PR adding the `goreleaser-on-tag.yml` reusable workflow + SKILL.md "Shipping binaries with GoReleaser OSS" section
  2. Open follow-up usp PR adopting that reusable workflow + adding `.goreleaser.yaml`
  3. Merge the standing release-please PR (chore(release): usp 0.1.0-alpha.1 #17) to cut `usp/v0.1.0-alpha.1` — binaries + Homebrew formula publish automatically
  4. Separate lint-cleanup PR drops `continue-on-error` from the lint job

Merge-time migration (release-please labels)

This PR changes .github/release-please-config.json from 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: pending label. 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:

  1. Relabel PR chore(release): usp 0.1.0-alpha.1 #17: remove autorelease: pending, add status:release-pending.
  2. Merge this PR (chore: OSS scaffolding for the initial public release #18).
  3. Trigger release-please via gh workflow run release-please.yml --repo hop-top/usp --ref main to confirm it recognizes chore(release): usp 0.1.0-alpha.1 #17.

After that, all future standing PRs use the new labels.

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.
Copilot AI review requested due to automatic review settings May 18, 2026 06:33
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 lint runs 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 think make check has 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.yml mints the release-bot token and invokes release-please, and publish.yml runs on release tags, so changes to those files can alter the release path without @hop-top/release review. 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 lint is still part of make 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 of check until 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.

Comment thread Makefile Outdated
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); \
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 43397d3make 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.

Comment thread .github/CODEOWNERS Outdated
@@ -0,0 +1,3 @@
# Release configuration — admin or release team only
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment on lines +7 to +8
"label": "status:release-pending",
"release-label": "status:release-tagged",
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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).

Comment thread .github/workflows/ci.yml Outdated
# `.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.
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment thread CONTRIBUTING.md Outdated
```sh
git clone https://github.com/hop-top/usp.git
cd usp
make check # build + test + lint
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 43397d3 — the quick-start now uses make build test (which matches what blocking CI gates on), and the file documents the 26-finding baseline + make check caveat in the targets table. make check becomes the canonical command once #16 lands and the baseline is clean.

- 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.
@jadb jadb merged commit 06022c1 into main May 18, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants