xref: /optee_os/.github/workflows/notify.yml (revision 72d6673ebbc99f5177af3d60d6b1dde969ef44e8)
1*72d6673eSJerome Forissier# The purpose of this workflow is to run the scripts/notify_maintainers.py
2*72d6673eSJerome Forissier# for pull requests against the OP-TEE OS main repository in a secure way.
3*72d6673eSJerome Forissier# It runs on the pull_request_target event, which grants write permission
4*72d6673eSJerome Forissier# (issues: write) using the default short-lived GITHUB_TOKEN. Due to this
5*72d6673eSJerome Forissier# write access to PRs and issues, to prevent security issues the
6*72d6673eSJerome Forissier# pull_request_target event also checks out the code in the target branch,
7*72d6673eSJerome Forissier# not the code from the PR. This code can therefore be trusted.
8*72d6673eSJerome Forissier#
9*72d6673eSJerome Forissier# 1. Job 'check_sensitive_files' determines if the PR modified any critical
10*72d6673eSJerome Forissier#    files (.github/workflows/notify.yml or scripts/notify_maintainers.py).
11*72d6673eSJerome Forissier# 2. Job 'notify_maintainers' runs conditionally:
12*72d6673eSJerome Forissier#    - Automatically runs if no critical files were changed. It checks out
13*72d6673eSJerome Forissier#      the PR branch and executes the notify_maintainers.py script.
14*72d6673eSJerome Forissier#    - Requires manual approval (via "Re-run jobs") if critical files were
15*72d6673eSJerome Forissier#      changed, enforcing a human security gate. In this case the job status
16*72d6673eSJerome Forissier#      is 'skipped' so the workflow overall status is 'success' and no error
17*72d6673eSJerome Forissier#      is shown. It is up to the project's admins to trigger a re-run or not.
18*72d6673eSJerome Forissier
19*72d6673eSJerome Forissiername: Maintainer notification
20*72d6673eSJerome Forissieron:
21*72d6673eSJerome Forissier  # Run on pull requests with trusted code checked out from the target branch
22*72d6673eSJerome Forissier  pull_request_target:
23*72d6673eSJerome Forissier    types: [opened, synchronize]
24*72d6673eSJerome Forissierpermissions:
25*72d6673eSJerome Forissier  contents: read
26*72d6673eSJerome Forissierjobs:
27*72d6673eSJerome Forissier  # Runs on the official repository, uses trusted code to check PR changes
28*72d6673eSJerome Forissier  check_sensitive_files:
29*72d6673eSJerome Forissier    name: Check sensitive files
30*72d6673eSJerome Forissier    runs-on: ubuntu-latest
31*72d6673eSJerome Forissier    if: github.repository == 'OP-TEE/optee_os'
32*72d6673eSJerome Forissier    outputs:
33*72d6673eSJerome Forissier      script_modified: ${{ steps.files.outputs.any_changed }}
34*72d6673eSJerome Forissier    steps:
35*72d6673eSJerome Forissier      - uses: actions/checkout@v4
36*72d6673eSJerome Forissier        with:
37*72d6673eSJerome Forissier          # Checkout the trusted base branch code
38*72d6673eSJerome Forissier          fetch-depth: 0
39*72d6673eSJerome Forissier      - name: Get changed files between base and PR head
40*72d6673eSJerome Forissier        id: files
41*72d6673eSJerome Forissier        uses: tj-actions/changed-files@v44
42*72d6673eSJerome Forissier        with:
43*72d6673eSJerome Forissier          # Compare the base SHA (trusted) against the PR head SHA (untrusted)
44*72d6673eSJerome Forissier          base_sha: ${{ github.event.pull_request.base.sha }}
45*72d6673eSJerome Forissier          files: |
46*72d6673eSJerome Forissier            .github/workflows/notify.yml
47*72d6673eSJerome Forissier            scripts/notify_maintainers.py
48*72d6673eSJerome Forissier      - name: Show result
49*72d6673eSJerome Forissier        run: |
50*72d6673eSJerome Forissier          echo "Sensitive files changed: ${{ steps.files.outputs.any_changed }}"
51*72d6673eSJerome Forissier  notify_maintainers:
52*72d6673eSJerome Forissier    name: Notify maintainers
53*72d6673eSJerome Forissier    runs-on: ubuntu-latest
54*72d6673eSJerome Forissier    needs: check_sensitive_files
55*72d6673eSJerome Forissier    env:
56*72d6673eSJerome Forissier      PR_NUMBER: ${{ github.event.pull_request.number }}
57*72d6673eSJerome Forissier      REPO: ${{ github.repository }}
58*72d6673eSJerome Forissier    permissions:
59*72d6673eSJerome Forissier      issues: write
60*72d6673eSJerome Forissier    if: |
61*72d6673eSJerome Forissier      github.repository == 'OP-TEE/optee_os' &&
62*72d6673eSJerome Forissier      (needs.check_sensitive_files.outputs.script_modified == 'false' ||
63*72d6673eSJerome Forissier       github.run_attempt > 1)
64*72d6673eSJerome Forissier    steps:
65*72d6673eSJerome Forissier      # Checkout the untrusted code from the PR Branch
66*72d6673eSJerome Forissier      - name: Checkout PR code
67*72d6673eSJerome Forissier        uses: actions/checkout@v4
68*72d6673eSJerome Forissier        with:
69*72d6673eSJerome Forissier          ref: ${{ github.event.pull_request.head.sha }}
70*72d6673eSJerome Forissier      - name: Install python3-github
71*72d6673eSJerome Forissier        run: |
72*72d6673eSJerome Forissier          sudo apt-get update
73*72d6673eSJerome Forissier          sudo apt-get install python3-github
74*72d6673eSJerome Forissier      - name: Run scripts/notify_maintainers.py
75*72d6673eSJerome Forissier        env:
76*72d6673eSJerome Forissier          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
77*72d6673eSJerome Forissier        run: scripts/notify_maintainers.py
78