From 4910617834e2c4bec51e5b724341ce17decbf38a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Proch=C3=A1zka?= <1665677+jprochazk@users.noreply.github.com> Date: Wed, 28 Jun 2023 21:11:01 +0200 Subject: [PATCH] Link to demo in PR + check checkboxes (#2543) ### What Part of https://github.com/rerun-io/rerun/issues/2167 ### Checklist * [x] I have read and agree to [Contributor Guide](https://github.com/rerun-io/rerun/blob/main/CONTRIBUTING.md) and the [Code of Conduct](https://github.com/rerun-io/rerun/blob/main/CODE_OF_CONDUCT.md) * [x] I've included a screenshot or gif (if applicable) * [x] I have tested https://demo.rerun.io/pr/2543 (if applicable) PR Build Summary: https://build.rerun.io/pr/2543 Docs preview: https://rerun.io/preview/2ceab68/docs Examples preview: https://rerun.io/preview/2ceab68/examples --- .github/pull_request_template.md | 1 + .github/workflows/README.md | 1 + .github/workflows/checkboxes.yml | 46 +++++++++++++++++++ .github/workflows/on_pull_request.yml | 29 ++++++------ .github/workflows/reusable_checks.yml | 26 ++++++----- ...k_docs.yml => reusable_update_pr_body.yml} | 19 ++++---- .../workflows/reusable_upload_web_demo.yml | 21 +++++++-- scripts/check_pr_checkboxes.py | 37 +++++++++++++++ scripts/requirements-dev.txt | 2 +- .../{pr_link_docs.py => update_pr_body.py} | 24 ++++++---- 10 files changed, 156 insertions(+), 50 deletions(-) create mode 100644 .github/workflows/checkboxes.yml rename .github/workflows/{reusable_pr_link_docs.yml => reusable_update_pr_body.yml} (61%) create mode 100755 scripts/check_pr_checkboxes.py rename scripts/{pr_link_docs.py => update_pr_body.py} (75%) diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 106a9bbd9245..87bbdebf4b99 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -15,6 +15,7 @@ To get an auto-generated PR description you can put "copilot:summary" or "copilo ### Checklist * [ ] I have read and agree to [Contributor Guide](https://github.com/rerun-io/rerun/blob/main/CONTRIBUTING.md) and the [Code of Conduct](https://github.com/rerun-io/rerun/blob/main/CODE_OF_CONDUCT.md) * [ ] I've included a screenshot or gif (if applicable) +* [ ] I have tested https://demo.rerun.io/pr/{{ pr-number }} (if applicable) PR Build Summary: {{ pr-build-summary }} diff --git a/.github/workflows/README.md b/.github/workflows/README.md index 36a5da5e255d..4db53f915f8b 100644 --- a/.github/workflows/README.md +++ b/.github/workflows/README.md @@ -59,6 +59,7 @@ uploaded anywhere. - `RELEASE_VERSION` - If producing a release, the version number. - `UPLOAD_COMMIT_OVERRIDE` - If set, will replace the value of ``. This is necessary because we want pull request builds associated with their originating commit, even if the web-build happens on an ephemeral merge-commit. + - `PR_NUMBER` - If set, will upload `demo.rerun.io/pr/` - [reusable_pr_summary.yml](reusable_pr_summary.yml) - This job updates the PR summary with the results of the CI run. - This summary can be found at: `https://build.rerun.io/pr//` diff --git a/.github/workflows/checkboxes.yml b/.github/workflows/checkboxes.yml new file mode 100644 index 000000000000..6b0d8df075ff --- /dev/null +++ b/.github/workflows/checkboxes.yml @@ -0,0 +1,46 @@ +# Checks that all checkboxes in a PR are checked + +name: Pull Request Checkboxes + +on: + pull_request: + types: + - opened + - synchronize + - reopened + - edited + +concurrency: + group: ${{ github.event.pull_request.number }}-pr-checkboxes + cancel-in-progress: true + +jobs: + pr-checkboxes: + name: Check PR checkboxes + + permissions: + contents: "read" + id-token: "write" + pull-requests: "write" + + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v3 + + - name: Set up Python + uses: actions/setup-python@v2 + with: + python-version: 3.x + + - name: Install deps + run: pip install PyGithub # NOLINT + + - name: Check PR checkboxes + run: | + ./scripts/check_pr_checkboxes.py \ + --github-token ${{ secrets.GITHUB_TOKEN }} \ + --github-repository ${{ github.repository }} \ + --pr-number ${{ github.event.pull_request.number }} + diff --git a/.github/workflows/on_pull_request.yml b/.github/workflows/on_pull_request.yml index a8b2ff16b04b..e5085ddea666 100644 --- a/.github/workflows/on_pull_request.yml +++ b/.github/workflows/on_pull_request.yml @@ -13,29 +13,30 @@ jobs: uses: ./.github/workflows/reusable_checks.yml with: CONCURRENCY: pr-${{ github.event.pull_request.number }} + PR_NUMBER: ${{ github.event.pull_request.number }} secrets: inherit min-test-wheel: - name: 'Minimum Wheel' + name: "Minimum Wheel" uses: ./.github/workflows/reusable_build_and_test_wheels.yml with: CONCURRENCY: pr-${{ github.event.pull_request.number }} SAVE_CACHE: false PLATFORM: linux - MATURIN_FEATURE_FLAGS: '--no-default-features --features extension-module' - WHEEL_ARTIFACT_NAME: 'linux-wheel-fast' + MATURIN_FEATURE_FLAGS: "--no-default-features --features extension-module" + WHEEL_ARTIFACT_NAME: "linux-wheel-fast" RRD_ARTIFACT_NAME: linux-rrd-fast secrets: inherit build-web: - name: 'Build Web' + name: "Build Web" uses: ./.github/workflows/reusable_build_web.yml with: CONCURRENCY: pr-${{ github.event.pull_request.number }} secrets: inherit upload-web: - name: 'Upload Web' + name: "Upload Web" needs: [min-test-wheel, build-web] uses: ./.github/workflows/reusable_upload_web.yml with: @@ -45,7 +46,7 @@ jobs: secrets: inherit build-web-demo: - name: 'Build Web Demo' + name: "Build Web Demo" needs: [min-test-wheel, build-web] uses: ./.github/workflows/reusable_build_web_demo.yml with: @@ -55,16 +56,17 @@ jobs: secrets: inherit upload-web-demo: - name: 'Upload Web Demo' + name: "Upload Web Demo" needs: [build-web-demo] uses: ./.github/workflows/reusable_upload_web_demo.yml with: CONCURRENCY: pr-${{ github.event.pull_request.number }} UPLOAD_COMMIT_OVERRIDE: ${{ github.event.pull_request.head.sha }} + PR_NUMBER: ${{ github.event.pull_request.number }} secrets: inherit run-notebook: - name: 'Run Notebook' + name: "Run Notebook" needs: [min-test-wheel] uses: ./.github/workflows/reusable_run_notebook.yml with: @@ -74,18 +76,19 @@ jobs: secrets: inherit save-pr-summary: - name: 'Save PR Summary' + name: "Save PR Summary" needs: [upload-web, run-notebook] uses: ./.github/workflows/reusable_pr_summary.yml with: CONCURRENCY: pr-${{ github.event.pull_request.number }} PR_NUMBER: ${{ github.event.pull_request.number }} secrets: inherit - - link-docs: - name: 'Link Docs' - uses: ./.github/workflows/reusable_pr_link_docs.yml + + update-pr-body: + name: "Update PR Body" + uses: ./.github/workflows/reusable_update_pr_body.yml with: CONCURRENCY: pr-${{ github.event.pull_request.number }} PR_NUMBER: ${{ github.event.pull_request.number }} secrets: inherit + diff --git a/.github/workflows/reusable_checks.yml b/.github/workflows/reusable_checks.yml index 1859f3b51ac1..c0575c3ed419 100644 --- a/.github/workflows/reusable_checks.yml +++ b/.github/workflows/reusable_checks.yml @@ -1,4 +1,4 @@ -name: 'Checks: Lints, Tests, Docs' +name: "Checks: Lints, Tests, Docs" on: workflow_call: @@ -22,6 +22,10 @@ on: required: false type: boolean default: false + PR_NUMBER: + required: false + type: string + default: "" concurrency: group: ${{ inputs.CONCURRENCY }}-checks @@ -42,8 +46,7 @@ env: RUSTC_WRAPPER: "sccache" jobs: - -# --------------------------------------------------------------------------- + # --------------------------------------------------------------------------- py-lints: name: Python lints (black, mypy, flake8) @@ -76,7 +79,7 @@ jobs: run: | just py-requirements -# --------------------------------------------------------------------------- + # --------------------------------------------------------------------------- py-test-docs: name: Test Python Docs @@ -100,7 +103,7 @@ jobs: run: | mkdocs build -f rerun_py/mkdocs.yml -# --------------------------------------------------------------------------- + # --------------------------------------------------------------------------- rs-lints: name: Rust lints (fmt, check, cranky, tests, doc) @@ -139,7 +142,6 @@ jobs: - name: Run sccache-cache uses: mozilla-actions/sccache-action@v0.0.3 - # First do our check with --locked to make sure `Cargo.lock` is up to date - name: Check all features uses: actions-rs/cargo@v1 @@ -203,7 +205,7 @@ jobs: command: test args: --all-targets --all-features -# --------------------------------------------------------------------------- + # --------------------------------------------------------------------------- rs-check-wasm: name: Check Rust web build (wasm32 + wasm-bindgen) @@ -240,13 +242,12 @@ jobs: command: run args: --locked -p re_build_web_viewer -- --debug -# --------------------------------------------------------------------------- + # --------------------------------------------------------------------------- toml-lints: name: Lint TOML files runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 - name: Set up cargo cache @@ -268,7 +269,7 @@ jobs: run: | taplo fmt --check -# --------------------------------------------------------------------------- + # --------------------------------------------------------------------------- misc-rerun-lints: name: Rerun lints @@ -293,7 +294,7 @@ jobs: run: | ./scripts/check_requirements.py -# --------------------------------------------------------------------------- + # --------------------------------------------------------------------------- spell-check: name: Spell Check @@ -305,7 +306,7 @@ jobs: - name: Check spelling of entire workspace uses: crate-ci/typos@master -# --------------------------------------------------------------------------- + # --------------------------------------------------------------------------- rs-cargo-deny: name: Cargo Deny ${{ matrix.platform }} @@ -324,3 +325,4 @@ jobs: shell: bash id: expected_version run: ./scripts/cargo_deny.sh + diff --git a/.github/workflows/reusable_pr_link_docs.yml b/.github/workflows/reusable_update_pr_body.yml similarity index 61% rename from .github/workflows/reusable_pr_link_docs.yml rename to .github/workflows/reusable_update_pr_body.yml index 04c9da2d09ed..840b41f3ce0b 100644 --- a/.github/workflows/reusable_pr_link_docs.yml +++ b/.github/workflows/reusable_update_pr_body.yml @@ -1,4 +1,4 @@ -name: Reusable PR Link Docs +name: Update links in PR Body on: workflow_call: @@ -15,8 +15,8 @@ concurrency: cancel-in-progress: true jobs: - pr-link-docs: - name: Link to docs preview in PR + update-pr-body: + name: Update PR body permissions: contents: "read" @@ -37,13 +37,10 @@ jobs: - name: Install deps run: pip install PyGithub # NOLINT - - name: Link to docs + - name: Update PR description run: | - python scripts/pr_link_docs.py \ - --github-token ${{ secrets.GITHUB_TOKEN }} \ - --github-repository ${GITHUB_REPOSITORY} \ - --pr-number ${{ inputs.PR_NUMBER }} - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - PR_NUMBER: ${{ inputs.PR_NUMBER }} + ./scripts/update_pr_body.py \ + --github-token '${{ secrets.GITHUB_TOKEN }}' \ + --github-repository '${{ github.repository }}' \ + --pr-number '${{ inputs.PR_NUMBER }}' diff --git a/.github/workflows/reusable_upload_web_demo.yml b/.github/workflows/reusable_upload_web_demo.yml index 57b5eec72b56..5694ddfe5fce 100644 --- a/.github/workflows/reusable_upload_web_demo.yml +++ b/.github/workflows/reusable_upload_web_demo.yml @@ -9,7 +9,7 @@ on: ADHOC_NAME: type: string required: false - default: '' + default: "" MARK_PRERELEASE_FOR_MAINLINE: required: false type: boolean @@ -21,26 +21,28 @@ on: RELEASE_VERSION: required: false type: string - default: 'prerelease' + default: "prerelease" # We need this because PRs use a merged commit but we really want # to track uploads based on the source commit. UPLOAD_COMMIT_OVERRIDE: required: false type: string - default: '' + default: "" UPLOAD_COMMIT: required: false type: boolean default: true + PR_NUMBER: + type: string + default: "" concurrency: group: ${{ inputs.CONCURRENCY }}-upload-web-demo cancel-in-progress: true jobs: - upload-web: - name: Upload Web Wemo to Google Cloud + name: Upload Web Demo to Google Cloud permissions: contents: "read" id-token: "write" @@ -103,3 +105,12 @@ jobs: path: "web_demo" destination: "rerun-demo/adhoc/${{inputs.ADHOC_NAME}}" parent: false + + - name: "Upload web demo (pr)" + if: ${{ inputs.PR_NUMBER != '' }} + uses: google-github-actions/upload-cloud-storage@v1 + with: + path: "web_demo" + destination: "rerun-demo/pr/${{ inputs.PR_NUMBER }}" + parent: false + diff --git a/scripts/check_pr_checkboxes.py b/scripts/check_pr_checkboxes.py new file mode 100755 index 000000000000..c1d33a9cd08f --- /dev/null +++ b/scripts/check_pr_checkboxes.py @@ -0,0 +1,37 @@ +#!/usr/bin/env python3 + +from __future__ import annotations + +import argparse + +from github import Github # NOLINT + + +def main() -> None: + parser = argparse.ArgumentParser(description="Generate a PR summary page") + parser.add_argument("--github-token", required=True, help="GitHub token") + parser.add_argument("--github-repository", required=True, help="GitHub repository") + parser.add_argument("--pr-number", required=True, type=int, help="PR number") + args = parser.parse_args() + + gh = Github(args.github_token) # NOLINT + repo = gh.get_repo(args.github_repository) + pr = repo.get_pull(args.pr_number) + + latest_commit = pr.get_commits().reversed[0] + print(f"Latest commit: {latest_commit.sha}") + + body_lower = pr.body.lower() + if "* [ ]" in body_lower or "- [ ]" in body_lower: + print("PR contains unchecked checkboxes") + exit(1) + elif "* [x]" in body_lower or "- [x]" in body_lower: + print("All clear") + exit(0) + else: + print("Don't delete the PR description") + exit(1) + + +if __name__ == "__main__": + main() diff --git a/scripts/requirements-dev.txt b/scripts/requirements-dev.txt index 91c041c08ddc..798130d962e7 100644 --- a/scripts/requirements-dev.txt +++ b/scripts/requirements-dev.txt @@ -6,7 +6,7 @@ cryptography==38.0.4 # for scripts/upload_image.py google-cloud-storage==2.9.0 # for scripts/upload_image.py -PyGithub==1.58.2 # for scripts/generate_pr_summary.py and scripts/pr_link_docs_preview.py +PyGithub==1.58.2 # for scripts/generate_pr_summary.py and scripts/update_pr_body.py Pillow # for scripts/upload_image.py tqdm requests diff --git a/scripts/pr_link_docs.py b/scripts/update_pr_body.py similarity index 75% rename from scripts/pr_link_docs.py rename to scripts/update_pr_body.py index 2e5c2f6a823b..845674eca756 100755 --- a/scripts/pr_link_docs.py +++ b/scripts/update_pr_body.py @@ -3,7 +3,7 @@ """ Script to generate a link to documentation preview in PRs. -This is expected to be run by the `reusable_pr_link_docs.yml` GitHub workflow. +This is expected to be run by the `reusable_update_pr_body.yml` GitHub workflow. Requires the following packages: pip install PyGithub # NOLINT @@ -40,19 +40,27 @@ def main() -> None: print(f"Latest commit: {latest_commit.sha}") short_sha = latest_commit.sha[:7] + body = pr.body + + # update preview links link = LINK_TEMPLATE.replace("{{ docs-link }}", f"https://rerun.io/preview/{short_sha}/docs") link = link.replace("{{ examples-link }}", f"https://rerun.io/preview/{short_sha}/examples") - if EMPTY_LINK in pr.body: + if EMPTY_LINK in body: print("Empty link found, updating it") - new_body = pr.body.replace(EMPTY_LINK, link) - pr.edit(body=new_body) + body = body.replace(EMPTY_LINK, link) else: - start = pr.body.find(LINK_START) - end = pr.body.find(LINK_END) + start = body.find(LINK_START) + end = body.find(LINK_END) if start != -1 and end != -1: print("Existing link found, updating it") - new_body = pr.body[:start] + link + pr.body[end + len(LINK_END) :] - pr.edit(body=new_body) + body = body[:start] + link + body[end + len(LINK_END) :] + + # update the pr number + if "{{ pr-number }}" in body: + body = body.replace("{{ pr-number }}", str(args.pr_number)) + + if body != pr.body: + pr.edit(body=body) if __name__ == "__main__":