Skip to content
name: build

on:
  push:
    branches: [main]
  pull_request:
  workflow_dispatch:

jobs:
  # Verifies all tests pass
  verify:
    runs-on: ubuntu-latest
    timeout-minutes: 30
    permissions:
      contents: read
      issues: read
      checks: write
      pull-requests: write
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0 # Fetch the whole history and tags.
      - uses: dtolnay/rust-toolchain@stable
        with:
          components: clippy, rustfmt
      - uses: Swatinem/rust-cache@v2

      - name: install hurl
        uses: rezi-labs/install-hurl@main

      - name: install just
        uses: rezi-labs/install-just@main

      - name: Run Rust checks and tests
        run: |
          cargo fmt -- --check
          cargo check
          cargo clippy
          cargo test

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3

      - name: Log in to Docker Hub
        if: github.ref == 'refs/heads/main'
        uses: docker/login-action@v3
        with:
          username: silenloc
          password: ${{ secrets.DOCKER_TOKEN }}

      - name: Build and test Docker image
        run: just docker build ci-${{ github.sha }}

      - name: Start Docker container for testing
        run: just docker run

      - name: Run acceptance tests
        run: just hurl test

      - name: Stop Docker container
        if: always()
        run: just docker stop

      - name: Push Docker image for release
        if: github.ref == 'refs/heads/main'
        run: docker push silenloc/chtmx:ci-${{ github.sha }}

  release:
    needs: verify
    if: github.ref == 'refs/heads/main'
    runs-on: ubuntu-latest
    outputs:
      released: ${{ steps.semantic.outputs.new_release_published }}
      version: ${{ steps.semantic.outputs.new_release_version }}
    permissions:
      contents: write
      issues: write
      pull-requests: write
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0
          persist-credentials: false
      
      - name: Semantic Release
        id: semantic
        uses: cycjimmy/semantic-release-action@v4
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        with:
          extra_plugins: |
            conventional-changelog-conventionalcommits@8.0.0
            @semantic-release/git@10.0.1
            @semantic-release/exec@6.0.3

  # Publish the artifacts (only if `verify` passed, and `release` created release)
  publish:
    needs: [verify, release]
    if: needs.verify.result == 'success' && needs.release.outputs.released == 'true'
    runs-on: ubuntu-latest
    timeout-minutes: 10
    permissions:
      contents: read
    steps:
      - name: Log in to Docker Hub
        uses: docker/login-action@v3
        with:
          username: silenloc
          password: ${{ secrets.DOCKER_TOKEN }}
      
      - name: Pull verified image
        run: docker pull silenloc/chtmx:ci-${{ github.sha }}

      - name: Retag and push with version and latest
        run: |
          docker tag silenloc/chtmx:ci-${{ github.sha }} silenloc/chtmx:${{ needs.release.outputs.version }}
          docker tag silenloc/chtmx:ci-${{ github.sha }} silenloc/chtmx:latest
          docker push silenloc/chtmx:${{ needs.release.outputs.version }}
          docker push silenloc/chtmx:latest