From afdf11fda35140c925e514fb5e128d987a43fba3 Mon Sep 17 00:00:00 2001 From: Russell Martin Date: Fri, 9 Aug 2024 15:57:14 -0400 Subject: [PATCH] Refactor PR Body regexing into independent GH Action --- .github/actions/app-create/action.yml | 66 ++-- .github/actions/install-briefcase/action.yml | 56 +-- .github/actions/pr-body-parse/action.yml | 37 ++ .github/workflows/ci.yml | 377 +++++++++++-------- 4 files changed, 316 insertions(+), 220 deletions(-) create mode 100644 .github/actions/pr-body-parse/action.yml diff --git a/.github/actions/app-create/action.yml b/.github/actions/app-create/action.yml index 7ba5a2c7..1e064e25 100644 --- a/.github/actions/app-create/action.yml +++ b/.github/actions/app-create/action.yml @@ -22,50 +22,54 @@ outputs: project-path: value: ${{ steps.create.outputs.path }} description: "The file path to the root of the created project." + briefcase-template-repo: + value: ${{ steps.template.outputs.repo }} + description: "Template repo used to create app." + briefcase-template-ref: + value: ${{ steps.template.outputs.ref }} + description: "Template ref used to create app." + runs: using: composite steps: - - name: Briefcase Template Override - id: template-override - env: - GITHUB_TOKEN: ${{ github.token }} + - name: Checkout beeware/.github + uses: actions/checkout@v4.1.7 + with: + path: beeware-app-create-.github + + - name: Check for Briefcase Template Repo Override + id: template-repo-override + uses: ./beeware-app-create-.github/.github/actions/pr-body-parse + with: + key-regex: 'BRIEFCASE[-_]*TEMPLATE[-_]*REPO' + testing-pr-body: ${{ inputs.testing-pr-body }} + + - name: Check for Briefcase Template Ref Override + id: template-ref-override + uses: ./beeware-app-create-.github/.github/actions/pr-body-parse + with: + key-regex: 'BRIEFCASE[-_]*TEMPLATE[-_]*REF' + testing-pr-body: ${{ inputs.testing-pr-body }} + + - name: Declare Briefcase Template + id: template shell: bash run: | - # Check Body of PR for template to use - # (only PRs will have a value for github.event.pull_request.number) - PR_BODY="${{ inputs.testing-pr-body }}" - if [[ -z "${PR_BODY}" && -n "${{ github.event.pull_request.number }}" ]]; then - PR_BODY=$(gh api repos/${{ github.repository }}/pulls/${{ github.event.pull_request.number }} --jq '.body') - fi - printf "::group::Retrieved PR Body\n%s\n::endgroup::\n" "${PR_BODY}" + REPO="${{ steps.template-repo-override.outputs.extracted-value || inputs.briefcase-template-source }}" + REF="${{ steps.template-ref-override.outputs.extracted-value || inputs.briefcase-template-branch }}" - TEMPLATE_REPO=$(printf "%s" "${PR_BODY}" | perl -wlne '/BRIEFCASE[-_]*TEMPLATE[-_]*REPO:\s*\K\S+/i and print $&') - TEMPLATE_REF=$(printf "%s" "${PR_BODY}" | perl -wlne '/BRIEFCASE[-_]*TEMPLATE[-_]*REF:\s*\K\S+/i and print $&') - - # If a template is not in the PR, use inputs specified in CI workflow - if [ -z "${TEMPLATE_REPO}" ]; then - TEMPLATE_REPO="${{ inputs.briefcase-template-source }}" + if [ -n "${REPO}" ]; then + printf -- "repo=--template '%q'\n" "${REPO}" | tee -a ${GITHUB_OUTPUT} fi - if [ -z "${TEMPLATE_REF}" ]; then - TEMPLATE_REF="${{ inputs.briefcase-template-branch }}" + if [ -n "${REF}" ]; then + printf -- "ref=--template-branch '%q'\n" "${REF}" | tee -a ${GITHUB_OUTPUT} fi - # Expose template repo and branch via outputs - echo "repo=${TEMPLATE_REPO}" | tee -a ${GITHUB_OUTPUT} - echo "ref=${TEMPLATE_REF}" | tee -a ${GITHUB_OUTPUT} - - name: Create Briefcase Project id: create shell: bash run: | - if [[ "${{ steps.template-override.outputs.repo }}" != "" ]]; then - TEMPLATE=$(printf -- "--template %q" "${{ steps.template-override.outputs.repo }}") - fi - if [[ "${{ steps.template-override.outputs.ref }}" != "" ]]; then - TEMPLATE_BRANCH=$(printf -- "--template-branch %q" "${{ steps.template-override.outputs.ref }}") - fi - # Map GUI toolkit through case insensitivity case "$(tr '[:upper:]' '[:lower:]' <<< "${{ inputs.framework }}")" in toga ) BOOTSTRAP=Toga ;; @@ -89,7 +93,7 @@ runs: rm -rf "${APP_DIR}" # Roll out the project - briefcase new --no-input ${TEMPLATE} ${TEMPLATE_BRANCH} \ + briefcase new --no-input ${{ steps.template.outputs.repo }} ${{ steps.template.outputs.ref }} \ -Q "formal_name=${APP_NAME}" \ -Q "app_name=${APP_DIR}" \ -Q "bootstrap=${BOOTSTRAP}" diff --git a/.github/actions/install-briefcase/action.yml b/.github/actions/install-briefcase/action.yml index 8de59741..c678c40d 100644 --- a/.github/actions/install-briefcase/action.yml +++ b/.github/actions/install-briefcase/action.yml @@ -32,38 +32,38 @@ outputs: runs: using: composite steps: - - name: Use Specified Briefcase Version - id: briefcase-override - env: - GITHUB_TOKEN: ${{ github.token }} + - name: Checkout beeware/.github + uses: actions/checkout@v4.1.7 + with: + path: beeware-install-briefcase-.github + + - name: Check for Briefcase Repo Override + id: briefcase-repo-override + uses: ./beeware-install-briefcase-.github/.github/actions/pr-body-parse + with: + key-regex: 'BRIEFCASE[-_]*REPO' + testing-pr-body: ${{ inputs.testing-pr-body }} + + - name: Check for Briefcase Ref Override + id: briefcase-ref-override + uses: ./beeware-install-briefcase-.github/.github/actions/pr-body-parse + with: + key-regex: 'BRIEFCASE[-_]*REF' + testing-pr-body: ${{ inputs.testing-pr-body }} + + - name: Declare Briefcase Source + id: briefcase shell: bash run: | - # Check Body of PR for Briefcase version to use - # (only PRs will have a value for github.event.pull_request.number) - PR_BODY="${{ inputs.testing-pr-body }}" - if [[ -z "${PR_BODY}" && -n "${{ github.event.pull_request.number }}" ]]; then - PR_BODY=$(gh api repos/${{ github.repository }}/pulls/${{ github.event.pull_request.number }} --jq '.body') - fi - printf "::group::Retrieved PR Body\n%s\n::endgroup::\n" "${PR_BODY}" - - BRIEFCASE_REPO=$(printf "%s" "${PR_BODY}" | perl -wlne '/BRIEFCASE[-_]*REPO:\s*\K\S+/i and print $&') - BRIEFCASE_REF=$(printf "%s" "${PR_BODY}" | perl -wlne '/BRIEFCASE[-_]*REF:\s*\K\S+/i and print $&') - - # If a version is not in the PR, use inputs specified in CI workflow - if [ -z "${BRIEFCASE_REPO}" ]; then - BRIEFCASE_REPO="${{ inputs.briefcase-url }}" - fi - if [ -z "${BRIEFCASE_REF}" ]; then - BRIEFCASE_REF="${{ inputs.briefcase-override-version }}" - fi + REPO="${{ steps.briefcase-repo-override.outputs.extracted-value || inputs.briefcase-url }}" + REF="${{ steps.briefcase-ref-override.outputs.extracted-value || inputs.briefcase-override-version }}" - # Expose repo and version via outputs - echo "repo=${BRIEFCASE_REPO}" | tee -a ${GITHUB_OUTPUT} - echo "ref=${BRIEFCASE_REF}" | tee -a ${GITHUB_OUTPUT} + printf -- "repo=%s\n" "${REPO}" | tee -a ${GITHUB_OUTPUT} + printf -- "ref=%s\n" "${REF}" | tee -a ${GITHUB_OUTPUT} - name: Derive Target Briefcase Version id: briefcase-derived - if: steps.briefcase-override.outputs.ref == '' + if: steps.briefcase.outputs.ref == '' shell: bash run: | # Branch or tag that triggered the workflow. @@ -136,8 +136,8 @@ runs: id: install shell: bash run: | - REPO="${{ steps.briefcase-override.outputs.repo || inputs.briefcase-url }}" - REF="${{ steps.briefcase-override.outputs.ref || steps.briefcase-derived.outputs.version }}" + REPO="${{ steps.briefcase.outputs.repo }}" + REF="${{ steps.briefcase.outputs.ref || steps.briefcase-derived.outputs.version }}" echo "Installing ${REPO}@${REF}" python -m pip install \ diff --git a/.github/actions/pr-body-parse/action.yml b/.github/actions/pr-body-parse/action.yml new file mode 100644 index 00000000..388b04c2 --- /dev/null +++ b/.github/actions/pr-body-parse/action.yml @@ -0,0 +1,37 @@ +name: PR Body Parse +description: Parse a value from the body of the relevant PR for a specific key + +inputs: + key-regex: + description: "The regex for the key identifying the value to return, e.g. BRIEFCASE[-_]*REPO" + required: true + testing-pr-body: + description: "Override value for body of PR; only for testing." + required: false + +outputs: + extracted-value: + value: ${{ steps.parse.outputs.extracted-value }} + description: "The value extracted from the PR's body for the specified key." + +runs: + using: composite + steps: + - name: Parse PR Body for ${{ inputs.key-regex }} + id: parse + env: + GITHUB_TOKEN: ${{ github.token }} + shell: bash + run: | + # Retrieve PR Body (only PRs will have a value for github.event.pull_request.number) + PR_BODY="${{ inputs.testing-pr-body }}" + if [[ -z "${PR_BODY}" && -n "${{ github.event.pull_request.number }}" ]]; then + PR_BODY=$(gh api repos/${{ github.repository }}/pulls/${{ github.event.pull_request.number }} --jq '.body') + fi + printf "::group::Retrieved PR Body\n%s\n::endgroup::\n" "${PR_BODY}" + + # Parse value with given regex + EXTRACTED_VALUE=$(printf "%s" "${PR_BODY}" | perl -wlne '/${{ inputs.key-regex }}:\s*\K\S+/i and print $&') + + # Expose value as an output + printf -- "extracted-value=%s\n" "${EXTRACTED_VALUE}" | tee -a ${GITHUB_OUTPUT} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9f25b46b..dee4aad5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -136,6 +136,61 @@ jobs: exit 1 fi + test-app-create: + name: App Create + needs: pre-commit + runs-on: ubuntu-latest + timeout-minutes: 30 + strategy: + fail-fast: false + matrix: + test-case: [ "default", "override", "pr-body" ] + include: + - expected-repo: "" + expected-ref: "" + override-repo: "" + override-ref: "" + pr-body: "" + - test-case: "override" + override-repo: "https://github.com/beeware/briefcase-template" + override-ref: "main" + expected-repo: "https://github.com/beeware/briefcase-template" + expected-ref: "main" + - test-case: "pr-body" + pr-body: "sadf asdf Briefcase-Template-Repo: https://github.com/beeware/briefcase-template foo BRIEFCASE-template-REF: main" + expected-repo: "https://github.com/beeware/briefcase-template" + expected-ref: "main" + steps: + - name: Checkout beeware/.github + uses: actions/checkout@v4.1.7 + + - name: Set up Python + uses: actions/setup-python@v5.1.1 + with: + python-version: 3.X + cache: pip + cache-dependency-path: | + **/setup.cfg + **/pyproject.toml + .pre-commit-config.yaml + + - name: Install Briefcase + uses: ./.github/actions/install-briefcase + + - name: Create Briefcase App + id: app + uses: ./.github/actions/app-create + with: + briefcase-template-source: ${{ matrix.override-repo }} + briefcase-template-branch: ${{ matrix.override-ref }} + testing-pr-body: ${{ matrix.pr-body }} + + - name: Verify App + shell: python + run: | + assert "${{ steps.app.outputs.briefcase-template-repo }}" == "${{ matrix.expected-repo }}" + assert "${{ steps.app.outputs.briefcase-template-ref }}" == "${{ matrix.expected-ref }}" + test-pre-commit-run: name: Pre-commit needs: pre-commit @@ -267,164 +322,164 @@ jobs: framework: [ toga, pyside6 ] runner-os: [ macos-latest, windows-latest, ubuntu-22.04 ] - test-verify-apps-briefcase: - name: Verify Briefcase - needs: [ pre-commit, test-package-python ] - uses: ./.github/workflows/app-build-verify.yml - with: - python-version: "3.10" # must match system python for ubuntu version - repository: beeware/briefcase - runner-os: ${{ matrix.runner-os }} - framework: ${{ matrix.framework }} - strategy: - fail-fast: false - matrix: - framework: [ toga ] - runner-os: [ macos-latest, windows-latest, ubuntu-22.04 ] - - test-verify-apps-briefcase-template: - name: Verify Briefcase Template - needs: pre-commit - uses: ./.github/workflows/app-build-verify.yml - with: - python-version: "3.11" - repository: beeware/briefcase-template - runner-os: ${{ matrix.runner-os }} - framework: ${{ matrix.framework }} - strategy: - fail-fast: false - matrix: - framework: [ toga ] - runner-os: [ macos-latest, windows-latest, ubuntu-latest ] - - test-verify-apps-android-templates: - name: Verify Android - needs: pre-commit - uses: ./.github/workflows/app-build-verify.yml - with: - python-version: "3.11" - repository: beeware/briefcase-android-gradle-template - runner-os: ${{ matrix.runner-os }} - target-platform: android - target-format: gradle - framework: ${{ matrix.framework }} - strategy: - fail-fast: false - matrix: - framework: [ toga ] # toga only - runner-os: [ macos-latest, windows-latest, ubuntu-latest ] - - test-verify-apps-iOS-templates: - name: Verify iOS - needs: pre-commit - uses: ./.github/workflows/app-build-verify.yml - with: - python-version: "3.11" - repository: beeware/briefcase-iOS-xcode-template - runner-os: macos-latest - target-platform: iOS - target-format: xcode - framework: ${{ matrix.framework }} - strategy: - fail-fast: false - matrix: - framework: [ toga ] # toga only - - test-verify-apps-linux-system-templates: - name: Verify Linux - needs: pre-commit - uses: ./.github/workflows/app-build-verify.yml - with: - python-version: "3.10" # must match system python for ubuntu version - repository: beeware/briefcase-linux-system-template - runner-os: ubuntu-22.04 - target-platform: linux - target-format: system - framework: ${{ matrix.framework }} - strategy: - fail-fast: false - matrix: - framework: [ toga, pyside6, pygame, console ] - - test-verify-apps-appimage-templates: - name: Verify AppImage - needs: pre-commit - uses: ./.github/workflows/app-build-verify.yml - with: - python-version: "3.11" - repository: beeware/briefcase-linux-appimage-template - runner-os: ubuntu-latest - target-platform: linux - target-format: appimage - framework: ${{ matrix.framework }} - strategy: - fail-fast: false - matrix: - # 2024-07-11 (beeware/briefcase#1908): pyside6 segfaults on AppImage start. - framework: [ toga, pygame, console ] - - test-verify-apps-flatpak-templates: - name: Verify Flatpak - needs: pre-commit - uses: ./.github/workflows/app-build-verify.yml - with: - python-version: "3.11" - repository: beeware/briefcase-linux-flatpak-template - runner-os: ubuntu-latest - target-platform: linux - target-format: flatpak - framework: ${{ matrix.framework }} - strategy: - fail-fast: false - matrix: - framework: [ toga, pyside6, pygame, console ] - - test-verify-apps-macOS-templates: - name: Verify macOS - needs: pre-commit - uses: ./.github/workflows/app-build-verify.yml - with: - python-version: "3.11" - repository: beeware/briefcase-macos-${{ matrix.format }}-template - runner-os: macos-latest - target-platform: macOS - target-format: ${{ matrix.format }} - framework: ${{ matrix.framework }} - strategy: - fail-fast: false - matrix: - framework: [ toga, pyside6, pygame, console ] - format: [ app, Xcode ] - - test-verify-apps-web-templates: - name: Verify Web - needs: pre-commit - uses: ./.github/workflows/app-build-verify.yml - with: - python-version: "3.11" - repository: beeware/briefcase-web-static-template - runner-os: ubuntu-latest - target-platform: web - target-format: static - framework: ${{ matrix.framework }} - strategy: - fail-fast: false - matrix: - framework: [ toga ] # toga only - - test-verify-apps-windows-templates: - name: Verify Windows - needs: pre-commit - uses: ./.github/workflows/app-build-verify.yml - with: - python-version: "3.11" - repository: beeware/briefcase-windows-${{ matrix.format }}-template - runner-os: windows-latest - target-platform: windows - target-format: ${{ matrix.format }} - framework: ${{ matrix.framework }} - strategy: - fail-fast: false - matrix: - framework: [ toga, pyside6, pygame, console ] - format: [ app, VisualStudio ] +# test-verify-apps-briefcase: +# name: Verify Briefcase +# needs: [ pre-commit, test-package-python ] +# uses: ./.github/workflows/app-build-verify.yml +# with: +# python-version: "3.10" # must match system python for ubuntu version +# repository: beeware/briefcase +# runner-os: ${{ matrix.runner-os }} +# framework: ${{ matrix.framework }} +# strategy: +# fail-fast: false +# matrix: +# framework: [ toga ] +# runner-os: [ macos-latest, windows-latest, ubuntu-22.04 ] +# +# test-verify-apps-briefcase-template: +# name: Verify Briefcase Template +# needs: pre-commit +# uses: ./.github/workflows/app-build-verify.yml +# with: +# python-version: "3.11" +# repository: beeware/briefcase-template +# runner-os: ${{ matrix.runner-os }} +# framework: ${{ matrix.framework }} +# strategy: +# fail-fast: false +# matrix: +# framework: [ toga ] +# runner-os: [ macos-latest, windows-latest, ubuntu-latest ] +# +# test-verify-apps-android-templates: +# name: Verify Android +# needs: pre-commit +# uses: ./.github/workflows/app-build-verify.yml +# with: +# python-version: "3.11" +# repository: beeware/briefcase-android-gradle-template +# runner-os: ${{ matrix.runner-os }} +# target-platform: android +# target-format: gradle +# framework: ${{ matrix.framework }} +# strategy: +# fail-fast: false +# matrix: +# framework: [ toga ] # toga only +# runner-os: [ macos-latest, windows-latest, ubuntu-latest ] +# +# test-verify-apps-iOS-templates: +# name: Verify iOS +# needs: pre-commit +# uses: ./.github/workflows/app-build-verify.yml +# with: +# python-version: "3.11" +# repository: beeware/briefcase-iOS-xcode-template +# runner-os: macos-latest +# target-platform: iOS +# target-format: xcode +# framework: ${{ matrix.framework }} +# strategy: +# fail-fast: false +# matrix: +# framework: [ toga ] # toga only +# +# test-verify-apps-linux-system-templates: +# name: Verify Linux +# needs: pre-commit +# uses: ./.github/workflows/app-build-verify.yml +# with: +# python-version: "3.10" # must match system python for ubuntu version +# repository: beeware/briefcase-linux-system-template +# runner-os: ubuntu-22.04 +# target-platform: linux +# target-format: system +# framework: ${{ matrix.framework }} +# strategy: +# fail-fast: false +# matrix: +# framework: [ toga, pyside6, pygame, console ] +# +# test-verify-apps-appimage-templates: +# name: Verify AppImage +# needs: pre-commit +# uses: ./.github/workflows/app-build-verify.yml +# with: +# python-version: "3.11" +# repository: beeware/briefcase-linux-appimage-template +# runner-os: ubuntu-latest +# target-platform: linux +# target-format: appimage +# framework: ${{ matrix.framework }} +# strategy: +# fail-fast: false +# matrix: +# # 2024-07-11 (beeware/briefcase#1908): pyside6 segfaults on AppImage start. +# framework: [ toga, pygame, console ] +# +# test-verify-apps-flatpak-templates: +# name: Verify Flatpak +# needs: pre-commit +# uses: ./.github/workflows/app-build-verify.yml +# with: +# python-version: "3.11" +# repository: beeware/briefcase-linux-flatpak-template +# runner-os: ubuntu-latest +# target-platform: linux +# target-format: flatpak +# framework: ${{ matrix.framework }} +# strategy: +# fail-fast: false +# matrix: +# framework: [ toga, pyside6, pygame, console ] +# +# test-verify-apps-macOS-templates: +# name: Verify macOS +# needs: pre-commit +# uses: ./.github/workflows/app-build-verify.yml +# with: +# python-version: "3.11" +# repository: beeware/briefcase-macos-${{ matrix.format }}-template +# runner-os: macos-latest +# target-platform: macOS +# target-format: ${{ matrix.format }} +# framework: ${{ matrix.framework }} +# strategy: +# fail-fast: false +# matrix: +# framework: [ toga, pyside6, pygame, console ] +# format: [ app, Xcode ] +# +# test-verify-apps-web-templates: +# name: Verify Web +# needs: pre-commit +# uses: ./.github/workflows/app-build-verify.yml +# with: +# python-version: "3.11" +# repository: beeware/briefcase-web-static-template +# runner-os: ubuntu-latest +# target-platform: web +# target-format: static +# framework: ${{ matrix.framework }} +# strategy: +# fail-fast: false +# matrix: +# framework: [ toga ] # toga only +# +# test-verify-apps-windows-templates: +# name: Verify Windows +# needs: pre-commit +# uses: ./.github/workflows/app-build-verify.yml +# with: +# python-version: "3.11" +# repository: beeware/briefcase-windows-${{ matrix.format }}-template +# runner-os: windows-latest +# target-platform: windows +# target-format: ${{ matrix.format }} +# framework: ${{ matrix.framework }} +# strategy: +# fail-fast: false +# matrix: +# framework: [ toga, pyside6, pygame, console ] +# format: [ app, VisualStudio ]