Skip to content

fix: make ban duration log message dynamic based on configuration #22

fix: make ban duration log message dynamic based on configuration

fix: make ban duration log message dynamic based on configuration #22

Workflow file for this run

name: CI/CD Pipeline
on:
push:
branches: [ main ]
paths-ignore:
- '**.md'
- 'docs/**'
- '.gitignore'
- 'LICENSE'
pull_request:
branches: [ main ]
permissions:
contents: write
packages: write
pull-requests: read
jobs:
# ============================================================================
# STAGE 1: TEST
# ============================================================================
test-unit:
name: Unit Tests
runs-on: ubuntu-latest
strategy:
matrix:
go-version: ['1.20', '1.21']
steps:
- uses: actions/checkout@v4
- name: Set up Go ${{ matrix.go-version }}
uses: actions/setup-go@v5
with:
go-version: ${{ matrix.go-version }}
cache: true
- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install -y libpcap-dev
- name: Run unit tests
run: go test ./... -v -race -coverprofile=coverage.out -covermode=atomic
- name: Upload coverage
uses: codecov/codecov-action@v4
with:
file: ./coverage.out
flags: unittests
token: ${{ secrets.CODECOV_TOKEN }}
test-integration:
name: Integration Tests
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: '1.20'
cache: true
- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install -y libpcap-dev
- name: Run integration tests
run: go test -tags=integration ./test/integration -v
test-e2e:
name: E2E Tests
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: '1.20'
cache: true
- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install -y libpcap-dev
- name: Build binary
run: make build
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Run E2E tests
working-directory: test/e2e
run: |
docker compose build
docker compose up -d
sleep 10
chmod +x run-simple-e2e.sh
bash run-simple-e2e.sh
- name: Show logs on failure
if: failure()
working-directory: test/e2e
run: |
docker logs btblocker-e2e-server || true
docker logs btblocker-e2e-client || true
- name: Cleanup
if: always()
working-directory: test/e2e
run: docker compose down -v
lint:
name: Lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: '1.20'
cache: true
- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install -y libpcap-dev
- name: golangci-lint
uses: golangci/golangci-lint-action@v4
with:
version: latest
args: --timeout=5m
# ============================================================================
# STAGE 2: VERSION PREPARATION (determine version and update files)
# ============================================================================
prepare-version:
name: Prepare Version
runs-on: ubuntu-latest
needs: [test-unit, test-integration, test-e2e, lint]
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
outputs:
version: ${{ steps.version.outputs.version }}
tag: ${{ steps.version.outputs.tag }}
should_release: ${{ steps.check.outputs.should_release }}
permissions:
contents: write
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
token: ${{ secrets.GITHUB_TOKEN }}
- name: Check if skip release
id: check
run: |
COMMIT_MSG=$(git log -1 --pretty=%B)
if echo "$COMMIT_MSG" | grep -qE "(chore: bump version|Bump version to)"; then
echo "should_release=false" >> $GITHUB_OUTPUT
exit 0
fi
echo "should_release=true" >> $GITHUB_OUTPUT
- name: Determine version bump
id: bump
if: steps.check.outputs.should_release == 'true'
run: |
LAST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "v0.0.0")
COMMITS=$(git log ${LAST_TAG}..HEAD --pretty=format:"%s")
BUMP="patch"
if echo "$COMMITS" | grep -qiE "^(feat|feature)(\(.+\))?!:|^BREAKING CHANGE:"; then
BUMP="major"
elif echo "$COMMITS" | grep -qiE "^(feat|feature)(\(.+\))?:"; then
BUMP="minor"
elif echo "$COMMITS" | grep -qiE "^(fix|perf|refactor|optimize)(\(.+\))?:"; then
BUMP="patch"
fi
echo "bump_type=$BUMP" >> $GITHUB_OUTPUT
echo "last_tag=$LAST_TAG" >> $GITHUB_OUTPUT
- name: Calculate new version
id: version
if: steps.check.outputs.should_release == 'true'
run: |
LAST_TAG=${{ steps.bump.outputs.last_tag }}
LAST_VERSION=${LAST_TAG#v}
IFS='.' read -ra PARTS <<< "$LAST_VERSION"
MAJOR="${PARTS[0]:-0}"
MINOR="${PARTS[1]:-0}"
PATCH="${PARTS[2]:-0}"
case "${{ steps.bump.outputs.bump_type }}" in
major) MAJOR=$((MAJOR + 1)); MINOR=0; PATCH=0 ;;
minor) MINOR=$((MINOR + 1)); PATCH=0 ;;
patch) PATCH=$((PATCH + 1)) ;;
esac
NEW_VERSION="${MAJOR}.${MINOR}.${PATCH}"
echo "version=${NEW_VERSION}" >> $GITHUB_OUTPUT
echo "tag=v${NEW_VERSION}" >> $GITHUB_OUTPUT
# ============================================================================
# STAGE 3: BUILD (with updated version)
# ============================================================================
build-binaries:
name: Build ${{ matrix.goos }}-${{ matrix.goarch }}
runs-on: ubuntu-latest
needs: [prepare-version]
if: needs.prepare-version.outputs.should_release == 'true'
strategy:
matrix:
goos: [linux]
goarch: [amd64]
steps:
- uses: actions/checkout@v4
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: '1.20'
- name: Install Linux dependencies
run: |
sudo apt-get update
sudo apt-get install -y libpcap-dev
- name: Build binary
env:
GOOS: ${{ matrix.goos }}
GOARCH: ${{ matrix.goarch }}
CGO_ENABLED: 1
VERSION: ${{ needs.prepare-version.outputs.version }}
COMMIT: ${{ github.sha }}
run: |
BINARY_NAME="btblocker-${{ matrix.goos }}-${{ matrix.goarch }}"
go build -v \
-ldflags="-s -w -X main.Version=${VERSION} -X main.Commit=${COMMIT}" \
-o "bin/${BINARY_NAME}" \
./cmd/btblocker
shell: bash
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: binary-${{ matrix.goos }}-${{ matrix.goarch }}
path: bin/*
retention-days: 1
build-nix:
name: Build Nix Package
runs-on: ubuntu-latest
needs: [prepare-version]
if: needs.prepare-version.outputs.should_release == 'true'
steps:
- uses: actions/checkout@v4
- name: Inject version into flake.nix
run: |
VERSION="${{ needs.prepare-version.outputs.version }}"
sed -i "s/version = \"[^\"]*\";/version = \"${VERSION}\";/" flake.nix
echo "Updated flake.nix to version ${VERSION}"
grep "version =" flake.nix
- name: Install Nix
uses: cachix/install-nix-action@v25
with:
extra_nix_config: |
experimental-features = nix-command flakes
accept-flake-config = true
- name: Setup Cachix
uses: cachix/cachix-action@v14
with:
name: btblocker
authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}'
- name: Build Nix package
run: nix build .#btblocker --print-build-logs
- name: Push to Cachix
run: |
nix path-info .#btblocker --closure-size --json | jq -r '.[].path' | cachix push btblocker
# ============================================================================
# STAGE 4: CREATE RELEASE (after builds)
# ============================================================================
create-release:
name: Create Release
runs-on: ubuntu-latest
needs: [prepare-version, build-binaries, build-nix]
if: needs.prepare-version.outputs.should_release == 'true'
outputs:
version: ${{ needs.prepare-version.outputs.version }}
tag: ${{ needs.prepare-version.outputs.tag }}
created: ${{ steps.create_release.outputs.created }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
token: ${{ secrets.GITHUB_TOKEN }}
- name: Create GitHub Release
id: create_release
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
TAG="${{ needs.prepare-version.outputs.tag }}"
# Create tag
git tag "$TAG"
git push origin "$TAG"
# Create release
gh release create "$TAG" \
--title "Release $TAG" \
--notes "Automated release $TAG"
echo "created=true" >> $GITHUB_OUTPUT
# ============================================================================
# STAGE 5: PUBLISH (upload artifacts to release, push Docker)
# ============================================================================
publish-artifacts:
name: Publish Artifacts
runs-on: ubuntu-latest
needs: [prepare-version, create-release]
if: needs.prepare-version.outputs.should_release == 'true'
steps:
- uses: actions/checkout@v4
- name: Download all artifacts
uses: actions/download-artifact@v4
with:
path: artifacts
- name: Create archives and checksums
run: |
cd artifacts
for dir in binary-*; do
platform=$(echo $dir | sed 's/binary-//')
cd "$dir"
# Create archive
if [[ "$platform" == *"windows"* ]]; then
zip "btblocker-${{ needs.create-release.outputs.version }}-${platform}.zip" *
sha256sum *.zip > *.zip.sha256
else
tar czf "btblocker-${{ needs.create-release.outputs.version }}-${platform}.tar.gz" *
sha256sum *.tar.gz > *.tar.gz.sha256
fi
cd ..
done
- name: Upload to release
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
cd artifacts
find . -name "*.tar.gz" -o -name "*.zip" -o -name "*.sha256" | while read file; do
gh release upload ${{ needs.create-release.outputs.tag }} "$file" --clobber
done
publish-docker:
name: Publish Docker Image
runs-on: ubuntu-latest
needs: [prepare-version, create-release]
if: needs.prepare-version.outputs.should_release == 'true'
steps:
- uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Log in to GHCR
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and push Docker image
uses: docker/build-push-action@v5
with:
context: .
platforms: linux/amd64,linux/arm64
push: true
tags: |
ghcr.io/${{ github.repository_owner }}/btblocker:latest
ghcr.io/${{ github.repository_owner }}/btblocker:${{ needs.create-release.outputs.version }}
cache-from: type=gha
cache-to: type=gha,mode=max
# ============================================================================
# PR CHECKS (on pull requests, only run tests - no build/release)
# ============================================================================
pr-summary:
name: PR Summary
runs-on: ubuntu-latest
needs: [test-unit, test-integration, test-e2e, lint]
if: github.event_name == 'pull_request'
steps:
- name: Check results
run: |
echo "✅ All PR checks passed!"
echo "Unit Tests: ${{ needs.test-unit.result }}"
echo "Integration Tests: ${{ needs.test-integration.result }}"
echo "E2E Tests: ${{ needs.test-e2e.result }}"
echo "Lint: ${{ needs.lint.result }}"