From 3d7fd2187ea37a32c14cc0ac90b11529bade5e53 Mon Sep 17 00:00:00 2001 From: Guillaume Everarts de Velp Date: Sun, 17 Aug 2025 16:43:36 +0200 Subject: [PATCH 1/2] feat: publish docker images --- .github/workflows/build.yml | 81 +++++++++++++++++++++++++++++++++++ .github/workflows/check.yml | 5 +-- .github/workflows/release.yml | 37 ---------------- Dockerfile | 28 ------------ Makefile | 49 ++++++++++++++++++--- docker/Dockerfile | 31 ++++++++++++++ go.mod | 4 +- 7 files changed, 160 insertions(+), 75 deletions(-) create mode 100644 .github/workflows/build.yml delete mode 100644 .github/workflows/release.yml delete mode 100644 Dockerfile create mode 100644 docker/Dockerfile diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..cbe7b65 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,81 @@ +name: Release + +on: push + +jobs: + binary: + if: startsWith(github.ref, 'refs/tags/v') + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup Go environment + uses: actions/setup-go@v5 + with: + go-version: 1.24.x + stable: true + + - name: Get dependencies + run: go get -v -t -d ./... + + - name: Build + run: | + TAG=$(git describe --tags --abbrev=0) + GIT_TAG=$TAG make clean build + + - name: Create release + uses: svenstaro/upload-release-action@v2 + with: + repo_token: ${{ secrets.GITHUB_TOKEN }} + file: build/* + tag: ${{ github.ref }} + overwrite: true + file_glob: true + + image: + runs-on: ubuntu-latest + + permissions: + contents: read + packages: write + attestations: write + id-token: write + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Store version in environment variable if this is a release tag + if: startsWith(github.ref, 'refs/tags/v') + run: echo "VERSION=${GITHUB_REF/refs\/tags\/v/}" >> $GITHUB_ENV + + - name: Enable images push + if: ${{ startsWith(github.ref, 'refs/heads/master') || startsWith(github.ref, 'refs/tags/v') }} + run: echo "DOCKER_BUILD_PUSH=true" >> $GITHUB_ENV + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + + - name: Authenticate to Docker Hub registry + uses: docker/login-action@v3 + with: + registry: docker.io + username: ${{ secrets.DOCKER_USER }} + password: ${{ secrets.DOCKER_PASS }} + + - name: Authenticate to Github Container registry + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ github.token }} + + - name: Build and push the images + run: | + make REGISTRY=docker.io IMAGE=${{ github.repository }} build-docker-multiarch + make REGISTRY=ghcr.io IMAGE=${{ github.repository }} build-docker-multiarch diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml index b8f6932..43b4019 100644 --- a/.github/workflows/check.yml +++ b/.github/workflows/check.yml @@ -3,14 +3,11 @@ on: [push, pull_request] jobs: check: runs-on: ubuntu-latest - strategy: - matrix: - go: [1.20.x, 1.21.x, 1.22.x] steps: - name: Setup Go environment uses: actions/setup-go@v5 with: - go-version: ${{ matrix.go }} + go-version: 1.24.x stable: true - name: Check out code into the Go module directory diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml deleted file mode 100644 index 3970b83..0000000 --- a/.github/workflows/release.yml +++ /dev/null @@ -1,37 +0,0 @@ -name: Release - -on: - push: - tags: - - v* - -jobs: - release: - runs-on: ubuntu-latest - - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Setup Go environment - uses: actions/setup-go@v5 - with: - go-version: 1.22.x - stable: true - - - name: Get dependencies - run: go get -v -t -d ./... - - - name: Build - run: | - TAG=$(git describe --tags --abbrev=0) - GIT_TAG=$TAG make clean build - - - name: Create release - uses: svenstaro/upload-release-action@v2 - with: - repo_token: ${{ secrets.GITHUB_TOKEN }} - file: build/* - tag: ${{ github.ref }} - overwrite: true - file_glob: true diff --git a/Dockerfile b/Dockerfile deleted file mode 100644 index 99c4b4b..0000000 --- a/Dockerfile +++ /dev/null @@ -1,28 +0,0 @@ -# build -FROM golang:1.18-stretch AS build-env - -WORKDIR /src - -ADD . . - -RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -a -o app . - -# run -FROM alpine:3.16 - -RUN apk add --no-cache \ - ca-certificates - -RUN addgroup -S app \ - && adduser -S -g app app - -WORKDIR /home/app - -COPY --from=build-env /src/app . - -RUN chown -R app:app ./ - -USER app -ENV USER=app - -ENTRYPOINT ["./app"] diff --git a/Makefile b/Makefile index a6e7bc9..9f77e3b 100644 --- a/Makefile +++ b/Makefile @@ -1,11 +1,50 @@ -BUILD_DIR=./build +SHELL := /bin/bash -clean: - rm -rf ${BUILD_DIR} +# Env var inputs for container image builds +# REGISTRY: The registry to which the build image should be pushed to. Defaults to "docker.io" (Docker Hub) +# IMAGE: The name of the image to build and publish in the afore mentioned registry. Defaults to "gotify/cli" +# PLATFORM: The platform for which the image should be built, defaults to amd64, arm64, i386, arm/v7 and riscv64 +REGISTRY ?= docker.io +IMAGE ?= gotify/cli +PLATFORM ?= linux/amd64,linux/arm64,linux/386,linux/arm/v7,linux/riscv64 + +# Env var inputs for all builds +# VERSION: The version for which the container image or the binary is being built. This variable has not default. +# When it is not provided, no version will be specified in the built package. +# COMMIT: The commit of this project for which the cli is being built, for reference in the tool's "version" command. +# Default to git's HEAD +# LD_FLAGS: Build flags, for the tool's "version" command. Defaults to current date, commit and version (if any). +COMMIT ?= $(shell git rev-parse --verify HEAD) +LD_FLAGS ?= $(if $(VERSION),-X main.Version=${VERSION}) \ + -X main.BuildDate=$(shell date "+%F-%T") \ + -X main.Commit=${COMMIT} + +# Resolve go version +ifdef GOTOOLCHAIN + GO_VERSION=$(GOTOOLCHAIN) +else + GO_VERSION=$(shell go mod edit -json | jq -r .Toolchain | sed -e 's/go//') +endif +DOCKER_GO_BUILD=go build -mod=readonly -a -installsuffix cgo -ldflags "$$LD_FLAGS" + +build-docker-multiarch: + docker buildx build \ + $(if $(DOCKER_BUILD_PUSH),--push) \ + -t ${REGISTRY}/${IMAGE}:${COMMIT} \ + $(if $(VERSION),-t ${REGISTRY}/${IMAGE}:latest) \ + $(if $(VERSION),-t ${REGISTRY}/${IMAGE}:${VERSION}) \ + $(if $(VERSION),-t ${REGISTRY}/${IMAGE}:$(shell echo $(VERSION) | cut -d '.' -f -2)) \ + $(if $(VERSION),-t ${REGISTRY}/${IMAGE}:$(shell echo $(VERSION) | cut -d '.' -f -1)) \ + --build-arg GO_VERSION=$(GO_VERSION) \ + --build-arg LD_FLAGS="$(LD_FLAGS)" \ + --platform $(PLATFORM) \ + -f docker/Dockerfile . + +_build_within_docker: OUTPUT = gotify-cli +_build_within_docker: + ${DOCKER_GO_BUILD} -o ${OUTPUT} build: - if [ '$(shell echo "${GIT_TAG}" | cut -c 1 )' != 'v' ]; then exit 1; fi; - $(eval LD_FLAGS := -X main.Version=$(shell echo ${GIT_TAG} | cut -c 2-) -X main.BuildDate=$(shell date "+%F-%T") -X main.Commit=$(shell git rev-parse --verify HEAD)) CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build -ldflags="${LD_FLAGS}" -o build/gotify-cli-windows-amd64.exe cli.go CGO_ENABLED=0 GOOS=windows GOARCH=386 go build -ldflags="${LD_FLAGS}" -o build/gotify-cli-windows-386.exe cli.go CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags="${LD_FLAGS}" -o build/gotify-cli-linux-amd64 cli.go diff --git a/docker/Dockerfile b/docker/Dockerfile new file mode 100644 index 0000000..e362cbf --- /dev/null +++ b/docker/Dockerfile @@ -0,0 +1,31 @@ +ARG BUILDKIT_SBOM_SCAN_CONTEXT=true +# Suppress warning about invalid variable expansion +ARG GO_VERSION=PLEASE_PROVIDE_GO_VERSION +ARG DEBIAN=sid-slim +ARG BUILDPLATFORM +ARG TARGETPLATFORM + +# Hack to normalize platform to match the chosed build image +# Get the gotify/build image tag +ARG __TARGETPLATFORM_DASHES=${TARGETPLATFORM/\//-} +ARG __TARGETPLATFORM_GO_NOTATION=${__TARGETPLATFORM_DASHES/arm\/v7/arm-7} + +# --- Go Builder --- +FROM --platform=${BUILDPLATFORM} docker.io/golang:${GO_VERSION}-alpine AS builder + +ARG LD_FLAGS="" + +RUN apk add --no-cache ca-certificates git make bash + +COPY . /src/gotify + +RUN cd /src/gotify && \ + LD_FLAGS=${LD_FLAGS} make OUTPUT=/target/app/gotify-cli _build_within_docker + +FROM docker.io/library/alpine:latest + +RUN apk add --no-cache ca-certificates + +COPY --from=builder /target/app/gotify-cli /gotify-cli + +ENTRYPOINT ["/gotify-cli"] diff --git a/go.mod b/go.mod index ea7acc4..0ce0a12 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,8 @@ module github.com/gotify/cli/v2 -go 1.18 +go 1.23 + +toolchain go1.24.1 require ( github.com/adrg/xdg v0.4.0 From b5d8b781249c106a9f627552e790354e2221f0c7 Mon Sep 17 00:00:00 2001 From: Jannis Mattheis Date: Sun, 31 Aug 2025 21:20:13 +0200 Subject: [PATCH 2/2] fix: cleanup --- .github/workflows/build.yml | 53 +++++++++++-------------------------- .github/workflows/check.yml | 7 +++++ Makefile | 20 ++++++-------- docker/Dockerfile | 25 +++++++---------- 4 files changed, 41 insertions(+), 64 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index cbe7b65..45977f1 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -8,25 +8,16 @@ jobs: runs-on: ubuntu-latest steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Setup Go environment - uses: actions/setup-go@v5 + - uses: actions/checkout@v4 + - uses: actions/setup-go@v5 with: go-version: 1.24.x stable: true - - name: Get dependencies - run: go get -v -t -d ./... - - - name: Build - run: | - TAG=$(git describe --tags --abbrev=0) - GIT_TAG=$TAG make clean build + - run: go get -v -t -d ./... + - run: make VERSION=${GITHUB_REF/refs\/tags\/v/} clean build - - name: Create release - uses: svenstaro/upload-release-action@v2 + - uses: svenstaro/upload-release-action@v2 with: repo_token: ${{ secrets.GITHUB_TOKEN }} file: build/* @@ -35,6 +26,7 @@ jobs: file_glob: true image: + if: ${{ startsWith(github.ref, 'refs/heads/master') || startsWith(github.ref, 'refs/tags/v') }} runs-on: ubuntu-latest permissions: @@ -44,38 +36,25 @@ jobs: id-token: write steps: - - name: Checkout repository - uses: actions/checkout@v4 + - uses: actions/checkout@v4 - - name: Store version in environment variable if this is a release tag - if: startsWith(github.ref, 'refs/tags/v') + - if: startsWith(github.ref, 'refs/tags/v') run: echo "VERSION=${GITHUB_REF/refs\/tags\/v/}" >> $GITHUB_ENV + - run: echo "DOCKER_BUILD_PUSH=true" >> $GITHUB_ENV - - name: Enable images push - if: ${{ startsWith(github.ref, 'refs/heads/master') || startsWith(github.ref, 'refs/tags/v') }} - run: echo "DOCKER_BUILD_PUSH=true" >> $GITHUB_ENV - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 - - - name: Set up QEMU - uses: docker/setup-qemu-action@v3 - - - name: Authenticate to Docker Hub registry - uses: docker/login-action@v3 + - uses: docker/setup-buildx-action@v3 + - uses: docker/setup-qemu-action@v3 + - uses: docker/login-action@v3 with: registry: docker.io username: ${{ secrets.DOCKER_USER }} password: ${{ secrets.DOCKER_PASS }} - - - name: Authenticate to Github Container registry - uses: docker/login-action@v3 + - uses: docker/login-action@v3 with: registry: ghcr.io username: ${{ github.actor }} password: ${{ github.token }} - - name: Build and push the images - run: | - make REGISTRY=docker.io IMAGE=${{ github.repository }} build-docker-multiarch - make REGISTRY=ghcr.io IMAGE=${{ github.repository }} build-docker-multiarch + - run: | + make REGISTRY=docker.io build-docker-multiarch + make REGISTRY=ghcr.io build-docker-multiarch diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml index 43b4019..2e9327f 100644 --- a/.github/workflows/check.yml +++ b/.github/workflows/check.yml @@ -18,3 +18,10 @@ jobs: - name: Test run: go test ./... + image: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: docker/setup-buildx-action@v3 + - run: | + make PLATFORM=linux/amd64 build-docker-multiarch diff --git a/Makefile b/Makefile index 9f77e3b..fc75d05 100644 --- a/Makefile +++ b/Makefile @@ -1,36 +1,33 @@ SHELL := /bin/bash # Env var inputs for container image builds -# REGISTRY: The registry to which the build image should be pushed to. Defaults to "docker.io" (Docker Hub) -# IMAGE: The name of the image to build and publish in the afore mentioned registry. Defaults to "gotify/cli" -# PLATFORM: The platform for which the image should be built, defaults to amd64, arm64, i386, arm/v7 and riscv64 +# REGISTRY: The registry to which the build image should be pushed to. +# IMAGE: The name of the image to build and publish in the afore mentioned registry. +# PLATFORM: The platform for which the image should be built REGISTRY ?= docker.io IMAGE ?= gotify/cli PLATFORM ?= linux/amd64,linux/arm64,linux/386,linux/arm/v7,linux/riscv64 # Env var inputs for all builds -# VERSION: The version for which the container image or the binary is being built. This variable has not default. +# VERSION: The version for which the container image or the binary is being built. # When it is not provided, no version will be specified in the built package. # COMMIT: The commit of this project for which the cli is being built, for reference in the tool's "version" command. -# Default to git's HEAD -# LD_FLAGS: Build flags, for the tool's "version" command. Defaults to current date, commit and version (if any). +# LD_FLAGS: Build flags, for the tool's "version" command. COMMIT ?= $(shell git rev-parse --verify HEAD) LD_FLAGS ?= $(if $(VERSION),-X main.Version=${VERSION}) \ -X main.BuildDate=$(shell date "+%F-%T") \ -X main.Commit=${COMMIT} -# Resolve go version ifdef GOTOOLCHAIN GO_VERSION=$(GOTOOLCHAIN) else GO_VERSION=$(shell go mod edit -json | jq -r .Toolchain | sed -e 's/go//') endif -DOCKER_GO_BUILD=go build -mod=readonly -a -installsuffix cgo -ldflags "$$LD_FLAGS" build-docker-multiarch: docker buildx build \ $(if $(DOCKER_BUILD_PUSH),--push) \ - -t ${REGISTRY}/${IMAGE}:${COMMIT} \ + -t ${REGISTRY}/${IMAGE}:master \ $(if $(VERSION),-t ${REGISTRY}/${IMAGE}:latest) \ $(if $(VERSION),-t ${REGISTRY}/${IMAGE}:${VERSION}) \ $(if $(VERSION),-t ${REGISTRY}/${IMAGE}:$(shell echo $(VERSION) | cut -d '.' -f -2)) \ @@ -40,9 +37,8 @@ build-docker-multiarch: --platform $(PLATFORM) \ -f docker/Dockerfile . -_build_within_docker: OUTPUT = gotify-cli -_build_within_docker: - ${DOCKER_GO_BUILD} -o ${OUTPUT} +clean: + rm -rf build build: CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build -ldflags="${LD_FLAGS}" -o build/gotify-cli-windows-amd64.exe cli.go diff --git a/docker/Dockerfile b/docker/Dockerfile index e362cbf..ddd303b 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -1,26 +1,21 @@ ARG BUILDKIT_SBOM_SCAN_CONTEXT=true -# Suppress warning about invalid variable expansion ARG GO_VERSION=PLEASE_PROVIDE_GO_VERSION -ARG DEBIAN=sid-slim ARG BUILDPLATFORM -ARG TARGETPLATFORM - -# Hack to normalize platform to match the chosed build image -# Get the gotify/build image tag -ARG __TARGETPLATFORM_DASHES=${TARGETPLATFORM/\//-} -ARG __TARGETPLATFORM_GO_NOTATION=${__TARGETPLATFORM_DASHES/arm\/v7/arm-7} -# --- Go Builder --- FROM --platform=${BUILDPLATFORM} docker.io/golang:${GO_VERSION}-alpine AS builder -ARG LD_FLAGS="" - -RUN apk add --no-cache ca-certificates git make bash +ARG TARGETPLATFORM +ARG TARGETOS +ARG TARGETARCH +ARG LD_FLAGS -COPY . /src/gotify +WORKDIR /src +COPY . /src -RUN cd /src/gotify && \ - LD_FLAGS=${LD_FLAGS} make OUTPUT=/target/app/gotify-cli _build_within_docker +RUN GOOS=${TARGETOS} \ + GOARCH=${TARGETARCH} \ + GOARM=$(echo $TARGETPLATFORM | sed -En 's|^linux/arm/v(.*)|\1|p') \ + go build -mod=readonly -a -installsuffix cgo -ldflags "${LD_FLAGS}" -o /target/app/gotify-cli FROM docker.io/library/alpine:latest