Skip to content

修复字幕翻译窗口暗色模式样式,保持窗口外层透明,同时让字幕条运行时背景正确使用暗色渐变 (#1657) #365

修复字幕翻译窗口暗色模式样式,保持窗口外层透明,同时让字幕条运行时背景正确使用暗色渐变 (#1657)

修复字幕翻译窗口暗色模式样式,保持窗口外层透明,同时让字幕条运行时背景正确使用暗色渐变 (#1657) #365

name: Docker Build
on:
push:
branches:
- main # 主分支有新 commit 时触发(合并 PR 后的 squash commit 在这里验)
tags:
- 'v*' # 匹配 v 开头的标签,例如 v1.0.0
paths-ignore:
- '**.md'
- 'docs/**'
- '.gitignore'
# PR 触发刻意不开:单个 PR 的多次 commit 会触发多次 multi-arch build,
# 200 PR/月 × N commit 占满 runner 队列;让 squash 进 main 的那次 push 来验证即可。
# 单 PR 想手动验,用 workflow_dispatch + ci 模式即可。
workflow_dispatch:
inputs:
build_mode:
description: '构建模式'
type: choice
options:
- ci
- custom
default: 'ci'
required: true
version:
description: '自定义版本号 (仅在 custom 模式下生效)'
required: false
default: ''
skip_dockerhub:
description: '跳过 Docker Hub 推送 (仅推送到 GHCR)'
type: boolean
required: false
default: false
# Concurrency configuration: queue Docker builds to avoid parallel runs
# - Same group for all triggers to ensure serialization
# - cancel-in-progress: false to wait for current build to complete
# - PR builds use separate group to not block main branch builds
concurrency:
group: ${{ github.workflow }}-${{ github.ref == 'refs/heads/main' && 'main' || github.head_ref || github.ref }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
env:
REGISTRY_GHCR: ghcr.io
IMAGE_NAME: project-n-e-k-o/n.e.k.o
# Embedding model pin (kept identical to .github/workflows/build-desktop.yml and
# docker/Dockerfile{,.full} ARG defaults). The weights are pre-fetched on the
# native runner and cached so the Docker build never hits huggingface.co — see
# the "Prepare embedding model" steps below and Dockerfile step 6b.
EMBEDDING_MODEL_REPO: jinaai/jina-embeddings-v5-text-nano-retrieval
EMBEDDING_MODEL_PROFILE_ID: local-text-retrieval-v1
EMBEDDING_MODEL_REVISION: ac5d898c8d382b17167c33e5c8af644a3519b47d
jobs:
# ============================================================================
# Job 1: Calculate version (shared by all build jobs)
# ============================================================================
calculate-version:
runs-on: ubuntu-latest
outputs:
image_version: ${{ steps.version_calc.outputs.VERSION }}
skip_dockerhub: ${{ steps.calc_skip.outputs.SKIP_DOCKERHUB }}
is_main_commit: ${{ steps.calc_is_main.outputs.IS_MAIN_COMMIT }}
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Calculate is_main_commit flag
id: calc_is_main
run: |
# True for: main branch push OR manual dispatch from main branch in CI mode
# 必须同时锁定 ref==main,否则在 feature branch 上手动 dispatch ci 模式
# 会让 ci-standard/ci-full 等共享别名被未合并代码覆盖
if [[ "$GITHUB_REF" == refs/heads/main ]] && [[ "$GITHUB_EVENT_NAME" == "push" ]]; then
echo "IS_MAIN_COMMIT=true" >> $GITHUB_OUTPUT
elif [[ "$GITHUB_EVENT_NAME" == "workflow_dispatch" ]] && [[ "${{ github.event.inputs.build_mode }}" == "ci" ]] && [[ "$GITHUB_REF" == refs/heads/main ]]; then
echo "IS_MAIN_COMMIT=true" >> $GITHUB_OUTPUT
else
echo "IS_MAIN_COMMIT=false" >> $GITHUB_OUTPUT
fi
- name: Calculate skip_dockerhub flag
id: calc_skip
run: |
# 策略:Docker Hub 只发 release(tag push)和手动 dispatch(按 input)。
# 主线 commit / PR(如果重新启用)只推 GHCR,避免主线滚动版污染对外 channel。
if [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then
echo "SKIP_DOCKERHUB=${{ github.event.inputs.skip_dockerhub || 'false' }}" >> $GITHUB_OUTPUT
elif [[ "$GITHUB_REF" == refs/tags/* ]]; then
# Release tag: 推 Docker Hub 作为对外公开发布 channel
echo "SKIP_DOCKERHUB=false" >> $GITHUB_OUTPUT
else
# 其他(main push / PR 等): 只推 GHCR
echo "SKIP_DOCKERHUB=true" >> $GITHUB_OUTPUT
fi
- name: Calculate Docker image version
id: version_calc
run: |
# 策略1: 如果是由 git tag 触发,则使用 tag 作为版本号 (去掉 'v' 前缀)
if [[ "$GITHUB_REF" == refs/tags/* ]]; then
VERSION=${GITHUB_REF#refs/tags/v}
echo "版本号来源于Git标签: $VERSION"
# 策略2: 如果手动触发且选择 CI 模式,使用 ci-{commit hash} 格式
elif [[ "$GITHUB_EVENT_NAME" == "workflow_dispatch" ]] && [[ "${{ github.event.inputs.build_mode }}" == "ci" ]]; then
COMMIT_SHORT=$(git rev-parse --short HEAD)
VERSION="ci-${COMMIT_SHORT}"
echo "版本号来源于CI模式(手动触发): $VERSION"
# 策略3: 如果手动触发且选择 custom 模式,使用自定义版本号
elif [[ "$GITHUB_EVENT_NAME" == "workflow_dispatch" ]] && [[ "${{ github.event.inputs.build_mode }}" == "custom" ]]; then
VERSION="${{ github.event.inputs.version }}"
if [ -z "$VERSION" ] || [ "$VERSION" = "" ]; then
COMMIT_SHORT=$(git rev-parse --short HEAD)
DATE=$(date +%Y%m%d)
VERSION="${DATE}-${COMMIT_SHORT}"
echo "版本号为自动生成(未提供自定义版本): $VERSION"
else
echo "版本号来源于手动输入: $VERSION"
fi
# 策略4: 如果是 PR 触发,使用 pr-{number}-ci 标签
elif [[ "$GITHUB_EVENT_NAME" == "pull_request" ]]; then
PR_NUMBER=${{ github.event.pull_request.number }}
VERSION="pr-${PR_NUMBER}-ci"
echo "版本号来源于PR编号: $VERSION"
# 策略5: 如果是 main 分支 commit,使用 ci-{commit hash} 格式
elif [[ "$GITHUB_REF" == refs/heads/main ]]; then
COMMIT_SHORT=$(git rev-parse --short HEAD)
VERSION="ci-${COMMIT_SHORT}"
echo "版本号来源于main分支commit: $VERSION"
# 策略6: 其他情况,生成基于日期和提交哈希的版本号
else
COMMIT_SHORT=$(git rev-parse --short HEAD)
DATE=$(date +%Y%m%d)
VERSION="${DATE}-${COMMIT_SHORT}"
echo "版本号为自动生成: $VERSION"
fi
echo "VERSION=$VERSION" >> $GITHUB_OUTPUT
# ============================================================================
# Job 2: Build and push STANDARD version (parallel with full version)
# ============================================================================
build-standard:
needs: calculate-version
# 仅在上游仓库运行:fork 上的 push / workflow_dispatch 用其 GITHUB_TOKEN 无法写入上游 GHCR namespace,会必然失败
if: github.repository == 'Project-N-E-K-O/N.E.K.O' && (github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository)
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
outputs:
skipped: ${{ steps.check-dockerfile.outputs.skipped }}
strategy:
matrix:
platform: [linux/amd64, linux/arm64]
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
# Pre-fetch the embedding weights on the native runner and cache them by
# revision, so the (QEMU-emulated, throttle-prone) Docker build below never
# touches huggingface.co. Cache hit -> the downloader is a no-op; only a
# cold cache (revision bump / 7-day eviction) actually downloads, natively,
# once. The weights ride into the build via the context (Dockerfile 6b).
# Standard image ships int8 only to stay lightweight.
- name: Cache embedding model weights (int8)
uses: actions/cache@v4
with:
path: data/embedding_models
key: embedding-model-${{ env.EMBEDDING_MODEL_REVISION }}-int8
- name: Prepare embedding model assets (int8)
run: |
python3 scripts/prepare_embedding_model.py \
--repo "$EMBEDDING_MODEL_REPO" \
--revision "$EMBEDDING_MODEL_REVISION" \
--profile-id "$EMBEDDING_MODEL_PROFILE_ID" \
--output-root data/embedding_models \
--variant int8
- name: Check if Dockerfile exists
id: check-dockerfile
run: |
if [ -f "./docker/Dockerfile" ]; then
echo "skipped=false" >> $GITHUB_OUTPUT
echo "✅ docker/Dockerfile found, proceeding with standard build"
else
echo "skipped=true" >> $GITHUB_OUTPUT
echo "⚠️ docker/Dockerfile not found, skipping standard build"
fi
- name: Set up QEMU
if: steps.check-dockerfile.outputs.skipped != 'true'
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
if: steps.check-dockerfile.outputs.skipped != 'true'
uses: docker/setup-buildx-action@v3
- name: Log in to GHCR
if: steps.check-dockerfile.outputs.skipped != 'true'
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Check Docker Hub credentials
id: check_dockerhub
if: steps.check-dockerfile.outputs.skipped != 'true' && needs.calculate-version.outputs.skip_dockerhub != 'true'
run: |
if [ -n "${{ secrets.DOCKERHUB_USERNAME }}" ] && [ -n "${{ secrets.DOCKERHUB_TOKEN }}" ]; then
echo "has_credentials=true" >> $GITHUB_OUTPUT
echo "✅ Docker Hub credentials found"
else
echo "has_credentials=false" >> $GITHUB_OUTPUT
echo "⚠️ Docker Hub credentials not configured, skipping Docker Hub push"
echo " To enable Docker Hub push, set DOCKERHUB_USERNAME and DOCKERHUB_TOKEN in repository secrets"
fi
- name: Log in to Docker Hub
if: steps.check-dockerfile.outputs.skipped != 'true' && needs.calculate-version.outputs.skip_dockerhub != 'true' && steps.check_dockerhub.outputs.has_credentials == 'true'
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Extract metadata for Docker (GHCR only)
if: steps.check-dockerfile.outputs.skipped != 'true' && (needs.calculate-version.outputs.skip_dockerhub == 'true' || (needs.calculate-version.outputs.skip_dockerhub != 'true' && steps.check_dockerhub.outputs.has_credentials != 'true'))
id: meta_ghcr
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY_GHCR }}/${{ env.IMAGE_NAME }}
flavor: |
suffix=-${{ matrix.platform }}
tags: |
# PR builds: pr-{number}-ci-standard-linux-amd64/arm64 AND pr-ci-standard-linux-amd64/arm64
type=raw,value=${{ needs.calculate-version.outputs.image_version }}-standard,enable=${{ startsWith(needs.calculate-version.outputs.image_version, 'pr-') }}
type=raw,value=pr-ci-standard,enable=${{ startsWith(needs.calculate-version.outputs.image_version, 'pr-') }}
# CI builds: ci-{hash}-standard-linux-amd64/arm64 AND ci-standard-linux-amd64/arm64
type=raw,value=${{ needs.calculate-version.outputs.image_version }}-standard,enable=${{ startsWith(needs.calculate-version.outputs.image_version, 'ci-') }}
type=raw,value=ci-standard,enable=${{ startsWith(needs.calculate-version.outputs.image_version, 'ci-') }}
# Other builds (manual/tag): use version as-is
type=raw,value=${{ needs.calculate-version.outputs.image_version }}-standard,enable=${{ !startsWith(needs.calculate-version.outputs.image_version, 'pr-') && !startsWith(needs.calculate-version.outputs.image_version, 'ci-') }}
- name: Extract metadata for Docker (both registries)
if: steps.check-dockerfile.outputs.skipped != 'true' && needs.calculate-version.outputs.skip_dockerhub != 'true' && steps.check_dockerhub.outputs.has_credentials == 'true'
id: meta_both
uses: docker/metadata-action@v5
with:
images: |
${{ env.REGISTRY_GHCR }}/${{ env.IMAGE_NAME }}
${{ secrets.DOCKERHUB_USERNAME }}/n.e.k.o
flavor: |
suffix=-${{ matrix.platform }}
tags: |
# PR builds: pr-{number}-ci-standard-linux-amd64/arm64 AND pr-ci-standard-linux-amd64/arm64
type=raw,value=${{ needs.calculate-version.outputs.image_version }}-standard,enable=${{ startsWith(needs.calculate-version.outputs.image_version, 'pr-') }}
type=raw,value=pr-ci-standard,enable=${{ startsWith(needs.calculate-version.outputs.image_version, 'pr-') }}
# CI builds: ci-{hash}-standard-linux-amd64/arm64 AND ci-standard-linux-amd64/arm64
type=raw,value=${{ needs.calculate-version.outputs.image_version }}-standard,enable=${{ startsWith(needs.calculate-version.outputs.image_version, 'ci-') }}
type=raw,value=ci-standard,enable=${{ startsWith(needs.calculate-version.outputs.image_version, 'ci-') }}
# Other builds (manual/tag): use version as-is
type=raw,value=${{ needs.calculate-version.outputs.image_version }}-standard,enable=${{ !startsWith(needs.calculate-version.outputs.image_version, 'pr-') && !startsWith(needs.calculate-version.outputs.image_version, 'ci-') }}
- name: Build and push standard image
if: steps.check-dockerfile.outputs.skipped != 'true'
uses: docker/build-push-action@v5
with:
context: .
file: ./docker/Dockerfile
platforms: ${{ matrix.platform }}
push: true
build-args: |
EMBEDDING_MODEL_REPO=${{ env.EMBEDDING_MODEL_REPO }}
EMBEDDING_MODEL_REVISION=${{ env.EMBEDDING_MODEL_REVISION }}
EMBEDDING_MODEL_PROFILE_ID=${{ env.EMBEDDING_MODEL_PROFILE_ID }}
tags: ${{ steps.meta_ghcr.outputs.tags || steps.meta_both.outputs.tags }}
labels: ${{ steps.meta_ghcr.outputs.labels || steps.meta_both.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
# ============================================================================
# Job 3: Build and push FULL version (parallel with standard version)
# ============================================================================
build-full:
needs: calculate-version
# 仅在上游仓库运行:fork 上的 push / workflow_dispatch 用其 GITHUB_TOKEN 无法写入上游 GHCR namespace,会必然失败
if: github.repository == 'Project-N-E-K-O/N.E.K.O' && (github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository)
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
strategy:
matrix:
platform: [linux/amd64, linux/arm64]
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
# Pre-fetch the embedding weights on the native runner and cache them by
# revision, so the (QEMU-emulated, throttle-prone) Docker build below never
# touches huggingface.co. Cache hit -> the downloader is a no-op; only a
# cold cache (revision bump / 7-day eviction) actually downloads, natively,
# once. The weights ride into the build via the context (Dockerfile.full
# 6b). Full image bundles both int8 and fp32.
- name: Cache embedding model weights (both)
uses: actions/cache@v4
with:
path: data/embedding_models
key: embedding-model-${{ env.EMBEDDING_MODEL_REVISION }}-both
- name: Prepare embedding model assets (both)
run: |
python3 scripts/prepare_embedding_model.py \
--repo "$EMBEDDING_MODEL_REPO" \
--revision "$EMBEDDING_MODEL_REVISION" \
--profile-id "$EMBEDDING_MODEL_PROFILE_ID" \
--output-root data/embedding_models \
--variant both
- 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 GHCR
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Check Docker Hub credentials
id: check_dockerhub
if: needs.calculate-version.outputs.skip_dockerhub != 'true'
run: |
if [ -n "${{ secrets.DOCKERHUB_USERNAME }}" ] && [ -n "${{ secrets.DOCKERHUB_TOKEN }}" ]; then
echo "has_credentials=true" >> $GITHUB_OUTPUT
echo "✅ Docker Hub credentials found"
else
echo "has_credentials=false" >> $GITHUB_OUTPUT
echo "⚠️ Docker Hub credentials not configured, skipping Docker Hub push"
echo " To enable Docker Hub push, set DOCKERHUB_USERNAME and DOCKERHUB_TOKEN in repository secrets"
fi
- name: Log in to Docker Hub
if: needs.calculate-version.outputs.skip_dockerhub != 'true' && steps.check_dockerhub.outputs.has_credentials == 'true'
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Extract metadata for Docker (GHCR only)
if: needs.calculate-version.outputs.skip_dockerhub == 'true' || (needs.calculate-version.outputs.skip_dockerhub != 'true' && steps.check_dockerhub.outputs.has_credentials != 'true')
id: meta_ghcr
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY_GHCR }}/${{ env.IMAGE_NAME }}
flavor: |
suffix=-${{ matrix.platform }}
tags: |
# PR builds: pr-{number}-ci-full-linux-amd64/arm64 AND pr-ci-full-linux-amd64/arm64
type=raw,value=${{ needs.calculate-version.outputs.image_version }}-full,enable=${{ startsWith(needs.calculate-version.outputs.image_version, 'pr-') }}
type=raw,value=pr-ci-full,enable=${{ startsWith(needs.calculate-version.outputs.image_version, 'pr-') }}
# CI builds: ci-{hash}-full-linux-amd64/arm64 AND ci-full-linux-amd64/arm64
type=raw,value=${{ needs.calculate-version.outputs.image_version }}-full,enable=${{ startsWith(needs.calculate-version.outputs.image_version, 'ci-') }}
type=raw,value=ci-full,enable=${{ startsWith(needs.calculate-version.outputs.image_version, 'ci-') }}
# Other builds (manual/tag): use version as-is
type=raw,value=${{ needs.calculate-version.outputs.image_version }}-full,enable=${{ !startsWith(needs.calculate-version.outputs.image_version, 'pr-') && !startsWith(needs.calculate-version.outputs.image_version, 'ci-') }}
- name: Extract metadata for Docker (both registries)
if: needs.calculate-version.outputs.skip_dockerhub != 'true' && steps.check_dockerhub.outputs.has_credentials == 'true'
id: meta_both
uses: docker/metadata-action@v5
with:
images: |
${{ env.REGISTRY_GHCR }}/${{ env.IMAGE_NAME }}
${{ secrets.DOCKERHUB_USERNAME }}/n.e.k.o
flavor: |
suffix=-${{ matrix.platform }}
tags: |
# PR builds: pr-{number}-ci-full-linux-amd64/arm64 AND pr-ci-full-linux-amd64/arm64
type=raw,value=${{ needs.calculate-version.outputs.image_version }}-full,enable=${{ startsWith(needs.calculate-version.outputs.image_version, 'pr-') }}
type=raw,value=pr-ci-full,enable=${{ startsWith(needs.calculate-version.outputs.image_version, 'pr-') }}
# CI builds: ci-{hash}-full-linux-amd64/arm64 AND ci-full-linux-amd64/arm64
type=raw,value=${{ needs.calculate-version.outputs.image_version }}-full,enable=${{ startsWith(needs.calculate-version.outputs.image_version, 'ci-') }}
type=raw,value=ci-full,enable=${{ startsWith(needs.calculate-version.outputs.image_version, 'ci-') }}
# Other builds (manual/tag): use version as-is
type=raw,value=${{ needs.calculate-version.outputs.image_version }}-full,enable=${{ !startsWith(needs.calculate-version.outputs.image_version, 'pr-') && !startsWith(needs.calculate-version.outputs.image_version, 'ci-') }}
- name: Build and push full image
uses: docker/build-push-action@v5
with:
context: .
file: ./docker/Dockerfile.full
platforms: ${{ matrix.platform }}
push: true
build-args: |
EMBEDDING_MODEL_REPO=${{ env.EMBEDDING_MODEL_REPO }}
EMBEDDING_MODEL_REVISION=${{ env.EMBEDDING_MODEL_REVISION }}
EMBEDDING_MODEL_PROFILE_ID=${{ env.EMBEDDING_MODEL_PROFILE_ID }}
tags: ${{ steps.meta_ghcr.outputs.tags || steps.meta_both.outputs.tags }}
labels: ${{ steps.meta_ghcr.outputs.labels || steps.meta_both.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
# ============================================================================
# Job 4: Create multi-arch manifests (runs after both versions are built)
# ============================================================================
create-manifests:
needs: [calculate-version, build-standard, build-full]
if: github.repository == 'Project-N-E-K-O/N.E.K.O' && (github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository) && always() && needs.build-full.result == 'success'
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- name: Log in to GHCR
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Check Docker Hub credentials
id: check_dockerhub
if: needs.calculate-version.outputs.skip_dockerhub != 'true'
run: |
if [ -n "${{ secrets.DOCKERHUB_USERNAME }}" ] && [ -n "${{ secrets.DOCKERHUB_TOKEN }}" ]; then
echo "has_credentials=true" >> $GITHUB_OUTPUT
echo "✅ Docker Hub credentials found"
else
echo "has_credentials=false" >> $GITHUB_OUTPUT
echo "⚠️ Docker Hub credentials not configured, skipping Docker Hub manifest push"
fi
- name: Log in to Docker Hub
if: needs.calculate-version.outputs.skip_dockerhub != 'true' && steps.check_dockerhub.outputs.has_credentials == 'true'
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Create and push multi-arch manifest for standard version (GHCR)
if: needs.build-standard.outputs.skipped != 'true'
run: |
VERSION=${{ needs.calculate-version.outputs.image_version }}
docker buildx imagetools create \
-t ghcr.io/${{ env.IMAGE_NAME }}:${VERSION}-standard \
ghcr.io/${{ env.IMAGE_NAME }}:${VERSION}-standard-linux-amd64 \
ghcr.io/${{ env.IMAGE_NAME }}:${VERSION}-standard-linux-arm64
- name: Create and push multi-arch manifest for standard version (DockerHub)
if: needs.build-standard.outputs.skipped != 'true' && needs.calculate-version.outputs.skip_dockerhub != 'true' && steps.check_dockerhub.outputs.has_credentials == 'true'
run: |
VERSION=${{ needs.calculate-version.outputs.image_version }}
docker buildx imagetools create \
-t ${{ secrets.DOCKERHUB_USERNAME }}/n.e.k.o:${VERSION}-standard \
${{ secrets.DOCKERHUB_USERNAME }}/n.e.k.o:${VERSION}-standard-linux-amd64 \
${{ secrets.DOCKERHUB_USERNAME }}/n.e.k.o:${VERSION}-standard-linux-arm64
- name: Create and push multi-arch manifest for full version (GHCR)
run: |
VERSION=${{ needs.calculate-version.outputs.image_version }}
docker buildx imagetools create \
-t ghcr.io/${{ env.IMAGE_NAME }}:${VERSION}-full \
ghcr.io/${{ env.IMAGE_NAME }}:${VERSION}-full-linux-amd64 \
ghcr.io/${{ env.IMAGE_NAME }}:${VERSION}-full-linux-arm64
- name: Create and push multi-arch manifest for full version (DockerHub)
if: needs.calculate-version.outputs.skip_dockerhub != 'true' && steps.check_dockerhub.outputs.has_credentials == 'true'
run: |
VERSION=${{ needs.calculate-version.outputs.image_version }}
docker buildx imagetools create \
-t ${{ secrets.DOCKERHUB_USERNAME }}/n.e.k.o:${VERSION}-full \
${{ secrets.DOCKERHUB_USERNAME }}/n.e.k.o:${VERSION}-full-linux-amd64 \
${{ secrets.DOCKERHUB_USERNAME }}/n.e.k.o:${VERSION}-full-linux-arm64
- name: Create and push CI short tags - standard (GHCR)
if: needs.calculate-version.outputs.is_main_commit == 'true' && needs.build-standard.outputs.skipped != 'true'
run: |
VERSION=${{ needs.calculate-version.outputs.image_version }}
# GHCR - ci-standard (without hash)
docker buildx imagetools create \
-t ghcr.io/${{ env.IMAGE_NAME }}:ci-standard \
ghcr.io/${{ env.IMAGE_NAME }}:${VERSION}-standard-linux-amd64 \
ghcr.io/${{ env.IMAGE_NAME }}:${VERSION}-standard-linux-arm64
- name: Create and push CI short tags - full (GHCR)
if: needs.calculate-version.outputs.is_main_commit == 'true'
run: |
VERSION=${{ needs.calculate-version.outputs.image_version }}
# GHCR - ci-full (without hash)
docker buildx imagetools create \
-t ghcr.io/${{ env.IMAGE_NAME }}:ci-full \
ghcr.io/${{ env.IMAGE_NAME }}:${VERSION}-full-linux-amd64 \
ghcr.io/${{ env.IMAGE_NAME }}:${VERSION}-full-linux-arm64
- name: Create and push CI short tags - standard (DockerHub)
if: needs.calculate-version.outputs.is_main_commit == 'true' && needs.build-standard.outputs.skipped != 'true' && needs.calculate-version.outputs.skip_dockerhub != 'true' && steps.check_dockerhub.outputs.has_credentials == 'true'
run: |
VERSION=${{ needs.calculate-version.outputs.image_version }}
# DockerHub - ci-standard (without hash)
docker buildx imagetools create \
-t ${{ secrets.DOCKERHUB_USERNAME }}/n.e.k.o:ci-standard \
${{ secrets.DOCKERHUB_USERNAME }}/n.e.k.o:${VERSION}-standard-linux-amd64 \
${{ secrets.DOCKERHUB_USERNAME }}/n.e.k.o:${VERSION}-standard-linux-arm64
- name: Create and push CI short tags - full (DockerHub)
if: needs.calculate-version.outputs.is_main_commit == 'true' && needs.calculate-version.outputs.skip_dockerhub != 'true' && steps.check_dockerhub.outputs.has_credentials == 'true'
run: |
VERSION=${{ needs.calculate-version.outputs.image_version }}
# DockerHub - ci-full (without hash)
docker buildx imagetools create \
-t ${{ secrets.DOCKERHUB_USERNAME }}/n.e.k.o:ci-full \
${{ secrets.DOCKERHUB_USERNAME }}/n.e.k.o:${VERSION}-full-linux-amd64 \
${{ secrets.DOCKERHUB_USERNAME }}/n.e.k.o:${VERSION}-full-linux-arm64
- name: Create and push PR short tags - standard (GHCR)
if: github.event_name == 'pull_request' && needs.build-standard.outputs.skipped != 'true'
run: |
VERSION=${{ needs.calculate-version.outputs.image_version }}
# GHCR - pr-ci-standard (without PR number)
docker buildx imagetools create \
-t ghcr.io/${{ env.IMAGE_NAME }}:pr-ci-standard \
ghcr.io/${{ env.IMAGE_NAME }}:${VERSION}-standard-linux-amd64 \
ghcr.io/${{ env.IMAGE_NAME }}:${VERSION}-standard-linux-arm64
- name: Create and push PR short tags - full (GHCR)
if: github.event_name == 'pull_request'
run: |
VERSION=${{ needs.calculate-version.outputs.image_version }}
# GHCR - pr-ci-full (without PR number)
docker buildx imagetools create \
-t ghcr.io/${{ env.IMAGE_NAME }}:pr-ci-full \
ghcr.io/${{ env.IMAGE_NAME }}:${VERSION}-full-linux-amd64 \
ghcr.io/${{ env.IMAGE_NAME }}:${VERSION}-full-linux-arm64
- name: Create and push latest manifests - standard (GHCR)
if: github.event_name != 'pull_request' && needs.calculate-version.outputs.is_main_commit != 'true' && needs.build-standard.outputs.skipped != 'true'
run: |
VERSION=${{ needs.calculate-version.outputs.image_version }}
# GHCR - latest (traditional alias pointing to standard)
docker buildx imagetools create \
-t ghcr.io/${{ env.IMAGE_NAME }}:latest \
ghcr.io/${{ env.IMAGE_NAME }}:${VERSION}-standard-linux-amd64 \
ghcr.io/${{ env.IMAGE_NAME }}:${VERSION}-standard-linux-arm64
# GHCR - latest-standard
docker buildx imagetools create \
-t ghcr.io/${{ env.IMAGE_NAME }}:latest-standard \
ghcr.io/${{ env.IMAGE_NAME }}:${VERSION}-standard-linux-amd64 \
ghcr.io/${{ env.IMAGE_NAME }}:${VERSION}-standard-linux-arm64
- name: Create and push latest manifests - full (GHCR)
if: github.event_name != 'pull_request' && needs.calculate-version.outputs.is_main_commit != 'true'
run: |
VERSION=${{ needs.calculate-version.outputs.image_version }}
# GHCR - latest-full
docker buildx imagetools create \
-t ghcr.io/${{ env.IMAGE_NAME }}:latest-full \
ghcr.io/${{ env.IMAGE_NAME }}:${VERSION}-full-linux-amd64 \
ghcr.io/${{ env.IMAGE_NAME }}:${VERSION}-full-linux-arm64
- name: Create and push latest manifests - standard (DockerHub)
if: github.event_name != 'pull_request' && needs.calculate-version.outputs.is_main_commit != 'true' && needs.build-standard.outputs.skipped != 'true' && needs.calculate-version.outputs.skip_dockerhub != 'true' && steps.check_dockerhub.outputs.has_credentials == 'true'
run: |
VERSION=${{ needs.calculate-version.outputs.image_version }}
# DockerHub - latest (traditional alias pointing to standard)
docker buildx imagetools create \
-t ${{ secrets.DOCKERHUB_USERNAME }}/n.e.k.o:latest \
${{ secrets.DOCKERHUB_USERNAME }}/n.e.k.o:${VERSION}-standard-linux-amd64 \
${{ secrets.DOCKERHUB_USERNAME }}/n.e.k.o:${VERSION}-standard-linux-arm64
# DockerHub - latest-standard
docker buildx imagetools create \
-t ${{ secrets.DOCKERHUB_USERNAME }}/n.e.k.o:latest-standard \
${{ secrets.DOCKERHUB_USERNAME }}/n.e.k.o:${VERSION}-standard-linux-amd64 \
${{ secrets.DOCKERHUB_USERNAME }}/n.e.k.o:${VERSION}-standard-linux-arm64
- name: Create and push latest manifests - full (DockerHub)
if: github.event_name != 'pull_request' && needs.calculate-version.outputs.is_main_commit != 'true' && needs.calculate-version.outputs.skip_dockerhub != 'true' && steps.check_dockerhub.outputs.has_credentials == 'true'
run: |
VERSION=${{ needs.calculate-version.outputs.image_version }}
# DockerHub - latest-full
docker buildx imagetools create \
-t ${{ secrets.DOCKERHUB_USERNAME }}/n.e.k.o:latest-full \
${{ secrets.DOCKERHUB_USERNAME }}/n.e.k.o:${VERSION}-full-linux-amd64 \
${{ secrets.DOCKERHUB_USERNAME }}/n.e.k.o:${VERSION}-full-linux-arm64