nuttx-apps/.github/workflows/pr_labeler.yml
Lup Yuen Lee fe546acfc7 github/workflow: Sync the new PR Labeling Workflow from NuttX Repo to NuttX Apps
This PR replicates the new PR Labeling Workflow from NuttX Repo to NuttX Apps Repo. For Future Syncing:
- Copy from NuttX Repo to NuttX Apps: `.github/workflows/labeler.yml` and `.github/workflows/pr_labeler.yml`
- Edit `.github/workflows/labeler.yml` and change `repository: apache/nuttx` to `repository: apache/nuttx-apps`
- Don't overwrite `.github/labeler.yml` by NuttX Repo

The new workflow reimplements PR Labeling with two triggers: pull_request and workflow_run. We no longer need pull_request_target, which is an unsafe trigger and may introduce security vulnerabilities.

The New PR Labeler is explained here:
- https://lupyuen.org/articles/prtarget
- https://github.com/apache/nuttx/issues/18359

Modified Files:

`.github/workflows/labeler.yml`: Changed the (read-write) pull_request_target trigger to (read-only) pull_request trigger. Compute the Size Label (e.g. Size: XS) and Arch Labels (e.g. Area: Examples). Save the PR Labels into a PR Artifact.

`.github/labeler.yml`: Added comment to clarify that NuttX PR Labeler only supports a subset of the `actions/labeler` syntax: `changed-files` and `any-glob-to-any-file`. Note: Don't overwrite this file by NuttX Repo.

New Files:

`.github/workflows/pr_labeler.yml`: Contains the workflow_run trigger, which is executed upon completion of the pull_request trigger. Download the PR Labels from the PR Artifact. Write the PR Labels into the PR.

Signed-off-by: Lup Yuen Lee <luppy@appkaki.com>
2026-02-23 20:33:22 +08:00

90 lines
3.5 KiB
YAML

# SPDX-License-Identifier: Apache-2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# This workflow will fetch the PR Labels from the PR Artifact, and write
# the PR Labels into the PR. The workflow is called after the
# "pull_request" trigger (labeler.yml). This "workflow_run" trigger uses a
# GitHub Token with Write Permission, so we must never run any untrusted
# code from the PR, and we must always extract and use the PR Artifact
# safely. See https://cwiki.apache.org/confluence/pages/viewpage.action?pageId=321719166#GitHubActionsSecurity-Buildstriggeredwithworkflow_run
name: "Set Pull Request Labels"
on:
workflow_run:
workflows: ["Pull Request Labeler"]
types:
- completed
jobs:
pr_labeler:
permissions:
contents: read
pull-requests: write
issues: write
runs-on: ubuntu-latest
if: >
github.event.workflow_run.event == 'pull_request' &&
github.event.workflow_run.conclusion == 'success'
steps:
# Download the PR Artifact, containing PR Number and PR Labels
- name: Download PR artifact
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
with:
script: |
const artifacts = await github.rest.actions.listWorkflowRunArtifacts({
owner: context.repo.owner,
repo: context.repo.repo,
run_id: ${{ github.event.workflow_run.id }},
});
const matchArtifact = artifacts.data.artifacts.filter((artifact) => {
return artifact.name == "pr"
})[0];
const download = await github.rest.actions.downloadArtifact({
owner: context.repo.owner,
repo: context.repo.repo,
artifact_id: matchArtifact.id,
archive_format: 'zip',
});
const fs = require('fs');
fs.writeFileSync('${{github.workspace}}/pr.zip', Buffer.from(download.data));
# Unzip the PR Artifact
- name: Unzip PR artifact
run: unzip pr.zip
# Write the PR Labels into the PR
- name: Write PR labels
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const owner = context.repo.owner;
const repo = context.repo.repo;
const fs = require('fs');
// Read the PR Number and PR Labels from the PR Artifact
// e.g. 'Size: XS\nArch: avr\n'
const issue_number = Number(fs.readFileSync('pr-id.txt'));
const labels = fs.readFileSync('pr-labels.txt', 'utf8')
.split('\n') // Split by newline
.filter(s => (s != '')); // Remove empty lines
console.log({ issue_number, labels });
// Write the PR Labels into the PR
// e.g. [ 'Size: XS', 'Arch: avr' ]
await github.rest.issues.setLabels({
owner,
repo,
issue_number,
labels
});