datahaven/.github/workflows/CI.yml
Steve Degosserie 9fff64020f
fix: Grant required permissions to reusable workflows in CI.yml (#355)
## Summary

Fixes the CI failure introduced by #349 where reusable workflows
couldn't use the permissions they declared.

## Root Cause

When using `workflow_call` (reusable workflows), the **called workflow's
permissions are constrained by the caller**. A called workflow cannot
request more permissions than the calling workflow grants.

PR #349 added explicit permissions to individual workflows (e.g.,
`actions: write` in task-build-operator.yml), but removed them from
CI.yml. This caused failures because:

```
CI.yml (contents: read only)
    └── task-build-operator.yml (requests actions: write)
        └── FAILS: caller doesn't grant actions: write
```

## Fix

Grant the necessary permissions in CI.yml so called workflows can use
them:

```yaml
permissions:
  contents: read
  actions: write    # For artifact upload/download
  packages: write   # For ghcr.io push
```

## Why the individual workflow permissions still matter

The explicit permissions in called workflows are still valuable for:
1. **Documentation** - Makes the intent clear
2. **Direct invocation** - Works when called via `workflow_dispatch`
3. **Defense in depth** - If CI.yml grants more than needed, called
workflows still request only what they need

Co-authored-by: Claude <noreply@anthropic.com>
2025-12-12 11:33:00 +00:00

75 lines
2.2 KiB
YAML

#! Main CI Specification for DataHaven Repository
name: CI
on:
workflow_dispatch:
push:
branches:
- main
- perm-*
pull_request:
branches: [main]
# Permissions granted to reusable workflows
# Note: Called workflows (workflow_call) are constrained by these permissions
permissions:
contents: read
actions: write # Required for artifact upload/download in build-operator, moonwall-tests
packages: write # Required for docker-build-ci to push to ghcr.io
concurrency:
group: pr-checks-${{ github.workflow }}-${{ github.head_ref || github.run_id }}
cancel-in-progress: true
jobs:
# First Tier - Build the binary first
build-operator:
uses: ./.github/workflows/task-build-operator.yml
# First Tier - Other parallel jobs
ts-build:
uses: ./.github/workflows/task-ts-build.yml
ts-lint:
uses: ./.github/workflows/task-ts-lint.yml
unit-tests:
uses: ./.github/workflows/task-rust-tests.yml
contract-tests:
uses: ./.github/workflows/task-foundry-tests.yml
rust-lint:
uses: ./.github/workflows/task-rust-lint.yml
# Second Tier - Jobs that depend on operator build
check-metadata:
needs: [build-operator]
uses: ./.github/workflows/task-check-metadata.yml
with:
binary-hash: ${{ needs.build-operator.outputs.binary-hash }}
docker-build-ci:
needs: [build-operator]
uses: ./.github/workflows/task-docker-ci.yml
# Note: GITHUB_TOKEN is automatically available to reusable workflows
with:
binary-hash: ${{ needs.build-operator.outputs.binary-hash }}
docker-build-release:
if: github.ref == 'refs/heads/main'
uses: ./.github/workflows/task-docker-release.yml
secrets:
DOCKERHUB_USERNAME: ${{ secrets.DOCKERHUB_USERNAME }}
DOCKERHUB_TOKEN: ${{ secrets.DOCKERHUB_TOKEN }}
moonwall-tests:
needs: [build-operator]
uses: ./.github/workflows/task-moonwall-tests.yml
with:
binary-hash: ${{ needs.build-operator.outputs.binary-hash }}
# Third Tier - E2E tests depend on docker build
e2e-tests:
needs: [docker-build-ci]
uses: ./.github/workflows/task-e2e.yml
# Note: GITHUB_TOKEN is automatically available to reusable workflows
with:
image-tag: ${{ needs.docker-build-ci.outputs.image-tag }}