From 9f7369d27732664ea2c5230d84cc562c2f90fdb4 Mon Sep 17 00:00:00 2001 From: Edgar Sipki Date: Fri, 30 Oct 2026 21:34:27 +0300 Subject: [PATCH] release: v1.3.0 plugins publish builds and smoke-tests for the platform the service reports in the new PluginsResponse.platform field, or --platform (#51), and packs plugins reproducibly, so an unchanged rebuild is an identical archive that is not uploaded again (#50). Co-Authored-By: Claude Opus 5.5 --- AGENTS.md | 4 ++-- README.md | 6 +++--- deploy/.env.dev.example | 4 ++-- deploy/charts/easyp-service/Chart.yaml | 6 +++--- deploy/charts/easyp-service/README.md | 2 +- deploy/docker-compose.dev.yml | 4 ++-- 6 files changed, 13 insertions(+), 13 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 791649c..53c151a 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -33,7 +33,7 @@ tidy. `api/` and `sdk/` carry their own `go.mod` and their own Apache-2.0 before the split a client importing the SDK had its licence scanner report Elastic-2.0 on their own build. -They are tagged separately — `v1.2.1`, `api/v1.2.1`, `sdk/v1.2.1` — and released +They are tagged separately — `v1.3.0`, `api/v1.3.0`, `sdk/v1.3.0` — and released in lockstep, so that one version number means one thing. A change to the wire contract therefore touches a module whose version is a promise to people outside this repository. @@ -162,7 +162,7 @@ go test ./... # Standard tests - **Entrypoint is always named `plugin`** — build output and migrate scan require `plugins/{group}/{name}/{version}/plugin`; Dockerfiles must `COPY` the entrypoint to `/plugin` (sidecars optional) - **A plugin runs outside its image** — the service unpacks the image filesystem and execs `plugin` as a plain process on its own base (`debian:trixie-slim`). Wrappers resolve paths from `DIR=${0%/*}`, never from `/`; absolute symlinks are skipped on unpack. `plugins build` proves it per version: it relativises in-bundle absolute links, round-trips the archive through `plugarchive`, and smoke-runs `plugin` in the runtime image as uid 65532 with an empty env — a failure leaves only `build.log`. `TestSmokeImageMatchesServiceBase` keeps the smoke image equal to the Dockerfile's runtime stage - **`easyp-svc plugins build `** — uses Docker multi-stage builds to extract image filesystems to the output directory (`plugins/` by default) and verifies each version; `--archive` keeps only the verified `{g}/{n}/{v}/plugin.tgz` instead. Supports `--filter`, `--parallel`, `--force`, `--dry-run`. Nothing is uploaded -- **`easyp-svc plugins publish [registry-path]`** — per version: build → verify → upload with sha256 metadata → `CreatePlugin` (or `UpdatePlugin` when it exists) → delete the local copy. Sources: a registry, `--archives ` (a `build --archive` tree), or with neither, `--plugins-dir` itself. Destination: S3 (`--cfg` supplies `registry.s3`, flags override it) or `--plugins-dir` (no object storage, same host). Skips what is registered and in storage, only registers what is in storage but not registered, skips uploads of an identical archive; `--force` republishes. Builds and smoke runs target the platform the service reports in `PluginsResponse.platform` (`runtime.GOOS/GOARCH` of the server), or `--platform`; an older server reports none and the build is for the local machine, with a warning. `plugarchive.PackDir` is reproducible (epoch mtimes, no owners, modes reduced to 0755/0644/0777), so an unchanged rebuild is an identical archive Preflight checks storage and the token before building. `--build-parallel` 4, `--parallel` 8, backing off on the rate and concurrency limits — the SDK deliberately does not retry `ResourceExhausted` — and stopping new versions at the licence tier's plugin cap. Every config under `deploy/` sets `rate_limit.max_concurrent_per_ip: 10` for it; against a server left at the default of 2, pass `--parallel 2`. Needs a v1.2.0+ server +- **`easyp-svc plugins publish [registry-path]`** — per version: build → verify → upload with sha256 metadata → `CreatePlugin` (or `UpdatePlugin` when it exists) → delete the local copy. Sources: a registry, `--archives ` (a `build --archive` tree), or with neither, `--plugins-dir` itself. Destination: S3 (`--cfg` supplies `registry.s3`, flags override it) or `--plugins-dir` (no object storage, same host). Skips what is registered and in storage, only registers what is in storage but not registered, skips uploads of an identical archive; `--force` republishes. Builds and smoke runs target the platform the service reports in `PluginsResponse.platform` (`runtime.GOOS/GOARCH` of the server), or `--platform`; an older server reports none and the build is for the local machine, with a warning. `plugarchive.PackDir` is reproducible (epoch mtimes, no owners, modes reduced to 0755/0644/0777), so an unchanged rebuild is an identical archive. Preflight checks storage and the token before building. `--build-parallel` 4, `--parallel` 8, backing off on the rate and concurrency limits — the SDK deliberately does not retry `ResourceExhausted` — and stopping new versions at the licence tier's plugin cap. Every config under `deploy/` sets `rate_limit.max_concurrent_per_ip: 10` for it; against a server left at the default of 2, pass `--parallel 2`. Needs a v1.2.0+ server - **Port 5432 conflict** — if postgres already runs locally, minimal stack uses port 5433 (`EASYP_POSTGRES_PORT`) - **Plugin binaries must exist** — publish them (`task publish-plugins`, or `task build-plugins` + `task run-local` without S3) before the service can generate code - **License:** `PasetoLicenseClient` verifies the token offline against `license.public_keys` (kid → hex; an entry under `"*"` verifies any key id). No key configured means community mode; a key that does not decode stops startup. Anything else that goes wrong resolves to community, never to an error diff --git a/README.md b/README.md index d35a5e3..5afa5ce 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,7 @@ Every release publishes an image, a Helm chart and the binaries. Pick one. | Tag | Meaning | |-----|---------| -| `v1.2.1` | a release; immutable | +| `v1.3.0` | a release; immutable | | `latest` | the newest release — only moves on a release tag | | `edge` | the tip of `master`; moves on every push | | `sha-` | one commit; immutable | @@ -38,7 +38,7 @@ kubectl create secret generic easyp-env \ --from-literal=DB_POSTGRES_DSN='postgres://user:pass@host:5432/easyp?sslmode=require' helm install easyp oci://ghcr.io/easyp-tech/charts/easyp-service \ - --version 1.2.1 \ + --version 1.3.0 \ --set secrets.existingSecret=easyp-env \ --set tls.enabled=false ``` @@ -1025,7 +1025,7 @@ A release tag produces, in this order: To verify an image before running it: ```bash -cosign verify ghcr.io/easyp-tech/service:v1.2.1 \ +cosign verify ghcr.io/easyp-tech/service:v1.3.0 \ --certificate-identity-regexp '^https://github.com/easyp-tech/service/\.github/workflows/release\.yml@refs/tags/v' \ --certificate-oidc-issuer https://token.actions.githubusercontent.com ``` diff --git a/deploy/.env.dev.example b/deploy/.env.dev.example index 755997f..88f8c7c 100644 --- a/deploy/.env.dev.example +++ b/deploy/.env.dev.example @@ -85,7 +85,7 @@ REGISTRY_S3_SECRET_ACCESS_KEY= # EASYP_GID=1000 # --- Service image --- -# Which published image the two tier containers run. A release tag (v1.2.1), +# Which published image the two tier containers run. A release tag (v1.3.0), # `edge` for the tip of master, or `sha-` to pin one commit. Bump this and # run `docker compose pull && docker compose up -d` to upgrade. # @@ -93,7 +93,7 @@ REGISTRY_S3_SECRET_ACCESS_KEY= # "the last release", and compose will happily keep a cached layer from months # ago. A config file in this repository and the binary that reads it have to # agree about which defaults exist. -# EASYP_SERVICE_VERSION=v1.2.1 +# EASYP_SERVICE_VERSION=v1.3.0 # --- Observability (docker-compose.observability.yml) --- # The telemetry backends write to an object store. These may point at the same diff --git a/deploy/charts/easyp-service/Chart.yaml b/deploy/charts/easyp-service/Chart.yaml index 39ad312..0d2ad35 100644 --- a/deploy/charts/easyp-service/Chart.yaml +++ b/deploy/charts/easyp-service/Chart.yaml @@ -51,14 +51,14 @@ type: application # YAML, an alert incapable of producing anything. tests/render.sh now runs # `promtool test rules` against real series rather than only `check rules`, # which reads expressions without knowing whether one can ever fire. -version: 1.2.1 +version: 1.3.0 # appVersion tracks the service release this chart was validated against and is # the default image tag — so it has to be a tag that exists. It was "0.9.0", # and the registry publishes "v0.9.0": a default install pulled a tag that has # never existed and stopped at ImagePullBackOff; `helm template` renders a -# wrong tag as happily as a right one. v1.2.1 is the release this chart ships +# wrong tag as happily as a right one. v1.3.0 is the release this chart ships # with — do not publish the chart before that tag exists. -appVersion: "v1.2.1" +appVersion: "v1.3.0" home: https://github.com/easyp-tech/service sources: diff --git a/deploy/charts/easyp-service/README.md b/deploy/charts/easyp-service/README.md index 441ca3a..558cbf1 100644 --- a/deploy/charts/easyp-service/README.md +++ b/deploy/charts/easyp-service/README.md @@ -34,7 +34,7 @@ checkout is not required: ```bash helm install easyp oci://ghcr.io/easyp-tech/charts/easyp-service \ - --version 1.2.1 \ + --version 1.3.0 \ --set secrets.existingSecret=easyp-env \ --set tls.enabled=false ``` diff --git a/deploy/docker-compose.dev.yml b/deploy/docker-compose.dev.yml index 3fb8c5a..bd3c0ca 100644 --- a/deploy/docker-compose.dev.yml +++ b/deploy/docker-compose.dev.yml @@ -150,7 +150,7 @@ services: # loader learned to supply defaults, with an error naming a key whose default # is documented. Set EASYP_SERVICE_VERSION to a release tag, to `edge` for # the tip of master, or to `sha-` to pin the exact commit under test. - image: ghcr.io/easyp-tech/service:${EASYP_SERVICE_VERSION:-v1.2.1} + image: ghcr.io/easyp-tech/service:${EASYP_SERVICE_VERSION:-v1.3.0} container_name: easyp-api-community restart: always user: "${EASYP_UID:-65532}:${EASYP_GID:-65532}" @@ -238,7 +238,7 @@ services: # loader learned to supply defaults, with an error naming a key whose default # is documented. Set EASYP_SERVICE_VERSION to a release tag, to `edge` for # the tip of master, or to `sha-` to pin the exact commit under test. - image: ghcr.io/easyp-tech/service:${EASYP_SERVICE_VERSION:-v1.2.1} + image: ghcr.io/easyp-tech/service:${EASYP_SERVICE_VERSION:-v1.3.0} container_name: easyp-api-enterprise restart: always user: "${EASYP_UID:-65532}:${EASYP_GID:-65532}"