mirror of
https://github.com/esp-rs/esp-hal.git
synced 2026-03-14 00:13:08 +00:00
* deduplicate huge bash code-blocks in `dispatch.yml` * fix function name after change * format
596 lines
21 KiB
YAML
596 lines
21 KiB
YAML
name: Dispatch
|
|
|
|
on:
|
|
# labels on PRs
|
|
pull_request_target:
|
|
types: [labeled]
|
|
# slash commands & trust commands
|
|
issue_comment:
|
|
types: [created, edited]
|
|
|
|
permissions:
|
|
actions: write
|
|
pull-requests: write
|
|
contents: read
|
|
|
|
jobs:
|
|
# ---------------------------------------------------------------------------
|
|
# LABEL: TRUSTED AUTHOR
|
|
# ---------------------------------------------------------------------------
|
|
label-trusted-author:
|
|
if: github.event_name == 'pull_request_target' &&
|
|
github.event.label.name == 'trusted-author'
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
with:
|
|
fetch-depth: 1
|
|
|
|
- name: Get PR author login
|
|
id: pr
|
|
uses: actions/github-script@v7
|
|
with:
|
|
script: |
|
|
const login = (context.payload.pull_request.user.login || '').toLowerCase();
|
|
if (!login) {
|
|
core.setFailed('Could not determine PR author login');
|
|
return;
|
|
}
|
|
core.setOutput('login', login);
|
|
|
|
- id: find
|
|
uses: peter-evans/find-comment@v3
|
|
with:
|
|
issue-number: ${{ github.event.pull_request.number }}
|
|
comment-author: github-actions[bot]
|
|
body-includes: "[HIL trust list]"
|
|
|
|
- name: Upsert trust list for author
|
|
id: upsert
|
|
uses: actions/github-script@v7
|
|
with:
|
|
script: |
|
|
const { upsertTrusted } = require('./.github/scripts/hil-trust.js');
|
|
const existing = `${{ toJson(steps.find.outputs.comment-body || '') }}`;
|
|
const login = '${{ steps.pr.outputs.login }}'.toLowerCase();
|
|
|
|
const { body } = upsertTrusted(existing, login);
|
|
core.setOutput('body', body);
|
|
|
|
- uses: peter-evans/create-or-update-comment@v4
|
|
with:
|
|
issue-number: ${{ github.event.pull_request.number }}
|
|
comment-id: ${{ steps.find.outputs.comment-id }}
|
|
body: ${{ steps.upsert.outputs.body }}
|
|
edit-mode: replace
|
|
|
|
- uses: peter-evans/create-or-update-comment@v4
|
|
with:
|
|
issue-number: ${{ github.event.pull_request.number }}
|
|
body: |
|
|
Author **@${{ steps.pr.outputs.login }}** was trusted for this PR via the `trusted-author` label.
|
|
They can now use `/hil quick`, `/hil full` and `/hil <CHIPS>` and their features.
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# TRUST MANAGEMENT (/trust, /revoke)
|
|
# ---------------------------------------------------------------------------
|
|
|
|
trust:
|
|
if: >
|
|
github.event_name == 'issue_comment' &&
|
|
github.event.issue.pull_request &&
|
|
(github.event.comment.author_association == 'MEMBER' ||
|
|
github.event.comment.author_association == 'OWNER') &&
|
|
startsWith(github.event.comment.body, '/trust ')
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
with:
|
|
fetch-depth: 1
|
|
|
|
- name: Parse login
|
|
id: parse
|
|
uses: actions/github-script@v7
|
|
with:
|
|
script: |
|
|
const { parseTrustCommand } = require('./.github/scripts/hil-trust.js');
|
|
const res = parseTrustCommand(context.payload.comment.body, 'trust');
|
|
if (res.error) core.setFailed(res.error);
|
|
core.setOutput('login', res.login);
|
|
|
|
- id: find
|
|
uses: peter-evans/find-comment@v3
|
|
with:
|
|
issue-number: ${{ github.event.issue.number }}
|
|
comment-author: github-actions[bot]
|
|
body-includes: "[HIL trust list]"
|
|
|
|
- name: Upsert trust list
|
|
id: upsert
|
|
uses: actions/github-script@v7
|
|
with:
|
|
script: |
|
|
const { upsertTrusted } = require('./.github/scripts/hil-trust.js');
|
|
const existing = `${{ toJson(steps.find.outputs.comment-body || '') }}`;
|
|
const login = '${{ steps.parse.outputs.login }}'.toLowerCase();
|
|
|
|
const { body } = upsertTrusted(existing, login);
|
|
core.setOutput('body', body);
|
|
|
|
- uses: peter-evans/create-or-update-comment@v4
|
|
with:
|
|
issue-number: ${{ github.event.issue.number }}
|
|
comment-id: ${{ steps.find.outputs.comment-id }}
|
|
body: ${{ steps.upsert.outputs.body }}
|
|
edit-mode: replace
|
|
|
|
- uses: peter-evans/create-or-update-comment@v4
|
|
with:
|
|
issue-number: ${{ github.event.issue.number }}
|
|
# separate short confirmation comment
|
|
body: "Trusted **@${{ steps.parse.outputs.login }}** for this PR. They can now use `/hil quick`, `/hil full` and `/hil <CHIPS>` and their features."
|
|
|
|
revoke:
|
|
if: >
|
|
github.event_name == 'issue_comment' &&
|
|
github.event.issue.pull_request &&
|
|
(github.event.comment.author_association == 'MEMBER' ||
|
|
github.event.comment.author_association == 'OWNER') &&
|
|
startsWith(github.event.comment.body, '/revoke ')
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
with:
|
|
fetch-depth: 1
|
|
|
|
- name: Parse login
|
|
id: parse
|
|
uses: actions/github-script@v7
|
|
with:
|
|
script: |
|
|
const { parseTrustCommand } = require('./.github/scripts/hil-trust.js');
|
|
const res = parseTrustCommand(context.payload.comment.body, 'revoke');
|
|
if (res.error) core.setFailed(res.error);
|
|
core.setOutput('login', res.login);
|
|
|
|
- id: find
|
|
uses: peter-evans/find-comment@v3
|
|
with:
|
|
issue-number: ${{ github.event.issue.number }}
|
|
comment-author: github-actions[bot]
|
|
body-includes: "[HIL trust list]"
|
|
|
|
- name: Remove from trust list
|
|
id: update
|
|
uses: actions/github-script@v7
|
|
with:
|
|
script: |
|
|
const { revokeTrusted } = require('./.github/scripts/hil-trust.js');
|
|
const existing = `${{ toJson(steps.find.outputs.comment-body || '') }}`;
|
|
const login = '${{ steps.parse.outputs.login }}'.toLowerCase();
|
|
|
|
const { body } = revokeTrusted(existing, login);
|
|
core.setOutput('body', body);
|
|
|
|
- uses: peter-evans/create-or-update-comment@v4
|
|
with:
|
|
issue-number: ${{ github.event.issue.number }}
|
|
comment-id: ${{ steps.find.outputs.comment-id }}
|
|
body: ${{ steps.update.outputs.body }}
|
|
edit-mode: replace
|
|
|
|
- uses: peter-evans/create-or-update-comment@v4
|
|
with:
|
|
issue-number: ${{ github.event.issue.number }}
|
|
body: "Revoked **@${{ steps.parse.outputs.login }}** for this PR."
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# SLASH-BASED DISPATCHES (/hil quick, /hil full, /hil <chips...>)
|
|
# ---------------------------------------------------------------------------
|
|
|
|
auth:
|
|
# Only PR comments need auth
|
|
if: github.event_name == 'issue_comment' && github.event.issue.pull_request
|
|
runs-on: ubuntu-latest
|
|
outputs:
|
|
allowed: ${{ steps.check.outputs.allowed }}
|
|
steps:
|
|
- id: check
|
|
uses: actions/github-script@v7
|
|
with:
|
|
script: |
|
|
const assoc = context.payload.comment.author_association;
|
|
const commenter = context.payload.comment.user.login.toLowerCase();
|
|
const pr = context.payload.issue.number;
|
|
|
|
if (assoc === 'MEMBER' || assoc === 'OWNER') {
|
|
core.setOutput('allowed', 'true');
|
|
return;
|
|
}
|
|
|
|
const { owner, repo } = context.repo;
|
|
const comments = await github.paginate(
|
|
github.rest.issues.listComments,
|
|
{ owner, repo, issue_number: pr, per_page: 100 }
|
|
);
|
|
const trust = comments.find(c =>
|
|
c.user?.login === 'github-actions[bot]' &&
|
|
typeof c.body === 'string' &&
|
|
c.body.includes('HIL_TRUST_JSON')
|
|
);
|
|
|
|
let allowed = false;
|
|
if (trust) {
|
|
const m = trust.body.match(/<!--\s*HIL_TRUST_JSON\s*([\s\S]*?)\s*HIL_TRUST_JSON\s*-->/);
|
|
if (m && m[1]) {
|
|
try {
|
|
const data = JSON.parse(m[1]);
|
|
const list = (data.trusted || []).map(s => String(s).toLowerCase());
|
|
allowed = list.includes(commenter);
|
|
} catch {}
|
|
}
|
|
}
|
|
core.setOutput('allowed', allowed ? 'true' : 'false');
|
|
|
|
hil-quick:
|
|
needs: auth
|
|
if: github.event_name == 'issue_comment' &&
|
|
needs.auth.outputs.allowed == 'true' &&
|
|
startsWith(github.event.comment.body, '/hil quick')
|
|
runs-on: ubuntu-latest
|
|
outputs:
|
|
run_id: ${{ steps.find-run.outputs.run_id }}
|
|
comment_id: ${{ steps.comment.outputs.comment-id }}
|
|
steps:
|
|
- uses: actions/checkout@v4 # for `require`
|
|
with:
|
|
fetch-depth: 1
|
|
|
|
- name: Parse tests
|
|
id: parse-tests
|
|
uses: actions/github-script@v7
|
|
with:
|
|
script: |
|
|
const { parseTests } = require('./.github/scripts/hil-parse.js');
|
|
core.setOutput('tests', parseTests(context.payload.comment.body));
|
|
|
|
- name: Dispatch HIL (quick)
|
|
uses: benc-uk/workflow-dispatch@v1
|
|
with:
|
|
workflow: hil.yml
|
|
ref: ${{ github.event.repository.default_branch }}
|
|
inputs: |
|
|
{
|
|
"repository": "${{ github.repository }}",
|
|
"branch": "refs/pull/${{ github.event.issue.number }}/head",
|
|
"matrix": "quick",
|
|
"pr_number": "${{ github.event.issue.number }}",
|
|
"chips": "",
|
|
"tests": "${{ steps.parse-tests.outputs.tests }}"
|
|
}
|
|
|
|
- name: Find HIL run URL (quick)
|
|
id: find-run
|
|
uses: actions/github-script@v7
|
|
with:
|
|
script: |
|
|
const { findHilRun } = require('./.github/scripts/hil-find-run.js');
|
|
|
|
const { runId, body } = await findHilRun({
|
|
github,
|
|
context,
|
|
pr: context.payload.issue.number,
|
|
selector: 'quick',
|
|
tests: '${{ steps.parse-tests.outputs.tests }}',
|
|
});
|
|
|
|
core.setOutput('run_id', runId);
|
|
core.setOutput('body', body);
|
|
|
|
- name: Confirm in PR
|
|
id: comment
|
|
uses: peter-evans/create-or-update-comment@v4
|
|
with:
|
|
issue-number: ${{ github.event.issue.number }}
|
|
body: ${{ steps.find-run.outputs.body }}
|
|
|
|
hil-quick-status:
|
|
needs: hil-quick
|
|
if: needs.hil-quick.outputs.run_id != '' && needs.hil-quick.outputs.comment_id != ''
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v4 # for `require`
|
|
with:
|
|
fetch-depth: 1
|
|
|
|
- name: Wait for quick HIL run and update comment
|
|
uses: actions/github-script@v7
|
|
with:
|
|
script: |
|
|
const { pollRun } = require('./.github/scripts/hil-status.js');
|
|
|
|
await pollRun({
|
|
github,
|
|
context,
|
|
runId: Number('${{ needs.hil-quick.outputs.run_id }}'),
|
|
commentId: Number('${{ needs.hil-quick.outputs.comment_id }}'),
|
|
kind: 'HIL (quick)',
|
|
});
|
|
|
|
hil-full:
|
|
needs: auth
|
|
if: github.event_name == 'issue_comment' &&
|
|
needs.auth.outputs.allowed == 'true' &&
|
|
startsWith(github.event.comment.body, '/hil full')
|
|
runs-on: ubuntu-latest
|
|
outputs:
|
|
run_id: ${{ steps.find-run.outputs.run_id }}
|
|
comment_id: ${{ steps.comment.outputs.comment-id }}
|
|
steps:
|
|
- uses: actions/checkout@v4 # for `require`
|
|
with:
|
|
fetch-depth: 1
|
|
|
|
- name: Parse tests
|
|
id: parse-tests
|
|
uses: actions/github-script@v7
|
|
with:
|
|
script: |
|
|
const { parseTests } = require('./.github/scripts/hil-parse.js');
|
|
core.setOutput('tests', parseTests(context.payload.comment.body));
|
|
|
|
- name: Dispatch HIL (full)
|
|
uses: benc-uk/workflow-dispatch@v1
|
|
with:
|
|
workflow: hil.yml
|
|
ref: ${{ github.event.repository.default_branch }}
|
|
inputs: |
|
|
{
|
|
"repository": "${{ github.repository }}",
|
|
"branch": "refs/pull/${{ github.event.issue.number }}/head",
|
|
"matrix": "full",
|
|
"pr_number": "${{ github.event.issue.number }}",
|
|
"chips": "",
|
|
"tests": "${{ steps.parse-tests.outputs.tests }}"
|
|
}
|
|
|
|
- name: Find HIL run URL (full)
|
|
id: find-run
|
|
uses: actions/github-script@v7
|
|
with:
|
|
script: |
|
|
const { findHilRun } = require('./.github/scripts/hil-find-run.js');
|
|
|
|
const { runId, body } = await findHilRun({
|
|
github,
|
|
context,
|
|
pr: context.payload.issue.number,
|
|
selector: 'full',
|
|
tests: '${{ steps.parse-tests.outputs.tests }}',
|
|
});
|
|
|
|
core.setOutput('run_id', runId);
|
|
core.setOutput('body', body);
|
|
|
|
- name: Confirm in PR
|
|
id: comment
|
|
uses: peter-evans/create-or-update-comment@v4
|
|
with:
|
|
issue-number: ${{ github.event.issue.number }}
|
|
body: ${{ steps.find-run.outputs.body }}
|
|
|
|
hil-full-status:
|
|
needs: hil-full
|
|
if: needs.hil-full.outputs.run_id != '' && needs.hil-full.outputs.comment_id != ''
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v4 # for `require`
|
|
with:
|
|
fetch-depth: 1
|
|
|
|
- name: Wait for full HIL run and update comment
|
|
uses: actions/github-script@v7
|
|
with:
|
|
script: |
|
|
const { pollRun } = require('./.github/scripts/hil-status.js');
|
|
|
|
await pollRun({
|
|
github,
|
|
context,
|
|
runId: Number('${{ needs.hil-full.outputs.run_id }}'),
|
|
commentId: Number('${{ needs.hil-full.outputs.comment_id }}'),
|
|
kind: 'HIL (full)',
|
|
});
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# PER-CHIP HIL: /hil esp32c3 [esp32s3 ...] [--tests ...]
|
|
# ---------------------------------------------------------------------------
|
|
|
|
hil-chips:
|
|
needs: auth
|
|
if: github.event_name == 'issue_comment' &&
|
|
needs.auth.outputs.allowed == 'true' &&
|
|
startsWith(github.event.comment.body, '/hil ') &&
|
|
!startsWith(github.event.comment.body, '/hil quick') &&
|
|
!startsWith(github.event.comment.body, '/hil full')
|
|
runs-on: ubuntu-latest
|
|
outputs:
|
|
run_id: ${{ steps.find-run.outputs.run_id }}
|
|
comment_id: ${{ steps.comment.outputs.comment-id }}
|
|
steps:
|
|
- uses: actions/checkout@v4 # for `require`
|
|
with:
|
|
fetch-depth: 1
|
|
|
|
- name: Parse chips
|
|
id: parse
|
|
uses: actions/github-script@v7
|
|
with:
|
|
script: |
|
|
const { parseChips } = require('./.github/scripts/hil-parse.js');
|
|
|
|
const res = parseChips(context.payload.comment.body);
|
|
|
|
core.setOutput('chips', res.chips);
|
|
core.setOutput('chips_label', res.chipsLabel);
|
|
core.setOutput('error', res.error);
|
|
|
|
- name: Parse tests
|
|
id: parse-tests
|
|
uses: actions/github-script@v7
|
|
with:
|
|
script: |
|
|
const { parseTests } = require('./.github/scripts/hil-parse.js');
|
|
core.setOutput('tests', parseTests(context.payload.comment.body));
|
|
|
|
- name: Report invalid chips
|
|
if: steps.parse.outputs.chips == '' && steps.parse.outputs.error != ''
|
|
uses: peter-evans/create-or-update-comment@v4
|
|
with:
|
|
issue-number: ${{ github.event.issue.number }}
|
|
body: |
|
|
@${{ github.event.comment.user.login }}, HIL **per-chip** request failed: ${{ steps.parse.outputs.error }}
|
|
|
|
- name: Dispatch HIL (per-chip)
|
|
if: steps.parse.outputs.chips != ''
|
|
uses: benc-uk/workflow-dispatch@v1
|
|
with:
|
|
workflow: hil.yml
|
|
ref: ${{ github.event.repository.default_branch }}
|
|
inputs: |
|
|
{
|
|
"repository": "${{ github.repository }}",
|
|
"branch": "refs/pull/${{ github.event.issue.number }}/head",
|
|
"matrix": "chips",
|
|
"pr_number": "${{ github.event.issue.number }}",
|
|
"chips": "${{ steps.parse.outputs.chips }}",
|
|
"tests": "${{ steps.parse-tests.outputs.tests }}"
|
|
}
|
|
|
|
- name: Find HIL run URL (per-chip)
|
|
if: steps.parse.outputs.chips != ''
|
|
id: find-run
|
|
uses: actions/github-script@v7
|
|
with:
|
|
script: |
|
|
const { findHilRun } = require('./.github/scripts/hil-find-run.js');
|
|
|
|
const { runId, body } = await findHilRun({
|
|
github,
|
|
context,
|
|
pr: context.payload.issue.number,
|
|
selector: '${{ steps.parse.outputs.chips }}',
|
|
tests: '${{ steps.parse-tests.outputs.tests }}',
|
|
});
|
|
|
|
core.setOutput('run_id', runId);
|
|
core.setOutput('body', body);
|
|
|
|
- name: Confirm in PR
|
|
if: steps.parse.outputs.chips != ''
|
|
id: comment
|
|
uses: peter-evans/create-or-update-comment@v4
|
|
with:
|
|
issue-number: ${{ github.event.issue.number }}
|
|
body: ${{ steps.find-run.outputs.body }}
|
|
|
|
hil-chips-status:
|
|
needs: hil-chips
|
|
if: needs.hil-chips.outputs.run_id != '' && needs.hil-chips.outputs.comment_id != ''
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v4 # for `require`
|
|
with:
|
|
fetch-depth: 1
|
|
|
|
- name: Wait for per-chip HIL run and update comment
|
|
uses: actions/github-script@v7
|
|
with:
|
|
script: |
|
|
const { pollRun } = require('./.github/scripts/hil-status.js');
|
|
|
|
await pollRun({
|
|
github,
|
|
context,
|
|
runId: Number('${{ needs.hil-chips.outputs.run_id }}'),
|
|
commentId: Number('${{ needs.hil-chips.outputs.comment_id }}'),
|
|
kind: 'HIL (per-chip)',
|
|
});
|
|
|
|
hil-deny:
|
|
needs: auth
|
|
if:
|
|
github.event_name == 'issue_comment' && needs.auth.outputs.allowed != 'true' &&
|
|
(startsWith(github.event.comment.body, '/hil quick') ||
|
|
startsWith(github.event.comment.body, '/hil full') ||
|
|
startsWith(github.event.comment.body, '/hil ') ||
|
|
startsWith(github.event.comment.body, '/test-size'))
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- name: Inform not allowed
|
|
uses: peter-evans/create-or-update-comment@v4
|
|
with:
|
|
issue-number: ${{ github.event.issue.number }}
|
|
body: |
|
|
@${{ github.event.comment.user.login }}, sorry — you're not allowed to execute HIL runs or binary size analysis for this PR.
|
|
Please ask an `esp-rs` member/owner to grant access with:
|
|
```
|
|
/trust @${{ github.event.comment.user.login }}
|
|
```
|
|
After that, you can use `/hil quick`, `/hil full`, `/hil <chips...>` or `/test-size`.
|
|
|
|
hil-help:
|
|
if: github.event_name == 'issue_comment' &&
|
|
github.event.issue.pull_request &&
|
|
startsWith(github.event.comment.body, '/hil') &&
|
|
!startsWith(github.event.comment.body, '/hil quick') &&
|
|
!startsWith(github.event.comment.body, '/hil full') &&
|
|
!contains(github.event.comment.body, 'esp32')
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- name: Explain usage
|
|
uses: peter-evans/create-or-update-comment@v4
|
|
with:
|
|
issue-number: ${{ github.event.issue.number }}
|
|
body: |
|
|
Usage:
|
|
- `/hil quick` — run a quick HIL matrix (only `ESP32-S3` (Xtensa) and `ESP32-C6` (RISC-V) tests)
|
|
- `/hil full` — run the full HIL matrix for all supported chips
|
|
- `/hil <chip> [<chip> ...]` — run the full HIL tests **only** for the listed chips
|
|
- `/test-size` — run binary size analysis for this PR
|
|
- You can optionally append `--test <name>[,<name>...]` to any `/hil` command to only run selected tests.
|
|
If you aren't a repository **member/owner**, you must be **trusted for this PR**.
|
|
Maintainers can grant access with a `trusted-author` label or with:
|
|
```
|
|
/trust @<login>
|
|
```
|
|
and revoke with:
|
|
```
|
|
/revoke @<login>
|
|
```
|
|
|
|
binary-size:
|
|
needs: auth
|
|
if: github.event_name == 'issue_comment' &&
|
|
needs.auth.outputs.allowed == 'true' &&
|
|
startsWith(github.event.comment.body, '/test-size')
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- name: Dispatch Binary Size Analysis
|
|
uses: benc-uk/workflow-dispatch@v1
|
|
with:
|
|
workflow: binary-size.yml
|
|
ref: ${{ github.event.repository.default_branch }}
|
|
inputs: |
|
|
{
|
|
"pr_number": "${{ github.event.issue.number }}"
|
|
}
|
|
|
|
- name: Confirm in PR
|
|
uses: peter-evans/create-or-update-comment@v4
|
|
with:
|
|
issue-number: ${{ github.event.issue.number }}
|
|
body: >
|
|
Triggered binary size analysis for
|
|
#${{ github.event.issue.number }}. Results will be posted as a comment when ready.
|