diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 46fe999..a9c5a67 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -16,26 +16,18 @@ env: IMAGE_NAME: ${{ github.repository }} jobs: - lint: - runs-on: ubuntu-latest - permissions: - contents: read - steps: - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - - - name: Lint Dockerfile - uses: hadolint/hadolint-action@2332a7b74a6de0dda2e2221d575162eba76ba5e5 # v3.3.0 - with: - dockerfile: Dockerfile - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4.0.0 - - - name: Validate bake file - run: docker buildx bake --print - build: - needs: [lint] + # Dockerfile lint (hadolint) and bake-graph validation moved to + # .github/workflows/lint.yml — the hadolint piece now delegates to + # netresearch/.github's reusable lint-container.yml. The bake-graph + # check stays inline there because the reusable model is single-target + # docker/build-push-action, not bake. This `build` job likewise stays + # inline: the bake multi-target shape (minimal + full variants from + # docker-bake.hcl with shared cache and combined tag fan-out) doesn't + # map onto build-container.yml's single-target shape, and a + # bake-to-matrix refactor would either duplicate the tag fan-out into + # `metadata-tags` for two parallel reusable calls or abandon + # docker-bake.hcl entirely. Both invasive; flagged as upstream follow-up. runs-on: ubuntu-latest permissions: contents: read diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml new file mode 100644 index 0000000..d448269 --- /dev/null +++ b/.github/workflows/lint.yml @@ -0,0 +1,54 @@ +# SPDX-License-Identifier: MIT +# Copyright (c) 2026 Netresearch DTT GmbH +# +# Static checks for the phpbu-docker repo. +# +# Splits into: +# - container-lint → delegates Dockerfile (hadolint) to netresearch/.github's +# reusable lint-container.yml on @main. Reusable pins +# hadolint to v2.14.0, which handles Docker 25's +# HEALTHCHECK --start-interval correctly. No +# shell-scandirs because phpbu-docker does not ship its +# own shell helpers (docker-entrypoint.sh is the only +# shipped script and lives under the build context, not +# a separate scandir). +# - bake-validate → stays inline. Validates the docker-bake.hcl multi- +# target build graph via `docker buildx bake --print`. +# Caller-specific — the reusable model is single-target +# build-push-action, not bake. + +name: lint + +on: + push: + branches: [main] + pull_request: + branches: [main] + workflow_dispatch: + +permissions: + contents: read + +jobs: + container-lint: + # hadolint only — no shellcheck (shell-scandirs left empty). + uses: netresearch/.github/.github/workflows/lint-container.yml@main + permissions: + contents: read + + bake-validate: + name: docker buildx bake --print + runs-on: ubuntu-latest + timeout-minutes: 5 + permissions: + contents: read + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: false + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4.0.0 + + - name: Validate bake file + run: docker buildx bake --print diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index 55ad93d..d9c60fd 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -1,36 +1,38 @@ -name: OpenSSF Scorecard +# SPDX-License-Identifier: MIT +# Copyright (c) 2026 Netresearch DTT GmbH +# +# OpenSSF Scorecard — supply-chain security health check. +# Delegates to the org-wide reusable in netresearch/.github. +# Runs weekly against main and uploads SARIF to GitHub code-scanning. +# Results also surface on the OpenSSF Scorecard public dashboard +# (https://securityscorecards.dev/) once enabled. + +name: scorecard on: branch_protection_rule: schedule: - - cron: '0 6 * * 1' # Weekly on Monday + - cron: '0 6 * * 1' # weekly, Monday 06:00 UTC push: branches: [main] + workflow_dispatch: -permissions: read-all +# Top-level permissions explicitly enumerated (SonarCloud rule +# githubactions:S8234). The reusable's job requests its own +# additional permissions via its own permissions block; this minimum +# lets supporting tooling read metadata without granting writes. +permissions: + contents: read jobs: analysis: name: Scorecard analysis - runs-on: ubuntu-latest permissions: + # required by scorecard-action for publishing results security-events: write + # needed to publish results and get a badge id-token: write - - steps: - - name: Checkout - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - with: - persist-credentials: false - - - name: Run Scorecard - uses: ossf/scorecard-action@4eaacf0543bb3f2c246792bd56e8cdeffafb205a # v2.4.3 - with: - results_file: results.sarif - results_format: sarif - publish_results: true - - - name: Upload results - uses: github/codeql-action/upload-sarif@9e0d7b8d25671d64c341c19c0152d693099fb5ba # v4.35.5 - with: - sarif_file: results.sarif + contents: read + # needed for nested API calls (Branch-Protection, Webhooks checks) + actions: read + uses: netresearch/.github/.github/workflows/scorecard.yml@main diff --git a/.github/workflows/security.yml b/.github/workflows/security.yml index 1b2560d..2b7fff8 100644 --- a/.github/workflows/security.yml +++ b/.github/workflows/security.yml @@ -52,19 +52,16 @@ jobs: sarif_file: 'trivy-results.sarif' category: 'trivy-${{ matrix.name }}' + # Secret-scanning now delegates to netresearch/.github's reusable, which + # runs betterleaks (gitleaks fork, OSS, no license required) against the + # full git history, uploads SARIF to GitHub code-scanning, and bakes in + # the dependabot[bot]+merge_group skip semantics. The trivy job above + # stays inline because it builds locally via bake before scanning — the + # security-container.yml reusable is designed for already-published + # images (matrix over tags) and can't be wired in until the build job + # itself migrates off bake. gitleaks: - runs-on: ubuntu-latest - # Skip for dependabot PRs - org secrets not available to external PRs - if: github.actor != 'dependabot[bot]' + uses: netresearch/.github/.github/workflows/gitleaks.yml@main permissions: contents: read - steps: - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - with: - fetch-depth: 0 - - - name: Run Gitleaks - uses: gitleaks/gitleaks-action@ff98106e4c7b2bc287b24eaf42907196329070c7 # v2 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - GITLEAKS_LICENSE: ${{ secrets.GITLEAKS_LICENSE }} + security-events: write diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 26a6696..d73ff3e 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -106,26 +106,22 @@ jobs: docker run --rm --entrypoint which phpbu:ci-full gpg docker run --rm --entrypoint which phpbu:ci-full ssh + # The previous `structure-test` job (inline bake + container-structure-test + # download + run) now delegates to netresearch/.github's reusable + # smoke-test-container.yml. The reusable builds via docker/build-push-action + # rather than bake — equivalent here because the bake `ci` target is just + # `target = "minimal"` with `platforms = ["linux/amd64"]` and a local + # `phpbu:ci` tag, which the reusable replicates verbatim via `target:` + + # `image-tag:`. The `smoke-test` matrix job above stays inline: it covers + # phpbu-specific surface (TZ env-var sanitisation, read-only fs, simulate + # mode with a fixture config) that's outside the reusable's structure-test + # scope. structure-test: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4.0.0 - - - name: Build test image - uses: docker/bake-action@a66e1c87e2eca0503c343edf1d208c716d54b8a8 # v7.1.0 - with: - targets: ci - load: true - - - name: Install container-structure-test - run: | - curl -LO https://github.com/GoogleContainerTools/container-structure-test/releases/download/v1.19.3/container-structure-test-linux-amd64 - echo "fa0fa333bb6ba5c14065e7468d2904f5c82d021d7e1c763c9a45c5f2fbe9ff5f container-structure-test-linux-amd64" | sha256sum -c - - chmod +x container-structure-test-linux-amd64 - sudo mv container-structure-test-linux-amd64 /usr/local/bin/container-structure-test - - - name: Run structure tests - run: container-structure-test test --image phpbu:ci --config tests/container-structure-test.yaml + uses: netresearch/.github/.github/workflows/smoke-test-container.yml@main + permissions: + contents: read + with: + image-tag: phpbu:ci + target: minimal + cst-config-path: tests/container-structure-test.yaml + cache-scope: structure-test