name: "Build and Push Images" on: workflow_dispatch: inputs: app: type: string description: "App to build, e.g. 'home-assistant'" required: true jobs: ################################################################# # 1) Parse metadata.yaml -> produce JSON array of (channel, platform) items ################################################################# read-channels: runs-on: ci-os outputs: channels: ${{ steps.export-channels.outputs.channels }} steps: - name: Checkout uses: actions/checkout@v4 - id: export-channels name: Read channels from metadata.yaml shell: bash run: | # Path to the directory with metadata.yaml context_dir="/workspace/pub/containers/apps/${{ github.event.inputs.app }}" metadata_file="${context_dir}/metadata.yaml" # If metadata.yaml doesn't exist, fail early. if [ ! -f "$metadata_file" ]; then echo "metadata.yaml not found at $metadata_file" exit 1 fi echo "Parsing channels from $metadata_file..." # First, get the total channel count: channel_count=$(cat "$metadata_file" | yq '.channels | length') # We'll build the array in bash: result="[" for i in $(seq 0 $((channel_count - 1))); do channel_name=$(yq e ".channels[$i].name" "$metadata_file") # Number of platforms in this channel: platform_count=$(yq e ".channels[$i].platforms | length" "$metadata_file") for j in $(seq 0 $((platform_count - 1))); do platform=$(yq e ".channels[$i].platforms[$j]" "$metadata_file") # Append JSON object result="${result}{\"channel\":\"${channel_name}\",\"platform\":\"${platform}\"}," done done # Remove trailing comma result="${result%,}]" echo "Found channel/platform combinations: $result" # Expose as job output for the next job's matrix echo "channels=$result" >> "$GITHUB_OUTPUT" ################################################################# # 2) For each (channel, platform) combination -> build & push ################################################################# build-and-push: runs-on: ci-os needs: read-channels strategy: fail-fast: false matrix: include: ${{ fromJSON(needs.read-channels.outputs.channels) }} # This means: for each object in the array, we have "matrix.channel" and "matrix.platform" steps: - name: Checkout uses: actions/checkout@v4 - id: set-context name: Determine Context run: | # We'll reuse the same directory from job #1 context_dir="/workspace/pub/containers/apps/${{ github.event.inputs.app }}" echo "context_dir=$context_dir" >> "$GITHUB_OUTPUT" - id: read-version name: Read Version from version.sh run: | version=$(bash "${{ steps.set-context.outputs.context_dir }}/ci/version.sh" || echo "") echo "Building channel '${{ matrix.channel }}' with platform '${{ matrix.platform }}'" echo "Version: $version" echo "version=$version" >> "$GITHUB_OUTPUT" - name: Build and Push with Kaniko uses: https://code.252.no/pub/kaniko-action@latest with: # We pass the directory that holds Dockerfile, metadata.yaml, ci/version.sh, etc. context: ${{ steps.set-context.outputs.context_dir }} # We'll build two tags: # 1) : # 2) : # Example: code.252.no/org/repo:stable, code.252.no/org/repo:2023.5.0 destinations: > code.252.no/${{ github.repository }}/${{ github.event.inputs.app }}:${{ matrix.channel }} code.252.no/${{ github.repository }}/${{ github.event.inputs.app }}:${{ steps.read-version.outputs.version }} # If your Dockerfile uses ARG TARGETPLATFORM (e.g. in FROM lines), pass it in build_args build_args: | TARGETPLATFORM=${{ matrix.platform }} VERSION=${{ steps.read-version.outputs.version }} credentials: "code.252.no=tommy:${{ secrets.REGISTRY_TOKEN }}" push: "true" cache: "false"