Files
InvoiceShelf/.github/workflows/docker.yaml
Darko Gjorgjijoski 55224e0007 ci(docker): authenticate composer against GitHub in the image build
Multi-arch builds run composer (incl. the merge-plugin's update) twice and exhausted GitHub's unauthenticated API rate limit, failing with 'Could not authenticate against github.com'. Pass the Actions token as a build secret and feed it to composer via COMPOSER_AUTH (build-time only, never in the image).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-15 00:31:31 +02:00

223 lines
6.7 KiB
YAML
Raw Permalink Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
name: Docker Build and Push
on:
release:
types: [published]
workflow_dispatch:
inputs:
tag:
description: 'Docker tag'
required: true
default: 'latest'
# Single source of truth for which major owns the moving stable tags
# (:latest, :{major}, :{major}.{minor}) and the temporary :nightly alias.
# Bump to "3" on BOTH the 2.x and 3.x branches when 3.0.0 GA is tagged, and
# drop the :nightly alias tag at the same time (end of the deprecation window).
env:
LATEST_MAJOR: "2"
jobs:
php_syntax_errors:
name: 1⃣ PHP Code Style errors
if: github.event_name == 'release' || github.event_name == 'workflow_dispatch'
runs-on: ubuntu-latest
steps:
- name: Set up PHP
uses: shivammathur/setup-php@v2
with:
php-version: 8.4
- name: Checkout code
uses: actions/checkout@v6
- name: Install dependencies
uses: ramsey/composer-install@4.0.0
- name: Check source code for syntax errors
run: ./vendor/bin/pint --test
tests:
name: 2⃣ PHP Tests
if: github.event_name == 'release' || github.event_name == 'workflow_dispatch'
needs:
- php_syntax_errors
runs-on: ubuntu-latest
strategy:
matrix:
php-version:
- 8.4
env:
extensions: bcmath, curl, dom, gd, imagick, json, libxml, mbstring, pcntl, pdo, pdo_mysql, zip
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: Setup PHP Action
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php-version }}
extensions: ${{ env.extensions }}
coverage: xdebug
tools: pecl, composer
- name: Install Composer dependencies
uses: ramsey/composer-install@4.0.0
- name: Install pnpm
uses: pnpm/action-setup@v6
- name: Use Node.js 24
uses: actions/setup-node@v6
with:
node-version: 24
cache: pnpm
- name: Install
run: pnpm install --frozen-lockfile
- name: Compile Front-end
run: pnpm build
- name: Apply tests ${{ matrix.php-version }}
run: php artisan test
release_artifact_build:
name: 🏗️ Build / Upload - Release File
if: github.event_name == 'release'
needs:
- tests
runs-on: ubuntu-latest
env:
extensions: bcmath, curl, dom, gd, imagick, json, libxml, mbstring, pcntl, pdo, pdo_mysql, zip
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: 8.4
extensions: ${{ env.extensions }}
coverage: none
- name: Install Composer dependencies
uses: ramsey/composer-install@4.0.0
with:
composer-options: --no-dev
- name: Install pnpm
uses: pnpm/action-setup@v6
- name: Use Node.js 24
uses: actions/setup-node@v6
with:
node-version: 24
cache: pnpm
- name: Install
run: pnpm install --frozen-lockfile
- name: Compile Front-end
run: pnpm build
- name: Build Dist
run: |
make clean dist
- name: Upload package
uses: svenstaro/upload-release-action@v2
with:
repo_token: ${{ github.token }}
file: InvoiceShelf.zip
asset_name: InvoiceShelf.zip
tag: ${{ github.ref }}
overwrite: true
release_docker_build:
name: 🐳 Release Docker Build
if: github.event_name == 'release'
needs:
- tests
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v4
- name: Log in to Docker Hub
uses: docker/login-action@v4
with:
username: ${{ secrets.DOCKER_HUB_USERNAME }}
password: ${{ secrets.DOCKER_HUB_TOKEN }}
- name: Extract metadata
id: meta
uses: docker/metadata-action@v6
with:
images: invoiceshelf/invoiceshelf
# Pre-release semver (e.g. 3.0.0-beta.1) automatically gets ONLY the exact
# {{version}} tag — metadata-action withholds {{major}} / {{major}}.{{minor}}.
# The moving stable tags (:latest, etc.) are gated on LATEST_MAJOR so a 2.x
# patch can never steal :latest from 3.x after the GA flip, and vice-versa.
tags: |
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=semver,pattern={{major}}
type=raw,value=latest,enable=${{ !contains(github.ref_name, '-') && startsWith(github.ref_name, format('{0}.', env.LATEST_MAJOR)) }}
type=raw,value=beta,enable=${{ contains(github.ref_name, '-beta') }}
type=raw,value=next,enable=${{ contains(github.ref_name, '-alpha') || contains(github.ref_name, '-beta') }}
# DEPRECATED transitional alias: keeps existing :nightly deployments converging
# onto stable until they migrate. Remove this line at the 3.0.0 GA flip.
type=raw,value=nightly,enable=${{ !contains(github.ref_name, '-') && startsWith(github.ref_name, format('{0}.', env.LATEST_MAJOR)) }}
- name: Build and push Docker image
uses: docker/build-push-action@v7
with:
context: .
file: docker/production/Dockerfile
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
secrets: |
composer_auth={"github-oauth":{"github.com":"${{ secrets.GITHUB_TOKEN }}"}}
manual_docker_build:
name: 🛠️ Manual Docker Build
if: github.event_name == 'workflow_dispatch'
needs:
- tests
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v4
- name: Log in to Docker Hub
uses: docker/login-action@v4
with:
username: ${{ secrets.DOCKER_HUB_USERNAME }}
password: ${{ secrets.DOCKER_HUB_TOKEN }}
- name: Build and push Docker image
uses: docker/build-push-action@v7
with:
context: .
file: docker/production/Dockerfile
platforms: linux/amd64,linux/arm64
push: true
tags: invoiceshelf/invoiceshelf:${{ github.event.inputs.tag }}
cache-from: type=gha
cache-to: type=gha,mode=max
secrets: |
composer_auth={"github-oauth":{"github.com":"${{ secrets.GITHUB_TOKEN }}"}}