name: Docker Build and Push on: release: types: [published] schedule: # Run nightly at 2 AM UTC - cron: '0 2 * * *' workflow_dispatch: inputs: tag: description: 'Docker tag' required: true default: 'latest' jobs: php_syntax_errors: name: 1️⃣ PHP Code Style errors if: github.event_name == 'release' runs-on: ubuntu-latest steps: - name: Set up PHP uses: shivammathur/setup-php@v2 with: php-version: 8.3 - name: Checkout code uses: actions/checkout@v4 - name: Install dependencies uses: ramsey/composer-install@v2 - name: Check source code for syntax errors run: ./vendor/bin/pint --test tests: name: 2️⃣ PHP Tests if: github.event_name == 'release' needs: - php_syntax_errors runs-on: ubuntu-latest strategy: matrix: php-version: - 8.2 - 8.3 - 8.4 env: extensions: bcmath, curl, dom, gd, imagick, json, libxml, mbstring, pcntl, pdo, pdo_mysql, zip steps: - name: Checkout code uses: actions/checkout@v4 - 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@v2 - name: Use Node.js 20 uses: actions/setup-node@v4 with: node-version: 20 - name: Install run: npm install - name: Compile Front-end run: npm run 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@v4 - name: Setup PHP uses: shivammathur/setup-php@v2 with: php-version: 8.2 extensions: ${{ env.extensions }} coverage: none - name: Install Composer dependencies uses: ramsey/composer-install@v2 with: composer-options: --no-dev - name: Use Node.js 20 uses: actions/setup-node@v4 with: node-version: 20 - name: Install run: npm install - name: Compile Front-end run: npm run 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@v4 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - name: Log in to Docker Hub uses: docker/login-action@v3 with: username: ${{ secrets.DOCKER_HUB_USERNAME }} password: ${{ secrets.DOCKER_HUB_TOKEN }} - name: Extract metadata id: meta uses: docker/metadata-action@v5 with: images: invoiceshelf/invoiceshelf tags: | type=semver,pattern={{version}} type=semver,pattern={{major}}.{{minor}} type=semver,pattern={{major}} type=raw,value=latest,enable={{is_default_branch}} - name: Build and push Docker image uses: docker/build-push-action@v5 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 manual_docker_build: name: 🛠️ Manual Docker Build if: github.event_name == 'workflow_dispatch' runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v4 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - name: Log in to Docker Hub uses: docker/login-action@v3 with: username: ${{ secrets.DOCKER_HUB_USERNAME }} password: ${{ secrets.DOCKER_HUB_TOKEN }} - name: Build and push Docker image uses: docker/build-push-action@v5 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 nightly_build: name: 🌙 Nightly Docker Build if: github.event_name == 'schedule' runs-on: ubuntu-latest strategy: matrix: branch: [master, develop] steps: - name: Checkout code uses: actions/checkout@v4 with: ref: ${{ matrix.branch }} fetch-depth: 2 - name: Check for recent changes id: changes run: | # Check if there are commits in the last 24 hours RECENT_COMMITS=$(git log --since="24 hours ago" --oneline | wc -l) echo "recent_commits=$RECENT_COMMITS" >> $GITHUB_OUTPUT if [ "$RECENT_COMMITS" -gt 0 ]; then echo "has_changes=true" >> $GITHUB_OUTPUT else echo "has_changes=false" >> $GITHUB_OUTPUT fi - name: Set up Docker Buildx if: steps.changes.outputs.has_changes == 'true' uses: docker/setup-buildx-action@v3 - name: Log in to Docker Hub if: steps.changes.outputs.has_changes == 'true' uses: docker/login-action@v3 with: username: ${{ secrets.DOCKER_HUB_USERNAME }} password: ${{ secrets.DOCKER_HUB_TOKEN }} - name: Set Docker tag if: steps.changes.outputs.has_changes == 'true' id: tag run: | if [ "${{ matrix.branch }}" = "master" ]; then echo "tag=nightly" >> $GITHUB_OUTPUT elif [ "${{ matrix.branch }}" = "develop" ]; then echo "tag=alpha" >> $GITHUB_OUTPUT fi - name: Build and push Docker image if: steps.changes.outputs.has_changes == 'true' uses: docker/build-push-action@v5 with: context: . file: docker/production/Dockerfile platforms: linux/amd64,linux/arm64 push: true tags: invoiceshelf/invoiceshelf:${{ steps.tag.outputs.tag }} cache-from: type=gha cache-to: type=gha,mode=max - name: No changes detected if: steps.changes.outputs.has_changes == 'false' run: | echo "No commits found in the last 24 hours for ${{ matrix.branch }} branch. Skipping build."