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
21 changes: 17 additions & 4 deletions .github/.env.base
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,22 @@ GOVULNCHECK_GO_VERSION=1.25.x

# Go sum file location for dependency verification and caching
# Default: go.sum (standard location in repository root)
# Custom examples: lib/go.sum, backend/go.sum, services/api/go.sum
# NOTE: For multi-module monorepos (go.work), set ENABLE_MULTI_MODULE_TESTING=true
# GO_SUM_FILE is still required but will be ignored for caching (uses **/go.sum pattern instead)
GO_SUM_FILE=go.sum

# Multi-module monorepo support
# When true: runs tests from repo root, magex discovers all Go modules and merges coverage
# Cache keys use **/go.sum pattern (no root go.sum required), skips root go.sum validation
# When false: runs tests from GO_MODULE_DIR (derived from GO_SUM_FILE path)
ENABLE_MULTI_MODULE_TESTING=false

# ================================================================================================
# 🖥️ RUNNER CONFIGURATION
# ================================================================================================

# https://docs.github.com/en/actions/reference/runners/github-hosted-runners

# Primary runner OS for most CI jobs
# Options: ubuntu-24.04, ubuntu-22.04, macos-15
# Note: macOS runners are 10x more expensive than Linux
Expand Down Expand Up @@ -147,7 +156,7 @@ GO_COVERAGE_PROVIDER=internal
CODECOV_TOKEN_REQUIRED=false

# Go Coverage Tool Version
GO_COVERAGE_VERSION=v1.1.13 # https://github.com/mrz1836/go-coverage/releases
GO_COVERAGE_VERSION=v1.1.15 # https://github.com/mrz1836/go-coverage/releases
GO_COVERAGE_USE_LOCAL=false # Use local version for development

# Core Coverage Settings
Expand Down Expand Up @@ -232,7 +241,7 @@ REDIS_CACHE_FORCE_PULL=false # Force pull Redis images even when cache
# 🪄 MAGE-X CONFIGURATION
# ================================================================================================

MAGE_X_VERSION=v1.8.0 # https://github.com/mrz1836/mage-x/releases
MAGE_X_VERSION=v1.8.7 # https://github.com/mrz1836/mage-x/releases
MAGE_X_USE_LOCAL=false # Use local version for development
MAGE_X_AUTO_DISCOVER_BUILD_TAGS=true # Enable auto-discovery of build tags
MAGE_X_AUTO_DISCOVER_BUILD_TAGS_EXCLUDE=race,custom # Comma-separated list of tags to exclude
Expand All @@ -250,6 +259,9 @@ MAGE_X_STATICCHECK_VERSION=2025.1.1 # https://github.c
MAGE_X_SWAG_VERSION=v1.16.6 # https://github.com/swaggo/swag/releases
MAGE_X_YAMLFMT_VERSION=v0.20.0 # https://github.com/google/yamlfmt/releases

# Exclude magefiles from prebuild - they require 'mage' build tag and fail without it
# MAGE_X_BUILD_EXCLUDE_PATTERN=magefiles

# Runtime variables (set by setup-goreleaser action):
# MAGE_X_GORELEASER_PATH - Path to installed goreleaser binary
# MAGE_X_GORELEASER_INSTALLED - Set to 'true' when goreleaser is available
Expand All @@ -269,6 +281,7 @@ MAGE_X_YAMLFMT_VERSION=v0.20.0 # https://github.c
# MAGE_X_DOWNLOAD_TIMEOUT=5000
# MAGE_X_DOWNLOAD_USER_AGENT=MAGE-X-Agent
# MAGE_X_PARALLEL=3
# MAGE_X_TEST_EXCLUDE_MODULES=magefiles # Comma-separated module names to exclude from tests/coverage (default: magefiles)
# MAGE_X_TEST_RACE=false
# MAGE_X_VERBOSE=true

Expand All @@ -293,7 +306,7 @@ NANCY_EXCLUDES=CVE-2024-38513,CVE-2023-45142
# Security Tools
GITLEAKS_VERSION=8.29.1 # https://github.com/gitleaks/gitleaks/releases
GOVULNCHECK_VERSION=v1.1.4 # https://pkg.go.dev/golang.org/x/vuln
NANCY_VERSION=v1.0.51 # https://github.com/sonatype-nexus-community/nancy/releases
NANCY_VERSION=v1.0.52 # https://github.com/sonatype-nexus-community/nancy/releases

# ================================================================================================
# 🪝 PRE-COMMIT SYSTEM CONFIGURATION (go-pre-commit)
Expand Down
165 changes: 118 additions & 47 deletions .github/actions/setup-go-with-cache/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,12 @@ inputs:
description: "Secondary Go version for toolchain comparison"
required: true
go-sum-file:
description: "Path to go.sum file for cache key generation"
description: "Path to go.sum file for cache key generation (single module mode only; ignored when enable-multi-module is true)"
required: true
enable-multi-module:
description: "Enable multi-module mode - uses pattern **/go.sum to hash all go.sum files for cache keys, skips root go.sum validation"
required: false
default: "false"

outputs:
go-version-actual:
Expand Down Expand Up @@ -102,6 +106,7 @@ runs:
# Validate go.sum exists for cache key generation
# --------------------------------------------------------------------
- name: 🔍 Validate go.sum exists
if: ${{ inputs.enable-multi-module != 'true' }}
shell: bash
run: |
GO_SUM_FILE="${{ inputs.go-sum-file }}"
Expand Down Expand Up @@ -131,35 +136,75 @@ runs:
echo "📋 Input Values:"
echo " matrix-os: '${{ inputs.matrix-os }}'"
echo " go-sum-file: '${{ inputs.go-sum-file }}'"
echo " enable-multi-module: '${{ inputs.enable-multi-module }}'"

# Verify go.sum file details
GO_SUM_FILE="${{ inputs.go-sum-file }}"
if [ -f "$GO_SUM_FILE" ]; then
echo ""
echo "📄 Go.sum File Analysis:"
echo " Path: $GO_SUM_FILE"
echo " Size: $(wc -c < "$GO_SUM_FILE") bytes"
echo " Lines: $(wc -l < "$GO_SUM_FILE") lines"
echo " SHA256: $(sha256sum "$GO_SUM_FILE" | cut -d' ' -f1)"
if [ "${{ inputs.enable-multi-module }}" == "true" ]; then
# Multi-module mode - show all go.sum files
echo ""
echo "🔍 First 5 lines of go.sum:"
head -5 "$GO_SUM_FILE" | sed 's/^/ /'
echo "📦 Multi-module mode enabled"
echo "🔍 Found go.sum files:"
find . -name "go.sum" -type f | while read file; do
echo " - $file ($(wc -l < "$file") lines, $(wc -c < "$file") bytes)"
done

echo ""
echo "🔍 Last 3 lines of go.sum:"
tail -3 "$GO_SUM_FILE" | sed 's/^/ /'
echo "🔑 Expected Module Cache Key Pattern:"
echo " Pattern: ${{ inputs.matrix-os }}-gomod-multi-[hash-of-all-go.sum]"
echo " Actual hash: ${{ hashFiles('**/go.sum') }}"
echo " Complete key: ${{ inputs.matrix-os }}-gomod-multi-${{ hashFiles('**/go.sum') }}"
else
echo "❌ ERROR: go.sum file not found at: $GO_SUM_FILE"
# Single module mode - verify go.sum file
GO_SUM_FILE="${{ inputs.go-sum-file }}"
if [ -f "$GO_SUM_FILE" ]; then
echo ""
echo "📄 Go.sum File Analysis:"
echo " Path: $GO_SUM_FILE"
echo " Size: $(wc -c < "$GO_SUM_FILE") bytes"
echo " Lines: $(wc -l < "$GO_SUM_FILE") lines"
echo " SHA256: $(sha256sum "$GO_SUM_FILE" | cut -d' ' -f1)"
echo ""
echo "🔍 First 5 lines of go.sum:"
head -5 "$GO_SUM_FILE" | sed 's/^/ /'
echo ""
echo "🔍 Last 3 lines of go.sum:"
tail -3 "$GO_SUM_FILE" | sed 's/^/ /'
else
echo "❌ ERROR: go.sum file not found at: $GO_SUM_FILE"
fi

# Show expected cache key pattern
echo ""
echo "🔑 Expected Module Cache Key Pattern:"
echo " Pattern: ${{ inputs.matrix-os }}-gomod-[hash-of-go.sum]"
echo " Actual hash: ${{ hashFiles(inputs.go-sum-file) }}"
echo " Complete key: ${{ inputs.matrix-os }}-gomod-${{ hashFiles(inputs.go-sum-file) }}"
fi

# Show expected cache key pattern
echo ""
echo "🔑 Expected Module Cache Key Pattern:"
echo " Pattern: ${{ inputs.matrix-os }}-gomod-[hash-of-go.sum]"
echo " Actual hash: ${{ hashFiles(inputs.go-sum-file) }}"
echo " Complete key: ${{ inputs.matrix-os }}-gomod-${{ hashFiles(inputs.go-sum-file) }}"
echo ""
echo "============================================================"

# --------------------------------------------------------------------
# Compute cache keys based on multi-module mode
# --------------------------------------------------------------------
- name: 🔑 Compute cache keys
id: cache-keys
shell: bash
run: |
if [ "${{ inputs.enable-multi-module }}" == "true" ]; then
echo "📦 Multi-module mode enabled - using hash of all go.sum files"
HASH="${{ hashFiles('**/go.sum') }}"
echo "module-key=${{ inputs.matrix-os }}-gomod-multi-${HASH}" >> $GITHUB_OUTPUT
echo "build-key=${{ inputs.matrix-os }}-gobuild-multi-${{ inputs.go-version }}-${HASH}" >> $GITHUB_OUTPUT
echo "mode=multi" >> $GITHUB_OUTPUT
else
echo "📁 Single module mode - using hash of ${{ inputs.go-sum-file }}"
HASH="${{ hashFiles(inputs.go-sum-file) }}"
echo "module-key=${{ inputs.matrix-os }}-gomod-${HASH}" >> $GITHUB_OUTPUT
echo "build-key=${{ inputs.matrix-os }}-gobuild-${{ inputs.go-version }}-${HASH}" >> $GITHUB_OUTPUT
echo "mode=single" >> $GITHUB_OUTPUT
fi
echo "🔑 Cache keys computed successfully"

# --------------------------------------------------------------------
# Restore Go module cache (shared across versions)
# --------------------------------------------------------------------
Expand All @@ -168,7 +213,7 @@ runs:
uses: actions/cache/restore@0400d5f644dc74513175e3cd8d07132dd4860809 # v4.2.4
with:
path: ~/go/pkg/mod
key: ${{ inputs.matrix-os }}-gomod-${{ hashFiles(inputs.go-sum-file) }}
key: ${{ steps.cache-keys.outputs.module-key }}

# --------------------------------------------------------------------
# DEBUG: Build cache key components
Expand All @@ -185,18 +230,27 @@ runs:
echo " matrix-os: '${{ inputs.matrix-os }}'"
echo " go-version: '${{ inputs.go-version }}'"
echo " go-sum-file: '${{ inputs.go-sum-file }}'"
echo " enable-multi-module: '${{ inputs.enable-multi-module }}'"

# Verify go.sum file details (for build cache key)
GO_SUM_FILE="${{ inputs.go-sum-file }}"
if [ -f "$GO_SUM_FILE" ]; then
if [ "${{ inputs.enable-multi-module }}" == "true" ]; then
# Multi-module mode - show summary of all go.sum files
echo ""
echo "📄 Go.sum File Analysis (for build cache):"
echo " Path: $GO_SUM_FILE"
echo " Size: $(wc -c < "$GO_SUM_FILE") bytes"
echo " SHA256: $(sha256sum "$GO_SUM_FILE" | cut -d' ' -f1)"
echo " Last Modified: $(stat -c %y "$GO_SUM_FILE" 2>/dev/null || stat -f %Sm "$GO_SUM_FILE" 2>/dev/null || echo 'Unknown')"
echo "📦 Multi-module mode enabled"
echo "🔍 Go.sum files count: $(find . -name "go.sum" -type f | wc -l)"
echo "🔑 Cache hash: ${{ hashFiles('**/go.sum') }}"
else
echo "❌ ERROR: go.sum file not found at: $GO_SUM_FILE"
# Single module mode - verify go.sum file details
GO_SUM_FILE="${{ inputs.go-sum-file }}"
if [ -f "$GO_SUM_FILE" ]; then
echo ""
echo "📄 Go.sum File Analysis (for build cache):"
echo " Path: $GO_SUM_FILE"
echo " Size: $(wc -c < "$GO_SUM_FILE") bytes"
echo " SHA256: $(sha256sum "$GO_SUM_FILE" | cut -d' ' -f1)"
echo " Last Modified: $(stat -c %y "$GO_SUM_FILE" 2>/dev/null || stat -f %Sm "$GO_SUM_FILE" 2>/dev/null || echo 'Unknown')"
else
echo "❌ ERROR: go.sum file not found at: $GO_SUM_FILE"
fi
fi

# Show cache paths that will be used
Expand All @@ -210,10 +264,17 @@ runs:

# Show expected cache key pattern
echo ""
echo "🔑 Expected Build Cache Key Pattern:"
echo " Pattern: ${{ inputs.matrix-os }}-gobuild-${{ inputs.go-version }}-[hash-of-go.sum]"
echo " Actual hash: ${{ hashFiles(inputs.go-sum-file) }}"
echo " Complete key: ${{ inputs.matrix-os }}-gobuild-${{ inputs.go-version }}-${{ hashFiles(inputs.go-sum-file) }}"
if [ "${{ inputs.enable-multi-module }}" == "true" ]; then
echo "🔑 Expected Build Cache Key Pattern:"
echo " Pattern: ${{ inputs.matrix-os }}-gobuild-multi-${{ inputs.go-version }}-[hash-of-all-go.sum]"
echo " Actual hash: ${{ hashFiles('**/go.sum') }}"
echo " Complete key: ${{ inputs.matrix-os }}-gobuild-multi-${{ inputs.go-version }}-${{ hashFiles('**/go.sum') }}"
else
echo "🔑 Expected Build Cache Key Pattern:"
echo " Pattern: ${{ inputs.matrix-os }}-gobuild-${{ inputs.go-version }}-[hash-of-go.sum]"
echo " Actual hash: ${{ hashFiles(inputs.go-sum-file) }}"
echo " Complete key: ${{ inputs.matrix-os }}-gobuild-${{ inputs.go-version }}-${{ hashFiles(inputs.go-sum-file) }}"
fi
echo ""
echo "============================================================"

Expand All @@ -227,7 +288,7 @@ runs:
path: |
~/.cache/go-build
~/.cache/go-build/test
key: ${{ inputs.matrix-os }}-gobuild-${{ inputs.go-version }}-${{ hashFiles(inputs.go-sum-file) }}
key: ${{ steps.cache-keys.outputs.build-key }}

# --------------------------------------------------------------------
# DEBUG: Cache restoration summary
Expand All @@ -247,17 +308,27 @@ runs:
# Show the actual keys that were used
echo ""
echo "🔑 Actual Cache Keys Used:"
MODULE_KEY="${{ inputs.matrix-os }}-gomod-${{ hashFiles(inputs.go-sum-file) }}"
BUILD_KEY="${{ inputs.matrix-os }}-gobuild-${{ inputs.go-version }}-${{ hashFiles(inputs.go-sum-file) }}"
echo " Module: $MODULE_KEY"
echo " Build: $BUILD_KEY"

# Break down the keys for analysis
echo ""
echo "🔍 Key Component Analysis:"
echo " OS component: '${{ inputs.matrix-os }}'"
echo " Go version component: '${{ inputs.go-version }}'"
echo " Go.sum hash component: '${{ hashFiles(inputs.go-sum-file) }}'"
if [ "${{ inputs.enable-multi-module }}" == "true" ]; then
MODULE_KEY="${{ inputs.matrix-os }}-gomod-multi-${{ hashFiles('**/go.sum') }}"
BUILD_KEY="${{ inputs.matrix-os }}-gobuild-multi-${{ inputs.go-version }}-${{ hashFiles('**/go.sum') }}"
echo " Module: $MODULE_KEY"
echo " Build: $BUILD_KEY"
echo ""
echo "🔍 Key Component Analysis (Multi-module mode):"
echo " OS component: '${{ inputs.matrix-os }}'"
echo " Go version component: '${{ inputs.go-version }}'"
echo " Go.sum hash component (all files): '${{ hashFiles('**/go.sum') }}'"
else
MODULE_KEY="${{ inputs.matrix-os }}-gomod-${{ hashFiles(inputs.go-sum-file) }}"
BUILD_KEY="${{ inputs.matrix-os }}-gobuild-${{ inputs.go-version }}-${{ hashFiles(inputs.go-sum-file) }}"
echo " Module: $MODULE_KEY"
echo " Build: $BUILD_KEY"
echo ""
echo "🔍 Key Component Analysis (Single module mode):"
echo " OS component: '${{ inputs.matrix-os }}'"
echo " Go version component: '${{ inputs.go-version }}'"
echo " Go.sum hash component: '${{ hashFiles(inputs.go-sum-file) }}'"
fi

# Cache effectiveness summary
echo ""
Expand Down
Loading