diff --git a/CLAUDE.md b/CLAUDE.md index 05a98c7..afa717e 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -46,7 +46,7 @@ sidecar). By default (no `DB_TYPE`/`DB_PATH` set) the service uses an in-memory ### Two audiences, two packages - **`internal/`** — the Argus *service* itself (API, DB, pipeline). Not importable by other projects. -- **`pkg/audit`** — the *client library* other Go services import (`go get github.com/LSFLK/argus/pkg/audit@latest`). Always pin a tagged release; do not use commit pseudo-versions. +- **`pkg/audit`** — the *client library* other Go services import (`go get github.com/LSFLK/argus/pkg/audit@latest`). See [Releases](https://github.com/LSFLK/argus/releases) for tags. Pin the resolved tag in `go.mod`; do not use retracted 1.x versions or commit pseudo-versions. to send audit events to a running Argus instance. This is a separate logical module from the service; don't leak service-internal types into it, and don't assume service-side dependencies (GORM, sinks) are available here. `pkg/audit/security.go` implements client-side request signing (RSA/Ed25519) that mirrors @@ -120,3 +120,8 @@ then pushed into `internal/api/v1/models` via `SetEnumConfig` for O(1) validatio The API is versioned by Go package path (`internal/api/v1/...`), not just by URL prefix — a `v2` would live alongside `v1` as a new package tree, mirroring the same handlers/services/models/database layers. + +Git tags, GitHub Releases, Helm chart versions, and the `pkg/audit` Go module are **separate** version +lines and are immutable once published. See `docs/RELEASE.md` (taken-name denylist). Do not move, +delete, or reuse those tags. Install docs use `@latest` and [Releases](https://github.com/LSFLK/argus/releases) +so they do not need a rewrite every bump. diff --git a/README.md b/README.md index c09d547..e97b397 100644 --- a/README.md +++ b/README.md @@ -33,6 +33,7 @@ ```bash go get github.com/LSFLK/argus/pkg/audit@latest ``` +Current tags are listed at [github.com/LSFLK/argus/releases](https://github.com/LSFLK/argus/releases). ### Step 2: Initialize the hardened audit client ```go @@ -71,6 +72,7 @@ In your application: ```bash go get github.com/LSFLK/argus/pkg/audit@latest ``` +See [Releases](https://github.com/LSFLK/argus/releases) for tagged versions. ### 2. Global Initialization Initialize the client in your main entry point. For high-scale systems, tune the batching settings to balance latency and throughput. @@ -147,12 +149,11 @@ Argus exports standard Prometheus metrics at `/metrics`: ## Deployment & Helm Chart -Argus provides an official Helm chart published as an **OCI Artifact** to GitHub Container Registry (`ghcr.io/lsflk/charts/argus`), as well as local chart source at [`deployments/helm/argus`](deployments/helm/argus). The application container image is published to `ghcr.io/lsflk/argus` (`:latest` and `:`). +Argus provides an official Helm chart published as an **OCI Artifact** to GitHub Container Registry (`ghcr.io/lsflk/charts/argus`), as well as local chart source at [`deployments/helm/argus`](deployments/helm/argus). The application container image is published to `ghcr.io/lsflk/argus` (`:latest` and `:`). Chart versions and the Go client (`pkg/audit`) are versioned independently. Check [Releases](https://github.com/LSFLK/argus/releases) for current tags; omit `--version` to install the latest chart. ### Install via OCI Artifact (Recommended) ```bash helm upgrade --install argus oci://ghcr.io/lsflk/charts/argus \ - --version 0.1.1 \ -n \ --create-namespace \ -f custom-values.yaml @@ -180,6 +181,7 @@ For full Helm configuration parameters, GitOps umbrella chart integration, and O - [API Reference](docs/API.md) - [Architecture Deep Dive](docs/ARCHITECTURE.md) - [Database Setup](docs/DATABASE_CONFIGURATION.md) +- [Release process](docs/RELEASE.md) (includes a denylist of tags you must not reuse) ## License Distributed under the Apache 2.0 License. See [LICENSE](LICENSE) for more information. diff --git a/deployments/helm/argus/README.md b/deployments/helm/argus/README.md index b46c0ba..c128d38 100644 --- a/deployments/helm/argus/README.md +++ b/deployments/helm/argus/README.md @@ -22,21 +22,20 @@ This chart provisions: ### 1. Install via OCI Artifact (Recommended) -Argus Helm charts are published as OCI artifacts to the GitHub Container Registry (`ghcr.io`). +Argus Helm charts are published as OCI artifacts to the GitHub Container Registry (`ghcr.io`). Check [Releases](https://github.com/LSFLK/argus/releases) for current tags. ```bash -# Install directly from OCI registry +# Install the latest published chart (omit --version). Pin --version only when you need a specific chart. helm upgrade --install argus oci://ghcr.io/lsflk/charts/argus \ - --version 0.1.1 \ --namespace \ --create-namespace \ --values ./custom-values.yaml ``` -To pull the packaged chart locally: +To pull the packaged chart locally (pin `--version` from [Releases](https://github.com/LSFLK/argus/releases) if you need a specific chart): ```bash -helm pull oci://ghcr.io/lsflk/charts/argus --version 0.1.1 +helm pull oci://ghcr.io/lsflk/charts/argus ``` ### 2. Standalone Deployment from Source @@ -57,7 +56,7 @@ When referencing Argus as a dependency in your umbrella chart (`Chart.yaml`): ```yaml dependencies: - name: argus - version: "0.1.1" + version: "x.y.z" # https://github.com/LSFLK/argus/releases repository: "oci://ghcr.io/lsflk/charts" ``` @@ -82,7 +81,7 @@ argus: The Helm chart automation follows a standard GitOps setup: - **Application image (`.github/workflows/build-image.yml`)**: Builds and pushes `ghcr.io/lsflk/argus` (`:` and `:latest`) on pushes to `main`. PRs that touch Go code or the Dockerfile build the image without pushing. After the first publish, set the GHCR package visibility to public under https://github.com/orgs/LSFLK/packages so clusters can pull without an imagePullSecret. -- **Dev Chart (`.github/workflows/build-dev-chart.yml`)**: On pushes to `main` with chart changes (or manual dispatch), packages and publishes a dev chart (`0.0.0-dev.`) to `oci://ghcr.io/lsflk/charts`. After the image push completes, publish the stable chart by dispatching this workflow with `version=0.1.1`. +- **Dev Chart (`.github/workflows/build-dev-chart.yml`)**: On pushes to `main` with chart changes (or manual dispatch), packages and publishes a dev chart (`0.0.0-dev.`) to `oci://ghcr.io/lsflk/charts`. After the image push completes, publish a **new** stable chart by dispatching this workflow with a `version` that is not already on [GHCR](https://github.com/LSFLK/argus/pkgs/container/charts%2Fargus) or in the [taken-names denylist](../../../docs/RELEASE.md#taken-names--never-reuse). - **Chart CI (`.github/workflows/helm-ci.yml`)**: Lints the chart and verifies template rendering on pull requests. ### Manual Packaging and Push @@ -97,7 +96,7 @@ helm package deployments/helm/argus -d .cr-release-packages/ echo "$CR_PAT" | helm registry login ghcr.io -u --password-stdin # 3. Push OCI artifact -helm push .cr-release-packages/argus-0.1.1.tgz oci://ghcr.io/lsflk/charts +helm push .cr-release-packages/argus-*.tgz oci://ghcr.io/lsflk/charts ``` --- diff --git a/docs/API.md b/docs/API.md index cb945fe..6f07895 100644 --- a/docs/API.md +++ b/docs/API.md @@ -192,7 +192,7 @@ curl http://localhost:3001/version ```json { "service": "argus", - "version": "1.0.0", + "version": "dev", "buildTime": "2024-01-20T10:00:00Z", "gitCommit": "abc123def456" } diff --git a/docs/RELEASE.md b/docs/RELEASE.md new file mode 100644 index 0000000..c754b80 --- /dev/null +++ b/docs/RELEASE.md @@ -0,0 +1,92 @@ +# Release process + +Published versions are **immutable**. Do not delete, move, retarget, force-push, or reuse a git tag, GitHub Release, Helm chart version, or container digest that has already been pushed. Go’s module proxy (`proxy.golang.org`) and checksum database (`sum.golang.org`) keep module versions even if the GitHub tag is later removed. + +Look up what already exists at [github.com/LSFLK/argus/releases](https://github.com/LSFLK/argus/releases) instead of copying numbers out of this file. Git tags (`git tag -l`), the [Helm package on GHCR](https://github.com/LSFLK/argus/pkgs/container/charts%2Fargus), and `ghcr.io/lsflk/argus` (`:latest` / `:`) are the other sources of truth. + +## Four independent version lines + +A number used in one line does not occupy that number in another. Client `v0.1.0`, root tag `v0.1.0`, and Helm `0.1.1` can all exist without matching. + +| Line | Identity | How it is published | +| --- | --- | --- | +| Root git tags | `github.com/LSFLK/argus` | `vX.Y.Z`. Other services should not import this module. | +| Client module | `github.com/LSFLK/argus/pkg/audit` | Nested tags `pkg/audit/vX.Y.Z`. This is what `go get` consumes. The GitHub Release title can be `vX.Y.Z`; the git tag is still `pkg/audit/vX.Y.Z`. | +| Helm chart | `oci://ghcr.io/lsflk/charts/argus` | `version` in `deployments/helm/argus/Chart.yaml`. OCI versions cannot be overwritten. | +| App image | `ghcr.io/lsflk/argus` | `:latest` (mutable) and `:`. Do not invent semver image tags. | + +Install docs should track **latest**, not a snapshot of today’s numbers. See [Releases](https://github.com/LSFLK/argus/releases) for current tags. + +```bash +go get github.com/LSFLK/argus/pkg/audit@latest +helm upgrade --install argus oci://ghcr.io/lsflk/charts/argus +``` + +`@latest` skips versions listed in `retract` in `pkg/audit/go.mod`. Pinning a retracted version (for example `@v1.0.0`) still works; that is intentional. + +## Policy + +Stay on **0.x** until the team agrees a stable 1.0. On 0.x, breaking changes bump the minor. After a real 1.0, breaking changes bump the major. + +To stop the toolchain from *selecting* a bad module version, add `retract` and ship a new tag. To warn humans, edit the GitHub Release notes. Do both; neither replaces the other. Do not `gh release delete --cleanup-tag` a published module version. + +## Cutting a client release (`pkg/audit`) + +1. Land the change on `main`. Run `go test ./...`. +2. Choose the next SemVer that does **not** already exist as `pkg/audit/vX.Y.Z` (`git tag -l 'pkg/audit/v*'` and the [Taken names](#taken-names--never-reuse) table). +3. Tag and push (no `--force`). Append the new tag to [Taken names](#taken-names--never-reuse). + +```bash +git tag -a pkg/audit/vX.Y.Z -m "pkg/audit vX.Y.Z" +git push origin pkg/audit/vX.Y.Z +gh release create "pkg/audit/vX.Y.Z" --title "vX.Y.Z" --notes "..." +``` + +Tags do not trigger image or chart workflows. + +## Cutting a Helm chart release + +1. Bump `deployments/helm/argus/Chart.yaml` `version` to a number that is **not** already on [GHCR](https://github.com/LSFLK/argus/pkgs/container/charts%2Fargus) or in [Taken names](#taken-names--never-reuse). Never republish an existing chart version (including to “fix” `appVersion`). +2. Merge to `main`, or dispatch [build-dev-chart.yml](../.github/workflows/build-dev-chart.yml) with that unpublished `version`. Append the new chart version to [Taken names](#taken-names--never-reuse). +3. A path-only change under `deployments/helm/` on `main` publishes `0.0.0-dev.`, not a stable chart. That is expected. + +## What CI does + +| Workflow | Trigger | Effect | +| --- | --- | --- | +| `build-image.yml` | Push/PR to `main` touching Go/Dockerfile paths | PR: build only. `main`: push `:sha` and retag `:latest`. | +| `build-dev-chart.yml` | Push to `main` touching `deployments/helm/**`, or manual dispatch | Empty input → `0.0.0-dev.`. An already-published chart version will fail (OCI immutable). | +| `helm-ci.yml` | PRs touching the chart | Lint/template only. | + +There is no Go test workflow. No workflow runs on git tags or GitHub Releases. + +## Taken names — never reuse + +This is a **denylist**, not “what to install” (that is always [Releases](https://github.com/LSFLK/argus/releases) / `@latest`). Before tagging, run `git tag -l` and confirm the name is absent here **and** on origin. Append a row when you publish a new name. Never retarget, delete, or `gh release delete --cleanup-tag` a row that is already here. + +### Git tags + +| Tag | Notes | +| --- | --- | +| `v0.1.0` | Root module. Initial repo. Not the Go client. Do not backfill a GitHub Release onto this tag. | +| `v1.0.0` | Root module. Do not move or delete. | +| `v1.0.1` | Root module. Do not move or delete. | +| `pkg/audit/v1.0.0` | Go client. **Retracted.** Cached by the module proxy and checksum DB. GitHub Release is marked retracted. | +| `pkg/audit/v1.0.1` | Retract-announcement only (itself retracted). Not a usable 1.x client. | +| `pkg/audit/v0.1.0` | Go client. GitHub Release title is `v0.1.0`; git tag is `pkg/audit/v0.1.0`. Distinct from root `v0.1.0`. | + +### Helm chart (GHCR) + +| Chart version | Notes | +| --- | --- | +| `0.1.1` | [`oci://ghcr.io/lsflk/charts/argus`](https://github.com/LSFLK/argus/pkgs/container/charts%2Fargus). Do not `helm push` this version again. | + +```bash +# Do not. +gh release delete v1.0.0 --cleanup-tag +gh release delete 'pkg/audit/v1.0.0' --cleanup-tag +git tag -d v0.1.0 +git push origin :refs/tags/v0.1.0 +git tag -f v0.1.0 +git tag -f pkg/audit/v0.1.0 +``` diff --git a/go.mod b/go.mod index 07bc31c..c9863e2 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/LSFLK/argus go 1.24.6 require ( - github.com/LSFLK/argus/pkg/audit v1.0.0 + github.com/LSFLK/argus/pkg/audit v0.1.0 github.com/aws/aws-sdk-go-v2 v1.41.7 github.com/aws/aws-sdk-go-v2/config v1.32.17 github.com/aws/aws-sdk-go-v2/service/s3 v1.101.0 diff --git a/go.sum b/go.sum index c2edc58..b4c0899 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,5 @@ -github.com/LSFLK/argus/pkg/audit v1.0.0 h1:iM0nC7k/l3adpg7ywKZ/ar4gphiPL2F5kA+au6WzMl4= -github.com/LSFLK/argus/pkg/audit v1.0.0/go.mod h1:VPLkj7lPFOPSTNZulUsf+OCWcjz9vdndCRhcc2hfQjM= +github.com/LSFLK/argus/pkg/audit v0.1.0 h1:UjPm6Bsa0r/4mi9XtN2Q8lHsBrQmboyxuOLoYanTnao= +github.com/LSFLK/argus/pkg/audit v0.1.0/go.mod h1:4VVVpK0P7nFEQLP+QU44rezK+Ds9PzE42ZyKw07abl0= github.com/aws/aws-sdk-go-v2 v1.41.7 h1:DWpAJt66FmnnaRIOT/8ASTucrvuDPZASqhhLey6tLY8= github.com/aws/aws-sdk-go-v2 v1.41.7/go.mod h1:4LAfZOPHNVNQEckOACQx60Y8pSRjIkNZQz1w92xpMJc= github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.10 h1:gx1AwW1Iyk9Z9dD9F4akX5gnN3QZwUB20GGKH/I+Rho= diff --git a/pkg/audit/go.mod b/pkg/audit/go.mod index c4a6955..dd1786e 100644 --- a/pkg/audit/go.mod +++ b/pkg/audit/go.mod @@ -1,3 +1,14 @@ module github.com/LSFLK/argus/pkg/audit go 1.24.6 + +// v1.0.0 was tagged before the team agreed the client API is stable. +// Do not move or delete pkg/audit/v1.0.0: proxy.golang.org and +// sum.golang.org already cached it. +// v1.0.1 exists only so the go command can discover these retract +// directives (it reads them from the highest release, even if retracted). +// Consumers should use a 0.x tag (`go get …@latest` skips retracted 1.x). +retract ( + v1.0.0 + v1.0.1 +)