Split up build workflow to use intermediate base image (#1647)
authorMarcel van der Veldt <m.vanderveldt@outlook.com>
Wed, 4 Sep 2024 10:07:14 +0000 (12:07 +0200)
committerGitHub <noreply@github.com>
Wed, 4 Sep 2024 10:07:14 +0000 (12:07 +0200)
.github/workflows/build-base-image.yml [new file with mode: 0644]
.github/workflows/release.yml
Dockerfile
Dockerfile.base [new file with mode: 0644]

diff --git a/.github/workflows/build-base-image.yml b/.github/workflows/build-base-image.yml
new file mode 100644 (file)
index 0000000..fa62a7d
--- /dev/null
@@ -0,0 +1,47 @@
+name: Build base image
+
+on:
+  workflow_dispatch:
+    inputs:
+      version:
+        description: "Version number"
+        required: true
+        type: string
+env:
+  PYTHON_VERSION: "3.11"
+
+jobs:
+  build-base-image:
+    name: Builds and pushes the Music Assistant base container to ghcr.io
+    runs-on: ubuntu-latest
+    permissions:
+      packages: write
+    steps:
+      - uses: actions/checkout@v4.1.4
+      - name: Download Widevine CDM client files from private repository
+        shell: bash
+        env:
+          TOKEN: ${{ secrets.PRIVILEGED_GITHUB_TOKEN }}
+        run: |
+          mkdir -p widevine_cdm && cd widevine_cdm
+          curl -OJ -H "Authorization: token ${TOKEN}" https://raw.githubusercontent.com/music-assistant/appvars/main/widevine_cdm_client/private_key.pem
+          curl -OJ -H "Authorization: token ${TOKEN}" https://raw.githubusercontent.com/music-assistant/appvars/main/widevine_cdm_client/client_id.bin
+      - name: Log in to the GitHub container registry
+        uses: docker/login-action@v3.3.0
+        with:
+          registry: ghcr.io
+          username: ${{ github.repository_owner }}
+          password: ${{ secrets.GITHUB_TOKEN }}
+      - name: Set up Docker Buildx
+        uses: docker/setup-buildx-action@v3.6.1
+
+      - name: Build and Push image
+        uses: docker/build-push-action@v6.7.0
+        with:
+          context: .
+          platforms: linux/amd64,linux/arm64
+          file: Dockerfile.base
+          tags: |-
+            ghcr.io/${{ github.repository_owner }}/base:${{ inputs.version }},
+            ghcr.io/${{ github.repository_owner }}/base:latest
+          push: true
index d88f519e6279fe7b57aa98feb616b7e5f5496e3e..9bec3e83f9c86008d2f7563b584e4cf6a7df4169 100644 (file)
@@ -3,14 +3,11 @@ name: Publish releases
 on:
   release:
     types: [published]
-  workflow_dispatch:
-    inputs:
-      dev_version:
-        description: 'DEV Build version (postfix)'
-        required: true
-        type: string
+
 env:
   PYTHON_VERSION: "3.11"
+  BASE_IMAGE_VERSION_STABLE: "1.0.0"
+  BASE_IMAGE_VERSION_BETA: "1.0.0"
 
 jobs:
   build-artifact:
@@ -23,28 +20,20 @@ jobs:
       - name: Get tag
         id: vars
         run: >-
-          if [[ -n "${{ inputs.dev_version }}" ]]; then
-            echo "tag=${inputs.dev_version}.dev$(git rev-parse --short "$GITHUB_SHA")" >> $GITHUB_OUTPUT
-          else
-            echo "tag=${GITHUB_REF#refs/*/}" >> $GITHUB_OUTPUT
-          fi  
+          echo "tag=${GITHUB_REF#refs/*/}" >> $GITHUB_OUTPUT
       - name: Validate version number
         run: >-
-          if [[ -n "${{ inputs.dev_version }}" ]]; then
-            echo "Skipping version validation for dev version via manual trigger"
-          else  
-            if [[ "${{ github.event.release.prerelease }}" == "true" ]]; then
-              if ! [[ "${{ steps.vars.outputs.tag }}" =~ "b" || "${{ steps.vars.outputs.tag }}" =~ "rc" ]]; then
-              echo "Pre-release: Tag is missing beta suffix (${{ steps.vars.outputs.tag }})"
-                exit 1
-              fi
-            else
-              if [[ "${{ steps.vars.outputs.tag }}" =~ "b" || "${{ steps.vars.outputs.tag }}" =~ "rc" ]]; then
-                echo "Release: Tag must not have a beta (or rc) suffix (${{ steps.vars.outputs.tag }})"
-                exit 1
-              fi
+          if [[ "${{ github.event.release.prerelease }}" == "true" ]]; then
+            if ! [[ "${{ steps.vars.outputs.tag }}" =~ "b" || "${{ steps.vars.outputs.tag }}" =~ "rc" ]]; then
+            echo "Pre-release: Tag is missing beta suffix (${{ steps.vars.outputs.tag }})"
+              exit 1
+            fi
+          else
+            if [[ "${{ steps.vars.outputs.tag }}" =~ "b" || "${{ steps.vars.outputs.tag }}" =~ "rc" ]]; then
+              echo "Release: Tag must not have a beta (or rc) suffix (${{ steps.vars.outputs.tag }})"
+              exit 1
             fi
-          fi  
+          fi
       - name: Set up Python ${{ env.PYTHON_VERSION }}
         uses: actions/setup-python@v5.2.0
         with:
@@ -73,10 +62,11 @@ jobs:
         with:
           name: release-dists
           path: dist/
-      
+
   pypi-publish:
+    name: Publish release to PyPI (stable releases only)
     runs-on: ubuntu-latest
-    if: ${{ inputs.dev_version }}
+    if: ${{ !github.event.release.prerelease }}
     needs: build-artifact
     steps:
       - name: Retrieve release distributions
@@ -97,24 +87,11 @@ jobs:
     runs-on: ubuntu-latest
     permissions:
       packages: write
-    needs: 
+    needs:
       - build-artifact
       - pypi-publish
-    if: |
-      always() &&
-      ((github.event.release.prerelease == false && needs.pypi-publish.result == 'success') || 
-      (github.event.release.prerelease == true && needs.pypi-publish.result == 'skipped') ||
-      (inputs.dev_version && needs.pypi-publish.result == 'skipped'))
     steps:
       - uses: actions/checkout@v4.1.4
-      - name: Download Widevine CDM client files from private repository
-        shell: bash
-        env:
-          TOKEN: ${{ secrets.PRIVILEGED_GITHUB_TOKEN }}
-        run: |
-          mkdir -p widevine_cdm && cd widevine_cdm
-          curl -OJ -H "Authorization: token ${TOKEN}" https://raw.githubusercontent.com/music-assistant/appvars/main/widevine_cdm_client/private_key.pem
-          curl -OJ -H "Authorization: token ${TOKEN}" https://raw.githubusercontent.com/music-assistant/appvars/main/widevine_cdm_client/client_id.bin
       - name: Retrieve release distributions
         uses: actions/download-artifact@v4
         with:
@@ -138,7 +115,7 @@ jobs:
           echo "major=${patch%.*.*}" >> $GITHUB_OUTPUT
       - name: Build and Push release
         uses: docker/build-push-action@v6.7.0
-        if: ${{ ! inputs.dev_version && github.event.release.prerelease == false }}
+        if: ${{ github.event.release.prerelease == false }}
         with:
           context: .
           platforms: linux/amd64,linux/arm64
@@ -150,10 +127,10 @@ jobs:
             ghcr.io/${{ github.repository_owner }}/server:stable,
             ghcr.io/${{ github.repository_owner }}/server:latest
           push: true
-          build-args: "MASS_VERSION=${{ needs.build-artifact.outputs.version }}"
+          build-args: "MASS_VERSION=${{ needs.build-artifact.outputs.version }},BASE_IMAGE_VERSION=${{env.BASE_IMAGE_VERSION_STABLE}}"
       - name: Build and Push pre-release
         uses: docker/build-push-action@v6.7.0
-        if: ${{ ! inputs.dev_version && github.event.release.prerelease == true }}
+        if: ${{ github.event.release.prerelease == true }}
         with:
           context: .
           platforms: linux/amd64,linux/arm64
@@ -162,20 +139,7 @@ jobs:
             ghcr.io/${{ github.repository_owner }}/server:${{ steps.tags.outputs.patch }},
             ghcr.io/${{ github.repository_owner }}/server:beta
           push: true
-          build-args: "MASS_VERSION=${{ needs.build-artifact.outputs.version }}"
-      - name: Build and Push dev-release
-        uses: docker/build-push-action@v6.7.0
-        if: inputs.dev_version
-        with:
-          context: .
-          platforms: linux/amd64,linux/arm64
-          file: Dockerfile
-          tags: |-
-            ghcr.io/${{ github.repository_owner }}/server:${{ needs.build-artifact.outputs.version }},
-            ghcr.io/${{ github.repository_owner }}/server:dev
-          push: true
-          build-args: |
-            MASS_VERSION=${{ needs.build-artifact.outputs.version }}
+          build-args: "MASS_VERSION=${{ needs.build-artifact.outputs.version }},BASE_IMAGE_VERSION=${{env.BASE_IMAGE_VERSION_BETA}}"
 
   release-notes-update:
     name: Updates the release notes and changelog
@@ -193,7 +157,7 @@ jobs:
     name: Updates the Addon repository with the new version
     needs:
       [
-        build-artifact,  
+        build-artifact,
         pypi-publish,
         build-and-push-container-image,
         release-notes-update,
index 0fde4109631de149522289b04ab37b2c939d43e6..a180546e2c990966b01bbab243d75e46e6b4176c 100644 (file)
@@ -1,48 +1,23 @@
 # syntax=docker/dockerfile:1
 
-FROM python:3.12-alpine3.20
+# FINAL docker image for music assistant server
+# This image is based on the base image and installs
+# the music assistant server from our built wheel on top.
 
-ARG MASS_VERSION
-ARG TARGETPLATFORM
-
-RUN set -x \
-    && apk add --no-cache \
-        ca-certificates \
-        jemalloc \
-        curl \
-        git \
-        wget \
-        tzdata \
-        sox \
-        cifs-utils \
-    # install ffmpeg from community repo
-    && apk add --no-cache ffmpeg --repository=https://dl-cdn.alpinelinux.org/alpine/v3.20/community \
-    # install snapcast from community repo
-    && apk add --no-cache snapcast --repository=https://dl-cdn.alpinelinux.org/alpine/v3.20/community \
-    # install libnfs from community repo
-    && apk add --no-cache libnfs --repository=https://dl-cdn.alpinelinux.org/alpine/v3.20/community \
-    # install openssl-dev (needed for airplay)
-    && apk add --no-cache openssl-dev
+ARG BASE_IMAGE_VERSION = "latest"
 
-# Copy widevine client files to container
-RUN mkdir -p /usr/local/bin/widevine_cdm
-COPY widevine_cdm/* /usr/local/bin/widevine_cdm/
+FROM ghcr.io/music-assistant/base:${BASE_IMAGE_VERSION}
 
-# Upgrade pip + Install uv
-RUN pip install --upgrade pip \
-    && pip install uv==0.2.27
+ARG MASS_VERSION
+ARG TARGETPLATFORM
 
-# Install Music Assistant from published wheel on PyPi
+# Install Music Assistant from prebuilt wheel
 RUN uv pip install \
     --system \
     --no-cache \
     --find-links "https://wheels.home-assistant.io/musllinux/" \
     dist/music_assistant-${MASS_VERSION}-py3-none-any.whl
 
-# Configure runtime environmental variables
-ENV LD_PRELOAD="/usr/lib/libjemalloc.so.2"
-ENV UV_SYSTEM_PYTHON="1"
-
 # Set some labels
 LABEL \
     org.opencontainers.image.title="Music Assistant Server" \
diff --git a/Dockerfile.base b/Dockerfile.base
new file mode 100644 (file)
index 0000000..4f8e698
--- /dev/null
@@ -0,0 +1,45 @@
+# syntax=docker/dockerfile:1
+
+# BASE docker image for music assistant container
+
+FROM python:3.12-alpine3.20
+
+ARG TARGETPLATFORM
+
+RUN set -x \
+    && apk add --no-cache \
+        ca-certificates \
+        jemalloc \
+        curl \
+        git \
+        wget \
+        tzdata \
+        sox \
+        cifs-utils \
+    # install ffmpeg from community repo
+    && apk add --no-cache ffmpeg --repository=https://dl-cdn.alpinelinux.org/alpine/v3.20/community \
+    # install snapcast from community repo
+    && apk add --no-cache snapcast --repository=https://dl-cdn.alpinelinux.org/alpine/v3.20/community \
+    # install libnfs from community repo
+    && apk add --no-cache libnfs --repository=https://dl-cdn.alpinelinux.org/alpine/v3.20/community \
+    # install openssl-dev (needed for airplay)
+    && apk add --no-cache openssl-dev
+
+# Copy widevine client files to container
+RUN mkdir -p /usr/local/bin/widevine_cdm
+COPY widevine_cdm/* /usr/local/bin/widevine_cdm/
+
+# Upgrade pip + Install uv
+RUN pip install --upgrade pip \
+    && pip install uv==0.2.27
+
+# Configure runtime environmental variables
+ENV LD_PRELOAD="/usr/lib/libjemalloc.so.2"
+ENV UV_SYSTEM_PYTHON="1"
+
+LABEL \
+    org.opencontainers.image.title="Music Assistant Base Image" \
+    org.opencontainers.image.description="Base Image for Music Assistant server - not to be used directly" \
+    org.opencontainers.image.source="https://github.com/music-assistant/server" \
+    org.opencontainers.image.authors="The Music Assistant Team" \
+    org.opencontainers.image.licenses="Apache License 2.0"