name: Docker Image on: workflow_dispatch: inputs: specific_version: description: "Optional: Specify a full version (e.g., v0.3.0 or v0.3.1-beta.1) to build. If empty, uses the latest release tag. MUST start with 'v'." required: false default: "" env: CARGO_TERM_COLOR: always jobs: determine_version: runs-on: ubuntu-latest outputs: version_with_v: ${{ steps.version_info.outputs.version_with_v }} is_valid_version: ${{ steps.version_info.outputs.is_valid_version }} steps: - name: Checkout code uses: actions/checkout@v4 with: fetch-depth: 0 - name: Get version information id: version_info run: | set -ex TARGET_VERSION="" SPECIFIC_VERSION="${{ github.event.inputs.specific_version }}" if [[ -n "$SPECIFIC_VERSION" ]]; then if [[ ! "$SPECIFIC_VERSION" =~ ^v[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9.-]+)?$ ]]; then echo "::error::Specified version '$SPECIFIC_VERSION' is not a valid format. It must start with 'v' (e.g., v0.3.0 or v0.3.1-beta.1)." echo "is_valid_version=false" >> $GITHUB_OUTPUT exit 1 fi TARGET_VERSION="$SPECIFIC_VERSION" echo "Using specified version: $TARGET_VERSION" else echo "No specific version provided, determining latest release tag..." TARGET_VERSION=$(git tag --list 'v*' --sort=-v:refname | head -n 1) if [[ -z "$TARGET_VERSION" ]]; then echo "::error::No version tags starting with 'v' (e.g., vX.Y.Z) found in the repository." echo "is_valid_version=false" >> $GITHUB_OUTPUT exit 1 fi echo "Latest release version found: $TARGET_VERSION" fi echo "version_with_v=$TARGET_VERSION" >> $GITHUB_OUTPUT echo "is_valid_version=true" >> $GITHUB_OUTPUT build_and_publish_image: needs: determine_version if: needs.determine_version.outputs.is_valid_version == 'true' runs-on: ubuntu-latest permissions: contents: read packages: write env: GHCR_IMAGE_PATH: ghcr.io/quantus-network/quantus-miner TARGET_VERSION_WITH_V: ${{ needs.determine_version.outputs.version_with_v }} steps: - 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: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - name: Check if Docker image already exists and fail if so id: check_image run: | set -ex IMAGE_TO_CHECK="${{ env.GHCR_IMAGE_PATH }}:${{ env.TARGET_VERSION_WITH_V }}" echo "Checking for image: $IMAGE_TO_CHECK" if docker manifest inspect "$IMAGE_TO_CHECK" > /dev/null 2>&1; then echo "::error::Image $IMAGE_TO_CHECK already exists. Aborting." exit 1 else echo "Image $IMAGE_TO_CHECK does not exist. Proceeding with build." fi - name: Checkout code at tag version uses: actions/checkout@v4 with: ref: ${{ env.TARGET_VERSION_WITH_V }} - name: Check if Dockerfile exists in tag id: check_dockerfile run: | if [ ! -f Dockerfile ]; then echo "::warning::Dockerfile not found in tag ${{ env.TARGET_VERSION_WITH_V }}, falling back to main branch Dockerfile" echo "use_main=true" >> $GITHUB_OUTPUT else echo "Dockerfile found in tag" echo "use_main=false" >> $GITHUB_OUTPUT fi - name: Checkout main branch for Dockerfile (if needed) if: steps.check_dockerfile.outputs.use_main == 'true' uses: actions/checkout@v4 with: ref: main sparse-checkout: | Dockerfile .dockerignore sparse-checkout-cone-mode: false path: dockerfile-source - name: Copy Dockerfile from main (if needed) if: steps.check_dockerfile.outputs.use_main == 'true' run: | cp dockerfile-source/Dockerfile ./ [ -f dockerfile-source/.dockerignore ] && cp dockerfile-source/.dockerignore ./ || true - name: Build and push Docker image uses: docker/build-push-action@v5 with: context: . file: ./Dockerfile push: true platforms: linux/amd64,linux/arm64 provenance: false tags: | ${{ env.GHCR_IMAGE_PATH }}:${{ env.TARGET_VERSION_WITH_V }} ${{ env.GHCR_IMAGE_PATH }}:latest cache-from: type=gha cache-to: type=gha,mode=max - name: Print completion message run: | echo "Successfully built and pushed ${{ env.GHCR_IMAGE_PATH }}:${{ env.TARGET_VERSION_WITH_V }}" echo "Image is also tagged as latest: ${{ env.GHCR_IMAGE_PATH }}:latest"