Skip to content

build

build #111

Workflow file for this run

# SPDX-License-Identifier: MIT
# Copyright (c) 2026 Netresearch DTT GmbH
name: build
on:
# Daily rebuild — picks up Alpine / PHP base-image CVE fixes for the same
# pinned GLPI release. (GLPI bundles its vendor/ in the release tarball, so
# there is no Composer "rolling" variant; the daily rebuild IS the GLPI-
# appropriate equivalent — fresh base, same app.)
schedule:
- cron: '0 4 * * *' # 04:00 UTC
push:
branches: [main]
paths-ignore:
- 'docs/**'
- '**.md'
- 'examples/**'
pull_request:
branches: [main]
workflow_dispatch:
inputs:
glpi_version:
description: 'Override GLPI version (default: read .glpi-version)'
required: false
default: ''
env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository_owner }}/glpi-php-fpm
permissions:
contents: read
concurrency:
group: build-${{ github.workflow }}-${{ github.ref }}
# Don't cancel the daily multi-arch rebuild mid-flight (half-attached
# manifests); do supersede an older push/PR build with a newer commit.
cancel-in-progress: ${{ github.event_name != 'schedule' }}
jobs:
# ─ Resolve version / tarball digest / facts once, upstream of the build ─
resolve:
name: resolve
runs-on: ubuntu-latest
permissions:
contents: read
outputs:
version: ${{ steps.r.outputs.version }}
major: ${{ steps.r.outputs.major }}
major_minor: ${{ steps.r.outputs.major_minor }}
glpi_sha256: ${{ steps.r.outputs.glpi_sha256 }}
build_date: ${{ steps.r.outputs.build_date }}
date_tag: ${{ steps.r.outputs.date_tag }}
is_release_from_file: ${{ steps.r.outputs.is_release_from_file }}
is_main_ref: ${{ steps.r.outputs.is_main_ref }}
push_artifacts: ${{ steps.r.outputs.push_artifacts }}
# Registry + image name are passed through resolve because a reusable
# workflow's `with:` block cannot read the caller's `env:` context.
registry: ${{ steps.r.outputs.registry }}
image_name: ${{ steps.r.outputs.image_name }}
steps:
- name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- name: Resolve version, tarball sha256, and facts
id: r
env:
# All ${{ }} interpolation flows through env vars, never straight
# into the run-script body — sonarcloud githubactions:S7630
# (shell injection); matters most for the user-supplied override.
INPUT_VERSION: ${{ inputs.glpi_version }}
EVENT: ${{ github.event_name }}
REF_FULL: ${{ github.ref }}
REGISTRY: ${{ env.REGISTRY }}
IMAGE_NAME: ${{ env.IMAGE_NAME }}
run: |
set -euo pipefail
if [ -n "$INPUT_VERSION" ]; then
VERSION="$INPUT_VERSION"
IS_RELEASE_FROM_FILE=false
else
VERSION=$(tr -d '[:space:]' < .glpi-version)
IS_RELEASE_FROM_FILE=true
fi
# GLPI release tags have no 'v' prefix; strip one defensively anyway.
VERSION="${VERSION#v}"
MAJOR=$(echo "$VERSION" | cut -d. -f1)
MAJOR_MINOR=$(echo "$VERSION" | cut -d. -f1-2)
# Resolve the bundled-tarball sha256 once and pin the build to it —
# a swapped release asset can't slip into the image (supply chain).
URL="https://github.com/glpi-project/glpi/releases/download/${VERSION}/glpi-${VERSION}.tgz"
GLPI_SHA256=$(curl -fsSL "$URL" | sha256sum | cut -d' ' -f1)
[ -n "$GLPI_SHA256" ] || { echo "could not hash $URL" >&2; exit 1; }
IS_MAIN_REF=false
[ "$REF_FULL" = "refs/heads/main" ] && IS_MAIN_REF=true
PUSH_ARTIFACTS=true
[ "$EVENT" = "pull_request" ] && PUSH_ARTIFACTS=false
{
echo "version=$VERSION"
echo "major=$MAJOR"
echo "major_minor=$MAJOR_MINOR"
echo "glpi_sha256=$GLPI_SHA256"
echo "build_date=$(date -u +'%Y-%m-%dT%H:%M:%SZ')"
echo "date_tag=$(date -u +'%Y%m%d')"
echo "is_release_from_file=$IS_RELEASE_FROM_FILE"
echo "is_main_ref=$IS_MAIN_REF"
echo "push_artifacts=$PUSH_ARTIFACTS"
echo "registry=$REGISTRY"
echo "image_name=$IMAGE_NAME"
} >> "$GITHUB_OUTPUT"
echo "─ resolved ─ GLPI $VERSION sha256=${GLPI_SHA256:0:16}… push=$PUSH_ARTIFACTS"
# ─ Build: per-arch build → digest → multi-arch merge → SLSA + cosign ───
build:
name: build
needs: resolve
permissions:
contents: read
packages: write
id-token: write
attestations: write
uses: ./.github/workflows/_build-cell.yml
with:
version: ${{ needs.resolve.outputs.version }}
major: ${{ needs.resolve.outputs.major }}
major_minor: ${{ needs.resolve.outputs.major_minor }}
glpi_sha256: ${{ needs.resolve.outputs.glpi_sha256 }}
build_date: ${{ needs.resolve.outputs.build_date }}
date_tag: ${{ needs.resolve.outputs.date_tag }}
registry: ${{ needs.resolve.outputs.registry }}
image_name: ${{ needs.resolve.outputs.image_name }}
is_main_ref: ${{ needs.resolve.outputs.is_main_ref == 'true' }}
is_release_from_file: ${{ needs.resolve.outputs.is_release_from_file == 'true' }}
push_artifacts: ${{ needs.resolve.outputs.push_artifacts == 'true' }}