Model baud rate generator and SCLK divider #1820
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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)', | |
| // Quick runs can legitimately take >15min, especially with queueing. | |
| maxPolls: 180, | |
| }); | |
| 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. |