Slice 2A: release.json schema + generator + processgit update check#126
Conversation
…date check` Adds the data plumbing for releases to be machine-discoverable and for deployments to be able to check for newer versions. Foundation for Slice 2B (download + apply), Slice 3 (updater sidecar), and any external tooling that wants to know what a release contains. Three additions: 1. build/release.schema.json JSON Schema (Draft 2020-12) describing the per-release manifest. Required fields: version/tag/released_at/prerelease, image (registry/repository/tag/digest/platforms), signing (method/issuer/ identity_regex), release_notes_url. Optional: binaries, source, migration, breaking_changes, deprecations, build provenance. Conservative schema_version=1 with `additionalProperties: false` throughout so we can add fields safely later. 2. build/release-helper/main.go Tiny stdlib-only Go program that emits release.json from environment variables. Designed to be driven from the GitHub Actions release workflow (in a follow-up workflow update, not part of this PR -- that change layers on top of #125 once it merges). 3. cmd/update.go New `processgit update` subcommand with `check` as the first verb. Queries the GitHub Releases API, walks the result list to handle channel filtering (stable / prerelease) more robustly than the /releases/latest endpoint, and compares to setting.AppVer using a small inline semver parser (no new dependencies). Flags: --repo, --channel, --github-api (for GHE), --github-token (optional, raises rate limit), --timeout, --json. Registered in cmd/main.go as a standalone (config-free) subcommand. Slice 2B will add `update download` (with sig verification) and `update apply` (atomic binary swap + migrate + re-exec). Those touch the running binary and deserve their own focused PR. Validation performed before this PR: - gofmt clean on both Go files - release-helper compiles standalone and emits valid JSON - Sample emitted JSON validates against the schema using jsonschema (Draft202012Validator) - cmd/main.go patch is a 1-line add to subCmdStandalone Co-authored-by: Claude <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 77c5197685
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| // brand-new repos that have only pre-releases). | ||
| // For `prerelease`, it returns the newest non-draft entry of any kind. | ||
| func fetchLatestRelease(ctx context.Context, apiBase, repo, channel, token string, timeout time.Duration) (*ghRelease, error) { | ||
| url := fmt.Sprintf("%s/repos/%s/releases?per_page=30", apiBase, repo) |
There was a problem hiding this comment.
Paginate release listing before declaring no stable release
This request hard-codes per_page=30 and never follows pagination, so update check --channel stable can incorrectly report "no published release found" when the first 30 releases are drafts/prereleases but an older stable release exists on later pages. This is a real failure mode for repos that publish many prereleases between stables, and it will suppress valid update information.
Useful? React with 👍 / 👎.
| Version: mustEnv("RELEASE_VERSION"), | ||
| Tag: mustEnv("RELEASE_TAG"), | ||
| ReleasedAt: time.Now().UTC().Format(time.RFC3339), | ||
| Prerelease: envBool("RELEASE_PRERELEASE", false), |
There was a problem hiding this comment.
Require prerelease flag instead of silently defaulting false
The manifest generator treats RELEASE_PRERELEASE as optional and defaults to false, so a missing env var will label a prerelease artifact as stable in release.json. Because this field is security/rollout metadata for update consumers, silently coercing a missing required input can produce incorrect channel behavior; this should fail fast like the other required release fields.
Useful? React with 👍 / 👎.
Slice 2A — Release manifest schema, generator, and
processgit update checkFoundation for the in-product update system. Read-only and additive — does not touch any running paths and adds no dependencies.
What ships in this PR
build/release.schema.jsonbuild/release-helper/main.gorelease.jsonfrom env vars (driven by the release workflow in a follow-up)cmd/update.goprocessgit updatesubcommand withcheckverbcmd/main.goCmdUpdateinsubCmdStandalone(1-line add)processgit update check— usageFlags:
--repo OWNER/NAME(defaultAlgomation-AI/ProcessGit, envPROCESSGIT_UPDATE_REPO)--channel stable|prerelease(defaultstable)--github-api URL(for GitHub Enterprise)--github-token TOKEN(optional; raises rate limit; envPROCESSGIT_UPDATE_GITHUB_TOKENorGITHUB_TOKEN)--timeout 15s--jsonfor machine-readable outputJSON output (for the updater sidecar and external tooling):
{ "current": "0.1.0", "latest": "0.1.2", "latest_tag": "v0.1.2", "update_available": true, "prerelease": false, "release_url": "https://github.com/Algomation-AI/ProcessGit/releases/tag/v0.1.2", "released_at": "2026-06-01T10:00:00Z", "release_name": "v0.1.2", "channel": "stable", "repo": "Algomation-AI/ProcessGit" }release.json— designEvery published release will carry a machine-readable manifest as a release asset. The schema covers:
version,tag,released_at,prereleaseregistry,repository,tag,digest,platforms,additional_tagsmethod(currentlycosign-keyless),issuer,identity_regex— enough for any consumer to construct acosign verifycommandadditionalProperties: falsethroughout so we can evolve safely withschema_versionbumps.release-helper— designgo run ./build/release-helperor by building a binary in the workflow)env: ...blockOUTPUT=env (defaults to stdout)Validation done
gofmtclean on both Go filesrelease-helpercompiles standalone and emits valid JSONjsonschema.Draft202012Validatorcmd/main.gochange is a single-line addition tosubCmdStandalonevprefix, pre-release ordering (numeric < alphanumeric, longer prefix list wins ties), build metadata strippedIntentionally NOT in this PR
.github/workflows/release.ymlupdate to callrelease-helper+ sign+attachrelease.json. Lives on top of #125 — will ship as a small follow-up PR once #125 merges.processgit update download(fetch image/binary, verify signatures, stage) andprocessgit update apply(atomic binary swap, migrate, re-exec). These touch the running binary and deserve their own PR.processgit-updatersidecar container./-/admin/updates.Sequencing for landing
processgit update check#126 — slice 2A)release.ymlto invokerelease-helperand attachrelease.jsonto the GH Releasev0.1.0— workflow produces the first signed image and the firstrelease.jsonprocessgit update checkshould now printup to date