name: Wait4X CI

on:
  push:
    branches:
      - 'main'
      - 'release/*'
    tags:
      - 'v*'
  pull_request:
    branches:
      - '*'

permissions:
  contents: read
  packages: write

jobs:
  check:
    name: Check
    runs-on: ubuntu-latest
    steps:
    - name: Checkout Code
      uses: actions/checkout@v5

    - name: Set up Go 1.23.x
      uses: actions/setup-go@v5
      with:
        go-version: 1.23.x

    - name: go-fmt
      run: make check-gofmt

    - name: go-vet
      run: make check-govet

    - name: revive
      run: |
        go install github.com/mgechev/revive@v1.1.4
        make check-revive

  test:
    name: Test
    needs: check
    runs-on: ubuntu-latest
    steps:
    - name: Checkout Code
      uses: actions/checkout@v5

    - name: Set up Go 1.23.x
      uses: actions/setup-go@v5
      with:
        go-version: 1.23.x

    - name: Test Wait4X
      run: make test

    - name: Convert coverage to lcov
      uses: jandelgado/gcov2lcov-action@v1.2.0
      with:
        infile: coverage.out
        outfile: coverage.lcov

    - name: Coveralls
      uses: coverallsapp/github-action@master
      with:
        github-token: ${{ secrets.GITHUB_TOKEN }}
        path-to-lcov: coverage.lcov

  build:
    name: Build
    needs: test
    runs-on: ubuntu-latest
    permissions:
      contents: write
      packages: write
      statuses: write
    steps:
      - name: Checkout Code
        uses: actions/checkout@v5
        with:
          fetch-depth: 0

      - name: Docker metadata
        id: meta
        uses: docker/metadata-action@v5
        with:
          # Maintaining "atkrad/wait4x" for backward compatibility
          # Note: This will be removed in v4.0.0. Please use the "wait4x/wait4x" image going forward.
          images: | 
            atkrad/wait4x
            wait4x/wait4x
            ghcr.io/${{ github.repository }}
          ### versioning strategy
          ### push semver tag v3.2.1 on the default branch
          # wait4x/wait4x:2.2.0
          # wait4x/wait4x:2.2
          # wait4x/wait4x:2
          # wait4x/wait4x:latest
          # ghcr.io/wait4x/wait4x:2.2.0
          # ghcr.io/wait4x/wait4x:2.2
          # ghcr.io/wait4x/wait4x:2
          # ghcr.io/wait4x/wait4x:latest
          ### push semver pre-release tag v3.0.0-beta.1 on the default branch
          # wait4x/wait4x:3.0.0-beta.1
          # ghcr.io/wait4x/wait4x:3.0.0-beta.1
          ### push on the default branch
          # wait4x/wait4x:edge
          # ghcr.io/wait4x/wait4x:edge
          tags: |
            type=semver,pattern={{version}}
            type=semver,pattern={{major}}.{{minor}}
            type=semver,pattern={{major}}
            type=ref,event=pr
            type=edge,branch=${{ github.event.repository.default_branch }}

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3
        with:
          buildkitd-config-inline: |
            [worker.oci]
              max-parallelism = 10

      - name: Login to Docker Hub (docker.io)
        if: ${{ github.event_name != 'pull_request' }}
        uses: docker/login-action@v3
        with:
          username: ${{ secrets.DOCKERHUB_USERNAME }}
          password: ${{ secrets.DOCKERHUB_TOKEN }}

      - name: Login to GitHub Container Registry (ghcr.io)
        if: ${{ github.event_name != 'pull_request' }}
        uses: docker/login-action@v3
        with:
          registry: ghcr.io
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}

      - name: Build artifacts
        uses: docker/bake-action@v6
        with:
          targets: artifact
          provenance: false
          set: |
            *.args.COMMIT_HASH=${{ github.sha }}
            *.args.COMMIT_REF_SLUG=${{ github.ref_name }}

      - name: Move artifacts
        run: |
          # Move all files except SHA256SUMS to the main dist directory
          find ./dist -type f -not -name "SHA256SUMS" -exec mv {} ./dist/ \;
          # Combine all SHA256SUMS files into one
          find ./dist -name "SHA256SUMS" -exec cat {} \; | sort -u > ./dist/SHA256SUMS.combined
          mv ./dist/SHA256SUMS.combined ./dist/SHA256SUMS
          # Remove empty directories
          find ./dist -type d -empty -delete

      - name: Upload artifacts
        uses: actions/upload-artifact@v4
        with:
          name: wait4x-artifacts
          path: ./dist/*
          if-no-files-found: error

      - name: Build images
        uses: docker/bake-action@v6
        with:
          targets: image
          push: ${{ github.ref_name == github.event.repository.default_branch || startsWith(github.ref, 'refs/tags/') }}
          sbom: true
          provenance: true
          files: |
            ./docker-bake.hcl
            cwd://${{ steps.meta.outputs.bake-file }}

      - name: Docker Hub Description
        uses: peter-evans/dockerhub-description@v4
        if: ${{ github.event_name == 'push' && github.ref_name == github.event.repository.default_branch }}
        with:
          username: ${{ secrets.DOCKERHUB_USERNAME }}
          password: ${{ secrets.DOCKERHUB_TOKEN }}
          short-description: ${{ github.event.repository.description }}

      - name: GitHub Release
        uses: softprops/action-gh-release@v2
        if: ${{ startsWith(github.ref, 'refs/tags/') }}
        with:
          draft: true
          generate_release_notes: true
          files: |
            dist/*.tar.gz
            dist/*.sha256sum
            dist/SHA256SUMS
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
