|
1 | 1 | name: Reusable change detection |
2 | 2 |
|
3 | | -on: # yamllint disable-line rule:truthy |
| 3 | +on: # yamllint disable-line rule:truthy |
4 | 4 | workflow_call: |
5 | 5 | outputs: |
6 | 6 | # Some of the referenced steps set outputs conditionally and there may be |
@@ -50,124 +50,60 @@ jobs: |
50 | 50 | name: Compute changed files |
51 | 51 | runs-on: ubuntu-latest |
52 | 52 | timeout-minutes: 10 |
| 53 | + env: |
| 54 | + branch_base: 'origin/${{ github.event.pull_request.base.ref }}' |
| 55 | + branch_pr: 'origin/${{ github.event.pull_request.head.ref }}' |
| 56 | + commits: ${{ github.event.pull_request.commits }} |
| 57 | + refspec_base: '+${{ github.event.pull_request.base.sha }}:remotes/origin/${{ github.event.pull_request.base.ref }}' |
| 58 | + refspec_pr: '+${{ github.event.pull_request.head.sha }}:remotes/origin/${{ github.event.pull_request.head.ref }}' |
53 | 59 | outputs: |
54 | 60 | config-hash: ${{ steps.config-hash.outputs.hash }} |
55 | | - run-cifuzz: ${{ steps.check.outputs.run-cifuzz }} |
56 | | - run-docs: ${{ steps.docs-changes.outputs.run-docs }} |
57 | | - run-hypothesis: ${{ steps.check.outputs.run-hypothesis }} |
58 | | - run-tests: ${{ steps.check.outputs.run-tests }} |
59 | | - run-win-msi: ${{ steps.win-msi-changes.outputs.run-win-msi }} |
| 61 | + run-cifuzz: ${{ steps.changes.outputs.run-cifuzz }} |
| 62 | + run-docs: ${{ steps.changes.outputs.run-docs }} |
| 63 | + run-hypothesis: ${{ steps.changes.outputs.run-hypothesis }} |
| 64 | + run-tests: ${{ steps.changes.outputs.run-tests }} |
| 65 | + run-win-msi: ${{ steps.changes.outputs.run-win-msi }} |
60 | 66 | steps: |
| 67 | + - uses: actions/setup-python@v5 |
| 68 | + with: |
| 69 | + python-version: "3" |
| 70 | + |
61 | 71 | - run: >- |
62 | 72 | echo '${{ github.event_name }}' |
| 73 | +
|
63 | 74 | - uses: actions/checkout@v4 |
64 | 75 | with: |
65 | 76 | persist-credentials: false |
66 | | - - name: Check for source changes |
67 | | - id: check |
| 77 | + ref: >- |
| 78 | + ${{ |
| 79 | + github.event_name == 'pull_request' |
| 80 | + && github.event.pull_request.head.sha |
| 81 | + || '' |
| 82 | + }} |
| 83 | +
|
| 84 | + # Adapted from https://github.com/actions/checkout/issues/520#issuecomment-1167205721 |
| 85 | + - name: Fetch commits to get branch diff |
| 86 | + if: github.event_name == 'pull_request' |
68 | 87 | run: | |
69 | | - if [ -z "$GITHUB_BASE_REF" ]; then |
70 | | - echo "run-tests=true" >> "$GITHUB_OUTPUT" |
71 | | - else |
72 | | - git fetch origin "$GITHUB_BASE_REF" --depth=1 |
73 | | - # git diff "origin/$GITHUB_BASE_REF..." (3 dots) may be more |
74 | | - # reliable than git diff "origin/$GITHUB_BASE_REF.." (2 dots), |
75 | | - # but it requires to download more commits (this job uses |
76 | | - # "git fetch --depth=1"). |
77 | | - # |
78 | | - # git diff "origin/$GITHUB_BASE_REF..." (3 dots) works with Git |
79 | | - # 2.26, but Git 2.28 is stricter and fails with "no merge base". |
80 | | - # |
81 | | - # git diff "origin/$GITHUB_BASE_REF.." (2 dots) should be enough on |
82 | | - # GitHub, since GitHub starts by merging origin/$GITHUB_BASE_REF |
83 | | - # into the PR branch anyway. |
84 | | - # |
85 | | - # https://github.com/python/core-workflow/issues/373 |
86 | | - grep_ignore_args=( |
87 | | - # file extensions |
88 | | - -e '\.md$' |
89 | | - -e '\.rst$' |
90 | | - # top-level folders |
91 | | - -e '^Doc/' |
92 | | - -e '^Misc/' |
93 | | - # configuration files |
94 | | - -e '^\.github/CODEOWNERS$' |
95 | | - -e '^\.pre-commit-config\.yaml$' |
96 | | - -e '\.ruff\.toml$' |
97 | | - -e 'mypy\.ini$' |
98 | | - ) |
99 | | - git diff --name-only "origin/$GITHUB_BASE_REF.." \ |
100 | | - | grep -qvE "${grep_ignore_args[@]}" \ |
101 | | - && echo "run-tests=true" >> "$GITHUB_OUTPUT" || true |
102 | | - fi |
| 88 | + # Fetch enough history to find a common ancestor commit (aka merge-base): |
| 89 | + git fetch origin "${refspec_pr}" --depth=$(( commits + 1 )) \ |
| 90 | + --no-tags --prune --no-recurse-submodules |
| 91 | +
|
| 92 | + # This should get the oldest commit in the local fetched history (which may not be the commit the PR branched from): |
| 93 | + COMMON_ANCESTOR=$( git rev-list --first-parent --max-parents=0 --max-count=1 "${branch_pr}" ) |
| 94 | + DATE=$( git log --date=iso8601 --format=%cd "${COMMON_ANCESTOR}" ) |
| 95 | +
|
| 96 | + # Get all commits since that commit date from the base branch (eg: master or main): |
| 97 | + git fetch origin "${refspec_base}" --shallow-since="${DATE}" \ |
| 98 | + --no-tags --prune --no-recurse-submodules |
103 | 99 |
|
104 | | - # Check if we should run hypothesis tests |
105 | | - GIT_BRANCH=${GITHUB_BASE_REF:-${GITHUB_REF#refs/heads/}} |
106 | | - echo "$GIT_BRANCH" |
107 | | - if $(echo "$GIT_BRANCH" | grep -q -w '3\.\(8\|9\|10\|11\)'); then |
108 | | - echo "Branch too old for hypothesis tests" |
109 | | - echo "run-hypothesis=false" >> "$GITHUB_OUTPUT" |
110 | | - else |
111 | | - echo "Run hypothesis tests" |
112 | | - echo "run-hypothesis=true" >> "$GITHUB_OUTPUT" |
113 | | - fi |
| 100 | + # We only want to run tests on PRs when related files are changed, |
| 101 | + # or when someone triggers a manual workflow run. |
| 102 | + - name: Compute changed files |
| 103 | + id: changes |
| 104 | + run: python Tools/build/compute-changes.py "${branch_base}" "${branch_pr}" |
114 | 105 |
|
115 | | - # oss-fuzz maintains a configuration for fuzzing the main branch of |
116 | | - # CPython, so CIFuzz should be run only for code that is likely to be |
117 | | - # merged into the main branch; compatibility with older branches may |
118 | | - # be broken. |
119 | | - FUZZ_RELEVANT_FILES='(\.c$|\.h$|\.cpp$|^configure$|^\.github/workflows/build\.yml$|^Modules/_xxtestfuzz)' |
120 | | - if [ "$GITHUB_BASE_REF" = "main" ] && [ "$(git diff --name-only "origin/$GITHUB_BASE_REF.." | grep -qE $FUZZ_RELEVANT_FILES; echo $?)" -eq 0 ]; then |
121 | | - # The tests are pretty slow so they are executed only for PRs |
122 | | - # changing relevant files. |
123 | | - echo "Run CIFuzz tests" |
124 | | - echo "run-cifuzz=true" >> "$GITHUB_OUTPUT" |
125 | | - else |
126 | | - echo "Branch too old for CIFuzz tests; or no C files were changed" |
127 | | - echo "run-cifuzz=false" >> "$GITHUB_OUTPUT" |
128 | | - fi |
129 | 106 | - name: Compute hash for config cache key |
130 | 107 | id: config-hash |
131 | 108 | run: | |
132 | 109 | echo "hash=${{ hashFiles('configure', 'configure.ac', '.github/workflows/build.yml') }}" >> "$GITHUB_OUTPUT" |
133 | | - - name: Get a list of the changed documentation-related files |
134 | | - if: github.event_name == 'pull_request' |
135 | | - id: changed-docs-files |
136 | | - uses: Ana06/get-changed-files@v2.3.0 |
137 | | - with: |
138 | | - filter: | |
139 | | - Doc/** |
140 | | - Misc/** |
141 | | - .github/workflows/reusable-docs.yml |
142 | | - format: csv # works for paths with spaces |
143 | | - - name: Check for docs changes |
144 | | - # We only want to run this on PRs when related files are changed, |
145 | | - # or when user triggers manual workflow run. |
146 | | - if: >- |
147 | | - ( |
148 | | - github.event_name == 'pull_request' |
149 | | - && steps.changed-docs-files.outputs.added_modified_renamed != '' |
150 | | - ) || github.event_name == 'workflow_dispatch' |
151 | | - id: docs-changes |
152 | | - run: | |
153 | | - echo "run-docs=true" >> "${GITHUB_OUTPUT}" |
154 | | - - name: Get a list of the MSI installer-related files |
155 | | - if: github.event_name == 'pull_request' |
156 | | - id: changed-win-msi-files |
157 | | - uses: Ana06/get-changed-files@v2.3.0 |
158 | | - with: |
159 | | - filter: | |
160 | | - Tools/msi/** |
161 | | - .github/workflows/reusable-windows-msi.yml |
162 | | - format: csv # works for paths with spaces |
163 | | - - name: Check for changes in MSI installer-related files |
164 | | - # We only want to run this on PRs when related files are changed, |
165 | | - # or when user triggers manual workflow run. |
166 | | - if: >- |
167 | | - ( |
168 | | - github.event_name == 'pull_request' |
169 | | - && steps.changed-win-msi-files.outputs.added_modified_renamed != '' |
170 | | - ) || github.event_name == 'workflow_dispatch' |
171 | | - id: win-msi-changes |
172 | | - run: | |
173 | | - echo "run-win-msi=true" >> "${GITHUB_OUTPUT}" |
0 commit comments