Skip to content

Initial release of Instana Go client library #5

Initial release of Instana Go client library

Initial release of Instana Go client library #5

Workflow file for this run

name: Instana Go Client Release
on:
push:
tags:
- 'v*.*.*'
workflow_dispatch:
inputs:
version:
description: 'Version to release (e.g., v1.0.0)'
required: true
type: string
permissions:
contents: write
packages: write
jobs:
version-validation:
name: Validate Version
runs-on: ubuntu-latest
outputs:
version: ${{ steps.get_version.outputs.version }}
last_tag: ${{ steps.get_version.outputs.last_tag }}
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Get version information
id: get_version
run: |
if [ "${{ github.event_name }}" == "workflow_dispatch" ]; then
VERSION="${{ github.event.inputs.version }}"
else
VERSION=${GITHUB_REF#refs/tags/}
fi
# Get last tag
LAST_TAG=$(git describe --tags --abbrev=0 HEAD^ 2>/dev/null || echo "")
echo "version=$VERSION" >> $GITHUB_OUTPUT
echo "last_tag=$LAST_TAG" >> $GITHUB_OUTPUT
echo "Version: $VERSION"
echo "Last tag: $LAST_TAG"
- name: Validate semver format
run: |
VERSION="${{ steps.get_version.outputs.version }}"
if ! [[ "$VERSION" =~ ^v[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9.]+)?(\+[a-zA-Z0-9.]+)?$ ]]; then
echo "❌ Invalid version format: $VERSION"
echo "Expected format: v1.2.3, v1.2.3-beta.1, v1.2.3+build.1"
exit 1
fi
echo "✅ Version format is valid"
- name: Check tag doesn't exist
run: |
VERSION="${{ steps.get_version.outputs.version }}"
if git rev-parse "$VERSION" >/dev/null 2>&1; then
echo "❌ Tag $VERSION already exists"
exit 1
fi
echo "✅ Tag doesn't exist yet"
- name: Verify clean working directory
run: |
if [ -n "$(git status --porcelain)" ]; then
echo "❌ Working directory is not clean"
git status
exit 1
fi
echo "✅ Working directory is clean"
quality-checks:
name: Quality Checks
runs-on: ubuntu-latest
needs: version-validation
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: '1.23'
- name: Run golangci-lint
uses: golangci/golangci-lint-action@v8
with:
version: v2.1.0
args: --timeout=5m
- name: Run tests with coverage
run: |
go test -v -race -coverprofile=coverage.out -covermode=atomic ./...
go tool cover -func=coverage.out
- name: Verify go.mod and go.sum
run: |
go mod tidy
if [ -n "$(git diff go.mod go.sum)" ]; then
echo "❌ go.mod or go.sum is not tidy"
git diff go.mod go.sum
exit 1
fi
echo "✅ go.mod and go.sum are tidy"
- name: Check code formatting
run: |
if [ -n "$(gofmt -l .)" ]; then
echo "❌ Code is not formatted"
gofmt -l .
exit 1
fi
echo "✅ Code is properly formatted"
multi-version-test:
name: Test Go ${{ matrix.go-version }}
runs-on: ubuntu-latest
needs: [quality-checks]
strategy:
matrix:
go-version: ['1.23'] # Only test minimum required version from go.mod
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Go ${{ matrix.go-version }}
uses: actions/setup-go@v5
with:
go-version: ${{ matrix.go-version }}
- name: Run tests
run: |
echo "Testing with Go ${{ matrix.go-version }}"
go test -v -race ./...
- name: Build
run: |
echo "Building with Go ${{ matrix.go-version }}"
go build -v ./...
cross-platform-build:
name: Build ${{ matrix.os }}-${{ matrix.arch }}
runs-on: ubuntu-latest
needs: [quality-checks]
strategy:
matrix:
os: [linux, darwin, windows]
arch: [amd64, arm64]
exclude:
- os: windows
arch: arm64
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: '1.23'
- name: Build for ${{ matrix.os }}-${{ matrix.arch }}
env:
GOOS: ${{ matrix.os }}
GOARCH: ${{ matrix.arch }}
run: |
echo "Building for ${{ matrix.os }}-${{ matrix.arch }}"
go build -v ./...
echo "✅ Build successful for ${{ matrix.os }}-${{ matrix.arch }}"
module-import-test:
name: Module Import Test
runs-on: ubuntu-latest
needs: [multi-version-test, cross-platform-build]
steps:
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: '1.23'
- name: Test module import
run: |
VERSION="${{ needs.version-validation.outputs.version }}"
echo "Testing module import for version $VERSION"
# Create temporary test directory
mkdir -p /tmp/test-import
cd /tmp/test-import
# Initialize test module
go mod init test-import
# Try to get the module (will fail if not yet available, but tests the path)
echo "Module path: github.com/instana/instana-go-client"
# Create test file
cat > main.go << 'EOF'
package main
import (
"fmt"
_ "github.com/instana/instana-go-client/client"
_ "github.com/instana/instana-go-client/config"
)
func main() {
fmt.Println("Import test successful")
}
EOF
echo "✅ Module import structure validated"
generate-changelog:
name: Generate CHANGELOG
runs-on: ubuntu-latest
needs: [version-validation, module-import-test]
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
token: ${{ secrets.GITHUB_TOKEN }}
- name: Generate CHANGELOG entry
run: |
VERSION="${{ needs.version-validation.outputs.version }}"
LAST_TAG="${{ needs.version-validation.outputs.last_tag }}"
DATE=$(date +%Y-%m-%d)
echo "Generating CHANGELOG for $VERSION"
echo "Comparing with $LAST_TAG"
# Get commits since last tag (excluding "Initial commit")
if [ -z "$LAST_TAG" ]; then
COMMITS=$(git log --pretty=format:"%s" --no-merges | grep -v "^Initial commit$")
else
COMMITS=$(git log ${LAST_TAG}..HEAD --pretty=format:"%s" --no-merges | grep -v "^Initial commit$")
fi
# Build changes list
CHANGES=""
while IFS= read -r subject; do
# Skip empty lines
[ -z "$subject" ] && continue
# Extract PR number if present
PR_NUM=$(echo "$subject" | grep -oP '\(#\K\d+(?=\))' || echo "")
# Clean up commit message (remove PR number from subject)
CLEAN_SUBJECT=$(echo "$subject" | sed 's/ (#[0-9]\+)$//')
# Build change entry
if [ -n "$PR_NUM" ]; then
CHANGES="${CHANGES}- ${CLEAN_SUBJECT} [\\#${PR_NUM}](https://github.com/instana/instana-go-client/pull/${PR_NUM})\n"
else
CHANGES="${CHANGES}- ${CLEAN_SUBJECT}\n"
fi
done <<< "$COMMITS"
# Generate new CHANGELOG section
cat > NEW_CHANGELOG.md << EOF
## [${VERSION}](https://github.com/instana/instana-go-client/tree/${VERSION}) (${DATE})
EOF
# Add comparison link only if there's a previous tag
if [ -n "$LAST_TAG" ]; then
echo "[Full Changelog](https://github.com/instana/instana-go-client/compare/${LAST_TAG}...${VERSION})" >> NEW_CHANGELOG.md
echo "" >> NEW_CHANGELOG.md
fi
cat >> NEW_CHANGELOG.md << EOF
**Changes:**
${CHANGES}
EOF
# Prepend to existing CHANGELOG
if [ -f CHANGELOG.md ]; then
cat NEW_CHANGELOG.md CHANGELOG.md > TEMP_CHANGELOG.md
mv TEMP_CHANGELOG.md CHANGELOG.md
else
mv NEW_CHANGELOG.md CHANGELOG.md
fi
echo "✅ CHANGELOG generated"
echo "Preview:"
head -n 20 CHANGELOG.md
- name: Commit CHANGELOG
run: |
VERSION="${{ needs.version-validation.outputs.version }}"
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git add CHANGELOG.md
git commit -m "chore: update CHANGELOG.md for release ${VERSION}"
git push
echo "✅ CHANGELOG committed and pushed"
create-release:
name: Create Release
runs-on: ubuntu-latest
needs: [version-validation, generate-changelog]
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
ref: main
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: '1.23'
- name: Extract release notes
id: release_notes
run: |
VERSION="${{ needs.version-validation.outputs.version }}"
# Extract the section for this version from CHANGELOG.md
awk "/## \[${VERSION}\]/,/## \[/" CHANGELOG.md | head -n -1 > RELEASE_NOTES.md
# Add installation instructions
cat >> RELEASE_NOTES.md << EOF
## Installation
\`\`\`bash
go get github.com/instana/instana-go-client@${VERSION}
\`\`\`
## Documentation
- [Quick Start Guide](https://github.com/instana/instana-go-client/blob/${VERSION}/QUICK_START.md)
- [API Reference](https://github.com/instana/instana-go-client/blob/${VERSION}/API_REFERENCE.md)
- [Architecture](https://github.com/instana/instana-go-client/blob/${VERSION}/ARCHITECTURE.md)
- [API Documentation](https://pkg.go.dev/github.com/instana/instana-go-client@${VERSION})
EOF
echo "Release notes generated"
cat RELEASE_NOTES.md
- name: Create GitHub Release
uses: softprops/action-gh-release@v1
with:
tag_name: ${{ needs.version-validation.outputs.version }}
name: Instana Go Client ${{ needs.version-validation.outputs.version }}
body_path: RELEASE_NOTES.md
draft: false
prerelease: ${{ contains(needs.version-validation.outputs.version, 'alpha') || contains(needs.version-validation.outputs.version, 'beta') || contains(needs.version-validation.outputs.version, 'rc') }}
files: |
LICENSE
README.md
QUICK_START.md
API_REFERENCE.md
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
verify-availability:
name: Verify Module Availability
runs-on: ubuntu-latest
needs: [version-validation, create-release]
steps:
- name: Trigger Go proxy
run: |
VERSION="${{ needs.version-validation.outputs.version }}"
echo "Triggering Go proxy for $VERSION"
curl -X POST "https://proxy.golang.org/github.com/instana/instana-go-client/@v/${VERSION}.info" || true
- name: Wait for proxy propagation
run: |
echo "Waiting for Go proxy to propagate..."
sleep 30
- name: Verify module on Go proxy
run: |
VERSION="${{ needs.version-validation.outputs.version }}"
echo "Verifying module availability on Go proxy..."
for i in {1..5}; do
echo "Attempt $i/5"
if curl -f "https://proxy.golang.org/github.com/instana/instana-go-client/@v/${VERSION}.info"; then
echo "✅ Module available on Go proxy"
exit 0
fi
echo "Not available yet, waiting..."
sleep 10
done
echo "⚠️ Module not yet available on proxy (may take a few minutes)"
- name: Check pkg.go.dev
run: |
VERSION="${{ needs.version-validation.outputs.version }}"
echo "Checking pkg.go.dev..."
# pkg.go.dev may take longer to update
if curl -f "https://pkg.go.dev/github.com/instana/instana-go-client@${VERSION}"; then
echo "✅ Documentation available on pkg.go.dev"
else
echo "⚠️ Documentation not yet on pkg.go.dev (may take up to an hour)"
fi
notify-success:
name: Notify Release Success
runs-on: ubuntu-latest
needs: [version-validation, create-release, verify-availability]
if: always()
steps:
- name: Get version
id: get_version
run: |
VERSION="${{ needs.version-validation.outputs.version }}"
echo "version=$VERSION" >> $GITHUB_OUTPUT
- name: Check release status
run: |
VERSION="${{ steps.get_version.outputs.version }}"
if [ "${{ needs.create-release.result }}" == "success" ] && [ "${{ needs.verify-availability.result }}" == "success" ]; then
echo "✅ Release $VERSION completed successfully"
echo ""
echo "📦 Module: github.com/instana/instana-go-client@$VERSION"
echo "🔗 Release: https://github.com/instana/instana-go-client/releases/tag/$VERSION"
echo "📚 Documentation: https://pkg.go.dev/github.com/instana/instana-go-client@$VERSION"
echo ""
echo "Installation:"
echo " go get github.com/instana/instana-go-client@$VERSION"
else
echo "❌ Release $VERSION failed"
echo "create-release: ${{ needs.create-release.result }}"
echo "verify-availability: ${{ needs.verify-availability.result }}"
exit 1
fi