# Contributing to OpenLicensd Thank you for your interest in contributing! ## Getting started 1. Fork the repository and clone it locally. 2. Install Go 1.27+ and Node.js 24+. 3. Start local PostgreSQL: `make dev-db` 4. Copy environment variables: `cp .env.example .env` 5. Make your changes and add tests where appropriate. 6. Run `make test` and `make lint` before opening a pull request. Run `make help` to see all available development targets. ## Development workflow ```bash # List all targets make help # Start PostgreSQL make dev-db # Run API server (loads .env) make dev-server # Run Nuxt dev server make dev-ui # Build UI static files make ui # Build binary make build # Run Go tests make test # Run Playwright UI smoke tests (requires Postgres, built binary, and Chromium) make dev-db make build cd ui && npm run test:e2e:install make test-ui # Lint (go vet + golangci-lint + ESLint) make lint # Generate admin password hash make hash-password PASSWORD=yourpassword ``` ## Docs site The documentation site is built with VitePress from the `docs/` directory and published to GitHub Pages. ```bash # Run the docs dev server (hot reload) make docs-dev # Build the static site (same check as CI) make docs-build ``` When editing `docs/*.md`, changes appear in the dev server immediately. Root-level guides (`README.md`, `QUICKSTART.md`, `CONTRIBUTING.md`, `CHANGELOG.md`, `COMPATIBILITY.md`, `SUPPORT.md`) are included in the site via VitePress file includes — edit those source files, not the wrapper pages in `docs/`. ## Releasing Releases are managed through [Release Drafter](https://github.com/release-drafter/release-drafter). Merging labeled pull requests to `main` updates draft releases automatically. ### Git tags Server releases use `vX.Y.Z` or `vX.Y.Z-rc.N` (for example `v0.5.0`, `v0.5.0-rc.1`). Do not publish unprefixed server tags. Historical server tags `0.0.1` through `0.3.0` predate this convention and remain in the repository for reference only. The Go SDK uses `sdk/go/vX.Y.Z` or `sdk/go/vX.Y.Z-rc.N`, independent of the server version. ### Server 1. Open the repository's **Releases** page on GitHub. 2. Review the stable or prerelease draft (tag format: `vX.Y.Z` or `vX.Y.Z-rc.N`). Release Drafter resolves the next version from the last published server tag — edit the draft tag/title if you need a different major (for example retarget `v0.9.1` to `v1.0.0` before publishing v1.0). Do not publish intermediate drafts you do not intend to ship (for example `v0.9.1` when releasing `v1.0.0`). 3. Before publishing, update [`CHANGELOG.md`](CHANGELOG.md): copy the draft release body into a new `## [X.Y.Z] - YYYY-MM-DD` section (use the publish date), then clear `## [Unreleased]` or replace it with the next draft contents. Commit the changelog update to `main` before or as part of the release publish. 4. Publish the draft when ready (leave **Set as the latest release** checked for server releases). Publishing triggers `.github/workflows/release.yml`, which builds Linux amd64/arm64 binaries and container images via GoReleaser and publishes the Helm chart in a separate workflow job. See [docs/deployment.md](docs/deployment.md#platforms) for the full platform matrix. The release job stamps `docs/openapi.yaml` `info.version` from the git tag (strip leading `v`) and attaches the stamped copy to the GitHub release. The stamp is publish-time only — git keeps the `0.0.0-dev` placeholder, and the workflow marks the file skip-worktree so GoReleaser still sees a clean worktree. GoReleaser also generates a changelog from git commits as a fallback for empty GitHub release bodies; with `release.mode: keep-existing`, Release Drafter notes on the published release are left unchanged. Each server release also ships SPDX JSON SBOMs (Syft): one per linux archive (generated by GoReleaser, checksumed in `checksums.txt`) and one per GHCR image platform (`linux/amd64`, `linux/arm64`, uploaded after the image is published). Local `make release` requires [Syft](https://github.com/anchore/syft) on your `PATH`. Published GHCR images are signed with keyless Cosign and include a GitHub Artifact Attestation with SLSA build provenance. See [docs/deployment.md](docs/deployment.md#releases) for verification commands. `charts/openlicensd/Chart.yaml` and `docs/openapi.yaml` keep `0.0.0-dev` placeholders in git (like the Go binary's `"dev"` default). Do not bump these on every release — the workflow stamps published artifacts from the tag. Install from OCI with `--version X.Y.Z`; when installing from the source chart, set `image.tag` explicitly. ### Go SDK The Go SDK is versioned independently from the server. Release Drafter maintains separate drafts scoped to SDK-owned paths (`sdk/**`, `docs/sdk/**`, and SDK workflow/config files; tag format: `sdk/go/vX.Y.Z`). The SDK drafter sets `latest: false` so SDK releases do not replace the server release as GitHub Latest. 1. Open the repository's **Releases** page on GitHub. 2. Review the **Go SDK** stable or prerelease draft. 3. Confirm the tag is `sdk/go/vX.Y.Z` (or `sdk/go/vX.Y.Z-rc.N` for prereleases). Release Drafter resolves the next version from the last published SDK tag — edit the draft tag/title if you need a different major (for example retarget `sdk/go/v0.4.0` to `sdk/go/v1.0.0` before publishing v1.0). 4. Uncheck **Set as the latest release** when publishing (the server release should remain Latest). 5. Publish the draft when ready. Publishing triggers `.github/workflows/sdk-release.yml`, which lints, tests, and warms the Go module proxy for pkg.go.dev. Consumers install with: ```bash go get github.com/alvarorg14/openlicensd/sdk/go@v1.0.0 ``` See [docs/sdk/go.md](docs/sdk/go.md) for integration documentation. For architecture details and AI assistant guidelines, see [AGENTS.md](AGENTS.md). ## Database migrations Schema changes use numbered SQL files in `server/internal/store/migrations/`. Migrations are forward-only — there are no down files. - Add a new file with the next sequence number (for example `010_my_change.sql`). - Never edit a migration that has already been applied in any environment. - Reviewers need `make dev-db-reset` when testing a new migration locally. See [docs/upgrade.md](docs/upgrade.md) for how migrations behave in production upgrades and rollbacks. ## Pull requests GitHub pre-fills new pull requests from [`.github/pull_request_template.md`](.github/pull_request_template.md). Fill every section; include `Closes #` in the TL;DR when the PR resolves an issue. - Keep changes focused and well-scoped. - Update documentation when behavior or configuration changes. - Use conventional commit messages when possible (e.g. `feat:`, `fix:`, `docs:`). - Ensure CI passes before requesting review. - Go coverage is uploaded to [Codecov](https://codecov.io/gh/alvarorg14/openlicensd) from CI; status checks are informational and do not block merges. - Add exactly one policy label to your PR: `breaking-change`, `feature`, `enhancement`, `bug`, `dependencies`, `documentation`, `deprecations`, or `ci`. - From v1.0.0, use `deprecations` when marking covered behavior as deprecated but still functional through all of 1.x; use `breaking-change` only when removing or incompatibly changing a covered surface (requires the next major release). See [COMPATIBILITY.md](COMPATIBILITY.md). - New GitHub Actions workflows must declare a top-level `permissions:` block (typically `contents: read`) and grant write scopes only on the jobs that need them. - Pin every `uses:` reference to a full commit SHA with a `# vX.Y.Z` comment (see existing workflows for the pattern); do not use floating `@v` tags. ## Reporting issues See [SUPPORT.md](SUPPORT.md) for where to ask questions vs. open bugs. When reporting a bug, please include: - OpenLicensd version (release tag or image tag) - Deployment method (Helm, Docker, binary, local dev) - PostgreSQL version - Whether Harbor integration is enabled - Relevant server logs - Steps to reproduce ## Security If you discover a security vulnerability, please report it via a [private GitHub security advisory](https://github.com/alvarorg14/openlicensd/security/advisories/new). See [SECURITY.md](SECURITY.md) for details. ## Code of conduct This project follows the [Contributor Covenant Code of Conduct](CODE_OF_CONDUCT.md). By participating, you agree to uphold this code.