feat(atlas): implement comprehensive MongoDB Atlas alerting system #20
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Release | |
| on: | |
| push: | |
| branches: [ main ] | |
| pull_request: | |
| branches: [ main ] | |
| permissions: | |
| contents: write | |
| packages: write | |
| issues: write | |
| pull-requests: write | |
| env: | |
| GO_VERSION: '1.24.5' | |
| GOLANGCI_LINT_VERSION: 'v2.4.0' | |
| jobs: | |
| # ============================================================================== | |
| # Code Quality and Security | |
| # ============================================================================== | |
| lint: | |
| name: 🔍 Code Quality & Linting | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 15 | |
| steps: | |
| - name: Checkout Code | |
| uses: actions/checkout@v4 | |
| - name: Setup Go | |
| uses: actions/setup-go@v5 | |
| with: | |
| go-version: ${{ env.GO_VERSION }} | |
| - name: Clean Go Module Cache (prevent lint issues) | |
| run: go clean -modcache || true | |
| - name: Download Dependencies | |
| run: go mod download | |
| - name: Sync vendor (ensure consistent vendoring for linter) | |
| shell: bash | |
| run: | | |
| # Clean any existing vendor directory to prevent conflicts | |
| if [ -d "vendor" ]; then | |
| rm -rf vendor/ | |
| fi | |
| go mod tidy | |
| go mod vendor | |
| echo "✅ Vendor directory synced successfully" | |
| - name: Run golangci-lint | |
| uses: golangci/golangci-lint-action@v7 | |
| with: | |
| version: ${{ env.GOLANGCI_LINT_VERSION }} | |
| args: --no-config --enable-only=errcheck,gosec,ineffassign --timeout=5m | |
| skip-pkg-cache: false | |
| skip-build-cache: false | |
| only-new-issues: false | |
| - name: Check Code Formatting | |
| run: | | |
| if [ "$(gofmt -s -l . | grep -v vendor/ | wc -l)" -gt 0 ]; then | |
| echo "❌ Code is not properly formatted. Run 'gofmt -s -w .'" | |
| echo "Files that need formatting:" | |
| gofmt -s -l . | grep -v vendor/ | |
| exit 1 | |
| fi | |
| echo "✅ Code is properly formatted" | |
| - name: Check Go Modules | |
| run: | | |
| go mod tidy | |
| if ! git diff --exit-code go.mod go.sum; then | |
| echo "❌ go.mod or go.sum is not up to date. Run 'go mod tidy'" | |
| exit 1 | |
| fi | |
| echo "✅ Go modules are up to date" | |
| # ============================================================================== | |
| # Testing Matrix | |
| # ============================================================================== | |
| test: | |
| name: 🧪 Tests | |
| runs-on: ${{ matrix.os }} | |
| timeout-minutes: 30 | |
| strategy: | |
| fail-fast: false | |
| max-parallel: 2 | |
| matrix: | |
| os: [ubuntu-latest, macos-latest, windows-latest] | |
| go-version: ['1.23', '1.24.5'] | |
| steps: | |
| - name: Checkout Code | |
| uses: actions/checkout@v4 | |
| - name: Setup Go ${{ matrix.go-version }} | |
| uses: actions/setup-go@v5 | |
| with: | |
| go-version: ${{ matrix.go-version }} | |
| - name: Download Dependencies | |
| run: go mod download | |
| - name: Sync vendor | |
| shell: bash | |
| run: | | |
| # Clean any existing vendor directory to prevent conflicts | |
| if [ -d "vendor" ]; then | |
| rm -rf vendor/ | |
| fi | |
| go mod tidy | |
| go mod vendor | |
| echo "✅ Vendor directory synced for ${{ matrix.os }}" | |
| - name: Create Test Temp Directory | |
| shell: bash | |
| run: | | |
| mkdir -p "${{ runner.temp }}/go-test-${{ matrix.os }}-${{ matrix.go-version }}" | |
| - name: Run Unit Tests | |
| env: | |
| CGO_ENABLED: 1 | |
| GOMAXPROCS: 2 | |
| TMPDIR: ${{ runner.temp }}/go-test-${{ matrix.os }}-${{ matrix.go-version }} | |
| TMP: ${{ runner.temp }}/go-test-${{ matrix.os }}-${{ matrix.go-version }} | |
| TEMP: ${{ runner.temp }}/go-test-${{ matrix.os }}-${{ matrix.go-version }} | |
| shell: bash | |
| run: go test -race -coverprofile="./coverage.out" -covermode=atomic -timeout=10m -p=1 ./... | |
| - name: Upload Coverage to Codecov | |
| if: matrix.os == 'ubuntu-latest' && matrix.go-version == '1.24.5' | |
| uses: codecov/codecov-action@v4 | |
| with: | |
| file: ./coverage.out | |
| flags: unittests | |
| name: codecov-umbrella | |
| # ============================================================================== | |
| # Build and Release | |
| # ============================================================================== | |
| build: | |
| name: 🏗️ Build Artifacts | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 20 | |
| needs: [lint, test] | |
| strategy: | |
| matrix: | |
| include: | |
| - os: linux | |
| arch: amd64 | |
| goos: linux | |
| goarch: amd64 | |
| - os: linux | |
| arch: arm64 | |
| goos: linux | |
| goarch: arm64 | |
| - os: darwin | |
| arch: amd64 | |
| goos: darwin | |
| goarch: amd64 | |
| - os: darwin | |
| arch: arm64 | |
| goos: darwin | |
| goarch: arm64 | |
| - os: windows | |
| arch: amd64 | |
| goos: windows | |
| goarch: amd64 | |
| ext: .exe | |
| steps: | |
| - name: Checkout Code | |
| uses: actions/checkout@v4 | |
| - name: Setup Go | |
| uses: actions/setup-go@v5 | |
| with: | |
| go-version: ${{ env.GO_VERSION }} | |
| - name: Build Binary | |
| env: | |
| GOOS: ${{ matrix.goos }} | |
| GOARCH: ${{ matrix.goarch }} | |
| CGO_ENABLED: 0 | |
| run: | | |
| VERSION=${GITHUB_REF_NAME:-dev} | |
| COMMIT=$(git rev-parse --short HEAD) | |
| BUILD_TIME=$(date -u +"%Y-%m-%dT%H:%M:%SZ") | |
| # Create unique dist directory for this build | |
| DIST_DIR="dist-${{ matrix.goos }}-${{ matrix.goarch }}" | |
| rm -rf "${DIST_DIR}" | |
| mkdir -p "${DIST_DIR}" | |
| # Build binary | |
| BINARY_NAME="matlas${{ matrix.ext }}" | |
| go build \ | |
| -ldflags="-s -w -X main.version=${VERSION} -X main.commit=${COMMIT} -X main.buildTime=${BUILD_TIME}" \ | |
| -o "${DIST_DIR}/${BINARY_NAME}" \ | |
| . | |
| # Create release archive | |
| cd "${DIST_DIR}" | |
| if [ "${{ matrix.goos }}" = "windows" ]; then | |
| zip "matlas_${{ matrix.goos }}_${{ matrix.goarch }}.zip" "${BINARY_NAME}" | |
| else | |
| tar -czf "matlas_${{ matrix.goos }}_${{ matrix.goarch }}.tar.gz" "${BINARY_NAME}" | |
| # Also create zip for consistency | |
| zip "matlas_${{ matrix.goos }}_${{ matrix.goarch }}.zip" "${BINARY_NAME}" | |
| fi | |
| - name: Upload Build Artifacts | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: matlas-${{ matrix.os }}-${{ matrix.arch }} | |
| path: | | |
| dist-${{ matrix.goos }}-${{ matrix.goarch }}/*.zip | |
| dist-${{ matrix.goos }}-${{ matrix.goarch }}/*.tar.gz | |
| retention-days: 90 | |
| prepare-release-assets: | |
| name: 📋 Prepare Release Assets | |
| runs-on: ubuntu-latest | |
| needs: build | |
| steps: | |
| - name: Download all artifacts | |
| uses: actions/download-artifact@v4 | |
| with: | |
| path: artifacts/ | |
| - name: Create consolidated dist directory | |
| run: | | |
| mkdir -p dist | |
| find artifacts/ -name "*.zip" -exec cp {} dist/ \; | |
| find artifacts/ -name "*.tar.gz" -exec cp {} dist/ \; | |
| - name: Generate checksums | |
| run: | | |
| cd dist | |
| sha256sum *.zip *.tar.gz > checksums.txt || shasum -a 256 *.zip *.tar.gz > checksums.txt | |
| echo "Generated checksums:" | |
| cat checksums.txt | |
| # ============================================================================== | |
| # Semantic Release | |
| # ============================================================================== | |
| release: | |
| name: 🚀 Semantic Release | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 15 | |
| needs: [prepare-release-assets] | |
| if: github.event_name == 'push' && github.ref == 'refs/heads/main' | |
| outputs: | |
| new_release_published: ${{ steps.semantic.outputs.new_release_published }} | |
| new_release_version: ${{ steps.semantic.outputs.new_release_version }} | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| # Use a Personal Access Token to trigger other workflows if needed | |
| token: ${{ secrets.SEMANTIC_RELEASE_TOKEN || secrets.GITHUB_TOKEN }} | |
| - name: Download all artifacts to recreate dist/ | |
| uses: actions/download-artifact@v4 | |
| with: | |
| path: artifacts/ | |
| - name: Recreate dist directory for semantic-release | |
| run: | | |
| mkdir -p dist | |
| find artifacts/ -name "*.zip" -exec cp {} dist/ \; | |
| find artifacts/ -name "*.tar.gz" -exec cp {} dist/ \; | |
| # Generate checksums | |
| cd dist | |
| sha256sum *.zip *.tar.gz > checksums.txt || shasum -a 256 *.zip *.tar.gz > checksums.txt | |
| - name: Set up Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: '20' | |
| cache: 'npm' | |
| - name: Install dependencies | |
| run: npm ci | |
| - name: Verify the integrity of provenance attestations and registry signatures for installed dependencies | |
| run: npm audit signatures | |
| - name: Run semantic-release | |
| id: semantic | |
| run: npx semantic-release | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.SEMANTIC_RELEASE_TOKEN || secrets.GITHUB_TOKEN }} | |
| - name: Create summary | |
| if: always() | |
| run: | | |
| echo "# 🚀 Semantic Release Summary" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| if [ "${{ steps.semantic.outputs.new_release_published }}" = "true" ]; then | |
| echo "## ✅ New Release Published" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "- **Version:** ${{ steps.semantic.outputs.new_release_version }}" >> $GITHUB_STEP_SUMMARY | |
| echo "- **Artifacts:** All platform binaries and checksums included" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "🎉 Release published with attached artifacts!" >> $GITHUB_STEP_SUMMARY | |
| else | |
| echo "## ℹ️ No Release Needed" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "No new release was necessary based on the commit messages since the last release." >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "### To trigger a release, use conventional commit messages:" >> $GITHUB_STEP_SUMMARY | |
| echo "- \`feat:\` for new features (minor version bump)" >> $GITHUB_STEP_SUMMARY | |
| echo "- \`fix:\` for bug fixes (patch version bump)" >> $GITHUB_STEP_SUMMARY | |
| echo "- \`feat!:\` or \`BREAKING CHANGE:\` for breaking changes (major version bump)" >> $GITHUB_STEP_SUMMARY | |
| fi | |
| # ============================================================================== | |
| # Integration and E2E Tests (conditional) | |
| # ============================================================================== | |
| integration-test: | |
| name: 🔧 Integration Tests | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 45 | |
| if: | | |
| github.event_name == 'pull_request' && | |
| contains(github.event.pull_request.labels.*.name, 'integration-tests') || | |
| github.event_name == 'push' && github.ref == 'refs/heads/main' | |
| steps: | |
| - name: Checkout Code | |
| uses: actions/checkout@v4 | |
| - name: Setup Go | |
| uses: actions/setup-go@v5 | |
| with: | |
| go-version: ${{ env.GO_VERSION }} | |
| - name: Build Application | |
| run: go build -o matlas . | |
| - name: Run Integration Tests (Safe Mode) | |
| env: | |
| ATLAS_PUBLIC_KEY: ${{ secrets.ATLAS_PUBLIC_KEY }} | |
| ATLAS_PRIVATE_KEY: ${{ secrets.ATLAS_PRIVATE_KEY }} | |
| ATLAS_PROJECT_ID: ${{ secrets.ATLAS_TEST_PROJECT_ID }} | |
| ATLAS_ORG_ID: ${{ secrets.ATLAS_TEST_ORG_ID }} | |
| run: | | |
| if [ -n "$ATLAS_PUBLIC_KEY" ] && [ -n "$ATLAS_PRIVATE_KEY" ]; then | |
| echo "🧪 Running integration tests with Atlas credentials" | |
| ./scripts/run-integration-tests-safe.sh all | |
| else | |
| echo "⚠️ Skipping integration tests - Atlas credentials not available" | |
| echo "To enable integration tests, add Atlas credentials to repository secrets" | |
| fi | |
| e2e-test: | |
| name: 🚀 End-to-End Tests | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 60 | |
| if: | | |
| github.event_name == 'pull_request' && | |
| contains(github.event.pull_request.labels.*.name, 'e2e-tests') || | |
| github.event_name == 'push' && github.ref == 'refs/heads/main' | |
| steps: | |
| - name: Checkout Code | |
| uses: actions/checkout@v4 | |
| - name: Setup Go | |
| uses: actions/setup-go@v5 | |
| with: | |
| go-version: ${{ env.GO_VERSION }} | |
| - name: Build Application | |
| run: go build -o matlas . | |
| - name: Run E2E Tests | |
| env: | |
| ATLAS_PUBLIC_KEY: ${{ secrets.ATLAS_PUBLIC_KEY }} | |
| ATLAS_PRIVATE_KEY: ${{ secrets.ATLAS_PRIVATE_KEY }} | |
| ATLAS_PROJECT_ID: ${{ secrets.ATLAS_TEST_PROJECT_ID }} | |
| ATLAS_ORG_ID: ${{ secrets.ATLAS_TEST_ORG_ID }} | |
| run: | | |
| if [ -n "$ATLAS_PUBLIC_KEY" ] && [ -n "$ATLAS_PRIVATE_KEY" ]; then | |
| echo "🚀 Running E2E tests with Atlas credentials" | |
| ./scripts/run-e2e-tests.sh all | |
| else | |
| echo "⚠️ Skipping E2E tests - Atlas credentials not available" | |
| fi |