# Builds and pushes a multi-arch Docker image to the Gitea container registry. # Triggered manually via workflow_dispatch — enter an existing semver tag (e.g. 1.2.3) # in the "Release tag" input. The workflow will fail early if the tag does not exist. # # Requires a repository secret REGISTRY_TOKEN — a Gitea PAT with write:package scope. # Create it at: Settings → Applications → Generate Token (scope: write:package) # Then add it: Repository → Settings → Secrets → Actions → REGISTRY_TOKEN # # After a successful run the image is available at: # //: name: Docker Publish on: workflow_dispatch: inputs: tag: description: 'Release tag (semver, e.g. 1.2.3)' required: true type: string jobs: build-push: runs-on: ubuntu-latest permissions: packages: write contents: read steps: - name: Checkout uses: actions/checkout@v4 with: fetch-depth: 0 - name: Validate tag exists run: | if ! git rev-parse "refs/tags/${{ inputs.tag }}" >/dev/null 2>&1; then echo "Error: tag '${{ inputs.tag }}' does not exist in this repository." exit 1 fi git checkout "refs/tags/${{ inputs.tag }}" # Strip the protocol from the server URL to get the registry hostname. # e.g. https://gitea.example.com → gitea.example.com - name: Derive registry hostname run: | echo "REGISTRY=$(echo '${{ gitea.server_url }}' | sed 's|https://||;s|http://||')" >> $GITHUB_ENV # Generates OCI-compliant tags and labels from the provided release tag. # 1.2.3 → image tags: 1.2.3 / 1.2 / 1 - name: Extract Docker metadata id: meta uses: docker/metadata-action@v5 with: images: ${{ env.REGISTRY }}/${{ gitea.repository }} tags: | type=semver,pattern={{version}},value=${{ inputs.tag }} type=semver,pattern={{major}}.{{minor}},value=${{ inputs.tag }} type=semver,pattern={{major}},value=${{ inputs.tag }} labels: | org.opencontainers.image.source=${{ gitea.server_url }}/${{ gitea.repository }} # QEMU enables emulation of arm64 on the amd64 runner. - name: Set up QEMU uses: docker/setup-qemu-action@v3 # BuildKit driver required for multi-platform builds and layer caching. - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - name: Log in to Gitea registry uses: docker/login-action@v3 with: registry: ${{ env.REGISTRY }} username: ${{ gitea.actor }} password: ${{ secrets.REGISTRY_TOKEN }} - name: Build and push uses: docker/build-push-action@v5 with: context: . platforms: linux/amd64,linux/arm64 push: true tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} # Registry-based layer cache — survives between runs without a separate cache store. cache-from: type=registry,ref=${{ env.REGISTRY }}/${{ gitea.repository }}:buildcache cache-to: type=registry,ref=${{ env.REGISTRY }}/${{ gitea.repository }}:buildcache,mode=max