From 336d8cc1637b526399d72a2614c76b9cef820119 Mon Sep 17 00:00:00 2001 From: Lukasz Raczylo Date: Sun, 7 Dec 2025 15:11:16 +0000 Subject: [PATCH] Move to shared github actions and goreleaser --- .github/workflows/autoupdate.yaml | 73 +---- .github/workflows/release.yaml | 230 +------------- .github/workflows/static.yml | 45 +++ .goreleaser.yaml | 126 ++++++++ Dockerfile.goreleaser | 6 + README.md | 8 + docs/CNAME | 1 + docs/index.html | 495 ++++++++++++++++++++++++++++++ 8 files changed, 706 insertions(+), 278 deletions(-) create mode 100644 .github/workflows/static.yml create mode 100644 .goreleaser.yaml create mode 100644 Dockerfile.goreleaser create mode 100644 docs/CNAME create mode 100644 docs/index.html diff --git a/.github/workflows/autoupdate.yaml b/.github/workflows/autoupdate.yaml index d8b6160..21abfb2 100644 --- a/.github/workflows/autoupdate.yaml +++ b/.github/workflows/autoupdate.yaml @@ -5,70 +5,13 @@ on: schedule: - cron: "0 3 * * *" -env: - GO_VERSION: ">=1.21" +permissions: + contents: write + actions: write jobs: - # This job is responsible for preparation of the build - # environment variables. - prepare: - name: Preparing build context - runs-on: ubuntu-latest - - steps: - - name: Checkout repo - uses: actions/checkout@v4 - - - name: Install Go - uses: actions/setup-go@v5 - id: cache - with: - go-version: ${{env.GO_VERSION}} - cache-dependency-path: "**/*.sum" - - - name: Go get dependencies - if: steps.cache.outputs.cache-hit != 'true' - run: | - go get ./... - - # This job is responsible for running tests and linting the codebase - test: - name: "Unit testing" - runs-on: ubuntu-latest - container: golang:1 - needs: [prepare] - - steps: - - name: Checkout repository - uses: actions/checkout@v4 - with: - fetch-depth: 0 # Ensure full history is checked out - token: ${{ secrets.GHCR_TOKEN }} - - - name: Install Go - uses: actions/setup-go@v5 - with: - go-version: ${{env.GO_VERSION}} - cache-dependency-path: "**/*.sum" - - - name: Install dependencies - run: | - apt-get update - apt-get install ca-certificates make -y - update-ca-certificates - go mod tidy - go get -u -v ./... - go mod tidy -v - - - name: Run unit tests - run: | - export GITHUB_TOKEN=${{ secrets.GHCR_TOKEN }} - CI_RUN=${CI} make test - git config --global --add safe.directory /__w/semver-generator/semver-generator - - - name: Commit changes - uses: stefanzweifel/git-auto-commit-action@v5 - with: - commit_message: "Update go.mod and go.sum" - commit_options: "--no-verify --signoff" - file_pattern: "go.mod go.sum" + autoupdate: + uses: lukaszraczylo/shared-actions/.github/workflows/go-autoupdate.yaml@main + with: + go-version: "1.24" + release-workflow: "release.yaml" diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 17818c3..bcd682c 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -1,222 +1,26 @@ -name: Test, scan, build, release +name: Test, build, release on: workflow_dispatch: push: paths-ignore: - - '**.md' - - '**/release.yaml' - - 'action.yml' + - '**.md' + - '**/release.yaml' + - 'action.yml' branches: - - "master" - - "main" + - main -env: - ENABLE_CODE_LINT: false - ENABLE_CODE_SCANS: false - DEPLOY: false - GO_VERSION: 1.21 +permissions: + contents: write + packages: write jobs: - prepare: - name: Preparing build context - runs-on: ubuntu-latest - outputs: - SANITISED_REPOSITORY_NAME: ${{ steps.get_env.outputs.SANITISED_REPOSITORY_NAME }} - DOCKER_IMAGE: ${{ steps.get_env.outputs.DOCKER_IMAGE }} - GITHUB_COMMIT_NUMBER: ${{ steps.get_env.outputs.GITHUB_COMMIT_NUMBER }} - GITHUB_SHA: ${{ steps.get_env.outputs.GITHUB_SHA }} - GITHUB_RUN_ID: ${{ steps.get_env.outputs.GITHUB_RUN_ID }} - RELEASE_VERSION: ${{ steps.get_env.outputs.RELEASE_VERSION }} - steps: - - name: Checkout repo - uses: actions/checkout@v3 - with: - fetch-depth: '0' - - name: Setting environment variables - id: get_env - run: | - DOWNLOAD_URL=$(curl -s https://api.github.com/repos/lukaszraczylo/semver-generator/releases/latest | grep -E ".*browser_download_url.*linux-" | grep -vE "(arm64|md5)" \ - | cut -d '"' -f 4) - curl -s -L -o semver-gen "$DOWNLOAD_URL" && chmod +x semver-gen - TMP_SANITISED_REPOSITORY_NAME=$(echo ${{ github.event.repository.name }} | sed -e 's|\.|-|g') - TMP_GITHUB_COMMITS_COUNT=$(git rev-list --count HEAD) - TMP_GITHUB_COUNT_NUMBER=$(echo ${GITHUB_RUN_NUMBER}) - TMP_RELEASE_VERSION=$(./semver-gen generate -l -c config-release.yaml | sed -e 's|SEMVER ||g') - - echo ">> Release version: $TMP_RELEASE_VERSION <<" - - # Setting outputs - echo "SANITISED_REPOSITORY_NAME=$TMP_SANITISED_REPOSITORY_NAME" > $GITHUB_OUTPUT - echo "DOCKER_IMAGE=ghcr.io/${{ github.repository_owner }}/$TMP_SANITISED_REPOSITORY_NAME" >> $GITHUB_OUTPUT - echo "GITHUB_COMMIT_NUMBER=$TMP_GITHUB_COMMITS_COUNT" >> $GITHUB_OUTPUT - echo "GITHUB_SHA=$(echo ${GITHUB_SHA::8})" >> $GITHUB_OUTPUT - echo "GITHUB_RUN_ID=$TMP_GITHUB_COUNT_NUMBER" >> $GITHUB_OUTPUT - echo "RELEASE_VERSION=$TMP_RELEASE_VERSION" >> $GITHUB_OUTPUT - - test: - needs: [ prepare ] - name: Code checks pipeline - runs-on: ubuntu-latest - container: github/super-linter:v3.15.5 - env: - CI: true - steps: - - name: Checkout repo - uses: actions/checkout@v3 - - name: Install Go - uses: actions/setup-go@v3 - with: - go-version: ${{ env.GO_VERSION }} - - name: Lint Code Base - if: env.ENABLE_CODE_LINT == true - env: - VALIDATE_ALL_CODEBASE: true - VALIDATE_DOCKERFILE: false # this leaves us with hadolint only - VALIDATE_GO: false # disable bulk validation of go files, run the linter manually - DEFAULT_BRANCH: main - GITHUB_TOKEN: ${{ secrets.GHCR_TOKEN }} - LOG_LEVEL: WARN - run: | - golangci-lint run --exclude-use-default ./... - /action/lib/linter.sh - - name: Run unit tests - env: - GITHUB_TOKEN: ${{ secrets.GHCR_TOKEN }} - run: | - make test CI_RUN=${CI} - - name: Upload codecov result - uses: codecov/codecov-action@v3 - continue-on-error: true - with: - token: ${{ secrets.CODECOV_TOKEN }} # not required for public repos - files: coverage.out - fail_ci_if_error: false - - code_scans: - needs: [ prepare ] - name: Code scans pipeline - runs-on: ubuntu-latest - steps: - - name: Checkout repo - uses: actions/checkout@v3 - - name: Install Go - uses: actions/setup-go@v3 - with: - go-version: ${{ env.GO_VERSION }} - - name: Configure git for private modules - run: | - make update - - name: WriteGoList - run: go list -json -m all > go.list - - name: Running nancy - if: env.ENABLE_CODE_SCANS == true - uses: sonatype-nexus-community/nancy-github-action@main - - name: Running gosec - if: env.ENABLE_CODE_SCANS == true - uses: securego/gosec@master - with: - args: ./... - - - build-binary: - needs: [ prepare, test, code_scans ] - name: Binary compilation and release - runs-on: ubuntu-latest - - steps: - - name: Checkout code - uses: actions/checkout@v3 - - name: Install Go - uses: actions/setup-go@v3 - with: - go-version: ${{ env.GO_VERSION }} - - name: Build binaries - run: | - LOCAL_VERSION=${{ needs.prepare.outputs.RELEASE_VERSION }} make dist-release - - - name: Get list of the commits since last release - run: | - echo "$(git log $(git describe --tags --abbrev=0)..HEAD --pretty=format:"%h %s")" > .release_notes - - - name: Create release [semver] - uses: ncipollo/release-action@v1 - with: - bodyFile: ./.release_notes - name: version ${{ needs.prepare.outputs.RELEASE_VERSION }} - token: ${{ secrets.GHCR_TOKEN }} - tag: ${{ needs.prepare.outputs.RELEASE_VERSION }} - prerelease: ${{ github.ref != 'refs/heads/master' && github.ref != 'refs/heads/main' }} - artifacts: "dist/*" - allowUpdates: true - - - name: Delete existing v1 tag and release - run: | - gh release delete v1 --cleanup-tag -y - env: - GH_TOKEN: ${{ secrets.GHCR_TOKEN }} - - - name: Create release [v1] - uses: ncipollo/release-action@v1 - with: - bodyFile: ./.release_notes - name: v1 - ${{ needs.prepare.outputs.RELEASE_VERSION }} - token: ${{ secrets.GHCR_TOKEN }} - tag: v1 - prerelease: ${{ github.ref != 'refs/heads/master' && github.ref != 'refs/heads/main' }} - artifacts: "dist/*" - allowUpdates: true - makeLatest: false - - build-docker: - needs: [ prepare, test, code_scans, build-binary ] - name: Docker image build - runs-on: ubuntu-latest - steps: - - name: Checkout repo - uses: actions/checkout@v3 - - name: Set up QEMU - uses: docker/setup-qemu-action@v2 - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v2 - - name: Login to GHCR - if: github.event_name != 'pull_request' - uses: docker/login-action@v2 - with: - registry: ghcr.io - username: ${{ github.ACTOR }} - password: ${{ secrets.GHCR_TOKEN }} - - name: Prepare for push - id: prep - run: | - if [ -z "${{ needs.prepare.outputs.RELEASE_VERSION }}" ]; then - TAGS="${{ needs.prepare.outputs.DOCKER_IMAGE }}:${{ needs.prepare.outputs.GITHUB_SHA }},${{ needs.prepare.outputs.DOCKER_IMAGE }}:latest,${{ needs.prepare.outputs.DOCKER_IMAGE }}:v1" - else - TAGS="${{ needs.prepare.outputs.DOCKER_IMAGE }}:${{ needs.prepare.outputs.GITHUB_SHA }},${{ needs.prepare.outputs.DOCKER_IMAGE }}:${{ needs.prepare.outputs.RELEASE_VERSION }},${{ needs.prepare.outputs.DOCKER_IMAGE }}:latest,${{ needs.prepare.outputs.DOCKER_IMAGE }}:v1" - fi - echo "TAGS=$TAGS" >> $GITHUB_OUTPUT - BRANCH=$(echo ${GITHUB_REF##*/} | tr '[A-Z]' '[a-z]') - LABELS="org.opencontainers.image.revision=${{ needs.prepare.outputs.GITHUB_SHA }}" - LABELS="$LABELS,org.opencontainers.image.created=$(date -u +'%Y-%m-%dT%H:%M:%SZ')" - LABELS="$LABELS,org.opencontainers.image.version=$VERSION" - LABELS="$LABELS,com.github.repo.branch=$BRANCH" - LABELS="$LABELS,com.github.repo.dockerfile=Dockerfile" - echo "LABELS=$LABELS" >> $GITHUB_OUTPUT - BUILD_ARGS="BRANCH=$BRANCH" - echo "args=$BUILD_ARGS" >> $GITHUB_OUTPUT - - name: Build image - id: docker_build - uses: docker/build-push-action@v4 - with: - builder: ${{ steps.buildx.outputs.name }} - platforms: linux/arm64,linux/amd64 - push: ${{ github.ref == 'refs/heads/master' || github.ref == 'refs/heads/main' }} - tags: ${{ steps.prep.outputs.tags }} - build-args: | - GITHUB_AUTH_TOKEN=${{ secrets.GHCR_TOKEN }} - MICROSERVICE_NAME=${{ github.event.repository.name }} - GITHUB_COMMIT_NUMBER=${{ needs.prepare.outputs.GITHUB_COMMIT_NUMBER }} - GITHUB_SHA=${{ needs.prepare.outputs.GITHUB_SHA }} - ${{ steps.prep.outputs.args }} - labels: ${{ steps.prep.outputs.labels }} - no-cache: false + release: + uses: lukaszraczylo/shared-actions/.github/workflows/go-release.yaml@main + with: + go-version: "1.24" + docker-enabled: true + rolling-release-tag: "v1" + semver-config: "config-release.yaml" + secrets: + homebrew-tap-token: ${{ secrets.HOMEBREW_TAP_TOKEN }} diff --git a/.github/workflows/static.yml b/.github/workflows/static.yml new file mode 100644 index 0000000..a9c7c55 --- /dev/null +++ b/.github/workflows/static.yml @@ -0,0 +1,45 @@ +# Simple workflow for deploying static content to GitHub Pages +name: Deploy static content to Pages + +on: + # Runs on pushes targeting the default branch + push: + branches: ["main"] + paths: + - 'docs/**' + + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: + +# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages +permissions: + contents: read + pages: write + id-token: write + +# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued. +# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete. +concurrency: + group: "pages" + cancel-in-progress: false + +jobs: + # Single deploy job since we're just deploying + deploy: + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Setup Pages + uses: actions/configure-pages@v5 + - name: Upload artifact + uses: actions/upload-pages-artifact@v3 + with: + # Upload entire repository + path: 'docs/' + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@v4 diff --git a/.goreleaser.yaml b/.goreleaser.yaml new file mode 100644 index 0000000..1deb9e3 --- /dev/null +++ b/.goreleaser.yaml @@ -0,0 +1,126 @@ +version: 2 + +before: + hooks: + - go mod tidy + +builds: + - id: semver-gen + main: . + binary: semver-gen + env: + - CGO_ENABLED=0 + goos: + - linux + - darwin + - windows + goarch: + - amd64 + - arm64 + ldflags: + - -s -w + - -X main.PKG_VERSION={{.Version}} + +archives: + - id: semver-gen + formats: [tar.gz] + name_template: "semver-gen-{{ .Version }}-{{ .Os }}-{{ .Arch }}" + format_overrides: + - goos: windows + formats: [zip] + files: + - LICENSE + - README.md + - config.yaml + +checksum: + name_template: "semver-gen-{{ .Version }}-checksums.txt" + algorithm: sha256 + +changelog: + sort: asc + filters: + exclude: + - '^docs:' + - '^test:' + - '^Merge' + - '^WIP' + - '^Update go.mod' + +release: + github: + owner: lukaszraczylo + name: semver-generator + name_template: "version {{.Version}}" + draft: false + prerelease: auto + +dockers: + - id: semver-gen-amd64 + goos: linux + goarch: amd64 + ids: + - semver-gen + image_templates: + - "ghcr.io/lukaszraczylo/semver-generator:{{ .Version }}-amd64" + - "ghcr.io/lukaszraczylo/semver-generator:latest-amd64" + - "ghcr.io/lukaszraczylo/semver-generator:v1-amd64" + dockerfile: Dockerfile.goreleaser + use: buildx + build_flag_templates: + - "--platform=linux/amd64" + extra_files: + - config-release.yaml + - entrypoint.sh + + - id: semver-gen-arm64 + goos: linux + goarch: arm64 + ids: + - semver-gen + image_templates: + - "ghcr.io/lukaszraczylo/semver-generator:{{ .Version }}-arm64" + - "ghcr.io/lukaszraczylo/semver-generator:latest-arm64" + - "ghcr.io/lukaszraczylo/semver-generator:v1-arm64" + dockerfile: Dockerfile.goreleaser + use: buildx + build_flag_templates: + - "--platform=linux/arm64" + extra_files: + - config-release.yaml + - entrypoint.sh + +docker_manifests: + - name_template: "ghcr.io/lukaszraczylo/semver-generator:{{ .Version }}" + image_templates: + - "ghcr.io/lukaszraczylo/semver-generator:{{ .Version }}-amd64" + - "ghcr.io/lukaszraczylo/semver-generator:{{ .Version }}-arm64" + + - name_template: "ghcr.io/lukaszraczylo/semver-generator:latest" + image_templates: + - "ghcr.io/lukaszraczylo/semver-generator:latest-amd64" + - "ghcr.io/lukaszraczylo/semver-generator:latest-arm64" + + - name_template: "ghcr.io/lukaszraczylo/semver-generator:v1" + image_templates: + - "ghcr.io/lukaszraczylo/semver-generator:v1-amd64" + - "ghcr.io/lukaszraczylo/semver-generator:v1-arm64" + +homebrew_casks: + - repository: + owner: lukaszraczylo + name: homebrew-taps + token: "{{ .Env.HOMEBREW_TAP_TOKEN }}" + directory: Casks + homepage: https://github.com/lukaszraczylo/semver-generator + description: "Automatic semantic version generator based on git commit messages" + license: MIT + url: + verified: github.com/lukaszraczylo/semver-generator + hooks: + post: + install: | + if OS.mac? + system_command "/usr/bin/xattr", + args: ["-dr", "com.apple.quarantine", "#{staged_path}/semver-gen"] + end diff --git a/Dockerfile.goreleaser b/Dockerfile.goreleaser new file mode 100644 index 0000000..110d61a --- /dev/null +++ b/Dockerfile.goreleaser @@ -0,0 +1,6 @@ +FROM ubuntu:jammy +COPY semver-gen /go/src/app/semver-gen +COPY config-release.yaml /go/src/app/config.yaml +COPY entrypoint.sh /entrypoint.sh +RUN chmod +x /entrypoint.sh +ENTRYPOINT ["/entrypoint.sh"] diff --git a/README.md b/README.md index f387c22..8c9d128 100644 --- a/README.md +++ b/README.md @@ -49,6 +49,14 @@ export GITHUB_TOKEN=yourPersonalApiToken #### As a binary +##### Homebrew (macOS) + +```bash +brew install --cask lukaszraczylo/taps/semver-gen +``` + +##### Manual Download + You can download latest versions of the binaries from the [release page](https://github.com/lukaszraczylo/semver-generator/releases/latest). **Supported OS and architectures:** diff --git a/docs/CNAME b/docs/CNAME new file mode 100644 index 0000000..fd2d5cc --- /dev/null +++ b/docs/CNAME @@ -0,0 +1 @@ +semver-generator.raczylo.com \ No newline at end of file diff --git a/docs/index.html b/docs/index.html new file mode 100644 index 0000000..588d8bf --- /dev/null +++ b/docs/index.html @@ -0,0 +1,495 @@ + + + + + + semver-generator - Automatic Semantic Version Generator + + + + + + + + + + + + + + + +
+
+
+
+
+ +
+
+
+
+ +
+
+

+ Semantic Version
Generator +

+

+ Automatic semantic versioning based on git commit messages. Use as a CLI tool, GitHub Action, or Docker container. +

+ +
+ Version + License + Go Report +
+
+
+
+
+
+
+
+
+ terminal +
+
$ semver-gen generate -l
+SEMVER 1.5.2
+
+$ semver-gen generate -r https://github.com/user/repo
+SEMVER 2.3.0
+
+
+
+
+
+
+ + +
+
+
+

Features

+

Automatic versioning that just works

+
+
+
+
+
+ +
+
+

Automatic Versioning

+

Calculates version based on commit message keywords

+
+
+
+
+
+
+ +
+
+

GitHub Action

+

Use directly in your CI/CD workflows

+
+
+
+
+
+
+ +
+
+

Docker Ready

+

Multi-arch Docker images for any environment

+
+
+
+
+
+
+ +
+
+

Configurable Keywords

+

Define your own trigger words for version bumps

+
+
+
+
+
+
+ +
+
+

Respects Tags

+

Optional mode to respect existing git tags

+
+
+
+
+
+
+ +
+
+

Release Candidates

+

Support for RC versions like 1.3.37-rc.1

+
+
+
+
+
+
+ + +
+
+
+

Installation

+

Get started in seconds

+
+
+
+

+ + Homebrew (macOS) +

+
brew install --cask lukaszraczylo/taps/semver-gen
+
+
+

+ + Manual Download +

+

Download from the releases page.

+

Supported: Darwin ARM64/AMD64, Linux ARM64/AMD64, Windows AMD64

+
+
+

+ + Docker +

+
docker pull ghcr.io/lukaszraczylo/semver-generator:latest
+
+
+
+
+ + +
+
+
+

Usage

+

Multiple ways to use semver-generator

+
+
+
+

+ + CLI Usage +

+
# Local repository
+semver-gen generate -l
+
+# Remote repository
+semver-gen generate -r https://github.com/user/repo
+
+# With custom config
+semver-gen generate -l -c semver.yaml
+
+# Strict mode (only exact matches)
+semver-gen generate -l -s
+
+# Respect existing tags
+semver-gen generate -l -e
+
+
+

Flags

+
    +
  • -l, --local Use local repository
  • +
  • -r, --repository Remote repository URL
  • +
  • -c, --config Path to config file
  • +
  • -s, --strict Strict matching
  • +
  • -e, --existing Respect existing tags
  • +
  • -d, --debug Enable debug mode
  • +
+
+
+
+ +
+

+ + GitHub Action +

+
jobs:
+  version:
+    runs-on: ubuntu-latest
+    outputs:
+      version: ${{ steps.semver.outputs.semantic_version }}
+    steps:
+      - uses: actions/checkout@v4
+        with:
+          fetch-depth: '0'
+
+      - name: Generate version
+        id: semver
+        uses: lukaszraczylo/semver-generator@v1
+        with:
+          config_file: semver.yaml
+          repository_local: true
+
+      - name: Use version
+        run: echo "Version: ${{ steps.semver.outputs.semantic_version }}"
+
+
+
+
+ + +
+
+
+

How It Works

+

Version calculation based on commit messages

+
+
+
+
0.0.1 - PATCH - starting commit
+0.0.2 - PATCH - another commit
+0.0.4 - PATCH - commit with 'Update' => DOUBLE increment PATCH
+0.1.0 - MINOR - commit with 'Change' => increment MINOR, reset PATCH
+0.1.1 - PATCH - additional commit
+1.0.1 - MAJOR - commit with 'BREAKING' => INCREMENT MAJOR, reset MINOR
+1.0.2 - PATCH - another commit
+
+
+
+
MAJOR
+

Breaking changes

+

Keywords: "breaking"

+
+
+
MINOR
+

New features

+

Keywords: "change", "improve"

+
+
+
PATCH
+

Bug fixes

+

Keywords: "update", "initial"

+
+
+
+
+
+ + +
+
+
+

Configuration

+

Customize keywords and behavior

+
+
+
+

semver.yaml

+
version: 1
+
+# Starting version (optional)
+force:
+  major: 1
+  minor: 0
+  patch: 0
+  commit: 69fbe2df696f40281b9104ff073d26186cde1024
+
+# Commits to ignore
+blacklist:
+  - "Merge branch"
+  - "Merge pull request"
+  - "feature/"
+
+# Keywords for version bumps
+wording:
+  patch:
+    - update
+    - initial
+    - fix
+  minor:
+    - change
+    - improve
+    - add
+  major:
+    - breaking
+  release:
+    - release-candidate
+    - add-rc
+
+
+
+
+ + + + + + +