diff --git a/.github/workflows/release-go.yml b/.github/workflows/release-go.yml new file mode 100644 index 0000000..83c39bf --- /dev/null +++ b/.github/workflows/release-go.yml @@ -0,0 +1,175 @@ +name: Release Go + +on: + release: + types: [created] + workflow_dispatch: + inputs: + version: + description: 'Version tag (e.g., v1.0.0)' + required: true + type: string + +permissions: + contents: write + +jobs: + validate-release: + name: Validate Release + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Set up Go + uses: actions/setup-go@v5 + with: + go-version-file: go.mod + + - name: Verify go.mod + run: | + echo "Verifying go.mod syntax..." + go mod verify + go mod tidy + if [ -n "$(git diff go.mod go.sum)" ]; then + echo "Error: go.mod or go.sum has uncommitted changes" + git diff go.mod go.sum + exit 1 + fi + + - name: Check module name + run: | + MODULE=$(grep '^module' go.mod | awk '{print $2}') + echo "Module name: $MODULE" + if [ -z "$MODULE" ]; then + echo "Error: Could not determine module name from go.mod" + exit 1 + fi + + - name: Validate tag format + if: github.event_name == 'release' + run: | + TAG=${GITHUB_REF#refs/tags/} + echo "Release tag: $TAG" + if [[ ! "$TAG" =~ ^v[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9]+)?$ ]]; then + echo "Warning: Tag '$TAG' does not follow semantic versioning (vX.Y.Z)" + echo "Tags should follow semantic versioning" + fi + + build-binaries: + name: Build ${{ matrix.goos }}/${{ matrix.goarch }} + runs-on: ${{ matrix.runner }} + needs: validate-release + strategy: + matrix: + include: + - goos: linux + goarch: amd64 + runner: ubuntu-latest + - goos: linux + goarch: arm64 + runner: ubuntu-latest + cc: aarch64-linux-gnu-gcc + - goos: darwin + goarch: amd64 + runner: macos-latest + - goos: darwin + goarch: arm64 + runner: macos-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up Go + uses: actions/setup-go@v5 + with: + go-version-file: go.mod + + - name: Get version + id: version + run: | + if [ "${{ github.event_name }}" == "release" ]; then + VERSION=${GITHUB_REF#refs/tags/} + else + VERSION=${{ github.event.inputs.version }} + fi + VERSION_NUM=${VERSION#v} + echo "version=$VERSION" >> $GITHUB_OUTPUT + echo "version_num=$VERSION_NUM" >> $GITHUB_OUTPUT + + - name: Install cross-compiler (linux/arm64) + if: matrix.cc != '' + run: | + sudo apt-get update + sudo apt-get install -y gcc-aarch64-linux-gnu + + - name: Build binary + env: + GOOS: ${{ matrix.goos }} + GOARCH: ${{ matrix.goarch }} + CGO_ENABLED: 1 + CC: ${{ matrix.cc || '' }} + run: | + VERSION=${{ steps.version.outputs.version }} + VERSION_PKG=github.com/manetu/security-token/version + LDFLAGS="-s -w -X ${VERSION_PKG}.Version=${VERSION}" + + mkdir -p dist + go build -ldflags "${LDFLAGS}" -o dist/manetu-security-token . + + cp LICENSE dist/ + + - name: Create archive + run: | + VERSION_NUM=${{ steps.version.outputs.version_num }} + cd dist + ARCHIVE_NAME="manetu-security-token_${VERSION_NUM}_${{ matrix.goos }}_${{ matrix.goarch }}.tar.gz" + tar -czvf "${ARCHIVE_NAME}" manetu-security-token LICENSE + echo "ARCHIVE_NAME=${ARCHIVE_NAME}" >> $GITHUB_ENV + + - name: Upload artifact + uses: actions/upload-artifact@v4 + with: + name: manetu-security-token_${{ steps.version.outputs.version_num }}_${{ matrix.goos }}_${{ matrix.goarch }} + path: dist/manetu-security-token_${{ steps.version.outputs.version_num }}_${{ matrix.goos }}_${{ matrix.goarch }}.* + + upload-release-assets: + name: Upload Release Assets + runs-on: ubuntu-latest + needs: build-binaries + if: github.event_name == 'release' + steps: + - name: Get version + id: version + run: | + VERSION=${GITHUB_REF#refs/tags/} + VERSION_NUM=${VERSION#v} + echo "version=$VERSION" >> $GITHUB_OUTPUT + echo "version_num=$VERSION_NUM" >> $GITHUB_OUTPUT + + - name: Download all artifacts + uses: actions/download-artifact@v4 + with: + path: artifacts + + - name: Generate checksums + run: | + VERSION_NUM=${{ steps.version.outputs.version_num }} + cd artifacts + + mkdir -p ../release + find . -type f -name "*.tar.gz" -exec cp {} ../release/ \; + + cd ../release + sha256sum * > manetu-security-token_${VERSION_NUM}_checksums.txt + + - name: Upload release assets + uses: softprops/action-gh-release@v2 + with: + files: | + release/* + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + diff --git a/.github/workflows/release-homebrew.yml b/.github/workflows/release-homebrew.yml new file mode 100644 index 0000000..88fe52a --- /dev/null +++ b/.github/workflows/release-homebrew.yml @@ -0,0 +1,149 @@ +name: Release to Homebrew + +on: + release: + types: [published] + workflow_dispatch: + inputs: + version: + description: 'Version tag (e.g., v1.0.0)' + required: true + type: string + +jobs: + update-homebrew-formula: + name: Update Homebrew Formula + runs-on: ubuntu-latest + steps: + - name: Get version + id: version + run: | + if [ "${{ github.event_name }}" == "release" ]; then + VERSION=${GITHUB_REF#refs/tags/} + else + VERSION=${{ github.event.inputs.version }} + fi + # Strip 'v' prefix for Homebrew version + VERSION_NUM=${VERSION#v} + echo "version=$VERSION" >> $GITHUB_OUTPUT + echo "version_num=$VERSION_NUM" >> $GITHUB_OUTPUT + echo "Version tag: $VERSION" + echo "Version number: $VERSION_NUM" + + - name: Download source tarball and calculate SHA256 + id: sha256 + run: | + VERSION=${{ steps.version.outputs.version }} + TARBALL_URL="https://github.com/manetu/security-token/archive/refs/tags/${VERSION}.tar.gz" + echo "Downloading source tarball from: $TARBALL_URL" + + curl -sL "$TARBALL_URL" -o source.tar.gz + SHA256=$(sha256sum source.tar.gz | awk '{print $1}') + echo "sha256=$SHA256" >> $GITHUB_OUTPUT + echo "SHA256: $SHA256" + + - name: Generate Homebrew formula + id: formula + run: | + VERSION=${{ steps.version.outputs.version }} + VERSION_NUM=${{ steps.version.outputs.version_num }} + SHA256=${{ steps.sha256.outputs.sha256 }} + + cat > manetu-security-token.rb << 'FORMULA_EOF' + # typed: false + # frozen_string_literal: true + + # Homebrew formula for Manetu Security Token CLI + # This formula builds from source using Go + class ManetuSecurityToken < Formula + desc "CLI to manage Manetu Service Account credentials within a PKCS#11 compatible HSM" + homepage "https://github.com/manetu/security-token" + url "https://github.com/manetu/security-token/archive/refs/tags/VERSION_PLACEHOLDER.tar.gz" + sha256 "SHA256_PLACEHOLDER" + license "MIT" + head "https://github.com/manetu/security-token.git", branch: "master" + + depends_on "go" => :build + + def install + ldflags = %W[ + -s -w + -X github.com/manetu/security-token/version.Version=#{version} + ] + system "go", "build", *std_go_args(ldflags:, output: bin/"manetu-security-token") + end + + test do + assert_match version.to_s, shell_output("#{bin}/manetu-security-token version") + end + end + FORMULA_EOF + + # Replace placeholders with actual values + sed -i "s/VERSION_PLACEHOLDER/${VERSION}/g" manetu-security-token.rb + sed -i "s/SHA256_PLACEHOLDER/${SHA256}/g" manetu-security-token.rb + + echo "Generated formula:" + cat manetu-security-token.rb + + - name: Checkout Homebrew tap + uses: actions/checkout@v4 + with: + repository: manetu/homebrew-tap + token: ${{ secrets.HOMEBREW_TAP_TOKEN }} + path: homebrew-tap + + - name: Update formula in tap + run: | + mkdir -p homebrew-tap/Formula + cp manetu-security-token.rb homebrew-tap/Formula/manetu-security-token.rb + + cd homebrew-tap + git config user.name "github-actions[bot]" + git config user.email "github-actions[bot]@users.noreply.github.com" + + git add Formula/manetu-security-token.rb + + # Check if there are staged changes + if git diff --cached --quiet; then + echo "No changes to formula" + exit 0 + fi + + VERSION=${{ steps.version.outputs.version }} + git commit -m "Update manetu-security-token to ${VERSION}" + git push + + - name: Create release summary + run: | + VERSION=${{ steps.version.outputs.version }} + VERSION_NUM=${{ steps.version.outputs.version_num }} + SHA256=${{ steps.sha256.outputs.sha256 }} + + cat >> $GITHUB_STEP_SUMMARY << EOF + ## Homebrew Formula Update + + **Version:** \`${VERSION}\` + **SHA256:** \`${SHA256}\` + + ### Installation + + Users can install manetu-security-token via Homebrew: + + \`\`\`bash + brew tap manetu/tap + brew install manetu-security-token + \`\`\` + + Or upgrade an existing installation: + + \`\`\`bash + brew upgrade manetu-security-token + \`\`\` + + ### Formula Location + + The updated formula is available at: + https://github.com/manetu/homebrew-tap/blob/main/Formula/manetu-security-token.rb + EOF + diff --git a/LICENSE b/LICENSE index 62f5ce7..ffb7cf9 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright 2022 Manetu Inc +Copyright 2026 Manetu Inc Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: diff --git a/Makefile b/Makefile index c2f2e68..de5970e 100644 --- a/Makefile +++ b/Makefile @@ -3,7 +3,9 @@ PROJECT_NAME := manetu-security-token GOPROJECT := github.com/manetu/security-token -VERSIONARGS := -X $(GOPROJECT)/version.GitCommit=$(shell git log -n1 --format=format:"%H")\ +VERSION ?= $(shell git describe --tags --always --dirty 2>/dev/null || echo "dev") +VERSIONARGS := -X $(GOPROJECT)/version.Version=$(VERSION) \ + -X $(GOPROJECT)/version.GitCommit=$(shell git log -n1 --format=format:"%H")\ -X $(GOPROJECT)/version.GoVersion=$(shell go version | cut -d' ' -f3) \ -X $(GOPROJECT)/version.BuildDate=$(shell date -u +'%Y-%m-%dT%H:%M:%SZ') diff --git a/main.go b/main.go index ab2c93c..f914559 100644 --- a/main.go +++ b/main.go @@ -42,7 +42,7 @@ func main() { Name: "version", Usage: "Report version and build information", Action: func(c *cli.Context) error { - fmt.Printf("manetu-security-token, git %s, goVersion %s, buildDate %s\n", version.GitCommit, version.GoVersion, version.BuildDate) + fmt.Printf("manetu-security-token %s, git %s, goVersion %s, buildDate %s\n", version.Version, version.GitCommit, version.GoVersion, version.BuildDate) return nil }, }, diff --git a/version/version.go b/version/version.go index e33ef18..191c370 100644 --- a/version/version.go +++ b/version/version.go @@ -1,5 +1,6 @@ package version +var Version = "dev" var GoVersion = "go" var GitCommit = "shahash" var BuildDate = "date -u +'%Y-%m-%dT%H:%M:%SZ'"