Skip to content

ci: support PR dependencies via depends-on#19075

Open
zhangning21 wants to merge 1 commit into
apache:masterfrom
zhangning21:feature/cross-repo-depends-on
Open

ci: support PR dependencies via depends-on#19075
zhangning21 wants to merge 1 commit into
apache:masterfrom
zhangning21:feature/cross-repo-depends-on

Conversation

@zhangning21

@zhangning21 zhangning21 commented Jun 10, 2026

Copy link
Copy Markdown

Summary

Add opt-in same- and cross-repository pull request dependencies to NuttX CI.

Why this is needed

NuttX and nuttx-apps are built together. For a normal PR, Fetch-Source checks
out the target branch from the changed repository and the corresponding branch
from the other repository. A feature that must change both repositories can
therefore fail in both PRs because neither target branch contains the companion
change yet. This feature lets CI test the exact combined changes before either
PR is merged. It also supports a PR depending on another PR in the same
repository.

Usage

A PR targeting master can declare one dependency per line:

Depends-On: https://github.com/apache/nuttx-apps/pull/1234
Depends-On: https://github.com/apache/nuttx/pull/5678

Alternatively, multiple dependencies can use a single bracket list:

Depends-On: [apache/nuttx-apps/pull/1234 https://github.com/apache/nuttx/pull/5678]

The Depends-On: marker is case-insensitive; Depends-On:, depends-on:,
and mixed-case spellings are equivalent. This document uses Depends-On: as
the canonical form.

Short references and full https://github.com/... URLs may be mixed. Multiple
Depends-On: lines are supported, and duplicate references are applied once in
first-seen order. Each declaration must be on one line; Markdown bullet
continuation is not supported. Markers in prose, not-depends-on:, indented
code, and fenced code blocks are ignored. Only references that strictly match
an allowed GitHub repository and a positive PR number are accepted; other
tokens are ignored. A declaration is invalid only when a Depends-On: marker
is present but no valid dependency can be parsed.

Fetch-Source fetches each declared pull/<N>/head, records its exact head SHA,
checks for common history, and cherry-picks the dependency commits before the
existing build matrix runs.

Implementation

  • .github/scripts/depends_on.py provides a standard-library parser with strict
    accepted-reference matching, repository allow-listing, Markdown code-block
    handling, ordered de-duplication, structured JSON output, and explicit
    ok/invalid/none states.
  • .github/scripts/test_depends_on.py contains 40 parser regression tests.
  • .github/workflows/build.yml keeps fork builds read-only, applies dependencies
    only to PRs targeting master, and reruns heavy CI after an edited event
    when the ordered parsed dependency state or base branch changes.
  • .github/workflows/depends-on-comment.yml runs after Build completes. Without
    checking out or executing fork code, it validates the untrusted report's
    structure, repository allow-list, run/current-head binding, and fixed
    rendering fields before posting a result. Retrying the same run updates that
    run's comment; earlier Build comments remain as history.
  • Documentation/testing/nuttx-ci.rst documents the accepted syntax, behavior,
    result comments, and operational limits.

The follow-up comment reports one of three outcomes:

  • ok: each dependency PR and its fetched head SHA (abbreviated in the
    comment);
  • invalid: a marker was found but no valid dependency could be parsed, so no
    dependency is applied and CI continues with the normal source selection;
  • failed: a valid dependency could not be applied, with a fixed diagnostic
    reason. This causes Fetch-Source to fail.

Impact and security

  • Opt-in compatibility: PRs without Depends-On: retain the existing source
    and build-matrix behavior.
  • Release/backport safety: Only PRs targeting master apply dependencies. A
    copied declaration in a release/backport PR is ignored, preserving the
    existing matching-release-branch behavior.
  • Runner budget: No build target is added or duplicated. Dependency fetch and
    cherry-pick happen once in Fetch-Source, not once per matrix target. Every
    Build gains one short Changes gate job, and every completed PR Build starts
    one short trusted comment job, which exits without commenting when no report
    exists. Build now listens for pull_request edited events. An unrelated
    title/body edit runs only the gate and does not request cancellation of an
    already-running code build, although GitHub may replace an older pending run
    in the same concurrency group. Reordering dependencies reruns the matrix.
  • Fork and input safety: Build retains only contents: read. The parser uses
    no awk, sed, eval, or third-party Python package. The default-branch
    workflow_run is the only part of this change with pull-requests: write;
    it never checks out fork code. It rejects reports with an invalid schema, repository, dependency number, full
    success SHA, or run/current-head binding, and renders only fixed text and
    validated values.
  • Failure behavior: Invalid declarations do not fail Build and are not
    applied. A valid dependency causes Fetch-Source to fail if fetch,
    common-history checking, revision-list generation, or cherry-pick fails.
    Defensive report validation and other ordinary job errors can also fail the
    job rather than silently producing an untrusted result.
  • No product impact: No runtime, hardware, ABI, build target, or application
    behavior changes.

Intentional limitations

  • The workflow fetches the dependency's pull/<N>/head at Build time and records
    the fetched SHA, but does not use the GitHub API to validate the dependency
    PR's open/closed state or target branch. The initiating PR must target
    master; authors must select compatible dependency PRs.
  • Updating a dependency PR does not automatically trigger the initiating PR.
    The initiating PR must be updated or its checks rerun to test the new SHA.
  • Results and comments belong to the initiating PR. They do not set a status on
    the dependency PR and do not prove that its independent checks passed. The
    trusted workflow validates an untrusted report for safe posting, but does not
    independently attest that the dependency was applied; the comment reflects
    the read-only Build workflow's report.
  • This validates combined source but does not automate synchronized merging.
    Owners still coordinate merge order and timing.
  • A dependency that cannot be cleanly cherry-picked fails the Build; authors
    should update the dependency rather than rely on CI to resolve it.

Testing

Host: macOS locally and Ubuntu GitHub-hosted runners. No target-hardware test
is applicable because this changes GitHub Actions workflows, a parser, and CI
documentation.

Local validation:

  • Black 24.8.0 and Flake8 7.1.1: passed;
  • python3 -m unittest discover -s .github/scripts -p 'test_depends_on.py':
    40/40 passed. These tests are currently run explicitly with this command;
    this change does not add a separate CI job for them;
  • py_compile, parser CLI smoke test with apache/*, and git diff --check:
    passed;
  • both changed workflows parsed as YAML and their job/repository references were
    checked;
  • targeted Sphinx HTML build for testing/nuttx-ci.rst: passed, including
    assertions for both declaration forms, invalid behavior, and all three
    comment outcomes.

GitHub Actions validation:

  • Lint and Build Documentation passed;
  • the dependency-specific Changes and Fetch-Source jobs passed.

End-to-end tests: These cases were run in a public staging fork environment
(zhn-test/*) using real fork PRs, dependency PRs, GitHub Actions runs,
artifacts, and bot comments. The links record those test runs; the upstream
configuration and usage examples above use apache/nuttx and
apache/nuttx-apps.

# Test case Actual input / base Feature result Evidence
1 Single cross-repo dependency depends-on: zhn-test/nuttx-apps/pull/3 Dependency applied; comment records SHA 92bb7d36ed PR #20 · run · comment
2 Multiple dependencies depends-on: zhn-test/nuttx-apps/pull/3
depends-on: zhn-test/nuttx-apps/pull/4
Both applied; comment records SHAs 92bb7d36ed and 39bf4ae20f PR #21 · run · comment
3 Invalid non-GitHub host depends-on: gitlab.com/zhn-test/nuttx-apps/pull/3 Rejected as invalid; warning comment posted and normal source selection continues PR #22 · run · comment
4 Non-existent dependency depends-on: zhn-test/nuttx-apps/pull/999999 Reported as failed; the dependency PR could not be fetched PR #23 · run · comment
5 No dependency No depends-on: declaration No dependency report or comment PR #24 · run
6 Prose, prefixed marker, and fenced code Mid-line depends-on, not-depends-on:, and fenced depends-on: examples All ignored; no dependency comment posted PR #25 · run
7 Unsupported bullet continuation depends-on: followed by two Markdown bullets Rejected as invalid; warning comment posted PR #26 · run · comment
8 Release/backport base Base releases/ci-test; depends-on: zhn-test/nuttx-apps/pull/3 Declaration ignored; no dependency comment posted PR #27 · run
9 Unrelated body edit Existing valid dependency plus unrelated prose Changes ran; Fetch-Source and all heavy jobs were skipped PR #28 · run
10 Per-Build comment history Same two dependencies as case 2; later Build at a new head New run-specific comment created; prior comment preserved PR #21 · run · new comment

@github-actions github-actions Bot added Area: CI Size: S The size of the change in this PR is small labels Jun 10, 2026
@lupyuen

lupyuen commented Jun 10, 2026

Copy link
Copy Markdown
Member
  1. Could you please fill in the PR Template, I'm concerned especially about the Impact of this PR, whether it will break any CI Builds: https://github.com/apache/nuttx/blob/master/CONTRIBUTING.md#23-pull-requests
  2. Could you provide the Test Logs? This is a major change to NuttX CI, we would need the logs for All NuttX Targets currently built by NuttX CI.
  3. How much reduction / increase in GitHub Actions Build Time would you expect with these changes? Note that we are running on a very strict budget for GitHub Runners: https://lupyuen.org/articles/ci3
  4. I'm not sure if I understand the purpose of the changes. Could you explain with a specific NuttX example, how this dependency management would work?
  5. Please check this CI Error thanks! https://github.com/apache/nuttx/actions/runs/27251914323/job/80478182912?pr=19075#step:6:71

@zhangning21 zhangning21 reopened this Jun 10, 2026
@lupyuen

lupyuen commented Jun 10, 2026

Copy link
Copy Markdown
Member

I noticed that you're using an AI Agent for OpenVela. I'm curious if you used it for creating this PR, because this PR doesn't seem to follow the NuttX Contributing Guidelines. Thanks :-)

id: gittargets
shell: bash
env:
PR_BODY: ${{ github.event.pull_request.body }}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this safe? Do we need to escape the PR Body? Otherwise we could have an Injection Attack?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for raising this. Yes, the PR body is untrusted input, so we need to be careful here.
The reason we pass the body through an env: variable instead of inlining ${{ github.event.pull_request.body }} directly into the run: script is precisely to avoid script injection. This is the mitigation GitHub documents in Security hardening for GitHub Actions
(https://docs.github.com/en/actions/security-guides/security-hardening-for-github-actions#using-an-intermediate-environment-variable):

│ - With env:, the body is delivered to the step as the value of an environment variable. It is never substituted into the script source, so shell metacharacters in the body (`, $(
), ;, &&, …) are treated as literal data, not executed.
│ - The dangerous form would be inlining it directly, e.g. run: echo "${{ github.event.pull_request.body }}", where a body like "; rm -rf / # would be injected into the script text.
We deliberately do not do that.

│ On top of the env: indirection, the body is only ever consumed as quoted data by text-processing tools — echo "$PR_BODY" | grep -oE … — never eval'd or executed. The values we extract are further constrained:
│ - dependencies must match a fixed regex (?:https://github.com/)?apache/nuttx(\?:-apps)?/pull/[0-9]+;
│ - the repo is checked against a 2-entry allow-list (apache/nuttx, apache/nuttx-apps);
│ - the PR number is [0-9]+ only, so the later git fetch origin "pull/${DEP_PR_NUM}/head:…" can't be abused.

│ Finally, this workflow runs on pull_request (not pull_request_target), so the job has a read-only GITHUB_TOKEN and no secrets — the blast radius is minimal even in the worst case.

│ If helpful, I can switch the echo "$PR_BODY" calls to printf '%s\n' "$PR_BODY" for slightly more robust handling of arbitrary text (purely a robustness nicety, not a security fix).

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@zhangning21 This GitHub Actions Design is very unusual for NuttX CI. If I understand correctly:

  1. We expect the PR Author to specify inside the PR Body the dependency: depends-on: apache/nuttx/pull/88888888
  2. What if the PR Author edits the dependency in the PR Body? Will the dependency be rechecked?
  3. I'm concerned about parsing the Untrusted Input from the PR Body. Isn't a PR Label a better way to provide the dependency? E.g. depends-on=nuttx/88888888
  4. Are there any other projects using this? I wonder if they are also OK with parsing Untrusted Input from the PR Body.
  5. @simbit18 @linguini1 @cederom Do we think it's a good idea to parse the dependency from the PR Body? depends-on: apache/nuttx/pull/88888888

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Purpose
│ nuttx and nuttx-apps are built together in CI, and for a normal PR the Fetch-Source job always checks out the master of the other repo. The main problem this solves is cross-repo PR interdependency: when one feature must change both repos, each PR's CI fails because the other repo's master doesn't yet contain the matching change — today the only workaround is to force-merge one side with CI skipped, which risks breaking master. The same mechanism also covers the case where a PR depends on another PR in the same repo. The author declares this in the PR body, e.g. depends-on: [apache/nuttx-apps/pull/XXX], and CI builds the combined code. It's fully opt-in — without a depends-on line, CI behaves exactly as today.

Now to your specific questions:

│ 1. Yes, the author specifies the dependency in the PR body.

│ 2. "If the author edits the dependency in the body, is it rechecked?"
│ If the author edits only the PR body, it is not rechecked immediately. This follows the current workflow behavior: the existing pull_request trigger does not run CI for PR description edits, only for normal CI-triggering events such as new commits. The dependency will be re-read on the next CI run.

│ 3. "Isn't a PR Label better than parsing untrusted body text?"
│ Labels would be more controlled, but they are not very practical here because external contributors usually cannot apply labels to upstream PRs, and dependency values are dynamic PR numbers rather than fixed categories. Using the PR body lets the contributor declare the dependency directly, while the workflow still validates it with a strict allowlist and numeric PR ID.

│ 4. "Do other projects parse dependencies from the PR body, and are they OK with the untrusted input?"
│ Yes . A similar approach is used by Zuul CI for cross-project dependencies. Zuul supports a Depends-On: directive, and for GitHub-based projects it is placed in the pull request
description: https://zuul-ci.org/docs/zuul/latest/gating.html#cross-project-dependencies

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The main problem this solves is cross-repo PR interdependency: when one feature must change both repos, each PR's CI fails because the other repo's master doesn't yet contain the matching change — today the only workaround is to force-merge one side with CI skipped, which risks breaking master.

I'm not sure if my Fellow Maintainers agree with me: But here's what I think about Breaking Changes that require both NuttX Repo and NuttX Apps Repo to be in sync...

Breaking Changes need to be carefully and manually managed. I expect the PR Author to test the changes in their own NuttX Repo and NuttX Apps Repo, and provide evidence that All NuttX Builds were successful. Then CI Team needs to standby and make sure that both NuttX Repo and NuttX Apps Repo are merged at the same time.

If we allow PR Authors to specify which version of NuttX / NuttX Apps to build: We might forget to do the manual checking and the simultaneous merging. And when NuttX / NuttX Apps repos go out of sync, we will have lots more problems :-(

@lupyuen

lupyuen commented Jun 10, 2026

Copy link
Copy Markdown
Member

Hi NuttX Admins: Please don't click "Approve Workflows To Run", I have concerns about the Safety of the GitHub Actions:

@zhangning21

Copy link
Copy Markdown
Author

I noticed that you're using an AI Agent for OpenVela. I'm curious if you used it for creating this PR, because this PR doesn't seem to follow the NuttX Contributing Guidelines. Thanks :-)

@lupyuen The packages_ai_agent repository is only a personal fork I used for testing some OpenVela community workflow ideas. It is unrelated to this Apache NuttX PR and is not used by this workflow.

I'll update the PR to follow the guidelines and ping you again. Apologies for the rough first pass, and thanks for the careful review!

Comment thread .github/workflows/build.yml Outdated
Comment on lines +100 to +120
ARRAY_DEPS=$(echo "$PR_BODY" | grep -oE 'depends-on:[[:space:]]*\[[^]]+\]' | head -1) || true
if [ -n "$ARRAY_DEPS" ]; then
DEPS=$(echo "$ARRAY_DEPS" | grep -oE '(https://github.com/)?apache/nuttx(-apps)?/pull/[0-9]+') || true
else
DEPS=$(echo "$PR_BODY" | grep -oE 'depends-on:[[:space:]]*(https://github.com/)?apache/nuttx(-apps)?/pull/[0-9]+' | sed 's/depends-on:[[:space:]]*//' | head -1) || true
fi

for DEP in $DEPS; do
DEP=$(echo "$DEP" | sed 's|https://github.com/||')
DEP_REPO=$(echo "$DEP" | awk -F'/pull/' '{print $1}')
DEP_PR_NUM=$(echo "$DEP" | awk -F'/pull/' '{print $2}')

if [[ "$DEP_REPO" != "apache/nuttx" && "$DEP_REPO" != "apache/nuttx-apps" ]]; then
echo "::warning::Ignoring unsupported dependency repo: $DEP_REPO"
continue
fi

DEPENDS_ON="$DEPENDS_ON ${DEP_REPO}/pull/${DEP_PR_NUM}"
done

DEPENDS_ON=$(echo "$DEPENDS_ON" | tr ' ' '\n' | awk 'NF && !a[$0]++' | xargs)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi NuttX Admins: This script will parse the Untrusted Input from the PR Body to extract the Dependency Info safely, which will prevent Injection Attacks inside the PR Body. I'm afraid the current NuttX CI Team doesn't have sufficient expertise to maintain this, we might introduce Injection Attacks in future.

I strongly suggest that we engage a NuttX Team Member familiar with GitHub Actions Script Security, who will be able to maintain this script, to prevent Injection Attacks in future. We must comply with the Apache Guidelines for GitHub Actions Security: https://infra.apache.org/github-actions-policy.html

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is a big concern. For now it might be a good idea to forgo this change.

@lupyuen lupyuen linked an issue Jun 10, 2026 that may be closed by this pull request
1 task
@lupyuen

lupyuen commented Jun 10, 2026

Copy link
Copy Markdown
Member

Testing: All targets currently built by NuttX CI (full build.yml matrix).
Full-target logs from this PR's own run will be linked once the workflow is
approved to run.

Could you show us a working version of this code in your Own NuttX Repo? Also we need the Test Logs for the various test cases thanks!

  1. No depends-on in PR Body
  2. depends-on with a Valid PR Number: apache/nuttx-apps/pull/???
  3. depends-on with a Invalid PR Number: apache/nuttx-apps/pull/88888888
  4. depends-on with a Non-Apache PR: lupyuen/nuttx-apps/pull/1
  5. depends-on with a typo: apache/nuttx-apps/push/???

@zhangning21

Copy link
Copy Markdown
Author

Testing: All targets currently built by NuttX CI (full build.yml matrix).
Full-target logs from this PR's own run will be linked once the workflow is
approved to run.

Could you show us a working version of this code in your Own NuttX Repo? Also we need the Test Logs for the various test cases thanks!

  1. No depends-on in PR Body
  2. depends-on with a Valid PR Number: apache/nuttx-apps/pull/???
  3. depends-on with a Invalid PR Number: apache/nuttx-apps/pull/88888888
  4. depends-on with a Non-Apache PR: lupyuen/nuttx-apps/pull/1
  5. depends-on with a typo: apache/nuttx-apps/push/???

@lupyuen Here's a working version running in my own forks (zhn-test/nuttx + zhn-test/nuttx-apps), with CI logs for each test case.

Note: on the fork the dependent PR is fetched from the fork's origin, so the examples use zhn-test/... instead of apache/...; the behavior is identical. The relevant evidence is the Apply depends-on PRs step in the Fetch-Source job.

# Test case depends-on value Apply step Result Log
1 No depends-on (none) skipped Baseline; CI proceeds run
2 Valid PR number [zhn-test/nuttx-apps/pull/1] success Fetched + cherry-picked run
3 Invalid PR number [zhn-test/nuttx/pull/88888888] failure fatal: couldn't find remote ref → exit 1 (fail-fast) run
4 Non-Apache repo [lupyuen/nuttx/pull/1] skipped Ignored by allowlist; CI proceeds run
5 Typo (push/) [zhn-test/nuttx/push/2] skipped Not matched; CI proceeds run

Note: cases 4 and 5 are silently ignored (no error, no warning) because the values don't match the dependency regex. If preferred, I can add a warning when a depends-on: line is present but yields no valid dependency, to catch typos/wrong repos early.

@lupyuen

lupyuen commented Jun 10, 2026

Copy link
Copy Markdown
Member
  1. When we create a NuttX Release Branch, like
    https://github.com/apache/nuttx/tree/releases/12.13
    It's meant to be compiled with the corresponding NuttX Apps Release Branch:
    https://github.com/apache/nuttx-apps/tree/releases/12.13
    Do you expect any problems with the code?
  2. Release Branch will have Back-Ported PRs like this:
    {bp-18485} sched/critmon: Fix CPU load stats incorrect when using SCHED_CPULOAD_… #18616
    Notice that the PR Body is cloned from the Original PR:
    sched/critmon: Fix CPU load stats incorrect when using SCHED_CPULOAD_CRITMONITOR #18485
    Suppose the Original PR Body specifies depends-on, and it's copied into the Back-Ported PR. Won't the Back-Ported PR build incorrectly against the depends-on branch, instead of the correct releases/12.13 branch?

@zhangning21

zhangning21 commented Jun 10, 2026

Copy link
Copy Markdown
Author
  1. When we create a NuttX Release Branch, like https://github.com/apache/nuttx/tree/releases/12.13 It's meant to be compiled with the corresponding NuttX Apps Release Branch: https://github.com/apache/nuttx-apps/tree/releases/12.13 Do you expect any problems with the code?
  2. Release Branch will have Back-Ported PRs like this: {bp-18485} sched/critmon: Fix CPU load stats incorrect when using SCHED_CPULOAD_… #18616
    Notice that the PR Body is cloned from the Original PR: sched/critmon: Fix CPU load stats incorrect when using SCHED_CPULOAD_CRITMONITOR #18485
    Suppose the Original PR Body specifies depends-on, and it's copied into the Back-Ported PR. Won't the Back-Ported PR build incorrectly against the depends-on branch, instead of the correct releases/12.13 branch?

@lupyuen Thanks again — good point about release branches and backports.

I've gone with the simplest and safest rule:

depends-on is processed only for PRs whose target branch is master.

if [ -n "$PR_BODY" ] && [ "$GITHUB_BASE_REF" = "master" ]; then
  # parse depends-on ...
fi

This avoids the backport problem without adding GitHub API calls or extra permissions.

What this means:

  • Backport / release-branch PRs ignore depends-on entirely. If a backport PR to releases/12.13 carries a copied depends-on: line from the original master PR, CI skips it and keeps the existing release behavior: build against the matching releases/12.13 branch of the other repo.

  • A copied master dependency cannot be accidentally cherry-picked onto a release branch.

  • No GitHub API call and no pull-requests permission are needed.

  • push / tag handling is unchanged; that path has no PR body and is unrelated to depends-on.

One limitation: this checks only the current PR's target branch. Without an API lookup, the workflow does not verify the dependency PR's own base branch, so this feature is intended for the normal master-branch cross-repo dependency case. A stricter version could query each dependency PR's base.ref and require it to match, but that would reintroduce an API call and extra permission surface. For now, restricting depends-on to PRs targeting master seems the simpler and safer trade-off.

I've validated this in my test fork with a backport-style PR targeting releases/12.13 whose body contains a copied depends-on: line. The Apply depends-on PRs step is skipped and CI builds against the matching releases/12.13 branch, so the copied dependency is ignored:

Validation run: https://github.com/zhn-test/nuttx/actions/runs/27262401865/job/80511061759

Please see the Apply depends-on PRs step in the Fetch-Source job. It is skipped. Any downstream build differences in my fork are unrelated to this depends-on handling.

If this approach looks OK, I'll update this PR first. After this PR is reviewed and the approach is agreed, I will submit the matching apache/nuttx-apps PR with the same workflow update so the two workflows stay consistent.

@lupyuen

lupyuen commented Jun 10, 2026

Copy link
Copy Markdown
Member

@zhangning21 Please hang on to the changes, I would like to hear from other maintainers about:

  1. Should we allow PR Metadata inside the PR Body:
    ci: support PR dependencies via depends-on #19075 (comment)
  2. We don't have CI Maintainers who can maintain these changes:
    ci: support PR dependencies via depends-on #19075 (comment)
  3. Overall this PR sounds too complex to implement PR Dependency? NuttX CI is already too complex, we might be making it harder to maintain. And there's GitHub Actions Security to be considered too.

@linguini1

Copy link
Copy Markdown
Contributor

I'm not sure we should allow metadata within the PR body. This is a cool idea but maybe it needs to be put on hold for now.

@lupyuen

lupyuen commented Jun 10, 2026

Copy link
Copy Markdown
Member

Yep I agree that embedding PR Metadata (e.g. depends-on) inside the PR Body can get problematic:

  • When we update the PR Metadata: The PR doesn't auto-rebuild. PR Reviewers might be misled by the metadata.
  • When the PR Metadata is Invalid: We don't see any warnings. This makes it harder to track down CI problems.

If we ever need to support PR Metadata in future, we would need a lot more work:

  1. Parsing the PR Body should be done safely in a separate GitHub Actions Workflow, in GitHub Script (JavaScript). PR Metadata should be carefully validated and stored as PR Labels or PR Artifacts. Similar to our PR Labeling: https://lupyuen.org/articles/prtarget
  2. If there are errors in parsing the PR Body: The GitHub Actions Workflow should trigger a PR Comment, to indicate why the parsing failed
  3. If there are changes to the PR Metadata: It should also trigger a PR Comment, to indicate the changes
  4. But with these changes, NuttX CI might become too complex to maintain :-(

@lupyuen

lupyuen commented Jun 12, 2026

Copy link
Copy Markdown
Member

Hi @zhangning21: I'm sorry that we have to close this PR because:

  1. NuttX Maintainers feel that embedding PR Metadata (like depends-on) inside the PR Body, might confuse PR Authors and PR Reviewers: (1) Editing the PR Metadata won't trigger a rebuild (2) Errors in the PR Metadata are silently ignored
  2. NuttX CI Team doesn't have the awk / sed skills to maintain the proposed Shell Script that safely parses and extracts the PR Metadata from the PR Body. Which might lead to Script Injection Attacks in future updates.

I'm also sorry for your time wasted in preparing this meticulous PR. Perhaps in future, you could create a NuttX Issue first, then assign it to me for discussion, so we can agree on the best solution?

I hope you understand that ASF Infrastructure Team is closely watching our usage of GitHub Actions. They nearly banned NuttX Project twice from using GitHub Actions, due to overuse and security concerns. Thanks :-)

@lupyuen lupyuen closed this Jun 12, 2026
@xiaoxiang781216

xiaoxiang781216 commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

@lupyuen please don't close PR without voting:

Hi @zhangning21: I'm sorry that we have to close this PR because:

  1. NuttX Maintainers feel that embedding PR Metadata (like depends-on) inside the PR Body,

Do you have other better method to fix the patch which has the cross-git dependence, which is a must have feature, but doesn't fix for a long time.

might confuse PR Authors and PR Reviewers: (1) Editing the PR Metadata won't trigger a rebuild

the dependence is described in the commit message, why change in commit message doesn't trigger a rebuild?

(2) Errors in the PR Metadata are silently ignored

if the description is wrong, ci doesn't cherry-pick the related patch on apps side, then ci will fail loudly.

  1. NuttX CI Team doesn't have the awk / sed skills to maintain the proposed Shell Script that safely parses and extracts the PR Metadata from the PR Body. Which might lead to Script Injection Attacks in future updates.

If awk/sed isn't good, let's stick to pure shell script or switch to python.

I'm also sorry for your time wasted in preparing this meticulous PR. Perhaps in future, you could create a NuttX Issue first, then assign it to me for discussion, so we can agree on the best solution?

How to verify the cross-git patch correctly is a well-known issue for our ci build system, not a new issue.

@lupyuen

lupyuen commented Jun 12, 2026

Copy link
Copy Markdown
Member

@xiaoxiang781216 I'm afraid I can't commit to these enhancements for NuttX CI. I'm already overwhelmed by the maintenance of NuttX CI, keeping it performant and secure, as mandated by ASF Infra Team. From now on: I'm stepping away from all NuttX CI Duties, and focusing instead on my Family Matters.

@simbit18 @acassis @cederom @linguini1 @raiden00pl @hartmannathan @jerpelea Sorry I need to take a break from NuttX Project, it's hurting my hypertension. Hope to catch you again in future. Goodbye!

@linguini1

Copy link
Copy Markdown
Contributor

@lupyuen best wishes! Hope to hear from you again soon :)

@acassis

acassis commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

@xiaoxiang781216 I'm afraid I can't commit to these enhancements for NuttX CI. I'm already overwhelmed by the maintenance of NuttX CI, keeping it performant and secure, as mandated by ASF Infra Team. From now on: I'm stepping away from all NuttX CI Duties, and focusing instead on my Family Matters.

@simbit18 @acassis @cederom @linguini1 @raiden00pl @hartmannathan @jerpelea Sorry I need to take a break from NuttX Project, it's hurting my hypertension. Hope to catch you again in future. Goodbye!

Hi @lupyuen that is completely understandable. Take a break and focus on your health and your family!
We are eternally grateful for your great support all these years, be sure you are was an inspiration for many people inclusive for myself.

I'm sure you will continue to do great things! I wish you all the best!

@acassis acassis left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@zhangning21 could you please add those information you added in the Summary into our CI Documentation: https://nuttx.apache.org/docs/latest/testing/nuttx-ci.html

@linguini1 linguini1 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems like a great solution, I think it's really cool and it does solve a huge headache NuttX has had for a while. However, given the concerns from Lup about parsing the PR body, I think before this is merged we should check with Apache Infra about what they think about this solution.

Allow pull requests targeting master to declare same- and
cross-repository dependencies. Parse declarations with a tested Python
helper, apply exact dependency commits before the existing build matrix,
and rerun heavy CI only when an edited description changes the dependency
state.

Keep fork builds read-only and use a trusted workflow_run to validate
artifacts and post per-build dependency results. Document the supported
declaration forms and operational limits.

Assisted-by: Kiro:gpt-5.6-sol
Signed-off-by: zhangning21 <zhangning21@xiaomi.com>
@zhangning21
zhangning21 force-pushed the feature/cross-repo-depends-on branch from b70fca1 to 1c399cf Compare July 21, 2026 13:34
@github-actions github-actions Bot added Size: L The size of the change in this PR is large and removed Size: S The size of the change in this PR is small labels Jul 21, 2026
@xiaoxiang781216

Copy link
Copy Markdown
Contributor

@linguini1 @acassis this pr is ready for review now.

@github-actions

Copy link
Copy Markdown

MemBrowse Memory Report

No memory changes detected for:

@zhangning21

Copy link
Copy Markdown
Author

@zhangning21 could you please add those information you added in the Summary into our CI Documentation: https://nuttx.apache.org/docs/latest/testing/nuttx-ci.html

Thanks @acassis! Done — I've added the Summary details to the CI documentation
you linked. There is now a new "Pull Request Dependencies" section in
Documentation/testing/nuttx-ci.rst covering:

  • the supported Depends-On: declaration forms: one dependency per line or a
    single inline list, short owner/repo/pull/N references or full
    https://github.com/... URLs; the marker is case-insensitive, with
    Depends-On: used as the canonical spelling;
  • master-only behavior: declarations in release and backport PRs are ignored,
    preserving the existing matching-release-branch behavior;
  • ordered dependency handling, including how Fetch-Source fetches each valid
    dependency's head SHA and cherry-picks its commits into the matching checkout
    before the existing build matrix runs;
  • the three report/comment outcomes: ok with the fetched head SHAs, invalid
    when a Depends-On: marker is present but no valid dependency can be parsed,
    and failed when a valid dependency cannot be applied;
  • the edited-description gate and the intentional limitations: no dependency-PR
    state validation through the GitHub API, no automatic retrigger when a
    dependency PR changes, and no automated synchronized merge.

The section renders like this on the CI docs page:

image

@linguini1
linguini1 dismissed their stale review July 21, 2026 14:38

Security concerns appear to be addressed (?)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Area: CI Size: L The size of the change in this PR is large

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FEATURE] Support PR dependencies via depends-on

5 participants