name: Release Docker Image concurrency: group: "release-image-${{ github.ref }}" on: pull_request: paths-ignore: - "*.md" - "**/*.md" - ".gitlab-ci.yml" - ".gitignore" - "renovate.json" - "pkg/**" - "docs/**" push: branches: - main paths-ignore: - "*.md" - "**/*.md" - ".gitlab-ci.yml" - ".gitignore" - "renovate.json" - "pkg/**" - "docs/**" # Allows you to run this workflow manually from the Actions tab workflow_dispatch: env: BUILTIN_REGISTRY: forgejo.ellis.link BUILTIN_REGISTRY_ENABLED: "${{ ((vars.BUILTIN_REGISTRY_USER && secrets.BUILTIN_REGISTRY_PASSWORD) || (github.event_name != 'pull_request' || github.event.pull_request.head.repo.fork == false)) && 'true' || 'false' }}" jobs: define-variables: name: "Setup Variables" runs-on: ubuntu-latest outputs: images: ${{ steps.var.outputs.images }} images_list: ${{ steps.var.outputs.images_list }} steps: - name: Setting variables uses: https://github.com/actions/github-script@v8 id: var with: script: | const githubRepo = '${{ github.repository }}'.toLowerCase() const repoId = githubRepo.split('/')[1] core.setOutput('github_repository', githubRepo) const builtinImage = '${{ env.BUILTIN_REGISTRY }}/' + githubRepo let images = [] if (process.env.BUILTIN_REGISTRY_ENABLED === "true") { images.push(builtinImage) } else { // Fallback to official registry for forks/PRs without credentials images.push('forgejo.ellis.link/continuwuation/continuwuity') } core.setOutput('images', images.join("\n")) core.setOutput('images_list', images.join(",")) build-release: name: "Build ${{ matrix.slug }} (release)" runs-on: dind needs: define-variables permissions: contents: read packages: write attestations: write id-token: write strategy: matrix: include: - platform: "linux/amd64" slug: "linux-amd64" - platform: "linux/arm64" slug: "linux-arm64" steps: - name: Checkout repository uses: actions/checkout@v5 with: persist-credentials: false - name: Prepare Docker build environment id: prepare uses: ./.forgejo/actions/prepare-docker-build with: platform: ${{ matrix.platform }} slug: ${{ matrix.slug }} target_cpu: "" profile: "release" images: ${{ needs.define-variables.outputs.images }} registry_user: ${{ vars.BUILTIN_REGISTRY_USER || github.actor }} registry_password: ${{ secrets.BUILTIN_REGISTRY_PASSWORD || secrets.GITHUB_TOKEN }} - name: Build and push Docker image by digest id: build uses: docker/build-push-action@v6 with: context: . file: "docker/Dockerfile" build-args: | GIT_COMMIT_HASH=${{ github.sha }} GIT_COMMIT_HASH_SHORT=${{ env.COMMIT_SHORT_SHA }} GIT_REMOTE_URL=${{github.event.repository.html_url }} GIT_REMOTE_COMMIT_URL=${{github.event.head_commit.url }} CARGO_INCREMENTAL=${{ env.BUILDKIT_ENDPOINT != '' && '1' || '0' }} TARGET_CPU= RUST_PROFILE=release platforms: ${{ matrix.platform }} labels: ${{ steps.prepare.outputs.metadata_labels }} annotations: ${{ steps.prepare.outputs.metadata_annotations }} cache-from: type=gha # cache-to: type=gha,mode=max sbom: true outputs: | ${{ env.BUILTIN_REGISTRY_ENABLED == 'true' && format('type=image,"name={0}",push-by-digest=true,name-canonical=true,push=true', needs.define-variables.outputs.images_list) || format('type=image,"name={0}",push=false', needs.define-variables.outputs.images_list) }} type=local,dest=/tmp/binaries env: SOURCE_DATE_EPOCH: ${{ env.TIMESTAMP }} - name: Upload Docker artifacts uses: ./.forgejo/actions/upload-docker-artifacts with: slug: ${{ matrix.slug }} cpu_suffix: ${{ steps.prepare.outputs.cpu_suffix }} artifact_suffix: "" digest_suffix: "" digest: ${{ steps.build.outputs.digest }} merge-release: name: "Create Multi-arch Release Manifest" runs-on: dind needs: [define-variables, build-release] steps: - name: Checkout repository uses: actions/checkout@v5 with: persist-credentials: false - name: Create multi-platform manifest uses: ./.forgejo/actions/create-docker-manifest with: digest_pattern: "digests-linux-{amd64,arm64}" tag_suffix: "" images: ${{ needs.define-variables.outputs.images }} registry_user: ${{ vars.BUILTIN_REGISTRY_USER || github.actor }} registry_password: ${{ secrets.BUILTIN_REGISTRY_PASSWORD || secrets.GITHUB_TOKEN }} build-maxperf: name: "Build ${{ matrix.slug }} (max-perf)" runs-on: dind needs: [define-variables, build-release] permissions: contents: read packages: write attestations: write id-token: write strategy: matrix: include: - platform: "linux/amd64" slug: "linux-amd64" target_cpu: "haswell" - platform: "linux/arm64" slug: "linux-arm64" target_cpu: "" steps: - name: Checkout repository uses: actions/checkout@v5 with: persist-credentials: false - name: Prepare max-perf Docker build environment id: prepare uses: ./.forgejo/actions/prepare-docker-build with: platform: ${{ matrix.platform }} slug: ${{ matrix.slug }} target_cpu: ${{ matrix.target_cpu }} profile: "release-max-perf" images: ${{ needs.define-variables.outputs.images }} registry_user: ${{ vars.BUILTIN_REGISTRY_USER || github.actor }} registry_password: ${{ secrets.BUILTIN_REGISTRY_PASSWORD || secrets.GITHUB_TOKEN }} - name: Build and push max-perf Docker image by digest id: build uses: docker/build-push-action@v6 with: context: . file: "docker/Dockerfile" build-args: | GIT_COMMIT_HASH=${{ github.sha }} GIT_COMMIT_HASH_SHORT=${{ env.COMMIT_SHORT_SHA }} GIT_REMOTE_URL=${{github.event.repository.html_url }} GIT_REMOTE_COMMIT_URL=${{github.event.head_commit.url }} CARGO_INCREMENTAL=${{ env.BUILDKIT_ENDPOINT != '' && '1' || '0' }} TARGET_CPU=${{ matrix.target_cpu }} RUST_PROFILE=release-max-perf platforms: ${{ matrix.platform }} labels: ${{ steps.prepare.outputs.metadata_labels }} annotations: ${{ steps.prepare.outputs.metadata_annotations }} cache-from: type=gha # cache-to: type=gha,mode=max sbom: true outputs: | ${{ env.BUILTIN_REGISTRY_ENABLED == 'true' && format('type=image,"name={0}",push-by-digest=true,name-canonical=true,push=true', needs.define-variables.outputs.images_list) || format('type=image,"name={0}",push=false', needs.define-variables.outputs.images_list) }} type=local,dest=/tmp/binaries env: SOURCE_DATE_EPOCH: ${{ env.TIMESTAMP }} - name: Upload max-perf Docker artifacts uses: ./.forgejo/actions/upload-docker-artifacts with: slug: ${{ matrix.slug }} cpu_suffix: ${{ steps.prepare.outputs.cpu_suffix }} artifact_suffix: "-maxperf" digest_suffix: "-maxperf" digest: ${{ steps.build.outputs.digest }} merge-maxperf: name: "Create Max-Perf Manifest" runs-on: dind needs: [define-variables, build-maxperf] steps: - name: Checkout repository uses: actions/checkout@v5 with: persist-credentials: false - name: Create max-perf manifest uses: ./.forgejo/actions/create-docker-manifest with: digest_pattern: "digests-maxperf-linux-{amd64-haswell,arm64}" tag_suffix: "-maxperf" images: ${{ needs.define-variables.outputs.images }} registry_user: ${{ vars.BUILTIN_REGISTRY_USER || github.actor }} registry_password: ${{ secrets.BUILTIN_REGISTRY_PASSWORD || secrets.GITHUB_TOKEN }}