feat: add linter configs, Dockerfile, CI/CD pipeline

- .golangci.yml — 50+ linters enabled
- .yamllint — yaml lint rules
- cicd.yaml — CI/CD with lint-go (golangci, staticcheck,
  gosec, revive), lint-yaml, build+test, publish
- Dockerfile — multi-stage scratch build
- go vet passes clean
This commit is contained in:
2026-07-03 01:49:00 +02:00
parent 8501fd074c
commit 442ac9f580
4 changed files with 273 additions and 0 deletions
+108
View File
@@ -0,0 +1,108 @@
run:
timeout: 5m
skip-dirs:
- vendor/
linters:
enable:
- errcheck
- gosimple
- govet
- ineffassign
- staticcheck
- typecheck
- unused
- asciicheck
- bodyclose
- cyclop
- decorder
- dupl
- dupword
- durationcheck
- errname
- errorlint
- exhaustive
- forcetypeassert
- gochecknoinits
- gocognit
- goconst
- gocritic
- gocyclo
- godot
- goimports
- gomoddirectives
- gomodguard
- goprintffuncname
- gosec
- grouper
- ifshort
- importas
- lll
- makezero
- mirror
- misspell
- nakedret
- nestif
- nilerr
- nilnil
- nlreturn
- noctx
- nolintlint
- nosprintfhostport
- prealloc
- predeclared
- promlinter
- reassign
- revive
- rowserrcheck
- sqlclosecheck
- stylecheck
- tagalign
- tagliatelle
- tenv
- testableexamples
- thelper
- tparallel
- unconvert
- unparam
- usestdlibvars
- wastedassign
- whitespace
- wsl
- zerologlint
linters-settings:
gocyclo:
min-complexity: 20
gocognit:
min-complexity: 30
lll:
line-length: 140
misspell:
locale: US
funlen:
lines: 80
statements: 60
revive:
rules:
- name: exported
severity: warning
- name: unexported-return
severity: warning
gosec:
excludes:
- G204 # subprocess launched with variables
issues:
exclude-rules:
- path: _test\.go
linters:
- errcheck
- gosec
- path: main\.go
linters:
- gochecknoinits
output:
formats:
- format: colored-line-number
+12
View File
@@ -0,0 +1,12 @@
extends: default
rules:
line-length:
max: 140
document-start: disable
braces:
min-spaces-inside: 0
max-spaces-inside: 1
brackets:
min-spaces-inside: 0
max-spaces-inside: 1
+12
View File
@@ -0,0 +1,12 @@
FROM golang:1.23-alpine AS builder
RUN apk add --no-cache git ca-certificates
WORKDIR /src
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 go build -ldflags="-s -w" -o /gosleep-timer .
FROM scratch
COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
COPY --from=builder /gosleep-timer /gosleep-timer
ENTRYPOINT ["/gosleep-timer"]
+141
View File
@@ -0,0 +1,141 @@
name: ci
'on':
push:
branches:
- '**'
pull_request:
workflow_dispatch:
env:
REGISTRY: gcr.forust.xyz
IMAGE_NAME: forust/gosleep-timer
jobs:
lint-go:
runs-on: [self-hosted, linux, arch, homelab]
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup Go
uses: actions/setup-go@v5
with:
go-version: '1.23'
- name: Lint with golangci-lint
uses: golangci/golangci-lint-action@v6
with:
version: latest
args: --config .golangci.yml --timeout 10m
- name: Run staticcheck
shell: bash
run: |
go install honnef.co/go/tools/cmd/staticcheck@latest
staticcheck ./...
- name: Run gosec
shell: bash
run: |
go install github.com/securego/gosec/v2/cmd/gosec@latest
gosec -no-fail -fmt=text ./...
- name: Run revive
shell: bash
run: |
go install github.com/mgechev/revive@latest
revive -config .revive.toml ./...
lint-yaml:
runs-on: [self-hosted, linux, arch, homelab]
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Lint YAML syntax
shell: bash
run: |
docker run --rm \
-v "$PWD:/work" \
-w /work \
cytopia/yamllint:latest \
-c .yamllint .
build:
runs-on: [self-hosted, linux, arch, homelab]
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup Go
uses: actions/setup-go@v5
with:
go-version: '1.23'
- name: Build
shell: bash
run: go build -ldflags="-s -w" -o gosleep-timer .
- name: Test
shell: bash
run: go test -v -race -coverprofile=cover.out ./...
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: gosleep-timer
path: gosleep-timer
publish:
needs: [lint-go, lint-yaml, build]
if: github.event_name != 'pull_request' && (github.ref_name == 'main' || github.ref_name == 'dev')
runs-on: [self-hosted, linux, arch, homelab]
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup Go
uses: actions/setup-go@v5
with:
go-version: '1.23'
- name: Read project version
id: version
shell: bash
run: |
version="$(go version -m 2>/dev/null || date +%Y%m%d)"
echo "version=$version" >> "$GITHUB_OUTPUT"
- name: Log in to registry
shell: bash
run: |
echo "${{ secrets.REGISTRY_PASSWORD }}" | docker login "${REGISTRY}" \
-u "${{ secrets.REGISTRY_USERNAME }}" \
--password-stdin
- name: Build and push image
shell: bash
run: |
image="${REGISTRY}/${IMAGE_NAME}"
tags=("latest" "${{ steps.version.outputs.version }}")
case "${GITHUB_REF_NAME}" in
main)
tags+=("main" "prod")
;;
dev)
tags+=("dev")
;;
esac
build_args=()
for tag in "${tags[@]}"; do
build_args+=(-t "${image}:${tag}")
done
docker build "${build_args[@]}" .
for tag in "${tags[@]}"; do
docker push "${image}:${tag}"
done