From c218cd8a3f7aba9809fe7b568c844f25313e5a44 Mon Sep 17 00:00:00 2001 From: Jennifer Power Date: Thu, 12 Sep 2024 17:55:16 -0400 Subject: [PATCH 1/4] feat: updates workflow approach for testlebot testing Signed-off-by: Jennifer Power --- .github/workflows/autofix-cd.yml | 43 ----------- .github/workflows/create-new.yml | 2 +- .github/workflows/linters.yml | 30 -------- .github/workflows/manual-autofix.yml | 11 --- .github/workflows/manual-transform.yml | 11 --- .../{transform-rules.yml => push-to-main.yml} | 58 ++++++++------- .github/workflows/release.yml | 52 +++++++++++++ .github/workflows/transform-on-push.yml | 18 ----- .../workflows/update-external-components.yml | 74 +++++++++++++++++++ .github/workflows/update-profiles.yml | 4 +- .github/workflows/validate.yml | 50 ++++++------- docs/design.md | 33 ++++----- 12 files changed, 199 insertions(+), 187 deletions(-) delete mode 100644 .github/workflows/autofix-cd.yml delete mode 100644 .github/workflows/linters.yml delete mode 100644 .github/workflows/manual-autofix.yml delete mode 100644 .github/workflows/manual-transform.yml rename .github/workflows/{transform-rules.yml => push-to-main.yml} (56%) create mode 100644 .github/workflows/release.yml delete mode 100644 .github/workflows/transform-on-push.yml create mode 100644 .github/workflows/update-external-components.yml diff --git a/.github/workflows/autofix-cd.yml b/.github/workflows/autofix-cd.yml deleted file mode 100644 index 385a333..0000000 --- a/.github/workflows/autofix-cd.yml +++ /dev/null @@ -1,43 +0,0 @@ -name: Component Definition Autofix - -on: - workflow_call: - inputs: - branch: - required: true - type: string - - -# Using concurrency to ensure any branch-modifying workflows are not run at the same time. -concurrency: - group: sync-${{ inputs.branch }} - cancel-in-progress: true - -jobs: - auto-update: - name: Autofix compdef content - runs-on: ubuntu-latest - steps: - - name: Generate app token - uses: tibdex/github-app-token@v2.1.0 - id: get_installation_token - with: - app_id: ${{ secrets.APP_ID }} - private_key: ${{ secrets.PRIVATE_KEY }} - permissions: >- - {"contents": "write"} - - name: Clone - uses: actions/checkout@v4 - with: - ref: ${{ inputs.branch }} - token: ${{ steps.get_installation_token.outputs.token }} - - name: Autofix components - id: autofix-component - uses: RedHatProductSecurity/trestle-bot/actions/autosync@v0.10.1 - with: - markdown_path: "markdown/components" - oscal_model: "compdef" - branch: ${{ inputs.branch }} - file_pattern: "*.json,markdown/*" - commit_user_name: "trestle-bot[bot]" - commit_user_email: "136850459+trestle-bot[bot]@users.noreply.github.com" diff --git a/.github/workflows/create-new.yml b/.github/workflows/create-new.yml index 765cb64..50d237e 100644 --- a/.github/workflows/create-new.yml +++ b/.github/workflows/create-new.yml @@ -38,7 +38,7 @@ jobs: token: ${{ steps.get_installation_token.outputs.token }} - name: Create new component definition id: create-cd - uses: RedHatProductSecurity/trestle-bot/actions/create-cd@v0.10.1 + uses: RedHatProductSecurity/trestle-bot/actions/create-cd@main with: markdown_path: "markdown/components" profile_name: ${{ github.event.inputs.import_name }} diff --git a/.github/workflows/linters.yml b/.github/workflows/linters.yml deleted file mode 100644 index fbd49c7..0000000 --- a/.github/workflows/linters.yml +++ /dev/null @@ -1,30 +0,0 @@ ---- -name: MegaLinter - -on: - push: - pull_request: - branches: - - main - -concurrency: - group: ${{ github.ref }}-${{ github.workflow }} - cancel-in-progress: true - -jobs: - lint: - name: MegaLinter - runs-on: ubuntu-latest - permissions: - issues: write - pull-requests: write - steps: - - name: Checkout Code - uses: actions/checkout@v4 - - - name: MegaLinter - id: ml - uses: oxsecurity/megalinter@v7 - env: - VALIDATE_ALL_CODEBASE: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }} - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/manual-autofix.yml b/.github/workflows/manual-autofix.yml deleted file mode 100644 index 9d0f2e9..0000000 --- a/.github/workflows/manual-autofix.yml +++ /dev/null @@ -1,11 +0,0 @@ -name: Run autofix adhoc - -on: - workflow_dispatch: - -jobs: - call-autofix: - uses: ./.github/workflows/autofix-cd.yml - with: - branch: ${{ github.ref_name }} - secrets: inherit diff --git a/.github/workflows/manual-transform.yml b/.github/workflows/manual-transform.yml deleted file mode 100644 index ff3d16e..0000000 --- a/.github/workflows/manual-transform.yml +++ /dev/null @@ -1,11 +0,0 @@ -name: Run transform adhoc - -on: - workflow_dispatch: - -jobs: - call-transform: - uses: ./.github/workflows/transform-rules.yml - with: - branch: ${{ github.ref_name }} - secrets: inherit diff --git a/.github/workflows/transform-rules.yml b/.github/workflows/push-to-main.yml similarity index 56% rename from .github/workflows/transform-rules.yml rename to .github/workflows/push-to-main.yml index cd36240..c706de0 100644 --- a/.github/workflows/transform-rules.yml +++ b/.github/workflows/push-to-main.yml @@ -1,20 +1,22 @@ -name: Transform Rules - +name: Push to main on: - workflow_call: - inputs: - branch: - required: true - type: string + push: + branches: + - main + paths: + - 'profiles/**' + - 'catalogs/**' + - 'component-definitions/**' + - 'md_comp/**' + - 'rules/**' -# Using concurrency to ensure any branch-modifying workflows are not run at the same time. concurrency: - group: sync-${{ inputs.branch }} + group: ${{ github.ref }}-${{ github.workflow }} cancel-in-progress: true jobs: - transform-rules: - name: Transform rules content + transform-and-sync: + name: Automatically Sync Content runs-on: ubuntu-latest steps: - name: Generate app token @@ -28,25 +30,31 @@ jobs: - name: Clone uses: actions/checkout@v4 with: - ref: ${{ inputs.branch }} token: ${{ steps.get_installation_token.outputs.token }} - - name: Transform rules - id: transform - uses: RedHatProductSecurity/trestle-bot/actions/rules-transform@v0.10.1 + - name: AutoSync + id: autosync + uses: RedHatProductSecurity/trestle-bot/actions/autosync@main with: - file_pattern: "*.json,rules/*" - branch: ${{ inputs.branch }} - commit_message: "Transform rules to OSCAL [skip ci]" + markdown_path: "markdown/components" + oscal_model: "compdef" + commit_message: "Autosync component definition content [skip ci]" commit_user_name: "trestle-bot[bot]" commit_user_email: "136850459+trestle-bot[bot]@users.noreply.github.com" - - name: Regenerate component definitions - uses: RedHatProductSecurity/trestle-bot/actions/autosync@v0.10.1 + - uses: dorny/paths-filter@v3 + id: changes + with: + filters: | + rules: + - 'rules/**' + - name: Transform + if: steps.changes.outputs.rules == 'true' + id: transform + uses: RedHatProductSecurity/trestle-bot/actions/rules-transform@main with: markdown_path: "markdown/components" - oscal_model: "compdef" - file_pattern: "markdown/*" - branch: ${{ inputs.branch }} - skip_assemble: true - commit_message: "Generate markdown changes [skip ci]" + commit_message: "Auto-transform rules [skip ci]" commit_user_name: "trestle-bot[bot]" commit_user_email: "136850459+trestle-bot[bot]@users.noreply.github.com" + + + diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..31d882b --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,52 @@ +name: Release + +on: + workflow_dispatch: + inputs: + version: + description: 'Release version' + required: true + +jobs: + release: + runs-on: ubuntu-latest + steps: + - name: Generate app token + uses: tibdex/github-app-token@v2.1.0 + id: get_installation_token + with: + app_id: ${{ secrets.APP_ID }} + private_key: ${{ secrets.PRIVATE_KEY }} + permissions: >- + {"contents": "write"} + - name: Clone + uses: actions/checkout@v4 + with: + token: ${{ steps.get_installation_token.outputs.token }} + - name: Autosync + uses: RedHatProductSecurity/trestle-bot/actions/autosync@main + with: + markdown_path: "markdown/components" + oscal_model: "compdef" + commit_message: "Update content for release [skip ci]" + commit_user_name: "trestle-bot[bot]" + commit_user_email: "136850459+trestle-bot[bot]@users.noreply.github.com" + version: ${{ github.event.inputs.version }} + - name: Create and push tags + env: + VERSION: ${{ github.event.inputs.version }} + run: | + git tag "${VERSION}" + git push origin "${VERSION}" + - name: Create Release + uses: actions/github-script@v7 + with: + github-token: ${{ steps.get_installation_token.outputs.token }} + script: | + await github.rest.repos.createRelease({ + owner: context.repo.owner, + repo: context.repo.repo, + tag_name: '${{ github.event.inputs.version }}', + name: 'Release v${{ github.event.inputs.version }}', + generate_release_notes: true, + }) diff --git a/.github/workflows/transform-on-push.yml b/.github/workflows/transform-on-push.yml deleted file mode 100644 index 26a33db..0000000 --- a/.github/workflows/transform-on-push.yml +++ /dev/null @@ -1,18 +0,0 @@ -name: Transform Rules On Push - -# Only run on pushes to branches other than main. Pushes to main should be -# a result of a pull request merge. The transform rules operation is not idempotent -# and the OSCAL JSON will be modified each time it is run. -on: - push: - branches-ignore: - - main - paths: - - 'rules/**' - -jobs: - call-transform: - uses: ./.github/workflows/transform-rules.yml - with: - branch: ${{ github.ref_name }} - secrets: inherit diff --git a/.github/workflows/update-external-components.yml b/.github/workflows/update-external-components.yml new file mode 100644 index 0000000..01163f6 --- /dev/null +++ b/.github/workflows/update-external-components.yml @@ -0,0 +1,74 @@ +name: Transform and update OSCAL content + +on: + workflow_dispatch: + inputs: + cac-reference: + description: 'Compliance as Code git reference' + required: true + default: 'master' + +jobs: + create: + name: Create content + runs-on: ubuntu-latest + container: + image: fedora:latest + steps: + - name: Install Deps + run: dnf install -y cmake make openscap-utils python3-pyyaml bats ansible python3-pip ShellCheck git gcc gcc-c++ python3-devel + - name: Checkout + uses: actions/checkout@v4 + with: + repository: ComplianceAsCode/content + ref: ${{ github.event.inputs.cac-reference }} + - name: Install deps python + run: pip install pcre2 -r requirements.txt -r test-requirements.txt + - name: Build + run: |- + ./build_product ocp4 + ./utils/rule_dir_json.py + ./utils/oscal/build_cd_from_policy.py -o build/ocp4.json -p fedramp_rev5_high -pr ocp4 -c nist_ocp4:high + env: + PYTHONPATH: ${{ github.workspace }} + - name: Create artifacts + uses: actions/upload-artifact@v4 + with: + name: trestle-content + path: build/ocp4.json + + update: + name: Update content + needs: create + runs-on: ubuntu-latest + permissions: + contents: write + pull-requests: write + container: + image: quay.io/continuouscompliance/trestle-bot:v0.10.1 + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Download artifacts + uses: actions/download-artifact@v4 + with: + name: trestle-content + path: /tmp + - name: Import Trestle content + run: | + rm -rf component-definitions/ocp4/ + trestle import -f /tmp/ocp4.json -o ocp4 + - name: Update content + uses: peter-evans/create-pull-request@v5.0.2 + with: + base: main + branch: "oscal-update-${{ github.run_id }}" + delete-branch: true + commit-message: "Update OSCAL content from CaC" + title: "Update OSCAL content from CaC" + body: | + Updates to transformed OCP4 component definitions from CaC. + + Auto-generated by GitHub Actions. + add-paths: | + component-definitions/ \ No newline at end of file diff --git a/.github/workflows/update-profiles.yml b/.github/workflows/update-profiles.yml index f6ef164..50b02fd 100644 --- a/.github/workflows/update-profiles.yml +++ b/.github/workflows/update-profiles.yml @@ -27,7 +27,7 @@ jobs: token: ${{ steps.get_installation_token.outputs.token }} - name: Update from upstream repo id: sync_upstreams - uses: RedHatProductSecurity/trestle-bot/actions/sync-upstreams@v0.10.1 + uses: RedHatProductSecurity/trestle-bot/actions/sync-upstreams@main with: branch: "sync-upstream-${{ github.run_id }}" target_branch: "main" @@ -40,7 +40,7 @@ jobs: https://github.com/RedHatProductSecurity/oscal-profiles@${{ github.event.inputs.ref }} - name: Regenerate component definitions if: ${{ steps.sync_upstreams.outputs.commit }} - uses: RedHatProductSecurity/trestle-bot/actions/autosync@v0.10.1 + uses: RedHatProductSecurity/trestle-bot/actions/autosync@main with: markdown_path: "markdown/components" oscal_model: "compdef" diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml index b3ddfd6..7663586 100644 --- a/.github/workflows/validate.yml +++ b/.github/workflows/validate.yml @@ -1,46 +1,44 @@ -name: Evaluate component definitions +name: Validate PR with CI on: pull_request: branches: - main paths: + - 'profiles/**' + - 'catalogs/**' - 'component-definitions/**' - - 'markdown/components/**' + - 'markdown/**' + - 'rules/**' concurrency: group: ${{ github.ref }}-${{ github.workflow }} cancel-in-progress: true jobs: - test: - name: Evaluate components + transform-and-regenerate: + name: Rules Transform and Content Syncing runs-on: ubuntu-latest - permissions: - contents: read steps: - name: Clone uses: actions/checkout@v4 - - name: Check components - id: check - uses: RedHatProductSecurity/trestle-bot/actions/autosync@v0.10.1 + - name: AutoSync + id: autosync + uses: RedHatProductSecurity/trestle-bot/actions/autosync@main with: - markdown_path: "markdown/components" + markdown_path: "md_comp" oscal_model: "compdef" dry_run: true - - name: Fail - if: ${{ steps.check.outputs.changes == 'true' }} - uses: actions/github-script@v7 + - uses: dorny/paths-filter@v3 + id: changes with: - script: | - core.setFailed('Changes detected. Manual intervention may be required.') - - # Only autofix if the test job fails and the PR is from the same repo - call-autofix: - needs: [test] - if: | - always() && contains(needs.*.result, 'failure') - && github.event.pull_request.base.repo.url == github.event.pull_request.head.repo.url - uses: ./.github/workflows/autofix-cd.yml - with: - branch: ${{ github.head_ref }} - secrets: inherit + filters: | + rules: + - 'rules/**' + - name: Transform + if: steps.changes.outputs.rules == 'true' + id: transform + uses: RedHatProductSecurity/trestle-bot/actions/rules-transform@feat/markdown-generation-transform + with: + markdown_path: "md_comp" + commit_message: "Auto-transform rules [skip ci]" + dry_run: true diff --git a/docs/design.md b/docs/design.md index 5aa40eb..b2b39b0 100644 --- a/docs/design.md +++ b/docs/design.md @@ -11,40 +11,33 @@ Associated Workflows The `create-new` workflow is triggered manually by going to the Action tab. This creates a new OSCAL component definitions in the trestle workspace. A new branch is created and a pull request is opened. -#### AutoFix +#### Transforming to OSCAL Associated Workflows -- [autofix-cd.yml](../.github/workflows/autofix-cd.yml) -- [manual-autofix.yml](../.github/workflows/manual-autofix.yml) - [validate.yml](../.github/workflows/validate.yml) +- [push-to-main.yml](../.github/workflows/push-to-main.yml) +- [release.yml](../.github/workflows/release.yml) -The `validate` workflow is triggered when a pull request is created or updated with updates to component definitions. It validates the trestle workspace and automatically sync any difference between the OSCAL JSON files and trestle managed Markdown files. The same workflow can be triggered through the Action tab using the `Run autofix adhoc` workflow. The `autofix-cd.yml` has all common logic for both workflows. The `validate.yml` and `manual-autofix.yml` workflows adds customer triggers and logic. +The `validate` workflow is triggered when a pull request is created or updated with updates to component definitions. It validates the trestle workspace and tests the changes to sync changes between Markdown, YAML, and JSON sources in `dry-run`` mode. -The `validate` workflow will run checks with read-only permissions when a pull request is opened from a from a fork, but the autofix workflow will not run. +Through `push-to-main` run the same steps as the `validate` workflow, but the changes are pushed back to the branch. -#### Transform +The `release` workflow will assign a version to the JSON content from user input, push the changes back to the default branch and create a +corresponding GitHub release. -Associated Workflows -- [transform-rules.yml](../.github/workflows/transform-rules.yml) -- [manual-transform.yml](../.github/workflows/manual-transform.yml) -- [transform-on-push.yml](../.github/workflows/transform-on-push.yml) - -The `transform-on-push` workflow when files under the `rules` directory are made. This will transform the rules managed in YAML into OSCAL JSON files. The `transform-rules.yml` workflow has all common logic for both workflows. The `manual-transform.yml` and `transform-on-push.yml` workflows adds customer triggers and logic. - -Concurrency groups are in place to ensure this does not run at the same time as any branch altering workflows to avoid overwrite to the branches. This can occur if a branch containing rules updates is modified while a pull request is open for the branch. - -#### Regenerate +#### Update Profile Associated Workflows -- [regenerate-cd.yml](../.github/workflows/regenerate-cd.yml) +- [update-profile.yml](../.github/workflows/update-profile.yml) -The regenerate workflow is triggered when changes to catalogs, profile, or component definitions in OSCAL JSON format are merged to main. This will regenerate the markdown and open a pull request if any changes are found. +The `update-profile` workflow is triggered manually to pull in updated profile information from upstream sources. This will update the profile information in the trestle workspace and open a pull request. #### Update Profile Associated Workflows -- [update-profile.yml](../.github/workflows/update-profile.yml) +- [update-external-components.yml](../.github/workflows/update-external-components.yml) -The `update-profile` workflow is triggered manually to pull in updated profile information from upstream sources. This will update the profile information in the trestle workspace and open a pull request. +The `update-external-components` transforms data from the [`ComplianceAsCode` content](https://github.com/ComplianceAsCode/content) +repository into OSCAL component definitions and updates the workspace. From ff40b52a3f2652f8f97a297a57270ffacb2bd387 Mon Sep 17 00:00:00 2001 From: Jennifer Power Date: Thu, 12 Sep 2024 17:58:06 -0400 Subject: [PATCH 2/4] chore: restore linters.yml workflow Signed-off-by: Jennifer Power --- .github/workflows/linters.yml | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 .github/workflows/linters.yml diff --git a/.github/workflows/linters.yml b/.github/workflows/linters.yml new file mode 100644 index 0000000..d2bfd52 --- /dev/null +++ b/.github/workflows/linters.yml @@ -0,0 +1,31 @@ +--- + +name: MegaLinter + +on: + push: + pull_request: + branches: + - main + +concurrency: + group: ${{ github.ref }}-${{ github.workflow }} + cancel-in-progress: true + +jobs: + lint: + name: MegaLinter + runs-on: ubuntu-latest + permissions: + issues: write + pull-requests: write + steps: + - name: Checkout Code + uses: actions/checkout@v4 + + - name: MegaLinter + id: ml + uses: oxsecurity/megalinter@v7 + env: + VALIDATE_ALL_CODEBASE: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file From f0fce37a7baa1f2bd0f93227a6794d416cb9917c Mon Sep 17 00:00:00 2001 From: Jennifer Power Date: Thu, 12 Sep 2024 18:04:01 -0400 Subject: [PATCH 3/4] chore: updates component markdown location Signed-off-by: Jennifer Power --- .github/workflows/push-to-main.yml | 2 +- .github/workflows/validate.yml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/push-to-main.yml b/.github/workflows/push-to-main.yml index c706de0..11648d3 100644 --- a/.github/workflows/push-to-main.yml +++ b/.github/workflows/push-to-main.yml @@ -7,7 +7,7 @@ on: - 'profiles/**' - 'catalogs/**' - 'component-definitions/**' - - 'md_comp/**' + - 'markdown/components/**' - 'rules/**' concurrency: diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml index 7663586..5172cf7 100644 --- a/.github/workflows/validate.yml +++ b/.github/workflows/validate.yml @@ -25,7 +25,7 @@ jobs: id: autosync uses: RedHatProductSecurity/trestle-bot/actions/autosync@main with: - markdown_path: "md_comp" + markdown_path: "markdown/components" oscal_model: "compdef" dry_run: true - uses: dorny/paths-filter@v3 @@ -39,6 +39,6 @@ jobs: id: transform uses: RedHatProductSecurity/trestle-bot/actions/rules-transform@feat/markdown-generation-transform with: - markdown_path: "md_comp" + markdown_path: "markdown/components" commit_message: "Auto-transform rules [skip ci]" dry_run: true From 85a3bd325276b4f0f00af68c57fd73e0c0fb2284 Mon Sep 17 00:00:00 2001 From: Jennifer Power Date: Fri, 13 Sep 2024 16:37:30 -0400 Subject: [PATCH 4/4] fix: fixes linting errors in YAML Signed-off-by: Jennifer Power --- .github/workflows/linters.yml | 10 +++++----- .github/workflows/push-to-main.yml | 5 +---- .github/workflows/update-external-components.yml | 2 +- .github/workflows/update-profiles.yml | 1 - 4 files changed, 7 insertions(+), 11 deletions(-) diff --git a/.github/workflows/linters.yml b/.github/workflows/linters.yml index d2bfd52..5ae0455 100644 --- a/.github/workflows/linters.yml +++ b/.github/workflows/linters.yml @@ -6,12 +6,12 @@ on: push: pull_request: branches: - - main - + - main + concurrency: group: ${{ github.ref }}-${{ github.workflow }} cancel-in-progress: true - + jobs: lint: name: MegaLinter @@ -22,10 +22,10 @@ jobs: steps: - name: Checkout Code uses: actions/checkout@v4 - + - name: MegaLinter id: ml uses: oxsecurity/megalinter@v7 env: VALIDATE_ALL_CODEBASE: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }} - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/push-to-main.yml b/.github/workflows/push-to-main.yml index 11648d3..7cb5094 100644 --- a/.github/workflows/push-to-main.yml +++ b/.github/workflows/push-to-main.yml @@ -52,9 +52,6 @@ jobs: uses: RedHatProductSecurity/trestle-bot/actions/rules-transform@main with: markdown_path: "markdown/components" - commit_message: "Auto-transform rules [skip ci]" + commit_message: "Auto-transform rules [skip ci]" commit_user_name: "trestle-bot[bot]" commit_user_email: "136850459+trestle-bot[bot]@users.noreply.github.com" - - - diff --git a/.github/workflows/update-external-components.yml b/.github/workflows/update-external-components.yml index 01163f6..9ceca76 100644 --- a/.github/workflows/update-external-components.yml +++ b/.github/workflows/update-external-components.yml @@ -71,4 +71,4 @@ jobs: Auto-generated by GitHub Actions. add-paths: | - component-definitions/ \ No newline at end of file + component-definitions/ diff --git a/.github/workflows/update-profiles.yml b/.github/workflows/update-profiles.yml index 50b02fd..643483e 100644 --- a/.github/workflows/update-profiles.yml +++ b/.github/workflows/update-profiles.yml @@ -50,4 +50,3 @@ jobs: commit_message: "Generate markdown changes [skip ci]" commit_user_name: "trestle-bot[bot]" commit_user_email: "136850459+trestle-bot[bot]@users.noreply.github.com" -