diff --git a/.github/workflows/test_pr.yml b/.github/workflows/test_pr.yml index 5187f40..00355be 100644 --- a/.github/workflows/test_pr.yml +++ b/.github/workflows/test_pr.yml @@ -3,29 +3,59 @@ run-name: "#${{github.event.number}} - ${{github.event.pull_request.title}}" on: pull_request: types: [opened, reopened, synchronize, labeled] +env: + VORON_TOOLKIT_OUTPUT_DIR: /workflow_output + VORON_TOOLKIT_INPUT_DIR: ${{ github.workspace }}/tests/test_repository_root/printer_mods + VORON_TOOLKIT_GH_STEP_SUMMARY: true + VORON_TOOLKIT_VERBOSE: true jobs: - voron_ci: - env: - VORON_TOOLKIT_OUTPUT_DIR: /workflow_output - VORON_TOOLKIT_INPUT_DIR: ${{ github.workspace }}/tests/test_repository_root/printer_mods - VORON_TOOLKIT_GH_STEP_SUMMARY: true - VORON_TOOLKIT_VERBOSE: true + voron_ci_dismiss_labels: + # If the PR was opened, reopened or new commits were pushed, dismiss all labels during post processing + if: ${{ github.event_name == 'pull_request' && github.event.action != 'labeled' }} + runs-on: ubuntu-latest + steps: + - name: Dismiss all CI labels ๐Ÿšฎ + id: dismiss-labels + run: | + mkdir -p ${{ env.VORON_TOOLKIT_OUTPUT_DIR }} + echo -n '{"pr_number": ${{ github.event.number }}, "action": "dismiss_labels"}' > ${{ env.VORON_TOOLKIT_OUTPUT_DIR }}/ci_result.json + echo -n ${{ github.event }} > ${{ env.VORON_TOOLKIT_OUTPUT_DIR }}/event.json + # Upload Artifact + - name: Upload build artifacts ๐Ÿ“ฆ + uses: actions/upload-artifact@65d862660abb392b8c4a3d1195a2108db131dd05 + with: + name: ci_output + path: ${{ env.VORON_TOOLKIT_OUTPUT_DIR }} + voron_ci_skip: + # The PR was labeled with any label OTHER than "Ready for CI", which means we should skip the CI run and the post processing + if: ${{ github.event_name == 'pull_request' && github.event.action == 'labeled' && !contains( github.event.pull_request.labels.*.name, 'Ready for CI')}} runs-on: ubuntu-latest steps: - - name: Ready for CI label detected โœ… - if: ${{ contains( github.event.pull_request.labels.*.name, 'Ready for CI') }} - id: label-detected + - name: Skip CI โฉ + id: skip-ci run: | mkdir -p ${{ env.VORON_TOOLKIT_OUTPUT_DIR }} - echo -n '{"pr_number": ${{ github.event.number }}, "skipped": false}' > ${{ env.VORON_TOOLKIT_OUTPUT_DIR }}/ci_result.json - - name: Ready for CI label not detected โŒ - if: ${{ !contains( github.event.pull_request.labels.*.name, 'Ready for CI') }} - id: label-not-detected + echo -n '{"pr_number": ${{ github.event.number }}, "action": "skip"}' > ${{ env.VORON_TOOLKIT_OUTPUT_DIR }}/ci_result.json + echo -n ${{ github.event }} > ${{ env.VORON_TOOLKIT_OUTPUT_DIR }}/event.json + # Upload Artifact + - name: Upload build artifacts ๐Ÿ“ฆ + uses: actions/upload-artifact@65d862660abb392b8c4a3d1195a2108db131dd05 + with: + name: ci_output + path: ${{ env.VORON_TOOLKIT_OUTPUT_DIR }} + voron_ci: + # The PR was labeled with the "Ready for CI label", which menas we should run the CI and post processing + if: ${{ github.event_name == 'pull_request' && github.event.action == 'labeled' && contains( github.event.pull_request.labels.*.name, 'Ready for CI')}} + runs-on: ubuntu-latest + steps: + - name: Save PR number ๐Ÿ’พ + id: run-ci run: | mkdir -p ${{ env.VORON_TOOLKIT_OUTPUT_DIR }} - echo -n '{"pr_number": ${{ github.event.number }}, "skipped": true}' > ${{ env.VORON_TOOLKIT_OUTPUT_DIR }}/ci_result.json + echo -n '{"pr_number": ${{ github.event.number }}, "action": "post_process"}' > ${{ env.VORON_TOOLKIT_OUTPUT_DIR }}/ci_result.json + echo -n ${{ github.event }} > ${{ env.VORON_TOOLKIT_OUTPUT_DIR }}/event.json - id: changed-files - if: ${{ !cancelled() && steps.label-detected.outcome == 'success' }} + if: ${{ !cancelled() }} name: Get changed files ๐Ÿ”€ # Check out files, separate with newlines to catch whitespace in filenames uses: tj-actions/changed-files@v37 @@ -33,7 +63,7 @@ jobs: separator: "\n" # Sanitize the file list - name: Prepare Sparse Checkout ๐Ÿงน - if: ${{ !cancelled() && steps.label-detected.outcome == 'success' }} + if: ${{ !cancelled() }} id: sanitize_file_list uses: docker://ghcr.io/vorondesign/voron_toolkit_docker:latest env: @@ -41,7 +71,7 @@ jobs: with: args: prepare-sparse-checkout - name: Perform sparse checkout โ†ช๏ธ - if: ${{ !cancelled() && steps.label-detected.outcome == 'success' }} + if: ${{ !cancelled() }} # Perform a sparse checkout, checking out only the files of the PR uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 with: @@ -51,7 +81,7 @@ jobs: sparse-checkout-cone-mode: false # Run whitespace/licenses/file sizes based on files in the test directory - name: Check files for whitespace/licenses/file sizes ๐Ÿ” - if: ${{ !cancelled() && steps.label-detected.outcome == 'success' }} + if: ${{ !cancelled() }} uses: docker://ghcr.io/vorondesign/voron_toolkit_docker:latest env: FILE_CHECKER_IGNORE_WARNINGS: true @@ -60,7 +90,7 @@ jobs: with: args: check-files - name: Check correct mod/file structure ๐Ÿ” - if: ${{ !cancelled() && steps.label-detected.outcome == 'success' }} + if: ${{ !cancelled() }} uses: docker://ghcr.io/vorondesign/voron_toolkit_docker:latest env: MOD_STRUCTURE_CHECKER_IGNORE_WARNINGS: false @@ -68,7 +98,7 @@ jobs: args: check-mod-structure # Run the corruption checker - name: Check for STL corruption ๐Ÿ” - if: ${{ !cancelled() && steps.label-detected.outcome == 'success' }} + if: ${{ !cancelled() }} uses: docker://ghcr.io/vorondesign/voron_toolkit_docker:latest env: CORRUPTION_CHECKER_IGNORE_WARNINGS: true @@ -76,7 +106,7 @@ jobs: args: check-stl-corruption # Run the rotation checker - name: Check for incorrect STL rotation ๐Ÿ” - if: ${{ !cancelled() && steps.label-detected.outcome == 'success' }} + if: ${{ !cancelled() }} uses: docker://ghcr.io/vorondesign/voron_toolkit_docker:latest env: ROTATION_CHECKER_IGNORE_WARNINGS: true @@ -86,7 +116,7 @@ jobs: args: check-stl-rotation # Generate a README - name: Generate README ๐Ÿ“’ - if: ${{ !cancelled() && steps.label-detected.outcome == 'success' }} + if: ${{ !cancelled() }} uses: docker://ghcr.io/vorondesign/voron_toolkit_docker:latest env: README_GENERATOR_MARKDOWN: false diff --git a/voron_toolkit/constants.py b/voron_toolkit/constants.py index 3b899ba..ac84561 100644 --- a/voron_toolkit/constants.py +++ b/voron_toolkit/constants.py @@ -9,9 +9,10 @@ CI_FAILURE_LABEL: str = "CI: Issues identified" CI_ERROR_LABEL: str = "Warning: CI Error" READY_FOR_CI_LABEL: str = "Ready for CI" +READY_TO_MERGE_LABEL: str = "Ready to merge" PR_COMMENT_TAG: str = "" PR_COMMENT_TOOLKIT_VERSION: str = f"" -ALL_CI_LABELS: list[str] = [CI_PASSED_LABEL, CI_FAILURE_LABEL, CI_ERROR_LABEL, READY_FOR_CI_LABEL] +ALL_CI_LABELS: list[str] = [CI_PASSED_LABEL, CI_FAILURE_LABEL, CI_ERROR_LABEL, READY_FOR_CI_LABEL, READY_TO_MERGE_LABEL] class ExtendedResult(NamedTuple): diff --git a/voron_toolkit/voronuser_utils/pr_helper.py b/voron_toolkit/voronuser_utils/pr_helper.py index b7cbebc..66ecca6 100644 --- a/voron_toolkit/voronuser_utils/pr_helper.py +++ b/voron_toolkit/voronuser_utils/pr_helper.py @@ -156,7 +156,7 @@ def _get_ci_result(self: Self) -> dict[str, Any]: logger.error("Artifact is missing ci_result.json file!") sys.exit(255) ci_result_dct: dict[str, Any] = json.loads(Path(self.tmp_path, "ci_result.json").read_text()) - if ("pr_number" not in ci_result_dct) or ("ci_skipped" not in ci_result_dct): + if ("pr_number" not in ci_result_dct) or ("action" not in ci_result_dct): logger.error("The ci_result.json file is missing the 'pr_number' or 'ci_skipped' key!") sys.exit(255) return ci_result_dct @@ -177,17 +177,17 @@ def run(self: Self) -> None: # Check if the artifact directory is empty, this might happen when the parent workflow did not execute any checks if not any(self.tmp_path.iterdir()): logger.warning( - "Result folder {} for run_id {} is empty! This may be due to a missing artifact or a skipped workflow run!", + "Result folder {} for run_id {} is empty! This may be due to a missing artifact!", self.artifact_name, self.workflow_run_id, ) return ci_result: dict[str, Any] = self._get_ci_result() - pr_number: int = int(ci_result["pr_number"]) - ci_skipped: bool = bool(ci_result["ci_skipped"]) - logger.info("Post Processing PR #{}", pr_number) - if pr_number > 0 and not ci_skipped: + pr_number: int = int(ci_result.get("pr_number", 0)) + pr_action: str = ci_result.get("action", "skip") + logger.info("Post Processing PR #{}, action: {}", pr_number, pr_action) + if pr_number > 0 and pr_action == "post_process": labels_to_set: set[str] = self._parse_artifact_and_get_labels() labels_on_pr: list[str] = GithubActionHelper.get_labels_on_pull_request( repo=self.github_repository, @@ -208,8 +208,8 @@ def run(self: Self) -> None: pull_request_number=pr_number, comment_body=pr_comment, ) - else: - logger.info("Workflow {} for PR #{} was skipped. Dismissing all labels!", self.workflow_run_id, pr_number) + elif pr_number > 0 and pr_action == "dismiss_labels": + logger.info("PR #{} has new commits. Dismissing all CI labels!", pr_number) GithubActionHelper.set_labels_on_pull_request( repo=self.github_repository, pull_request_number=pr_number, @@ -222,6 +222,8 @@ def run(self: Self) -> None: if label not in ALL_CI_LABELS ], ) + else: + logger.info("Skipping post processing of PR #{}!", self.workflow_run_id, pr_number) def main() -> None: