From 5636b00f334666c70e8701180d21e36658d1c574 Mon Sep 17 00:00:00 2001 From: Graham McIntire Date: Sat, 31 Jan 2026 16:48:28 -0600 Subject: [PATCH] add github ci --- .github/workflows/ci.yml | 212 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 212 insertions(+) create mode 100644 .github/workflows/ci.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..b2ac93e --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,212 @@ +# GitHub Actions CI/CD Configuration for Towerops Agent +# Builds and publishes Docker image to GitHub Container Registry + +name: CI + +on: + push: + branches: + - main + - '**' + tags: + - 'v*' + pull_request: + branches: + - main + +env: + REGISTRY: ghcr.io + IMAGE_NAME: ${{ github.repository }} + +jobs: + test: + name: Test + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Install Rust toolchain + uses: dtolnay/rust-toolchain@stable + with: + toolchain: "1.91" + components: rustfmt, clippy + + - name: Install protobuf compiler + run: sudo apt-get update && sudo apt-get install -y protobuf-compiler + + - name: Cache cargo registry + uses: actions/cache@v4 + with: + path: | + ~/.cargo/registry + ~/.cargo/git + target + key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }} + restore-keys: | + ${{ runner.os }}-cargo- + + - name: Check + run: cargo check --release + + - name: Format check + run: cargo fmt -- --check + + - name: Test + run: cargo test + + # Temporarily disabled: + # - name: Clippy + # run: cargo clippy -- -D warnings + + build-branch: + name: Build (Branch) + needs: test + runs-on: ubuntu-latest + if: github.event_name == 'push' && github.ref != 'refs/heads/main' && !startsWith(github.ref, 'refs/tags/') + permissions: + contents: read + packages: write + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Log in to GitHub Container Registry + uses: docker/login-action@v3 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Extract branch name + id: branch + run: echo "name=${GITHUB_REF#refs/heads/}" >> $GITHUB_OUTPUT + + - name: Build and push + uses: docker/build-push-action@v6 + with: + context: . + push: true + tags: | + ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.branch.outputs.name }} + ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.sha }} + cache-from: type=gha + cache-to: type=gha,mode=max + + build-main: + name: Build (Main) + needs: test + runs-on: ubuntu-latest + if: github.event_name == 'push' && github.ref == 'refs/heads/main' + permissions: + contents: read + packages: write + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 # Needed for git describe + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Log in to GitHub Container Registry + uses: docker/login-action@v3 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Generate version info + id: version + run: | + VERSION=$(git describe --tags --always --dirty=-modified | sed 's/^v//') + TIMESTAMP=$(date +%Y%m%d-%H%M%S) + SHORT_SHA=${GITHUB_SHA::7} + echo "version=$VERSION" >> $GITHUB_OUTPUT + echo "timestamp=$TIMESTAMP" >> $GITHUB_OUTPUT + echo "short_sha=$SHORT_SHA" >> $GITHUB_OUTPUT + echo "Building version $VERSION at $TIMESTAMP" + + - name: Build and push + uses: docker/build-push-action@v6 + with: + context: . + platforms: linux/amd64 + push: true + build-args: | + VERSION=${{ steps.version.outputs.version }} + tags: | + ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest + ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:main + ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.version }} + ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:main-${{ steps.version.outputs.short_sha }} + ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:main-${{ steps.version.outputs.timestamp }} + cache-from: type=gha + cache-to: type=gha,mode=max + + - name: Summary + run: | + echo "### Built and pushed with tags:" >> $GITHUB_STEP_SUMMARY + echo "- \`latest\` (for production)" >> $GITHUB_STEP_SUMMARY + echo "- \`main\` (for Watchtower tracking)" >> $GITHUB_STEP_SUMMARY + echo "- \`${{ steps.version.outputs.version }}\` (git describe)" >> $GITHUB_STEP_SUMMARY + echo "- \`main-${{ steps.version.outputs.short_sha }}\` (commit)" >> $GITHUB_STEP_SUMMARY + echo "- \`main-${{ steps.version.outputs.timestamp }}\` (timestamp)" >> $GITHUB_STEP_SUMMARY + + release: + name: Release (Multi-arch) + needs: test + runs-on: ubuntu-latest + if: startsWith(github.ref, 'refs/tags/v') + permissions: + contents: read + packages: write + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Log in to GitHub Container Registry + uses: docker/login-action@v3 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Extract version from tag + id: version + run: | + TAG=${GITHUB_REF#refs/tags/} + VERSION=${TAG#v} + echo "tag=$TAG" >> $GITHUB_OUTPUT + echo "version=$VERSION" >> $GITHUB_OUTPUT + echo "Releasing version: $VERSION" + + - name: Build and push (multi-arch) + uses: docker/build-push-action@v6 + with: + context: . + platforms: linux/amd64,linux/arm64 + push: true + build-args: | + VERSION=${{ steps.version.outputs.version }} + tags: | + ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.version }} + ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.tag }} + ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest + cache-from: type=gha + cache-to: type=gha,mode=max + + - name: Summary + run: | + echo "### Released version: ${{ steps.version.outputs.version }}" >> $GITHUB_STEP_SUMMARY + echo "Multi-architecture build (amd64, arm64)" >> $GITHUB_STEP_SUMMARY