immich/.github/workflows/docker.yml

271 lines
10 KiB
YAML

name: Docker
on:
workflow_dispatch:
push:
branches: [main]
pull_request:
release:
types: [published]
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
permissions: {}
env:
GHCR_NAMESPACE: ghcr.io/${{ github.repository_owner }}
DOCKERHUB_NAMESPACE: docker.io/altran1502
jobs:
pre-job:
runs-on: ubuntu-latest
permissions:
contents: read
outputs:
should_run: ${{ steps.check.outputs.should_run }}
highest-overall: ${{ steps.scope.outputs.highest-overall }}
highest-in-line: ${{ steps.scope.outputs.highest-in-line }}
steps:
- id: token
uses: immich-app/devtools/actions/create-workflow-token@1af396ae134e4bc3b63d947e672bc68bf4ff9dc5 # create-workflow-token-action-v3.0.0
with:
client-id: ${{ secrets.PUSH_O_MATIC_APP_CLIENT_ID }}
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
permission-contents: read
- name: Check what should run
id: check
uses: immich-app/devtools/actions/pre-job@03514eceb4a27cd714976a866b350df5ce175720 # pre-job-action-v2.1.0
with:
github-token: ${{ steps.token.outputs.token }}
filters: |
server:
- 'server/**'
- 'openapi/**'
- 'web/**'
- 'i18n/**'
machine-learning:
- 'machine-learning/**'
force-filters: |
- '.github/workflows/docker.yml'
force-events: 'workflow_dispatch,release'
- name: Determine release scope
id: scope
if: ${{ github.event_name == 'release' }}
env:
GH_TOKEN: ${{ steps.token.outputs.token }}
REPO: ${{ github.repository }}
TAG: ${{ github.event.release.tag_name }}
PRERELEASE: ${{ github.event.release.prerelease }}
run: |
overall=$(gh api "repos/${REPO}/releases/latest" --jq '.tag_name' 2>/dev/null || true)
releases=$(gh api "repos/${REPO}/releases" --paginate --slurp | jq 'flatten | map(select(.draft | not))')
in_line=$(jq -r --argjson pre "${PRERELEASE}" '.[] | select(.prerelease == $pre) | .tag_name' <<< "${releases}" \
| grep -E "^${TAG%%.*}\." | sort --version-sort | tail -1)
echo "highest-overall=$([[ "${TAG}" == "${overall}" ]] && echo true || echo false)" | tee -a "$GITHUB_OUTPUT"
echo "highest-in-line=$([[ "${TAG}" == "${in_line}" ]] && echo true || echo false)" | tee -a "$GITHUB_OUTPUT"
retag_ml:
name: Re-Tag ML
needs: pre-job
permissions:
contents: read
packages: write
if: ${{ fromJSON(needs.pre-job.outputs.should_run).machine-learning == false && !github.event.pull_request.head.repo.fork }}
runs-on: ubuntu-latest
strategy:
matrix:
include: &ml-variants
- image: immich-machine-learning
device: cpu
- image: immich-machine-learning
device: cuda
suffixes: '-cuda'
platforms: linux/amd64
- image: immich-machine-learning
device: openvino
suffixes: '-openvino'
platforms: linux/amd64
- image: immich-machine-learning
device: armnn
suffixes: '-armnn'
platforms: linux/arm64
- image: immich-machine-learning
device: rknn
suffixes: '-rknn'
platforms: linux/arm64
- image: immich-machine-learning
device: rocm
suffixes: '-rocm'
platforms: linux/amd64
runner-mapping: '{"linux/amd64": "pokedex-large"}'
steps:
- name: Login to GitHub Container Registry
uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4.6.0
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Re-tag image
env:
REGISTRY_NAME: 'ghcr.io'
REPOSITORY: ${{ github.repository_owner }}/${{ matrix.image }}
TAG_OLD: main${{ matrix.suffixes }}
TAG_PR: ${{ github.event.number == 0 && github.ref_name || format('pr-{0}', github.event.number) }}${{ matrix.suffixes }}
TAG_COMMIT: commit-${{ github.event_name != 'pull_request' && github.sha || github.event.pull_request.head.sha }}${{ matrix.suffixes }}
run: |
docker buildx imagetools create -t "${REGISTRY_NAME}/${REPOSITORY}:${TAG_PR}" "${REGISTRY_NAME}/${REPOSITORY}:${TAG_OLD}"
docker buildx imagetools create -t "${REGISTRY_NAME}/${REPOSITORY}:${TAG_COMMIT}" "${REGISTRY_NAME}/${REPOSITORY}:${TAG_OLD}"
retag_server:
name: Re-Tag Server
needs: pre-job
permissions:
contents: read
packages: write
if: ${{ fromJSON(needs.pre-job.outputs.should_run).server == false && !github.event.pull_request.head.repo.fork }}
runs-on: ubuntu-latest
steps:
- name: Login to GitHub Container Registry
uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4.6.0
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Re-tag image
env:
REGISTRY_NAME: 'ghcr.io'
REPOSITORY: ${{ github.repository_owner }}/immich-server
TAG_OLD: main
TAG_PR: ${{ github.event.number == 0 && github.ref_name || format('pr-{0}', github.event.number) }}
TAG_COMMIT: commit-${{ github.event_name != 'pull_request' && github.sha || github.event.pull_request.head.sha }}
run: |
docker buildx imagetools create -t "${REGISTRY_NAME}/${REPOSITORY}:${TAG_PR}" "${REGISTRY_NAME}/${REPOSITORY}:${TAG_OLD}"
docker buildx imagetools create -t "${REGISTRY_NAME}/${REPOSITORY}:${TAG_COMMIT}" "${REGISTRY_NAME}/${REPOSITORY}:${TAG_OLD}"
machine-learning:
name: Build and Push ML
needs: pre-job
if: ${{ fromJSON(needs.pre-job.outputs.should_run).machine-learning == true }}
strategy:
fail-fast: false
matrix:
include: *ml-variants
uses: immich-app/devtools/.github/workflows/multi-runner-build.yml@4d420cf8e5ea499f99b2c2849ff9a219d5f7b178 # multi-runner-build-workflow-v4.0.0
permissions:
contents: read
actions: read
packages: write
with:
image: ${{ matrix.image }}
context: machine-learning
dockerfile: machine-learning/Dockerfile
platforms: ${{ matrix.platforms }}
runner-mapping: ${{ matrix.runner-mapping }}
suffixes: ${{ matrix.suffixes }}
tags: &tag-rules |
type=ref,event=branch
type=ref,event=pr
type=sha,format=long,prefix=commit-
type=semver,pattern={{version}},prefix=v
type=semver,pattern={{major}},prefix=v,enable=${{ needs.pre-job.outputs.highest-in-line == 'true' }}
type=match,pattern=v(\d+),group=1,prefix=v,suffix=-rc,enable=${{ github.event.release.prerelease == true && needs.pre-job.outputs.highest-in-line == 'true' }}
type=raw,value=release,enable=${{ github.event_name == 'release' && github.event.release.prerelease == false && needs.pre-job.outputs.highest-overall == 'true' }}
build-args: |
DEVICE=${{ matrix.device }}
server:
name: Build and Push Server
needs: pre-job
if: ${{ fromJSON(needs.pre-job.outputs.should_run).server == true }}
uses: immich-app/devtools/.github/workflows/multi-runner-build.yml@4d420cf8e5ea499f99b2c2849ff9a219d5f7b178 # multi-runner-build-workflow-v4.0.0
permissions:
contents: read
actions: read
packages: write
with:
image: immich-server
context: .
dockerfile: server/Dockerfile
tags: *tag-rules
build-args: |
DEVICE=cpu
mirror:
name: Mirror to Docker Hub
needs: [pre-job, machine-learning, server]
if: ${{ github.event_name == 'release' && github.event.release.prerelease == false }}
permissions:
packages: read
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
# Slightly hacky; we reuse the ml matrix but tack on immich-server too
image: [immich-server]
include: *ml-variants
env:
IMAGE: ${{ matrix.image }}
SUFFIX: ${{ matrix.suffixes }}
steps:
- name: Login to GitHub Container Registry
uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4.6.0
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Login to Docker Hub
uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4.6.0
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Generate docker image tags
id: meta
uses: docker/metadata-action@dc802804100637a589fabce1cb79ff13a1411302 # v6.2.0
with:
flavor: |
latest=false
images: ${{ env.GHCR_NAMESPACE }}/${{ env.IMAGE }}
tags: *tag-rules
- name: Mirror tags to Docker Hub
env:
TAGS: ${{ steps.meta.outputs.tags }}
run: |
for tag in ${TAGS}; do
version="${tag##*:}"
docker buildx imagetools create \
-t "${DOCKERHUB_NAMESPACE}/${IMAGE}:${version}${SUFFIX}" \
"${GHCR_NAMESPACE}/${IMAGE}:${version}${SUFFIX}"
done
success-check-server:
name: Docker Build & Push Server Success
needs: [server, retag_server, mirror]
permissions: {}
runs-on: ubuntu-latest
if: always()
steps:
- uses: immich-app/devtools/actions/success-check@81113db03f6d743efee81e0058c0b43f6cd6f36d # success-check-action-v0.0.6
with:
needs: ${{ toJSON(needs) }}
success-check-ml:
name: Docker Build & Push ML Success
needs: [machine-learning, retag_ml, mirror]
permissions: {}
runs-on: ubuntu-latest
if: always()
steps:
- uses: immich-app/devtools/actions/success-check@81113db03f6d743efee81e0058c0b43f6cd6f36d # success-check-action-v0.0.6
with:
needs: ${{ toJSON(needs) }}