From 9bfaebe1492f8a782310bb2285fee832d0ad3975 Mon Sep 17 00:00:00 2001 From: Barry Morrison <689591+esacteksab@users.noreply.github.com> Date: Sat, 14 Mar 2026 10:28:35 -0600 Subject: [PATCH 1/4] docs: update docs to reflect the state of things after refactoring --- README.md | 202 +++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 184 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index 57331d9..d3996a2 100644 --- a/README.md +++ b/README.md @@ -1,34 +1,200 @@ # Go Development Container -A lightweight Docker container for Go development based on Ubuntu 24.04. +Ubuntu-based Go development image published to Docker Hub, with automated multi-version builds. + +## Overview + +This repository builds and publishes one or more Go images on a schedule using GitHub Actions. + +- Registry: [Docker Hub - esacteksab/go](https://hub.docker.com/r/esacteksab/go) +- Runtime base: Ubuntu 24.04 (digest pinned) +- Build schedule: Every Friday at 9:00 AM Central Time (US/Chicago) + +## How Versions Are Selected + +The workflow resolves the build matrix in one of two ways: + +1. If repository variable `GO_VERSION` is set, only that exact version is built. +1. If `GO_VERSION` is not set, versions are queried from `https://go.dev/dl/?mode=json`, then reduced to the latest stable patch release for each stable Go minor line. + +## Multi-Version Build Behavior + +For each Go version in the matrix, the workflow: + +1. Resolves the digest for `golang:-bookworm`. +1. Passes `GO_VERSION` and `GO_IMAGE_DIGEST` as build args. +1. Builds an Ubuntu runtime image and copies `/usr/local/go` from the digest-pinned Go source stage. + +This keeps builds reproducible while still supporting multiple Go versions. + +## Tags Published + +For each built version ``: + +- `esacteksab/go:` +- `esacteksab/go:-YYYY-MM-DD` + +Additionally: + +- `esacteksab/go:latest` is applied to the highest version in the matrix for that run. + +## Image Characteristics + +- `CGO_ENABLED=0` +- `GOPATH=/go` +- `PATH` includes `/usr/local/go/bin` and `/go/bin` +- `GO_VERSION` is set in the final image environment +- OCI label `org.opencontainers.image.version` is set to the built Go version + +## Manual Build Example ```bash -esacteksab/go 1.25.8 f1f694493a08 2 minutes ago 445MB -golang 1.24.3-bookworm f254902cf370 2 days ago 853MB +docker build \ + --build-arg GO_VERSION=1.25.8 \ + --build-arg GO_IMAGE_DIGEST=sha256: \ + -t esacteksab/go:1.25.8 . ``` -## Overview +## Troubleshooting CI Failures + +### 1. Failed to Resolve Go Image Digest + +Symptom in workflow logs: + +- `Failed to resolve digest for golang:-bookworm` + +Common causes: + +- Temporary Docker Hub or network outage on GitHub-hosted runners. +- Invalid or unavailable Go version in the matrix. + +What to do: + +1. Re-run the failed workflow once to rule out transient network errors. +1. Verify the version exists: `docker buildx imagetools inspect golang:-bookworm`. +1. If using repository variable `GO_VERSION`, confirm it matches a real upstream tag (example: `1.25.8`). + +### 2. Invalid GO_VERSION Override + +Symptom in workflow logs: + +- Matrix resolves to one value, then digest or build steps fail. + +What to do: + +1. Check repository variable `GO_VERSION` in GitHub Actions settings. +1. Use semantic Go version format only (for example `1.25.8`, not `go1.25.8`). +1. Clear the variable to return to API-driven multi-version builds. + +### 3. Docker Hub Login or Push Failure -This repository contains a Dockerfile and GitHub Actions workflow that creates an image and publishes to Docker Hub weekly. +Symptom in workflow logs: -## Container Details +- Login step fails, or push returns `denied`/`unauthorized`. -- **Base Image:** Ubuntu 24.04 -- **Go Version:** Configurable via repository variables `GO_VERSION=1.25.8` -- **Registry:** [Docker Hub - esacteksab/go](https://hub.docker.com/r/esacteksab/go) -- **Build Schedule:** Every Friday at 9:00 AM Central Time (US/Chicago) +What to do: -## Available Tags +1. Confirm `DOCKERHUB_TOKEN` secret exists and is valid. +1. Confirm Docker Hub username in the workflow matches the account that owns the token. +1. Recreate the token in Docker Hub and update the GitHub secret if token scope or expiration changed. -- `latest` - The most recent build -- `1.25.8` (or current Go version) - Tagged with the specific Go version -- `1.25.8-YYYY-MM-DD` - Version with build date for historical reference +### 4. Context Warning for vars.GO_VERSION in Editor -## Features +Symptom in editor diagnostics: -- Optimized for static Go binary builds (`CGO_ENABLED=0`) -- Multi-layered image optimization for smaller size -- Configurable Go version via build arguments +- `Context access might be invalid: GO_VERSION` + +What it means: + +- This is often a static validation warning when the repository variable is not defined. +- Workflow runtime still works because the expression falls back to an empty string. + +What to do: + +1. Define repository variable `GO_VERSION` if you want override mode. +1. Leave it undefined if you want API-driven multi-version mode. + +## Release Notes Label Mapping + +GitHub release notes are generated from [.github/release.yml](.github/release.yml), and PR labels determine which section each change appears in. + +Apply labels consistently to ensure entries land in the expected category. + +### :warning: Breaking changes and deprecations + +- `type: breaking` +- `type: deprecation` +- `type: regression` +- `type: revert` + +### :whale: Image and runtime updates + +- `type: release` +- `type: feat` +- `type: fix` +- `type: perf` +- `type: enhancement` +- `enhancement` +- `bug` + +### :rocket: CI and build pipeline + +- `type: ci` +- `type: build` +- `type: refactor` + +### :book: Documentation and tests + +- `type: docs` +- `type: test` +- `type: style` +- `documentation` + +### :tools: Development dependency updates + +- `github_actions` +- `javascript` +- `npm` +- `python` + +### :package: Container dependency updates + +- `dependencies` +- `docker` +- `go` + +### :broom: Chores and maintenance + +- `chore` +- `type: chore` +- `type: task` + +### :grey_question: Other labeled changes + +- `question` +- `invalid` +- `duplicate` +- `wontfix` + +### Excluded from changelog + +- `ignore-changelog` + +### Note about commit message types + +Conventional commit prefixes (for example `chore:` or `feat:`) do not automatically place PRs into a section unless matching labels are applied. + +### PR checklist snippet + +Copy and paste into PR descriptions: + +```markdown +## Release Notes Checklist + +- [ ] I applied at least one release label that matches `.github/release.yml`. +- [ ] If this PR should be excluded from release notes, I applied `ignore-changelog`. +- [ ] If this is a breaking change, I applied `type: breaking` and documented impact/migration notes. +``` ## License From 1e2ea31d0e5d4047e834c3f7c1adf3e84cc55ad1 Mon Sep 17 00:00:00 2001 From: Barry Morrison <689591+esacteksab@users.noreply.github.com> Date: Sat, 14 Mar 2026 10:54:17 -0600 Subject: [PATCH 2/4] refactor(docker): Uses a Go base image instead --- .github/workflows/build.yml | 13 ++++++++++++- Dockerfile | 33 +++++---------------------------- 2 files changed, 17 insertions(+), 29 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 05671c4..f538cb7 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -21,7 +21,7 @@ jobs: - name: Get Go versions id: versions env: - GO_VERSION: ${{ vars.GO_VERSION }} + GO_VERSION: ${{ vars.GO_VERSION || '' }} run: | if [ -n "$GO_VERSION" ]; then # Repository variable overrides the API — build only that version @@ -60,6 +60,16 @@ jobs: - name: Set up Docker Buildx uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd #v4.0.0 + - name: Resolve Go image digest + id: go-image + run: | + digest=$(docker buildx imagetools inspect "golang:${{ matrix.go-version }}-bookworm" | awk '/^Digest:[[:space:]]/ {print $2; exit}') + if [ -z "$digest" ]; then + echo "Failed to resolve digest for golang:${{ matrix.go-version }}-bookworm" >&2 + exit 1 + fi + echo "digest=$digest" >> $GITHUB_OUTPUT + - name: Log in to Docker Hub uses: docker/login-action@b45d80f862d83dbcd57f89517bcf500b2ab88fb2 #v4.0.0 with: @@ -90,5 +100,6 @@ jobs: tags: ${{ steps.tags.outputs.tags }} build-args: | GO_VERSION=${{ matrix.go-version }} + GO_IMAGE_DIGEST=${{ steps.go-image.outputs.digest }} cache-from: type=gha cache-to: type=gha,mode=max diff --git a/Dockerfile b/Dockerfile index 9d5de7f..84ea037 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,31 +1,6 @@ -FROM ubuntu:24.04@sha256:d1e2e92c075e5ca139d51a140fff46f84315c0fdce203eab2807c7e495eff4f9 AS base - ARG GO_VERSION=1.25.8 - -# Install dependencies, download Go, and set it up in one layer -RUN set -eux && \ - apt-get update && \ - apt-get install -y --no-install-recommends \ - ca-certificates=20240203 \ - wget=1.21.4-1ubuntu4.1 && \ - wget -O go.tar.gz "https://go.dev/dl/go${GO_VERSION}.linux-amd64.tar.gz" && \ - tar -C /usr/local -xzf go.tar.gz && \ - rm go.tar.gz && \ - rm /root/.wget-hsts && \ - mkdir -p /go/src /go/bin && \ - chmod -R 750 /go && \ - apt-get clean && apt-get autoremove -y && \ - rm -rf /var/lib/apt/lists/* && \ - rm -rf /var/log/apt/* && \ - rm -rf /var/log/dpkg.log - -# Set environment variables -ENV GOPATH=/go -ENV PATH=$GOPATH/bin:/usr/local/go/bin:$PATH -ENV CGO_ENABLED=0 - -# Set the working directory -WORKDIR /go +ARG GO_IMAGE_DIGEST=sha256:7af46e70d2017aef0b4ce2422afbcf39af0511a61993103e948b61011233ec42 +FROM golang:${GO_VERSION}-bookworm@${GO_IMAGE_DIGEST} AS go-dist FROM ubuntu:24.04@sha256:d1e2e92c075e5ca139d51a140fff46f84315c0fdce203eab2807c7e495eff4f9 @@ -47,7 +22,9 @@ ENV PATH=$GOPATH/bin:/usr/local/go/bin:$PATH ENV CGO_ENABLED=0 ENV GO_VERSION=${GO_VERSION} -COPY --from=base /usr/local/go /usr/local/go +COPY --from=go-dist /usr/local/go /usr/local/go + +RUN mkdir -p /go/src /go/bin && chmod -R 750 /go # Set the working directory WORKDIR /go From 57e08cb2a9c82cbf3fb3d9516127b010ecc7266d Mon Sep 17 00:00:00 2001 From: Barry Morrison <689591+esacteksab@users.noreply.github.com> Date: Sat, 14 Mar 2026 10:55:34 -0600 Subject: [PATCH 3/4] ci: updates dependabot, release workflow --- .github/dependabot.yml | 23 +++++++++++++-- .github/pull_request_template.md | 9 ++++++ .github/release.yml | 48 ++++++++++++++++++++++---------- 3 files changed, 63 insertions(+), 17 deletions(-) create mode 100644 .github/pull_request_template.md diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 5a03671..97f8165 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -3,6 +3,10 @@ version: 2 updates: - package-ecosystem: "pip" directory: "/" + labels: + - "python" + commit-message: + prefix: "chore(dev-deps)" groups: python-minor-and-patch: update-types: @@ -10,7 +14,7 @@ updates: - "patch" schedule: interval: "weekly" - day: "friday" + day: "thursday" time: "19:00" timezone: "America/Chicago" cooldown: @@ -18,6 +22,10 @@ updates: - package-ecosystem: "github-actions" directory: "/" + labels: + - "github_actions" + commit-message: + prefix: "chore(dev-deps)" groups: github-actions: update-types: @@ -25,7 +33,7 @@ updates: - "patch" schedule: interval: "weekly" - day: "friday" + day: "thursday" time: "19:00" timezone: "America/Chicago" cooldown: @@ -33,6 +41,11 @@ updates: - package-ecosystem: "docker" directory: "/" + labels: + - "dependencies" + - "docker" + commit-message: + prefix: "chore(deps)" schedule: interval: "daily" time: "13:00" @@ -42,6 +55,10 @@ updates: - package-ecosystem: "npm" directory: "/" + labels: + - "javascript" + commit-message: + prefix: "chore(dev-deps)" groups: npm-minor-and-patch: update-types: @@ -49,7 +66,7 @@ updates: - "patch" schedule: interval: "weekly" - day: "friday" + day: "thursday" time: "19:00" timezone: "America/Chicago" cooldown: diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 0000000..ca400b5 --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,9 @@ +## Summary + +- + +## Release Notes Checklist + +- [ ] I applied at least one release label that matches `.github/release.yml`. +- [ ] If this PR should be excluded from release notes, I applied `ignore-changelog`. +- [ ] If this is a breaking change, I applied `type: breaking` and documented impact/migration notes. diff --git a/.github/release.yml b/.github/release.yml index 9a3fa84..67e680a 100644 --- a/.github/release.yml +++ b/.github/release.yml @@ -1,42 +1,62 @@ +--- changelog: exclude: labels: - ignore-changelog categories: - - title: ":warning: Update considerations and deprecations" + - title: ":warning: Breaking changes and deprecations" labels: - "type: breaking" - "type: deprecation" - "type: regression" - "type: revert" - - title: ":rocket: New features and improvements" + - title: ":whale: Image and runtime updates" labels: - "type: release" - "type: feat" - - "type: enhancement" - - "type: refactor" + - "type: fix" - "type: perf" + - "type: enhancement" + - "enhancement" + - "bug" - - title: ":lady_beetle: Bug fixes" + - title: ":rocket: CI and build pipeline" labels: - - "type: fix" + - "type: ci" + - "type: build" + - "type: refactor" - - title: ":nail_care: Style, UI, UX" + - title: ":book: Documentation and tests" labels: + - "type: docs" + - "type: test" - "type: style" + - "documentation" - - title: ":book: Documentation" + - title: ":tools: Development dependency updates" labels: - - "type: docs" + - "github_actions" + - "javascript" + - "npm" + - "python" - - title: ":hammer: Build/Test Dependency Upgrades" + - title: ":package: Container dependency updates" labels: - - "type: dependencies" - "dependencies" - - "type: test" - - "type: ci" - - "type: build" + - "docker" + - "go" + + - title: ":broom: Chores and maintenance" + labels: + - "chore" - "type: chore" - "type: task" + + - title: ":grey_question: Other labeled changes" + labels: + - "question" + - "invalid" + - "duplicate" + - "wontfix" From 18caa3280dc4b0fe661e19f1f704b418c8260b09 Mon Sep 17 00:00:00 2001 From: Barry Morrison <689591+esacteksab@users.noreply.github.com> Date: Sat, 14 Mar 2026 10:56:50 -0600 Subject: [PATCH 4/4] ci: add labeler workflow --- .github/workflows/labeler.yml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 .github/workflows/labeler.yml diff --git a/.github/workflows/labeler.yml b/.github/workflows/labeler.yml new file mode 100644 index 0000000..76ef367 --- /dev/null +++ b/.github/workflows/labeler.yml @@ -0,0 +1,14 @@ +name: Labeler + +on: + pull_request: + types: + - opened + +permissions: + contents: read + pull-requests: write + +jobs: + label-pr: + uses: esacteksab/.github/.github/workflows/labeler.yml@1bc431f64337f1576cb374586c7cc51e3f723fb7 # v0.80.0