Skip to content

feat(push): derive VERSION from CI tag refs and git describe#75

Merged
bnema merged 4 commits intomainfrom
feat/push-version-from-tag-refs
Feb 11, 2026
Merged

feat(push): derive VERSION from CI tag refs and git describe#75
bnema merged 4 commits intomainfrom
feat/push-version-from-tag-refs

Conversation

@bnema
Copy link
Owner

@bnema bnema commented Feb 11, 2026

Summary

  • detect version from CI tag refs first (refs/tags/*, GitHub/GitLab/Azure envs) before local git fallback
  • inject VERSION into the docker build environment during gordon push --build and forward it with --build-arg VERSION
  • update push docs and tests for tag-ref parsing and CI version resolution behavior

Summary by CodeRabbit

  • New Features

    • Added a --token option for remote authentication in the CLI push command.
  • Improvements

    • Version resolution now prefers CI/CD tag refs (common CI env vars) before falling back to git describe --dirty.
    • --tag and --build help text updated; builds now inject a VERSION env var and use VERSION as a build arg key.
  • Documentation

    • Updated CLI help and getting-started guide to document remote push workflow, token usage, and Gordon-based push flow.
  • Tests

    • Added unit tests for tag parsing and version extraction.

Copilot AI review requested due to automatic review settings February 11, 2026 03:49
@coderabbitai
Copy link

coderabbitai bot commented Feb 11, 2026

Caution

Review failed

The pull request is closed.

📝 Walkthrough

Walkthrough

The PR updates push command version resolution to prefer CI/CD tag refs, adds helpers to parse those refs, falls back to git describe --dirty, and changes the build to propagate VERSION as an environment variable. Documentation and tests were updated accordingly.

Changes

Cohort / File(s) Summary
Documentation
docs/cli/push.md, docs/getting-started.md
Rewrote CLI help for --tag and --build, added --token option and remote deploy guidance; replaced local docker build/tag/push steps with gordon push --build --no-confirm workflow and clarified behaviors.
Core Version Resolution & Build
internal/adapters/in/cli/push.go
Added versionFromTagRefs(getenv) and parseTagRef to read CI/CD env vars (GITHUB_REF, GITHUB_REF_TYPE, GITHUB_REF_NAME, CI_COMMIT_TAG, BUILD_SOURCEBRANCH); determineVersion falls back to CI refs before Git; getGitVersion uses git describe --dirty; build now sets VERSION in the environment and passes VERSION as the build-arg key (no =value).
Tests
internal/adapters/in/cli/push_test.go
Added unit tests for parseTagRef and versionFromTagRefs; updated build tests to assert presence of a VERSION build token without a hardcoded VERSION=<value>.

Sequence Diagram

sequenceDiagram
    participant CLI as CLI Push
    participant Ver as Version Resolver
    participant CI as CI/CD Env
    participant Git as Git
    participant Build as Build System

    CLI->>Ver: determineVersion(optional tag)
    alt tag provided
        Ver-->>CLI: use provided tag
    else tag empty
        Ver->>CI: read env (GITHUB_REF, GITHUB_REF_TYPE, GITHUB_REF_NAME, CI_COMMIT_TAG, BUILD_SOURCEBRANCH)
        CI-->>Ver: ref values
        alt tag ref found
            Ver->>Ver: parseTagRef(ref)
            Ver-->>CLI: extracted version
        else no tag ref
            Ver->>Git: git describe --dirty
            Git-->>Ver: git describe output
            Ver-->>CLI: version from git
        end
    end
    CLI->>Build: run build with VERSION env var set
    Build-->>CLI: build complete
Loading

Estimated Code Review Effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Poem

🐰 I sniff CI refs and git's small trail,
I peel the tags where versions hail,
I hop from env to describe if thin,
Then tuck VERSION into the build bin,
A carrot-coded push — hop, ship, and grin.

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 25.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: implementing version derivation from CI tag refs and git describe as the primary objective of the pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/push-version-from-tag-refs

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

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 improves gordon push version resolution by preferring CI-provided tag references (GitHub/GitLab/Azure) before falling back to local git describe, and ensures the resolved VERSION is available to Docker builds.

Changes:

  • Add CI tag-ref parsing (refs/tags/*) and use it as the first source for the version when --tag isn’t provided.
  • Pass VERSION into docker buildx build via environment + --build-arg VERSION (env-resolved).
  • Update docs and add unit tests for tag-ref parsing and CI env precedence.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

File Description
internal/adapters/in/cli/push.go Adds CI-based version detection, updates git describe behavior, and injects VERSION into Docker build.
internal/adapters/in/cli/push_test.go Adds tests for tag-ref parsing and CI env version resolution; updates build-arg expectations.
docs/cli/push.md Documents the new version resolution order and VERSION injection behavior.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

// using docker push gives us chunked uploads (~5MB per request).
fmt.Println("\nBuilding image...")
buildCmd := exec.CommandContext(ctx, "docker", buildImageArgs(version, platform, dockerfile, buildArgs, versionRef, latestRef)...) // #nosec G204
buildCmd.Env = append(os.Environ(), "VERSION="+version)
Copy link

Copilot AI Feb 11, 2026

Choose a reason for hiding this comment

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

buildCmd.Env = append(os.Environ(), "VERSION="+version) can leave duplicate VERSION entries if the parent process already has VERSION set. Many getenv implementations return the first match, so Docker may read the preexisting value instead of the computed one, causing --build-arg VERSION to resolve incorrectly. Prefer constructing Env by replacing any existing VERSION= entry (or prepending the new VERSION=... before os.Environ()) so the intended value always wins.

Suggested change
buildCmd.Env = append(os.Environ(), "VERSION="+version)
buildCmd.Env = append([]string{"VERSION=" + version}, os.Environ()...)

Copilot uses AI. Check for mistakes.
}

func parseTagRef(ref string) string {
ref = strings.TrimSpace(strings.TrimSuffix(ref, "^{}"))
Copy link

Copilot AI Feb 11, 2026

Choose a reason for hiding this comment

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

parseTagRef trims ^{} before trimming whitespace. If a ref ever includes trailing whitespace/newlines (common with env-var values), TrimSuffix(ref, "^{}") won’t match and the returned tag could incorrectly include ^{}. Consider TrimSpace first, then TrimSuffix, or iteratively strip both to make the function correct in isolation.

Suggested change
ref = strings.TrimSpace(strings.TrimSuffix(ref, "^{}"))
ref = strings.TrimSpace(ref)
ref = strings.TrimSuffix(ref, "^{}")

Copilot uses AI. Check for mistakes.
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Fix all issues with AI agents
In `@docs/getting-started.md`:
- Around line 121-127: Clarify that using --expiry 0 when running gordon auth
token generate --subject deploy --scopes push,pull --expiry 0 creates a
non‑expiring token and is a security risk; update the docs to add a brief
warning next to the command about long‑lived secrets, recommend scoping the
token (push,pull), suggest setting a finite expiry value instead of 0 and/or
establishing a rotation policy, and mention storing the token securely and
limiting its use to remote deploys.
- Around line 142-147: Update the `--build` explanation for `gordon push myapp`
to state that the `--build` flag runs `docker buildx build` and therefore
requires Docker with Buildx (not a Podman-only setup); edit the sentence around
the `--build` bullet (the line referencing `docker buildx build`) to add a
one-line note that Podman alone is not supported for `--build` or alternatively
mention any supported Podman workaround if available.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@docs/getting-started.md`:
- Around line 148-149: Update the `--build` description to explicitly state how
VERSION is resolved: explain that VERSION is taken from CI tag refs
(refs/tags/*) when present, and otherwise falls back to the output of `git
describe --dirty`; also add or reference the `docs/cli/push.md` link for full
resolution details so users know which tag/source determines VERSION.

Comment on lines +148 to +149
- `--build` runs `docker buildx build` first, injecting `VERSION` from the tag
into the build and then pushing both version and `latest` tags. This requires
Copy link

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Clarify how VERSION is determined.

The phrase "injecting VERSION from the tag" is somewhat vague. Users may wonder which tag is used and how VERSION is resolved. Based on the PR objectives, VERSION is derived from CI tag refs (refs/tags/*) first, falling back to git describe --dirty. Consider briefly mentioning this resolution order or linking to docs/cli/push.md for details.

📝 Suggested clarification
-- `--build` runs `docker buildx build` first, injecting `VERSION` from the tag
-  into the build and then pushing both version and `latest` tags. This requires
+- `--build` runs `docker buildx build` first, injecting `VERSION` (determined
+  from CI tag refs or `git describe`) into the build and then pushing both
+  version and `latest` tags. This requires
   Docker with Buildx; a Podman-only setup is not supported for `--build`.
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
- `--build` runs `docker buildx build` first, injecting `VERSION` from the tag
into the build and then pushing both version and `latest` tags. This requires
- `--build` runs `docker buildx build` first, injecting `VERSION` (determined
from CI tag refs or `git describe`) into the build and then pushing both
version and `latest` tags. This requires
🤖 Prompt for AI Agents
In `@docs/getting-started.md` around lines 148 - 149, Update the `--build`
description to explicitly state how VERSION is resolved: explain that VERSION is
taken from CI tag refs (refs/tags/*) when present, and otherwise falls back to
the output of `git describe --dirty`; also add or reference the
`docs/cli/push.md` link for full resolution details so users know which
tag/source determines VERSION.

@bnema bnema merged commit ebd2ab3 into main Feb 11, 2026
2 of 3 checks passed
@bnema bnema deleted the feat/push-version-from-tag-refs branch February 11, 2026 20:55
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.

1 participant