From 09a82ea73b90bb4469994ed02c5c7c778ce90226 Mon Sep 17 00:00:00 2001 From: Priveetee Date: Mon, 31 Aug 2026 14:19:48 +0200 Subject: [PATCH 1/6] ci: route workflows to R730 runners --- .github/workflows/ci.yml | 2 +- .github/workflows/coverage.yml | 2 +- .github/workflows/docker.yml | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f0e65a0..4a943f5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,7 +15,7 @@ concurrency: jobs: go: - runs-on: ${{ github.event_name == 'pull_request' && 'ubuntu-24.04' || fromJSON('["self-hosted","Linux","X64","arko","downloader"]') }} + runs-on: ${{ github.event_name == 'pull_request' && 'ubuntu-24.04' || fromJSON('["self-hosted","Linux","X64","r730","downloader"]') }} permissions: contents: read steps: diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 4e0297f..783f37c 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -15,7 +15,7 @@ concurrency: jobs: coverage: - runs-on: ${{ github.event_name == 'pull_request' && 'ubuntu-24.04' || fromJSON('["self-hosted","Linux","X64","arko","downloader"]') }} + runs-on: ${{ github.event_name == 'pull_request' && 'ubuntu-24.04' || fromJSON('["self-hosted","Linux","X64","r730","downloader"]') }} permissions: contents: read steps: diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index f3d53d8..63642aa 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -20,7 +20,7 @@ concurrency: jobs: build-and-push: - runs-on: [self-hosted, Linux, X64, arko, downloader] + runs-on: [self-hosted, Linux, X64, r730, downloader] permissions: contents: read packages: write @@ -141,7 +141,7 @@ jobs: notify-orchestrator: needs: build-and-push if: github.ref_name == 'dev' || github.ref_name == 'main' || startsWith(github.ref, 'refs/tags/v') - runs-on: [self-hosted, Linux, X64, arko, downloader] + runs-on: [self-hosted, Linux, X64, r730, downloader] permissions: contents: read env: From f02d7b547ad1046f725c4daffab12febae226888 Mon Sep 17 00:00:00 2001 From: Priveetee Date: Mon, 31 Aug 2026 15:21:29 +0200 Subject: [PATCH 2/6] perf: parallelize multi-architecture image builds --- .github/actionlint.yaml | 1 + .github/workflows/docker.yml | 158 ++++++++++++++++++++++++++++------- 2 files changed, 128 insertions(+), 31 deletions(-) diff --git a/.github/actionlint.yaml b/.github/actionlint.yaml index 927074b..ce09d65 100644 --- a/.github/actionlint.yaml +++ b/.github/actionlint.yaml @@ -1,4 +1,5 @@ self-hosted-runner: labels: - arko + - r730 - downloader diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 63642aa..fb4782a 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -19,23 +19,20 @@ concurrency: cancel-in-progress: true jobs: - build-and-push: + prepare: runs-on: [self-hosted, Linux, X64, r730, downloader] permissions: contents: read - packages: write outputs: - digest: ${{ steps.build.outputs.digest }} + build-time: ${{ steps.build-info.outputs.build-time }} image: ${{ steps.build-info.outputs.image }} + labels: ${{ steps.meta.outputs.labels }} + metadata-json: ${{ steps.meta.outputs.json }} version: ${{ steps.build-info.outputs.version }} - steps: - name: Checkout uses: actions/checkout@v7 - - name: Isolate Docker credentials - run: echo "DOCKER_CONFIG=$RUNNER_TEMP/docker-config" >> "$GITHUB_ENV" - - name: Resolve build metadata id: build-info env: @@ -81,13 +78,6 @@ jobs: echo "build-time=$(date -u +'%Y-%m-%dT%H:%M:%SZ')" } >> "$GITHUB_OUTPUT" - - name: Log in to GitHub Container Registry - uses: docker/login-action@v4 - with: - registry: ${{ env.REGISTRY }} - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - - name: Extract metadata id: meta uses: docker/metadata-action@v6 @@ -104,7 +94,37 @@ jobs: type=raw,value=latest,enable=${{ github.ref_name == 'dev' }} type=raw,value=beta,enable=${{ github.ref_name == 'dev' }} + build-platform: + needs: prepare + runs-on: [self-hosted, Linux, X64, r730, downloader] + timeout-minutes: 30 + permissions: + contents: read + packages: write + strategy: + fail-fast: false + matrix: + include: + - platform: linux/amd64 + arch: amd64 + - platform: linux/arm64 + arch: arm64 + steps: + - name: Checkout + uses: actions/checkout@v7 + + - name: Isolate Docker credentials + run: echo "DOCKER_CONFIG=$RUNNER_TEMP/docker-config" >> "$GITHUB_ENV" + + - name: Log in to GitHub Container Registry + uses: docker/login-action@v4 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + - name: Set up QEMU + if: matrix.arch == 'arm64' uses: docker/setup-qemu-action@v4 with: platforms: arm64 @@ -113,33 +133,109 @@ jobs: - name: Set up Docker Buildx uses: docker/setup-buildx-action@v4 - - name: Build and push + - name: Build and push platform image id: build uses: docker/build-push-action@v7 with: context: . file: Dockerfile.wolfi build-args: | - BUILD_VERSION=${{ steps.build-info.outputs.version }} + BUILD_VERSION=${{ needs.prepare.outputs.version }} BUILD_REVISION=${{ github.sha }} - BUILD_TIME=${{ steps.build-info.outputs.build-time }} - platforms: linux/amd64,linux/arm64 - push: true - tags: ${{ steps.meta.outputs.tags }} - labels: ${{ steps.meta.outputs.labels }} - cache-from: type=gha - cache-to: type=gha,mode=max + BUILD_TIME=${{ needs.prepare.outputs.build-time }} + platforms: ${{ matrix.platform }} + labels: ${{ needs.prepare.outputs.labels }} + outputs: type=image,name=${{ needs.prepare.outputs.image }},push-by-digest=true,name-canonical=true,push=true + provenance: false + cache-from: type=gha,scope=downloader-${{ matrix.arch }} + cache-to: type=gha,mode=max,scope=downloader-${{ matrix.arch }} - name: Verify published FFmpeg runtime env: - IMAGE: ${{ steps.build-info.outputs.image }} + IMAGE: ${{ needs.prepare.outputs.image }} + DIGEST: ${{ steps.build.outputs.digest }} + run: | + docker pull "$IMAGE@$DIGEST" + docker run --rm --entrypoint ffmpeg "$IMAGE@$DIGEST" -version + + - name: Export digest + env: + DIGEST: ${{ steps.build.outputs.digest }} run: | - image="$IMAGE:sha-${GITHUB_SHA::7}" - docker pull "$image" - docker run --rm --entrypoint ffmpeg "$image" -version + digest_dir="$RUNNER_TEMP/downloader-digests" + rm -rf "$digest_dir" + mkdir -p "$digest_dir" + touch "$digest_dir/${DIGEST#sha256:}" + + - name: Upload digest + uses: actions/upload-artifact@v7 + with: + name: downloader-digest-${{ matrix.arch }}-${{ github.run_id }}-${{ github.run_attempt }} + path: ${{ runner.temp }}/downloader-digests/* + if-no-files-found: error + retention-days: 1 + + publish: + needs: [prepare, build-platform] + runs-on: [self-hosted, Linux, X64, r730, downloader] + timeout-minutes: 10 + permissions: + contents: read + packages: write + outputs: + digest: ${{ steps.manifest.outputs.digest }} + steps: + - name: Isolate Docker credentials + run: echo "DOCKER_CONFIG=$RUNNER_TEMP/docker-config" >> "$GITHUB_ENV" + + - name: Prepare digest directory + run: rm -rf "$RUNNER_TEMP/downloader-digests" + + - name: Download digests + uses: actions/download-artifact@v8 + with: + path: ${{ runner.temp }}/downloader-digests + pattern: downloader-digest-*-${{ github.run_id }}-${{ github.run_attempt }} + merge-multiple: true + + - name: Log in to GitHub Container Registry + uses: docker/login-action@v4 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v4 + + - name: Publish manifest list + id: manifest + env: + DIGEST_DIR: ${{ runner.temp }}/downloader-digests + IMAGE: ${{ needs.prepare.outputs.image }} + METADATA_JSON: ${{ needs.prepare.outputs.metadata-json }} + run: | + mapfile -t digests < <(find "$DIGEST_DIR" -maxdepth 1 -type f -printf '%f\n' | sort) + if [[ "${#digests[@]}" -ne 2 ]]; then + echo "Expected two platform digests, found ${#digests[@]}" + exit 1 + fi + mapfile -t tags < <(jq -r '.tags[]' <<< "$METADATA_JSON") + tag_args=() + for tag in "${tags[@]}"; do tag_args+=(--tag "$tag"); done + source_args=() + for digest in "${digests[@]}"; do source_args+=("$IMAGE@sha256:$digest"); done + docker buildx imagetools create "${tag_args[@]}" "${source_args[@]}" + manifest_json="$(docker buildx imagetools inspect "${tags[0]}" --format '{{json .Manifest}}')" + digest="$(jq -r '.digest' <<< "$manifest_json")" + if [[ "$digest" != sha256:* ]]; then + echo "Published manifest has no valid digest" + exit 1 + fi + echo "digest=$digest" >> "$GITHUB_OUTPUT" notify-orchestrator: - needs: build-and-push + needs: [prepare, publish] if: github.ref_name == 'dev' || github.ref_name == 'main' || startsWith(github.ref, 'refs/tags/v') runs-on: [self-hosted, Linux, X64, r730, downloader] permissions: @@ -149,9 +245,9 @@ jobs: steps: - name: Send image digest env: - DIGEST: ${{ needs.build-and-push.outputs.digest }} - IMAGE: ${{ needs.build-and-push.outputs.image }} - VERSION: ${{ needs.build-and-push.outputs.version }} + DIGEST: ${{ needs.publish.outputs.digest }} + IMAGE: ${{ needs.prepare.outputs.image }} + VERSION: ${{ needs.prepare.outputs.version }} run: | if [[ "$GITHUB_REF_NAME" == "dev" ]]; then channel="beta"; else channel="stable"; fi jq -n \ From a156c5cae859d5a1d06762589267454bebc28540 Mon Sep 17 00:00:00 2001 From: Priveetee Date: Mon, 31 Aug 2026 20:21:43 +0200 Subject: [PATCH 3/6] fix: verify downloader image on target platform --- .github/workflows/docker.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index fb4782a..87a6d9b 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -154,9 +154,10 @@ jobs: env: IMAGE: ${{ needs.prepare.outputs.image }} DIGEST: ${{ steps.build.outputs.digest }} + PLATFORM: ${{ matrix.platform }} run: | - docker pull "$IMAGE@$DIGEST" - docker run --rm --entrypoint ffmpeg "$IMAGE@$DIGEST" -version + docker pull --platform "$PLATFORM" "$IMAGE@$DIGEST" + docker run --rm --platform "$PLATFORM" --entrypoint ffmpeg "$IMAGE@$DIGEST" -version - name: Export digest env: From b8a20724fe9fe92c4c85fcf91138fef4ffbd5f1d Mon Sep 17 00:00:00 2001 From: Priveetee Date: Mon, 31 Aug 2026 20:36:46 +0200 Subject: [PATCH 4/6] fix: validate downloader arm image without emulation --- .github/workflows/docker.yml | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 87a6d9b..3e17132 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -155,9 +155,18 @@ jobs: IMAGE: ${{ needs.prepare.outputs.image }} DIGEST: ${{ steps.build.outputs.digest }} PLATFORM: ${{ matrix.platform }} + ARCH: ${{ matrix.arch }} run: | docker pull --platform "$PLATFORM" "$IMAGE@$DIGEST" - docker run --rm --platform "$PLATFORM" --entrypoint ffmpeg "$IMAGE@$DIGEST" -version + if [[ "$ARCH" == "amd64" ]]; then + docker run --rm --platform "$PLATFORM" --entrypoint ffmpeg "$IMAGE@$DIGEST" -version + else + container_id="$(docker create --platform "$PLATFORM" --entrypoint ffmpeg "$IMAGE@$DIGEST")" + trap 'docker rm "$container_id" >/dev/null' EXIT + ffmpeg_path="$RUNNER_TEMP/ffmpeg-$ARCH" + docker cp "$container_id:/usr/bin/ffmpeg" "$ffmpeg_path" + readelf -h "$ffmpeg_path" | grep -q 'Machine:.*AArch64' + fi - name: Export digest env: From 2120ae26472afb72049d05a8e1da27040dc984bc Mon Sep 17 00:00:00 2001 From: Tax_Tux <138765817+Priveetee@users.noreply.github.com> Date: Mon, 31 Aug 2026 21:31:05 +0200 Subject: [PATCH 5/6] chore: benchmark dev runners From 37d6e790695292ff0af45301fd7ed4338618d743 Mon Sep 17 00:00:00 2001 From: Priveetee Date: Mon, 7 Sep 2026 14:48:53 +0200 Subject: [PATCH 6/6] chore: prepare downloader 1.8.0 --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index bd8bf88..27f9cd3 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.7.0 +1.8.0