From 4b69e0636c93d7ca7cecc123bb59996a7a380bb0 Mon Sep 17 00:00:00 2001 From: Markus Pesch Date: Sat, 31 May 2025 22:17:53 +0200 Subject: [PATCH] feat: use goreleaser --- .dockerignore | 1 + .drone.yml | 555 ------------------ .gitea/workflows/golang-tests.yaml | 21 + .gitea/workflows/markdown-linters.yaml | 20 + .gitea/workflows/release.yaml | 52 ++ .../update-docker-hub-description.yaml | 20 + .gitignore | 7 +- .golangci.yml | 29 - .goreleaser.yaml | 175 ++++++ .markdownlint.yaml | 136 +++++ Dockerfile | 19 +- Makefile | 115 ++-- README.md | 43 +- go.mod | 2 +- manifest.tmpl | 20 - 15 files changed, 532 insertions(+), 683 deletions(-) create mode 100644 .dockerignore delete mode 100644 .drone.yml create mode 100644 .gitea/workflows/golang-tests.yaml create mode 100644 .gitea/workflows/markdown-linters.yaml create mode 100644 .gitea/workflows/release.yaml create mode 100644 .gitea/workflows/update-docker-hub-description.yaml delete mode 100644 .golangci.yml create mode 100644 .goreleaser.yaml create mode 100644 .markdownlint.yaml delete mode 100644 manifest.tmpl diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..37224e3 --- /dev/null +++ b/.dockerignore @@ -0,0 +1 @@ +civ \ No newline at end of file diff --git a/.drone.yml b/.drone.yml deleted file mode 100644 index 37510a2..0000000 --- a/.drone.yml +++ /dev/null @@ -1,555 +0,0 @@ ---- -kind: pipeline -type: kubernetes -name: linter - -platform: - os: linux - -steps: -- name: markdown lint - commands: - - markdownlint *.md - image: git.cryptic.systems/volker.raschek/markdownlint:0.44.0 - resources: - limits: - cpu: 50 - memory: 50M - -- name: email-notification - environment: - PLUGIN_HOST: - from_secret: smtp_host - PLUGIN_USERNAME: - from_secret: smtp_username - PLUGIN_PASSWORD: - from_secret: smtp_password - PLUGIN_FROM: - from_secret: smtp_mail_address - image: git.cryptic.systems/volker.raschek/drone-email:0.1.5 - resources: - limits: - cpu: 150 - memory: 150M - when: - status: - - changed - - failure - -trigger: - event: - exclude: - - tag - ---- -kind: pipeline -type: kubernetes -name: unit-test - -steps: -- name: unit-test - commands: - - go test -v ./... - image: docker.io/library/golang:1.24 - resources: - limits: - cpu: 250 - memory: 500M - -depends_on: -- linter - -trigger: - event: - exclude: - - tag - ---- -kind: pipeline -type: docker -name: dry-run-amd64 - -platform: - os: linux - arch: amd64 - -steps: -- name: build - image: docker.io/plugins/docker:latest - settings: - dockerfile: Dockerfile - auto_tag: false - dry_run: true - tags: latest-amd64 - repo: volkerraschek/civ - no_cache: true - volumes: - - name: docker_socket - path: /var/run/docker.sock - -- name: notify - image: docker.io/drillster/drone-email:latest - environment: - PLUGIN_HOST: - from_secret: smtp_host - PLUGIN_USERNAME: - from_secret: smtp_username - PLUGIN_PASSWORD: - from_secret: smtp_password - PLUGIN_FROM: - from_secret: smtp_mail_address - when: - status: - - changed - - failure - -volumes: -- name: docker_socket - host: - path: /var/run/docker.sock - -depends_on: -- unit-test - -trigger: - branch: - exclude: - - master - event: - - pull_request - - push - ---- -kind: pipeline -type: docker -name: dry-run-arm64-v8 - -platform: - os: linux - arch: arm64 - -steps: -- name: build - image: docker.io/plugins/docker:latest - settings: - dockerfile: Dockerfile - auto_tag: false - dry_run: true - tags: latest-arm64-v8 - repo: volkerraschek/civ - no_cache: true - -- name: notify - image: docker.io/drillster/drone-email:latest - environment: - PLUGIN_HOST: - from_secret: smtp_host - PLUGIN_USERNAME: - from_secret: smtp_username - PLUGIN_PASSWORD: - from_secret: smtp_password - PLUGIN_FROM: - from_secret: smtp_mail_address - volumes: - - name: docker_socket - path: /var/run/docker.sock - when: - status: - - changed - - failure - -volumes: -- name: docker_socket - host: - path: /var/run/docker.sock - -depends_on: -- unit-test - -trigger: - branch: - exclude: - - master - event: - - pull_request - - push - ---- -kind: pipeline -type: docker -name: latest-amd64 - -platform: - os: linux - arch: amd64 - -steps: -- name: build - image: docker.io/plugins/docker:latest - settings: - dockerfile: Dockerfile - auto_tag: false - tags: latest-amd64 - repo: volkerraschek/civ - username: - from_secret: container_image_registry_user - password: - from_secret: container_image_registry_password - no_cache: true - volumes: - - name: docker_socket - path: /var/run/docker.sock - -- name: notify - image: docker.io/drillster/drone-email:latest - environment: - PLUGIN_HOST: - from_secret: smtp_host - PLUGIN_USERNAME: - from_secret: smtp_username - PLUGIN_PASSWORD: - from_secret: smtp_password - PLUGIN_FROM: - from_secret: smtp_mail_address - when: - status: - - changed - - failure - -volumes: -- name: docker_socket - host: - path: /var/run/docker.sock - -depends_on: -- unit-test - -trigger: - branch: - - master - event: - - cron - - push - repo: - - volker.raschek/civ - ---- -kind: pipeline -type: docker -name: latest-arm64-v8 - -platform: - os: linux - arch: arm64 - -steps: -- name: build - image: docker.io/plugins/docker:latest - settings: - dockerfile: Dockerfile - auto_tag: false - tags: latest-arm64-v8 - repo: volkerraschek/civ - username: - from_secret: container_image_registry_user - password: - from_secret: container_image_registry_password - no_cache: true - -- name: notify - image: docker.io/drillster/drone-email:latest - environment: - PLUGIN_HOST: - from_secret: smtp_host - PLUGIN_USERNAME: - from_secret: smtp_username - PLUGIN_PASSWORD: - from_secret: smtp_password - PLUGIN_FROM: - from_secret: smtp_mail_address - volumes: - - name: docker_socket - path: /var/run/docker.sock - when: - status: - - changed - - failure - -volumes: -- name: docker_socket - host: - path: /var/run/docker.sock - -depends_on: -- unit-test - -trigger: - branch: - - master - event: - - cron - - push - repo: - - volker.raschek/civ - ---- -kind: pipeline -type: kubernetes -name: latest-manifest - -steps: -- name: build-manifest - image: docker.io/plugins/manifest:latest - settings: - auto_tag: false - ignore_missing: true - spec: manifest.tmpl - username: - from_secret: container_image_registry_user - password: - from_secret: container_image_registry_password - -- name: notify - image: docker.io/drillster/drone-email:latest - environment: - PLUGIN_HOST: - from_secret: smtp_host - PLUGIN_USERNAME: - from_secret: smtp_username - PLUGIN_PASSWORD: - from_secret: smtp_password - PLUGIN_FROM: - from_secret: smtp_mail_address - resources: - limits: - cpu: 50 - memory: 25M - when: - status: - - changed - - failure - -depends_on: -- latest-amd64 -- latest-arm64-v8 - -trigger: - branch: - - master - event: - - cron - - push - repo: - - volker.raschek/civ - ---- -kind: pipeline -type: docker -name: tagged-amd64 - -platform: - os: linux - arch: amd64 - -steps: -- name: build - image: docker.io/plugins/docker:latest - settings: - dockerfile: Dockerfile - auto_tag: true - auto_tag_suffix: amd64 - repo: volkerraschek/civ - username: - from_secret: container_image_registry_user - password: - from_secret: container_image_registry_password - build_args: - - VERSION=${DRONE_TAG} - no_cache: true - volumes: - - name: docker_socket - path: /var/run/docker.sock - -- name: notify - image: docker.io/drillster/drone-email:latest - environment: - PLUGIN_HOST: - from_secret: smtp_host - PLUGIN_USERNAME: - from_secret: smtp_username - PLUGIN_PASSWORD: - from_secret: smtp_password - PLUGIN_FROM: - from_secret: smtp_mail_address - when: - status: - - changed - - failure - -volumes: -- name: docker_socket - host: - path: /var/run/docker.sock - -trigger: - event: - - tag - repo: - - volker.raschek/civ - ---- -kind: pipeline -type: docker -name: tagged-arm64-v8 - -platform: - os: linux - arch: arm64 - -steps: -- name: build - image: docker.io/plugins/docker:latest - settings: - dockerfile: Dockerfile - auto_tag: true - auto_tag_suffix: arm64-v8 - repo: volkerraschek/civ - username: - from_secret: container_image_registry_user - password: - from_secret: container_image_registry_password - build_args: - - MARKDOWNLINT_VERSION=${DRONE_TAG} - no_cache: true - volumes: - - name: docker_socket - path: /var/run/docker.sock - -- name: notify - image: docker.io/drillster/drone-email:latest - environment: - PLUGIN_HOST: - from_secret: smtp_host - PLUGIN_USERNAME: - from_secret: smtp_username - PLUGIN_PASSWORD: - from_secret: smtp_password - PLUGIN_FROM: - from_secret: smtp_mail_address - when: - status: - - changed - - failure - -volumes: -- name: docker_socket - host: - path: /var/run/docker.sock - -trigger: - event: - - tag - repo: - - volker.raschek/civ - ---- -kind: pipeline -type: kubernetes -name: tagged-manifest - -steps: -- name: build-manifest - image: docker.io/plugins/manifest:latest - settings: - auto_tag: true - ignore_missing: true - spec: manifest.tmpl - username: - from_secret: container_image_registry_user - password: - from_secret: container_image_registry_password - -- name: notify - image: docker.io/drillster/drone-email:latest - environment: - PLUGIN_HOST: - from_secret: smtp_host - PLUGIN_USERNAME: - from_secret: smtp_username - PLUGIN_PASSWORD: - from_secret: smtp_password - PLUGIN_FROM: - from_secret: smtp_mail_address - resources: - limits: - cpu: 50 - memory: 25M - when: - status: - - changed - - failure - -depends_on: -- tagged-amd64 -- tagged-arm64-v8 - -trigger: - event: - - tag - repo: - - volker.raschek/civ - ---- -kind: pipeline -type: kubernetes -name: sync - -platform: - os: linux - arch: amd64 - -steps: -- name: github - image: docker.io/appleboy/drone-git-push:latest - resources: - limits: - cpu: 50 - memory: 25M - settings: - branch: master - remote: ssh://git@github.com/volker-raschek/civ.git - force: true - ssh_key: - from_secret: ssh_key - -- name: email-notification - environment: - PLUGIN_HOST: - from_secret: smtp_host - PLUGIN_USERNAME: - from_secret: smtp_username - PLUGIN_PASSWORD: - from_secret: smtp_password - PLUGIN_FROM: - from_secret: smtp_mail_address - image: docker.io/drillster/drone-email:latest - resources: - limits: - cpu: 50 - memory: 25M - when: - status: - - changed - - failure - -depends_on: -- latest-manifest - -trigger: - branch: - - master - event: - - cron - - push - repo: - - volker.raschek/civ diff --git a/.gitea/workflows/golang-tests.yaml b/.gitea/workflows/golang-tests.yaml new file mode 100644 index 0000000..c46ec77 --- /dev/null +++ b/.gitea/workflows/golang-tests.yaml @@ -0,0 +1,21 @@ +name: Golang Tests + +on: + pull_request: + types: [ "opened", "reopened", "synchronize" ] + push: + branches: [ '**' ] + tags-ignore: [ '**' ] + +jobs: + unittest: + runs-on: + - ubuntu-latest + steps: + - uses: actions/checkout@v4.2.2 + - uses: actions/setup-go@v5.5.0 + with: + go-version: stable + - env: + GOPROXY: ${{ vars.GOPROXY }} + run: make test/unit diff --git a/.gitea/workflows/markdown-linters.yaml b/.gitea/workflows/markdown-linters.yaml new file mode 100644 index 0000000..e2715a7 --- /dev/null +++ b/.gitea/workflows/markdown-linters.yaml @@ -0,0 +1,20 @@ +name: Markdown linter + +on: + pull_request: + types: [ "opened", "reopened", "synchronize" ] + push: + branches: [ '**' ] + tags-ignore: [ '**' ] + workflow_dispatch: {} + +jobs: + markdown-lint: + container: + image: git.cryptic.systems/volker.raschek/markdownlint:0.45.0 + runs-on: + - ubuntu-latest + steps: + - uses: actions/checkout@v4.2.2 + - name: Lint Markdown files + run: markdownlint --config .markdownlint.yaml . \ No newline at end of file diff --git a/.gitea/workflows/release.yaml b/.gitea/workflows/release.yaml new file mode 100644 index 0000000..8be91bf --- /dev/null +++ b/.gitea/workflows/release.yaml @@ -0,0 +1,52 @@ +name: Release + +on: + push: + tags: [ '**' ] + +permissions: + contents: write + +jobs: + release: + runs-on: + - ubuntu-latest + steps: + - uses: actions/checkout@v4.2.2 + - uses: docker/setup-qemu-action@v3.6.0 + - uses: actions/setup-go@v5.5.0 + with: + go-version: stable + - uses: docker/login-action@v3.4.0 + with: + registry: git.cryptic.systems + username: ${{ github.repository_owner }} + password: ${{ secrets.GIT_CRYPTIC_SYSTEMS_PACKAGE_REGISTRY_TOKEN }} + - env: + GITEA_TOKEN: ${{ secrets.GIT_CRYPTIC_SYSTEMS_PACKAGE_REGISTRY_TOKEN }} + GONOSUMDB: ${{ vars.GONOSUMDB }} + GOPROXY: ${{ vars.GOPROXY }} + uses: goreleaser/goreleaser-action@v6.3.0 + with: + version: "~> v2" + args: release --clean + + sync-to-hub-docker-io: + needs: + - release + runs-on: ubuntu-latest + steps: + - name: Copy images to docker.io + run: | + TAG=$(echo ${{ github.ref_name }} | sed 's/v//gm') + + apt-get update --yes + apt-get install --yes skopeo + skopeo copy \ + --all \ + --dest-password ${{ secrets.DOCKER_IO_PASSWORD }} \ + --dest-username ${{ secrets.DOCKER_IO_USERNAME }} \ + --src-password ${{ secrets.GIT_CRYPTIC_SYSTEMS_PACKAGE_REGISTRY_TOKEN }} \ + --src-username volker.raschek \ + docker://git.cryptic.systems/volker.raschek/civ:${TAG} \ + docker://docker.io/volkerraschek/civ:${TAG} diff --git a/.gitea/workflows/update-docker-hub-description.yaml b/.gitea/workflows/update-docker-hub-description.yaml new file mode 100644 index 0000000..24426e3 --- /dev/null +++ b/.gitea/workflows/update-docker-hub-description.yaml @@ -0,0 +1,20 @@ +name: Update Docker Hub Description + +on: + push: + branches: [ 'master' ] + paths: [ 'README.md' ] + workflow_dispatch: {} + +jobs: + update-description-on-hub-docker-io: + runs-on: + - ubuntu-latest + steps: + - uses: actions/checkout@v4.2.2 + - uses: peter-evans/dockerhub-description@v4.0.2 + with: + username: ${{ secrets.DOCKER_IO_USERNAME }} + password: ${{ secrets.DOCKER_IO_PASSWORD }} + repository: volkerraschek/civ + readme-filepath: README.md \ No newline at end of file diff --git a/.gitignore b/.gitignore index 4ed4c78..315d21a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,3 @@ -civ* +civ coverage.txt -config*.yml -config*.yaml -*_result.yml -*_result.yaml \ No newline at end of file +dist \ No newline at end of file diff --git a/.golangci.yml b/.golangci.yml deleted file mode 100644 index 78a7d8a..0000000 --- a/.golangci.yml +++ /dev/null @@ -1,29 +0,0 @@ -run: - skip-dirs: - - it - timeout: 10m - tests: true - -linters: - disable-all: true - enable: - # Default - - deadcode - - errcheck - - gosimple - - govet - - ineffassign - - staticcheck - - structcheck - - typecheck - - unused - - varcheck - - # Additionally linters - - bodyclose - - misspell - - nilerr - - rowserrcheck - - sqlclosecheck - - unparam - - whitespace \ No newline at end of file diff --git a/.goreleaser.yaml b/.goreleaser.yaml new file mode 100644 index 0000000..fcbbfba --- /dev/null +++ b/.goreleaser.yaml @@ -0,0 +1,175 @@ +project_name: civ + +archives: +- formats: [ "tar.xz" ] + files: + - README.md + - LICENSE + +before: + hooks: + - go mod tidy + +builds: +- main: main.go + binary: >- + {{ .ProjectName }}- + {{- .Version }}- + {{- .Os }}- + {{- if eq .Arch "amd64" }}amd64 + {{- else if eq .Arch "amd64_v1" }}amd64 + {{- else }}{{ .Arch }}{{ end }} + {{- if .Arm }}-{{ .Arm }}{{ end }} + env: + - CGO_ENABLED=0 + - GONOSUMDB={{ .Env.GONOSUMDB }} + - GOPROXY={{ .Env.GOPROXY }} + goos: + - linux + goarch: + - amd64 + - arm + - arm64 + - riscv64 + goarm: + - "6" + - "7" + flags: + - -trimpath + ldflags: + - -s -w -X 'main.version={{ trimprefix .Tag "v" }}' + +changelog: + filters: + exclude: + - '^chore' + - '^docs' + - '^test' + - Merge pull request + - Merge branch + - go mod tidy + format: "{{.SHA}}: {{.Message}} (@{{.AuthorUsername}})" + groups: + - title: Features + regexp: '^.*?feat(\([[:word:]]+\))??!?:.+$' + order: 0 + - title: "Bug fixes" + regexp: '^.*?fix(\([[:word:]]+\))??!?:.+$' + order: 1 + - title: Others + order: 999 + sort: asc + use: git + +dockers: +- build_flag_templates: + - --label=org.opencontainers.image.created={{ time "2006-01-02T15:04:05Z07:00" }} + - --label=org.opencontainers.image.description={{ .ProjectName }} + - --label=org.opencontainers.image.documentation={{ .ProjectName }} + - --label=org.opencontainers.image.revision={{ .FullCommit }} + - --label=org.opencontainers.image.source={{ .GitURL }} + - --label=org.opencontainers.image.title={{ .ProjectName }} + - --label=org.opencontainers.image.url=https://git.cryptic.systems/volker.raschek/{{ .ProjectName }} + - --label=org.opencontainers.image.version={{ trimprefix .Tag "v" }} + - --platform=linux/amd64 + - --pull + dockerfile: Dockerfile + goarch: amd64 + goos: linux + image_templates: + - 'git.cryptic.systems/volker.raschek/{{ .ProjectName }}:{{ trimprefix .Tag "v" }}-amd64' + skip_push: false + use: buildx + +- build_flag_templates: + - --label=org.opencontainers.image.created={{ time "2006-01-02T15:04:05Z07:00" }} + - --label=org.opencontainers.image.description={{ .ProjectName }} + - --label=org.opencontainers.image.documentation={{ .ProjectName }} + - --label=org.opencontainers.image.revision={{ .FullCommit }} + - --label=org.opencontainers.image.source={{ .GitURL }} + - --label=org.opencontainers.image.title={{ .ProjectName }} + - --label=org.opencontainers.image.url=https://git.cryptic.systems/volker.raschek/{{ .ProjectName }} + - --label=org.opencontainers.image.version={{ trimprefix .Tag "v" }} + - --platform=linux/arm/v6 + - --pull + dockerfile: Dockerfile + goarch: arm + goarm: "6" + goos: linux + image_templates: + - 'git.cryptic.systems/volker.raschek/{{ .ProjectName }}:{{ trimprefix .Tag "v" }}-arm-v6' + skip_push: false + use: buildx + +- build_flag_templates: + - --label=org.opencontainers.image.created={{ time "2006-01-02T15:04:05Z07:00" }} + - --label=org.opencontainers.image.description={{ .ProjectName }} + - --label=org.opencontainers.image.documentation={{ .ProjectName }} + - --label=org.opencontainers.image.revision={{ .FullCommit }} + - --label=org.opencontainers.image.source={{ .GitURL }} + - --label=org.opencontainers.image.title={{ .ProjectName }} + - --label=org.opencontainers.image.url=https://git.cryptic.systems/volker.raschek/{{ .ProjectName }} + - --label=org.opencontainers.image.version={{ trimprefix .Tag "v" }} + - --platform=linux/arm/v7 + - --pull + dockerfile: Dockerfile + goarch: arm + goarm: "7" + goos: linux + image_templates: + - 'git.cryptic.systems/volker.raschek/{{ .ProjectName }}:{{ trimprefix .Tag "v" }}-arm-v7' + skip_push: false + use: buildx + +- build_flag_templates: + - --label=org.opencontainers.image.created={{ time "2006-01-02T15:04:05Z07:00" }} + - --label=org.opencontainers.image.description={{ .ProjectName }} + - --label=org.opencontainers.image.documentation={{ .ProjectName }} + - --label=org.opencontainers.image.revision={{ .FullCommit }} + - --label=org.opencontainers.image.source={{ .GitURL }} + - --label=org.opencontainers.image.title={{ .ProjectName }} + - --label=org.opencontainers.image.url=https://git.cryptic.systems/volker.raschek/{{ .ProjectName }} + - --label=org.opencontainers.image.version={{ trimprefix .Tag "v" }} + - --platform=linux/arm64 + - --pull + dockerfile: Dockerfile + goarch: arm64 + goos: linux + image_templates: + - 'git.cryptic.systems/volker.raschek/{{ .ProjectName }}:{{ trimprefix .Tag "v" }}-arm64' + skip_push: false + use: buildx + +- build_flag_templates: + - --label=org.opencontainers.image.created={{ time "2006-01-02T15:04:05Z07:00" }} + - --label=org.opencontainers.image.description={{ .ProjectName }} + - --label=org.opencontainers.image.documentation={{ .ProjectName }} + - --label=org.opencontainers.image.revision={{ .FullCommit }} + - --label=org.opencontainers.image.source={{ .GitURL }} + - --label=org.opencontainers.image.title={{ .ProjectName }} + - --label=org.opencontainers.image.url=https://git.cryptic.systems/volker.raschek/{{ .ProjectName }} + - --label=org.opencontainers.image.version={{ trimprefix .Tag "v" }} + - --platform=linux/riscv64 + - --pull + dockerfile: Dockerfile + goarch: riscv64 + goos: linux + image_templates: + - 'git.cryptic.systems/volker.raschek/{{ .ProjectName }}:{{ trimprefix .Tag "v" }}-riscv64' + skip_push: false + use: buildx + +docker_manifests: +- name_template: 'git.cryptic.systems/volker.raschek/{{ .ProjectName }}:{{ trimprefix .Tag "v" }}' + image_templates: + - 'git.cryptic.systems/volker.raschek/{{ .ProjectName }}:{{ trimprefix .Tag "v" }}-amd64' + - 'git.cryptic.systems/volker.raschek/{{ .ProjectName }}:{{ trimprefix .Tag "v" }}-arm-v6' + - 'git.cryptic.systems/volker.raschek/{{ .ProjectName }}:{{ trimprefix .Tag "v" }}-arm-v7' + - 'git.cryptic.systems/volker.raschek/{{ .ProjectName }}:{{ trimprefix .Tag "v" }}-arm64' + - 'git.cryptic.systems/volker.raschek/{{ .ProjectName }}:{{ trimprefix .Tag "v" }}-riscv64' + +gitea_urls: + api: https://git.cryptic.systems/api/v1 + download: https://git.cryptic.systems + +version: 2 diff --git a/.markdownlint.yaml b/.markdownlint.yaml new file mode 100644 index 0000000..34c4081 --- /dev/null +++ b/.markdownlint.yaml @@ -0,0 +1,136 @@ +# markdownlint YAML configuration +# https://github.com/DavidAnson/markdownlint/blob/main/schema/.markdownlint.yaml + +# Default state for all rules +default: true + +# Path to configuration file to extend +extends: null + +# MD003/heading-style/header-style - Heading style +MD003: + # Heading style + style: "atx" + +# MD004/ul-style - Unordered list style +MD004: + style: "dash" + +# MD007/ul-indent - Unordered list indentation +MD007: + # Spaces for indent + indent: 2 + # Whether to indent the first level of the list + start_indented: false + +# MD009/no-trailing-spaces - Trailing spaces +MD009: + # Spaces for line break + br_spaces: 2 + # Allow spaces for empty lines in list items + list_item_empty_lines: false + # Include unnecessary breaks + strict: false + +# MD010/no-hard-tabs - Hard tabs +MD010: + # Include code blocks + code_blocks: true + +# MD012/no-multiple-blanks - Multiple consecutive blank lines +MD012: + # Consecutive blank lines + maximum: 1 + +# MD013/line-length - Line length +MD013: + # Number of characters + line_length: 120 + # Number of characters for headings + heading_line_length: 120 + # Number of characters for code blocks + code_block_line_length: 120 + # Include code blocks + code_blocks: false + # Include tables + tables: false + # Include headings + headings: true + # Strict length checking + strict: false + # Stern length checking + stern: false + +# MD022/blanks-around-headings/blanks-around-headers - Headings should be surrounded by blank lines +MD022: + # Blank lines above heading + lines_above: 1 + # Blank lines below heading + lines_below: 1 + +# MD025/single-title/single-h1 - Multiple top-level headings in the same document +MD025: + # Heading level + level: 1 + # RegExp for matching title in front matter + front_matter_title: "^\\s*title\\s*[:=]" + +# MD026/no-trailing-punctuation - Trailing punctuation in heading +MD026: + # Punctuation characters + punctuation: ".,;:!。,;:!" + +# MD029/ol-prefix - Ordered list item prefix +MD029: + # List style + style: "one_or_ordered" + +# MD030/list-marker-space - Spaces after list markers +MD030: + # Spaces for single-line unordered list items + ul_single: 1 + # Spaces for single-line ordered list items + ol_single: 1 + # Spaces for multi-line unordered list items + ul_multi: 1 + # Spaces for multi-line ordered list items + ol_multi: 1 + +# MD033/no-inline-html - Inline HTML +MD033: + # Allowed elements + allowed_elements: [] + +# MD035/hr-style - Horizontal rule style +MD035: + # Horizontal rule style + style: "---" + +# MD036/no-emphasis-as-heading/no-emphasis-as-header - Emphasis used instead of a heading +MD036: + # Punctuation characters + punctuation: ".,;:!?。,;:!?" + +# MD041/first-line-heading/first-line-h1 - First line in a file should be a top-level heading +MD041: + # Heading level + level: 1 + # RegExp for matching title in front matter + front_matter_title: "^\\s*title\\s*[:=]" + +# MD044/proper-names - Proper names should have the correct capitalization +MD044: + # List of proper names + names: [] + # Include code blocks + code_blocks: false + +# MD046/code-block-style - Code block style +MD046: + # Block style + style: "fenced" + +# MD048/code-fence-style - Code fence style +MD048: + # Code fence syle + style: "backtick" diff --git a/Dockerfile b/Dockerfile index e007d4d..7e5dad5 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,18 +1,5 @@ -FROM docker.io/library/golang:1.17-alpine3.13 AS build +FROM scratch AS build -ARG VERSION=latest +COPY civ-* /usr/bin/civ -COPY . /workspace - -WORKDIR /workspace - -RUN set -ex && \ - apk update && \ - apk add git make && \ - make install VERSION=${VERSION} DESTDIR=/civ PREFIX=/usr - -FROM docker.io/library/alpine:3.21 - -COPY --from=build /civ / - -ENTRYPOINT [ "/usr/bin/civ" ] +ENTRYPOINT [ "/usr/bin/civ" ] \ No newline at end of file diff --git a/Makefile b/Makefile index 80bf842..906300b 100644 --- a/Makefile +++ b/Makefile @@ -1,50 +1,58 @@ -VERSION?=$(shell git describe --abbrev=0)+$(shell date +'%Y%m%d%H%I%S') - -EXECUTABLE:=civ +EXECUTABLE=civ +VERSION?=$(shell git describe --abbrev=0)+hash.$(shell git rev-parse --short HEAD) +# Destination directory and prefix to place the compiled binaries, documentaions +# and other files. DESTDIR?= PREFIX?=/usr/local -# BINARIES -# ============================================================================== -all: ${EXECUTABLE} +# CONTAINER_RUNTIME +# The CONTAINER_RUNTIME variable will be used to specified the path to a +# container runtime. This is needed to start and run a container image. +CONTAINER_RUNTIME?=$(shell which podman) -${EXECUTABLE}: +# DCMERGE_IMAGE_REGISTRY_NAME +# Defines the name of the new container to be built using several variables. +DCMERGE_IMAGE_REGISTRY_NAME:=git.cryptic.systems +DCMERGE_IMAGE_REGISTRY_USER:=volker.raschek + +DCMERGE_IMAGE_NAMESPACE?=${DCMERGE_IMAGE_REGISTRY_USER} +DCMERGE_IMAGE_NAME:=${EXECUTABLE} +DCMERGE_IMAGE_VERSION?=latest +DCMERGE_IMAGE_FULLY_QUALIFIED=${DCMERGE_IMAGE_REGISTRY_NAME}/${DCMERGE_IMAGE_NAMESPACE}/${DCMERGE_IMAGE_NAME}:${DCMERGE_IMAGE_VERSION} + +# BIN +# ============================================================================== +civ: + CGO_ENABLED=0 \ GOPROXY=$(shell go env GOPROXY) \ - GOPRIVATE=$(shell go env GOPRIVATE) \ - go build -ldflags "-X main.version=${VERSION:v%=%}" -o ${@} - -# UN/INSTALL -# ============================================================================== -PHONY+=install -install: ${EXECUTABLE} - install --directory ${DESTDIR}${PREFIX}/bin - install --mode 755 ${EXECUTABLE} ${DESTDIR}${PREFIX}/bin/${EXECUTABLE} - - install --directory ${DESTDIR}${PREFIX}/licenses/${EXECUTABLE} - install --mode 644 LICENSE ${DESTDIR}${PREFIX}/licenses/${EXECUTABLE}/LICENSE - -PHONY+=uninstall -uninstall: - -rm --recursive --force \ - ${DESTDIR}${PREFIX}/bin/${EXECUTABLE} \ - ${DESTDIR}${PREFIX}/licenses/${EXECUTABLE}/LICENSE + go build -ldflags "-X 'main.version=${VERSION}'" -o ${@} main.go # CLEAN # ============================================================================== PHONY+=clean clean: - rm --force --recursive ${EXECUTABLE}* || true + rm --force --recursive civ -# TEST +# TESTS # ============================================================================== PHONY+=test/unit test/unit: - go test -v -race -coverprofile=coverage.txt -covermode=atomic -timeout 600s -count=1 ./pkg/... + CGO_ENABLED=0 \ + GOPROXY=$(shell go env GOPROXY) \ + go test -v -p 1 -coverprofile=coverage.txt -covermode=count -timeout 1200s ./pkg/... + +PHONY+=test/integration +test/integration: + CGO_ENABLED=0 \ + GOPROXY=$(shell go env GOPROXY) \ + go test -v -p 1 -count=1 -timeout 1200s ./it/... PHONY+=test/coverage test/coverage: test/unit - go tool cover -html=coverage.txt + CGO_ENABLED=0 \ + GOPROXY=$(shell go env GOPROXY) \ + go tool cover -html=coverage.txt # GOLANGCI-LINT # ============================================================================== @@ -52,11 +60,52 @@ PHONY+=golangci-lint golangci-lint: golangci-lint run --concurrency=$(shell nproc) -# GOSEC +# INSTALL # ============================================================================== -PHONY+=gosec -gosec: - gosec $(shell pwd)/... +PHONY+=uninstall +install: civ + install --directory ${DESTDIR}/etc/bash_completion.d + ./civ completion bash > ${DESTDIR}/etc/bash_completion.d/${EXECUTABLE} + + install --directory ${DESTDIR}${PREFIX}/bin + install --mode 0755 ${EXECUTABLE} ${DESTDIR}${PREFIX}/bin/${EXECUTABLE} + + install --directory ${DESTDIR}${PREFIX}/share/licenses/${EXECUTABLE} + install --mode 0644 LICENSE ${DESTDIR}${PREFIX}/share/licenses/${EXECUTABLE}/LICENSE + +# UNINSTALL +# ============================================================================== +PHONY+=uninstall +uninstall: + -rm --force --recursive \ + ${DESTDIR}/etc/bash_completion.d/${EXECUTABLE} \ + ${DESTDIR}${PREFIX}/bin/${EXECUTABLE} \ + ${DESTDIR}${PREFIX}/share/licenses/${EXECUTABLE} + +# BUILD CONTAINER IMAGE +# ============================================================================== +PHONY+=container-image/build +container-image/build: + ${CONTAINER_RUNTIME} build \ + --build-arg VERSION=${VERSION} \ + --file Dockerfile \ + --no-cache \ + --pull \ + --tag ${DCMERGE_IMAGE_FULLY_QUALIFIED} \ + . + +# DELETE CONTAINER IMAGE +# ============================================================================== +PHONY:=container-image/delete +container-image/delete: + - ${CONTAINER_RUNTIME} image rm ${DCMERGE_IMAGE_FULLY_QUALIFIED} + +# PUSH CONTAINER IMAGE +# ============================================================================== +PHONY+=container-image/push +container-image/push: + echo ${DCMERGE_IMAGE_REGISTRY_PASSWORD} | ${CONTAINER_RUNTIME} login ${DCMERGE_IMAGE_REGISTRY_NAME} --username ${DCMERGE_IMAGE_REGISTRY_USER} --password-stdin + ${CONTAINER_RUNTIME} push ${DCMERGE_IMAGE_FULLY_QUALIFIED} # PHONY # ============================================================================== diff --git a/README.md b/README.md index af9d60c..018ef57 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,11 @@ # civ - container image verifier -The container image verifier - `civ` checks based on constraints container -images. For this purpose is a config file required which contains the constraint -definitions. The config file must be passed as argument to `civ`. `civ` writes +The container image verifier - `civ` checks based on constraints container images. For this purpose is a config file +required which contains the constraint definitions. The config file must be passed as argument to `civ`. `civ` writes the results into a separate file. -Currently is `json` and `yaml` supported. As default will be `yaml` used. -Optionally can be specified via the second arg the result file. +Currently is `json` and `yaml` supported. As default will be `yaml` used. Optionally can be specified via the second arg +the result file. `civ config.yaml [ result.yaml ]` @@ -16,12 +15,12 @@ Optionally can be specified via the second arg the result file. #### Exists -Verify if container image `volkerraschek/civ:latest` has label +Verify if container image `git.cryptic.systems/volker.raschek/civ:latest` has label `org.opencontainers.image.documentation` defined. ```yaml images: - volkerraschek/civ:latest: + git.cryptic.systems/volker.raschek/civ:latest: labelConstraints: org.opencontainers.image.documentation: exists: true @@ -29,25 +28,24 @@ images: #### Compare Semantic Versioning -Verify, if the container image `volkerraschek/civ:latest` has label -`org.opencontainers.image.version` defined and has a greater version than -`2.5.7`. +Verify, if the container image `git.cryptic.systems/volker.raschek/civ:latest` has label +`org.opencontainers.image.version` defined and has a greater version than `2.5.7`. ```yaml images: - volkerraschek/civ:latest: + git.cryptic.systems/volker.raschek/civ:latest: labelConstraints: org.opencontainers.image.version: compareSemver: greaterThan: 2.5.7 ``` -Alternatively, can `lessThan` and `equal` be used. For example to define a range -of `2.5.7~2.8.4` with `lessThan` and `greaterThan`. +Alternatively, can `lessThan` and `equal` be used. For example to define a range of `2.5.7~2.8.4` with `lessThan` and +`greaterThan`. ```yaml images: - volkerraschek/civ:latest: + git.cryptic.systems/volker.raschek/civ:latest: labelConstraints: org.opencontainers.image.version: compareSemver: @@ -57,13 +55,12 @@ images: #### Compare String -Verify, if the container image `volkerraschek/civ:latest` has label -`org.opencontainers.image.documentation` defined and the value starts with -`https://` and ends with `README.md`. +Verify, if the container image `git.cryptic.systems/volker.raschek/civ:latest` has label +`org.opencontainers.image.documentation` defined and the value starts with `https://` and ends with `README.md`. ```yaml images: - volkerraschek/civ:latest: + git.cryptic.systems/volker.raschek/civ:latest: labelConstraints: org.opencontainers.image.documentation: compareString: @@ -71,18 +68,16 @@ images: hasSuffix: "README.md" ``` -Alternatively, can be `equal` used to compare the value of a label with a -expected value. +Alternatively, can be `equal` used to compare the value of a label with a expected value. #### Count labels with corresponding prefix, suffix or match pattern -No more than 3 labels with the prefix `org.opencontainers` and exactly one -labels with the suffix `version` may be defined for the image -`volkerraschek/civ:latest`. +No more than 3 labels with the prefix `org.opencontainers` and exactly one labels with the suffix `version` may be +defined for the image `git.cryptic.systems/volker.raschek/civ:latest`. ```yaml images: - volkerraschek/civ:latest: + git.cryptic.systems/volker.raschek/civ:latest: labelConstraints: org.opencontainers%: count: diff --git a/go.mod b/go.mod index 9795dd6..283e638 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module git.cryptic.systems/volker.raschek/civ -go 1.21 +go 1.24 toolchain go1.24.3 diff --git a/manifest.tmpl b/manifest.tmpl deleted file mode 100644 index 1c9a056..0000000 --- a/manifest.tmpl +++ /dev/null @@ -1,20 +0,0 @@ -image: volkerraschek/civ:{{#if build.tag}}{{trimPrefix "v" build.tag}}{{else}}latest{{/if}} -{{#if build.tags}} -tags: -{{#each build.tags}} - - {{this}} -{{/each}} - - "latest" -{{/if}} -manifests: - - - image: volkerraschek/civ:{{#if build.tag}}{{trimPrefix "v" build.tag}}-{{else}}latest{{/if}}-amd64 - platform: - architecture: amd64 - os: linux - - - image: volkerraschek/civ:{{#if build.tag}}{{trimPrefix "v" build.tag}}-{{else}}latest{{/if}}-arm-v7 - platform: - architecture: arm - os: linux - variant: v7 \ No newline at end of file