1515
1616permissions :
1717 contents : read
18+ pull-requests : read
1819
1920defaults :
2021 run :
2122 shell : bash
2223
2324jobs :
24- package :
25- name : Validate package
25+ changes :
26+ name : Detect changed paths
27+ runs-on : ubuntu-24.04
28+ outputs :
29+ github_actions : ${{ steps.changed_paths.outputs.github_actions }}
30+ markdown : ${{ steps.changed_paths.outputs.markdown }}
31+ python : ${{ steps.changed_paths.outputs.python }}
32+ package : ${{ steps.changed_paths.outputs.package }}
33+
34+ steps :
35+ - name : Detect changed paths
36+ id : changed_paths
37+ env :
38+ GH_TOKEN : ${{ github.token }}
39+ PULL_REQUEST_NUMBER : ${{ github.event.pull_request.number }}
40+ run : |
41+ github_actions_changed=false
42+ markdown_changed=false
43+ python_changed=false
44+ package_changed=false
45+
46+ if [[ "${{ github.event_name }}" != "pull_request" ]]; then
47+ github_actions_changed=true
48+ markdown_changed=true
49+ python_changed=true
50+ package_changed=true
51+ else
52+ changed_files="$(mktemp)"
53+ gh api --paginate \
54+ "repos/${GITHUB_REPOSITORY}/pulls/${PULL_REQUEST_NUMBER}/files" \
55+ --jq '.[].filename' > "${changed_files}"
56+
57+ while IFS= read -r changed_file; do
58+ case "${changed_file}" in
59+ .github/workflows/*)
60+ github_actions_changed=true
61+ ;;
62+ esac
63+
64+ case "${changed_file}" in
65+ *.md|.markdownlint-cli2.yaml)
66+ markdown_changed=true
67+ ;;
68+ esac
69+
70+ case "${changed_file}" in
71+ .python-version|pyproject.toml|uv.lock|src/*|tests/*)
72+ python_changed=true
73+ ;;
74+ esac
75+
76+ case "${changed_file}" in
77+ .python-version|LICENSE|README.md|pyproject.toml|uv.lock|src/*)
78+ package_changed=true
79+ ;;
80+ esac
81+ done < "${changed_files}"
82+ fi
83+
84+ {
85+ echo "github_actions=${github_actions_changed}"
86+ echo "markdown=${markdown_changed}"
87+ echo "python=${python_changed}"
88+ echo "package=${package_changed}"
89+ } >> "${GITHUB_OUTPUT}"
90+
91+ github_actions :
92+ name : Lint GitHub Actions
93+ needs : changes
94+ if : needs.changes.outputs.github_actions == 'true'
2695 runs-on : ubuntu-24.04
2796 env :
2897 ACTIONLINT_VERSION : " 1.7.12"
29- IMPORT_NAME : src_py_lib
30- MARKDOWNLINT_CLI2_VERSION : " 0.22.1"
31- PYTHON_VERSION : " 3.11"
32- UV_VERSION : " 0.11.7"
3398
3499 steps :
35100 - name : Check out code
@@ -38,15 +103,7 @@ jobs:
38103 persist-credentials : false
39104 ref : ${{ inputs.ref || github.ref }}
40105
41- - name : Cache actionlint
42- id : cache-actionlint
43- uses : actions/cache@v5
44- with :
45- path : ~/.local/bin/actionlint
46- key : actionlint-${{ runner.os }}-${{ runner.arch }}-${{ env.ACTIONLINT_VERSION }}
47-
48106 - name : Install actionlint
49- if : steps.cache-actionlint.outputs.cache-hit != 'true'
50107 run : |
51108 mkdir -p "${HOME}/.local/bin"
52109 asset="actionlint_${ACTIONLINT_VERSION}_linux_amd64.tar.gz"
@@ -63,20 +120,45 @@ jobs:
63120 run : |
64121 "${HOME}/.local/bin/actionlint"
65122
66- - name : Cache npm
67- uses : actions/cache@v5
123+ markdown :
124+ name : Lint Markdown
125+ needs : changes
126+ if : needs.changes.outputs.markdown == 'true'
127+ runs-on : ubuntu-24.04
128+ env :
129+ MARKDOWNLINT_CLI2_VERSION : " 0.22.1"
130+
131+ steps :
132+ - name : Check out code
133+ uses : actions/checkout@v6
68134 with :
69- path : ~/.npm
70- key : npm- ${{ runner.os }}-markdownlint-cli2-${{ env.MARKDOWNLINT_CLI2_VERSION }}
135+ persist-credentials : false
136+ ref : ${{ inputs.ref || github.ref }}
71137
72138 - name : Lint Markdown
73139 run : npx --yes "markdownlint-cli2@${MARKDOWNLINT_CLI2_VERSION}"
74140
141+ python :
142+ name : Validate Python
143+ needs : changes
144+ if : needs.changes.outputs.python == 'true'
145+ runs-on : ubuntu-24.04
146+ env :
147+ IMPORT_NAME : src_py_lib
148+ PYTHON_VERSION : " 3.11"
149+ UV_VERSION : " 0.11.7"
150+
151+ steps :
152+ - name : Check out code
153+ uses : actions/checkout@v6
154+ with :
155+ persist-credentials : false
156+ ref : ${{ inputs.ref || github.ref }}
157+
75158 - name : Set up Python
76159 uses : actions/setup-python@v6
77160 with :
78161 python-version : ${{ env.PYTHON_VERSION }}
79- cache : pip
80162
81163 - name : Cache uv
82164 uses : actions/cache@v5
@@ -115,12 +197,43 @@ jobs:
115197 raise SystemExit(f"unexpected import name: {src_py_lib.__name__}")
116198 PY
117199
200+ package_build :
201+ name : Build and smoke-test package
202+ needs : changes
203+ if : inputs.build-package && needs.changes.outputs.package == 'true'
204+ runs-on : ubuntu-24.04
205+ env :
206+ IMPORT_NAME : src_py_lib
207+ PYTHON_VERSION : " 3.11"
208+ UV_VERSION : " 0.11.7"
209+
210+ steps :
211+ - name : Check out code
212+ uses : actions/checkout@v6
213+ with :
214+ persist-credentials : false
215+ ref : ${{ inputs.ref || github.ref }}
216+
217+ - name : Set up Python
218+ uses : actions/setup-python@v6
219+ with :
220+ python-version : ${{ env.PYTHON_VERSION }}
221+
222+ - name : Cache uv
223+ uses : actions/cache@v5
224+ with :
225+ path : ~/.cache/uv
226+ key : uv-${{ runner.os }}-py${{ env.PYTHON_VERSION }}-${{ hashFiles('uv.lock') }}
227+ restore-keys : |
228+ uv-${{ runner.os }}-py${{ env.PYTHON_VERSION }}-
229+
230+ - name : Install uv
231+ run : python -m pip install "uv==${UV_VERSION}"
232+
118233 - name : Build wheel
119- if : inputs.build-package
120234 run : uv build --wheel --out-dir dist --no-create-gitignore
121235
122236 - name : Smoke test installed wheel
123- if : inputs.build-package
124237 run : |
125238 python -m venv build/ci-venv
126239 . build/ci-venv/bin/activate
@@ -133,3 +246,29 @@ jobs:
133246 if src_py_lib.__name__ != os.environ["IMPORT_NAME"]:
134247 raise SystemExit(f"unexpected import name: {src_py_lib.__name__}")
135248 PY
249+
250+ package :
251+ name : Validate package
252+ needs : [changes, github_actions, markdown, python, package_build]
253+ if : always()
254+ runs-on : ubuntu-24.04
255+
256+ steps :
257+ - name : Confirm validation results
258+ run : |
259+ for validation_result in \
260+ "${{ needs.changes.result }}" \
261+ "${{ needs.github_actions.result }}" \
262+ "${{ needs.markdown.result }}" \
263+ "${{ needs.python.result }}" \
264+ "${{ needs.package_build.result }}"
265+ do
266+ case "${validation_result}" in
267+ success|skipped)
268+ ;;
269+ *)
270+ echo "::error title=Validation failed::At least one validation job ended with '${validation_result}'."
271+ exit 1
272+ ;;
273+ esac
274+ done
0 commit comments