Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 28 additions & 30 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,59 +6,57 @@ on:
branches:
- master

env:
GO_VERSION: "1.23.0"
GO_LANG_CI_LINT_VERSION: "v1.60.1"

name: run tests
jobs:
lint:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Install Go
uses: actions/setup-go@v5
with:
go-version: ${{ env.GO_VERSION }}
- name: Checkout code
uses: actions/checkout@v4
go-version-file: go.mod

- name: Run linters
uses: golangci/golangci-lint-action@v6
with:
version: ${{ env.GO_LANG_CI_LINT_VERSION }}
version: v1.64.7
problem-matchers: true
args: --issues-exit-code=0 --out-format=sarif > linter-results.sarif # we expect some findings, but for this demo just continue

- name: Upload SARIF to Code Scanning
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: ./linter-results.sarif

test:
strategy:
matrix:
go-version: [ "1.23.0", "1.22.5" ]
platform: [ubuntu-latest, macos-latest, windows-latest]
runs-on: ${{ matrix.platform }}
runs-on: ubuntu-latest
steps:
- name: Install Go
if: success()
uses: actions/setup-go@v5
with:
go-version: ${{ matrix.go-version }}
- name: Checkout code
uses: actions/checkout@v4
- name: Run tests
run: go test -v -covermode=count
with:
fetch-depth: 0

coverage:
runs-on: ubuntu-latest
steps:
- name: Install Go
if: success()
uses: actions/setup-go@v5
with:
go-version: ${{ env.GO_VERSION }}
- name: Checkout code
uses: actions/checkout@v4
- name: Calc coverage
go-version-file: go.mod

- name: Verify go version
run: |
go test -v -covermode=count -coverprofile=coverage.out
echo "GOVERSION=$(go version)" >> $GITHUB_ENV
go version

- name: Run tests
run: go test -v -covermode=count -coverprofile=coverage.out

- name: Coveralls
uses: coverallsapp/github-action@cfd0633edbd2411b532b808ba7a8b5e04f76d2c8 #2.3.4
with:
github-token: ${{ secrets.github_token }}
file: coverage.out
format: golang
format: golang
87 changes: 71 additions & 16 deletions .github/workflows/upload_assets.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,26 @@ on:
- 'v*'

env:
GO_VERSION: "1.23.0"
# name of the resulting binary and the docker-image. must match name
# in .goreleaser.yml
BINARY: my-app

name: Upload release assets after tagging
jobs:
build:
name: create assets
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Install Go
uses: actions/setup-go@v5
with:
go-version: ${{ env.GO_VERSION }}
- name: Checkout code
uses: actions/checkout@v4
go-version-file: go.mod

- name: Run GoReleaser
uses: goreleaser/goreleaser-action@90a3faa9d0182683851fbfa97ca1a2cb983bfca3 #v6
with:
Expand All @@ -26,31 +32,80 @@ jobs:
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

- name: Upload binary artifact
uses: actions/upload-artifact@v4
with:
name: binary
path: dist/go-ci-demo_linux_amd64_v1/${{ env.BINARY }}
retention-days: 1

docker-image:
needs: build
env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}

name: create docker image
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
with:
driver-opts: image=moby/buildkit:latest
#buildkitd-flags: --debug

- name: Log in to the Container registry
uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567
uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: build Docker image

# Download the binary artifact from the build job
- name: Download binary artifact
uses: actions/download-artifact@v4
with:
name: binary
path: ./docker-build

- name: Prepare docker build
run: |
VERSION=$(git describe --tags)
docker build --build-arg "version=$VERSION" --tag ${IMAGE_NAME} .
- name: push Docker image
cp Dockerfile ./docker-build
chmod 755 ./docker-build/${{ env.BINARY }}

- name: Get tag info for image label
id: tag
run: |
TAG=$(git describe --tags)
docker tag ${IMAGE_NAME} ${REGISTRY}/${IMAGE_NAME}:${GITHUB_SHA}
docker tag ${IMAGE_NAME} ${REGISTRY}/${IMAGE_NAME}:${TAG}
docker tag ${IMAGE_NAME} ${REGISTRY}/${IMAGE_NAME}:latest
docker push ${REGISTRY}/${IMAGE_NAME}:${GITHUB_SHA}
docker push ${REGISTRY}/${IMAGE_NAME}:${TAG}
docker push ${REGISTRY}/${IMAGE_NAME}:latest
TAG=$(git describe --tags)
echo "tag=$TAG" >> $GITHUB_OUTPUT

- name: Build and push Docker image
uses: docker/build-push-action@v5
with:
context: ./docker-build
build-args: |
binary=${{ env.BINARY }}
push: true
tags: |
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.sha }}
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.tag.outputs.tag }}
cache-from: type=gha
cache-to: type=gha,mode=max

- name: Tag and push latest
if: steps.tag.outputs.tag != 'v99.9.9'
uses: docker/build-push-action@v5
with:
context: ./docker-build
build-args: |
binary=${{ env.BINARY }}
push: true
tags: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest
cache-from: type=gha
no-cache: false
pull: false
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
golang-ci-template-github-actions
*zip
*.out

dist/
10 changes: 7 additions & 3 deletions .goreleaser.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,16 @@
version: 2
before:
hooks:
# You may remove this if you don't use go modules.
- go mod tidy
project_name: go-ci-demo
builds:
- env:
- binary: my-app
env:
- CGO_ENABLED=0
dir: .
ldflags:
- -s -w
- -X "main.BuildVersion={{.Tag}}"
goos:
- linux
- darwin
Expand All @@ -34,4 +38,4 @@ changelog:
filters:
exclude:
- '^docs:'
- '^test:'
- '^test:'
19 changes: 4 additions & 15 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,17 +1,6 @@
# example docker image for
# https://github.com/jandelgado/golang-ci-template-github-actions/

FROM golang:1.23-alpine as builder
ARG version

WORKDIR /go/src/app
ADD . /go/src/app

RUN CGO_ENABLED=0 \
go build -ldflags "-s -w" -o app

FROM gcr.io/distroless/base-debian10
FROM gcr.io/distroless/static-debian12
ARG binary
LABEL maintainer="Jan Delgado <[email protected]>"

COPY --from=builder /go/src/app/app /
ENTRYPOINT ["/app"]
COPY ./$binary /app
ENTRYPOINT ["/app"]
68 changes: 45 additions & 23 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,46 +1,55 @@
# golang ci template using github actions

[![Build Status](https://github.com/jandelgado/golang-ci-template-github-actions/workflows/test%20and%20build/badge.svg)](https://github.com/jandelgado/golang-ci-template-github-actions/actions?workflow=test%20and%20build)
[![Build Status](https://github.com/jandelgado/golang-ci-template-github-actions/workflows/run%20tests/badge.svg)](https://github.com/jandelgado/golang-ci-template-github-actions/actions?workflow=run%20tests)
[![Coverage Status](https://coveralls.io/repos/github/jandelgado/golang-ci-template-github-actions/badge.svg?branch=master)](https://coveralls.io/github/jandelgado/golang-ci-template-github-actions?branch=master)
[![Go Report Card](https://goreportcard.com/badge/github.com/jandelgado/golang-ci-template-github-actions)](https://goreportcard.com/report/github.com/jandelgado/golang-ci-template-github-actions)
[![Go Report Card](https://goreportcard.com/badge/github.com/jandelgado/golang-ci-template-github-actions)](https://goreportcard.com/report/github.com/jandelgado/golang-ci-template-github-actions)

<!-- vim-markdown-toc GFM -->

* [Info](#info)
* [Go-Version](#go-version)
* [Dependabot](#dependabot)
* [Creating a release](#creating-a-release)
* [Test coverage (coveralls)](#test-coverage-coveralls)
* [Linting & Test](#linting--test)
* [Linter](#linter)
* [Test](#test)
* [Author](#author)

<!-- vim-markdown-toc -->

## Info
## Info

This repository serves as a template for github-actions integrated go projects.
It consists of a `hello, world!` like example in source file [main.go](main.go)
which gets compiled into the binary `golang-ci-template-github-actions`. The CI
runs some [linters](https://github.com/golangci/golangci-lint-action) on the
code, before the unit tests are executed. Test coverage is uploaded to
coveralls.io.
which gets compiled into the binary `my-app` using goreleaser. The CI is
configured to run
[golangci-linter](https://github.com/golangci/golangci-lint-action) on the code,
before the unit tests are executed. Test coverage is uploaded to coveralls.io.

[goreleaser](https://github.com/goreleaser/goreleaser) is used to create the
final multi-plattform assets, which are automatically uploaded to the
final multi-plattform assets, which are automatically uploaded to the
[release](https://github.com/jandelgado/golang-ci-template-github-actions/releases/latest).
The [release-process](#creating-a-release) is triggered by pushing a git tag to
the repository.

Finally, a docker image is built, which gets published to
[ghcr.io](https://github.com/jandelgado/golang-ci-template-github-actions/pkgs/container/golang-ci-template-github-actions).
[ghcr.io](https://github.com/jandelgado/golang-ci-template-github-actions/pkgs/container/my-app).
Run it with

```console
$ docker run --rm ghcr.io/jandelgado/golang-ci-template-github-actions:latest
$ docker run --rm ghcr.io/jandelgado/my-app:latest
hello, world!
```

## Go-Version

The go version to use is configured in `go.mod` with the `toolchain` directive.
When building locally, set `GOTOOLCHAIN` to `auto` to automatically install
the configured toolchain (introduced with go 1.21).

## Dependabot

We use [dependabot](https://docs.github.com/en/code-security/dependabot) to
We use [dependabot](https://docs.github.com/en/code-security/dependabot) to
both keep the go dependencies as well as the used github action up-to-date.
The configuration can be found [here](.github/dependabot.yml).

Expand All @@ -53,28 +62,41 @@ $ git tag -a "v1.2.3" -m "this is release v1.2.3"
$ git push origin v1.2.3
```

The push of the new tag triggers the CI, which uses goreleaser to:
* build multiplatform release artifacts
* create a new release
* upload the artifacts, which are then available on the [releases page](/jandelgado/golang-ci-template-github-actions/releases).
The push of the new tag triggers the CI, which uses goreleaser with
[this configuration](.goreleaser.yml) to

Finally, a docker image is built, which gets published to
* build multi-platform release artifacts
* create a new release
* upload the artifacts, which are then available on the [releases page](/jandelgado/golang-ci-template-github-actions/releases).

Finally, a docker image is built using the previously built artefacts. The image
is published to
[ghcr.io](https://github.com/jandelgado/golang-ci-template-github-actions/pkgs/container/golang-ci-template-github-actions).

## Test coverage (coveralls)
To run goreleaser locally, start the tool with `gorelaser build --snapshot --clean`.

## Linting & Test

### Linter

[golangci-linter](https://github.com/golangci/golangci-lint-action) is
configured for code-linting. The report is uploaded so that linting results
are visible in the MR:

![pr screenshot](images/linter.png)

### Test

We use the
[coveralls-github-action](https://github.com/coverallsapp/github-action) to
upload the golang coverage to coveralls.

Don't forget to enable `Leave comments (x) ` in coveralls, under `repo
settings` > `pull request alerts`, so that the coveralls-action posts a comment
Don't forget to enable `Leave comments (x)` in coveralls, under
`repo settings` > `pull request alerts`, so that the coveralls-action posts a comment
with the test coverage to affected pull requests:

![pr screenshot](images/pr.png)

## Author

(c) copyright 2021 by Jan Delgado, License MIT


(c) copyright 2021-2025 by Jan Delgado, License MIT
Loading
Loading