|
2 | 2 | # Copyright (C) 2021 Prediction Machine Advisers, LLC |
3 | 3 | # This file is available under MIT license |
4 | 4 | # based on https://github.com/predictionmachine/pm-github-actions/blob/main/.github/workflows/pm-gh-actions.yml |
5 | | -# pm-version 0.3.10 |
| 5 | +# pm-version 0.4.0 |
6 | 6 | ############################################################################################ |
7 | 7 |
|
8 | 8 | name: PM CI workflow |
|
20 | 20 | branches: |
21 | 21 | - main |
22 | 22 | - dev |
23 | | -env: |
24 | | - GUIDELINE_REPO: 'https://github.com/predictionmachine/pm-coding-template' |
25 | | - |
26 | 23 | jobs: |
27 | | - # Check branch name standard as per `pm-coding-template` |
28 | | - # Ref: [Github: branches, pull request](/docs/coding-standard.md#github-branches-pull-requests) |
29 | | - check-branch-naming-convention: |
30 | | - name: Check branch naming convention as per pm-coding-template |
31 | | - runs-on: ubuntu-latest |
32 | | - timeout-minutes: 10 |
33 | | - if: ${{ github.event_name == 'pull_request' }} |
34 | | - env: |
35 | | - BRANCH_NAME_RULE: 'https://github.com/predictionmachine/pm-coding-template#github-branches-pull-requests' |
36 | | - steps: |
37 | | - - name: Check branch name |
38 | | - id: branchCheck |
39 | | - run: | |
40 | | - echo "branch name: $GITHUB_HEAD_REF" |
41 | | - if [[ "$GITHUB_HEAD_REF" =~ "/" ]];then |
42 | | - echo "::set-output name=is_valid_name::true" |
43 | | - else |
44 | | - echo "::set-output name=is_valid_name::false" |
45 | | - fi |
46 | | - - uses: marocchino/sticky-pull-request-comment@v2 |
47 | | - if: ${{ steps.branchCheck.outputs.is_valid_name == 'false' }} |
48 | | - with: |
49 | | - header: invalid-branch-name-comments |
50 | | - message: | |
51 | | - 👋 @${{ github.event.pull_request.user.login }} |
52 | | - Please use a valid [branch name](${{ env.BRANCH_NAME_RULE }}). |
53 | | - Make sure you have followed our [contribution guidelines](${{ env.GUIDELINE_REPO }}). |
54 | | - - name: Exit job for invalid branch name |
55 | | - if: ${{ steps.branchCheck.outputs.is_valid_name == 'false' }} |
56 | | - run: | |
57 | | - echo "Invalid branch name: $GITHUB_HEAD_REF" |
58 | | - echo "Please use the standard mentioned here: $BRANCH_NAME_RULE" |
59 | | - exit 1 |
60 | | -
|
61 | | - enforce-pr-description: |
62 | | - name: 'Check PR description, fail if empty' |
63 | | - runs-on: ubuntu-latest |
64 | | - timeout-minutes: 10 |
65 | | - env: |
66 | | - TEMPLATE_URL: 'https://github.com/predictionmachine/pm-coding-template/blob/main/.github/pull_request_template.md' |
67 | | - steps: |
68 | | - - name: Check PR description |
69 | | - if: ${{ github.event_name == 'pull_request' }} |
70 | | - id: getPrBody |
71 | | - env: |
72 | | - PR_BODY: ${{ github.event.pull_request.body }} |
73 | | - run: | |
74 | | - echo ${PR_BODY:0:5} |
75 | | - if [ "${PR_BODY:0:5}" == "" ];then |
76 | | - echo "::set-output name=is_empty_body::true" |
77 | | - fi |
78 | | - - uses: marocchino/sticky-pull-request-comment@v2 |
79 | | - if: ${{ steps.getPrBody.outputs.is_empty_body == 'true' }} |
80 | | - with: |
81 | | - header: pr-empty-comments |
82 | | - message: | |
83 | | - 👋 @${{ github.event.pull_request.user.login }} |
84 | | - Please use the PR template mentioned [here](${{ env.TEMPLATE_URL }}) |
85 | | - Please make sure you have followed our [contributing guidelines](${{ env.GUIDELINE_REPO }}). |
86 | | - - name: Exit the job for empty PR description |
87 | | - if: ${{ steps.getPrBody.outputs.is_empty_body == 'true' }} |
88 | | - run: | |
89 | | - echo "Failed due to empty PR description" |
90 | | - exit 1 |
91 | | -
|
92 | | - check-unwanted-files: |
93 | | - name: Check for unwanted files - .zip etc. |
94 | | - runs-on: ubuntu-latest |
95 | | - timeout-minutes: 10 |
96 | | - steps: |
97 | | - - name: Checkout code |
98 | | - uses: actions/checkout@v2 |
99 | | - - name: 'Check if file exists, and set flag' |
100 | | - id: fileCheck |
101 | | - run: | |
102 | | - file_count=$(find ./ -type f \( -iname \*.zip -o -iname \*.parque \) | wc -l ) # get file count of the unwanted files |
103 | | - if [[ "$file_count==0" ]];then |
104 | | - echo "No unwanted files found" |
105 | | - exit 0 |
106 | | - else |
107 | | - echo "::set-output name=is_unwanted_file::true" |
108 | | - echo "::set-output name=file_paths::$(find $PWD -type f \( -iname \*.zip -o -iname \*.parque \))" |
109 | | - echo "Please remove unwanted files" |
110 | | - exit 0 |
111 | | - fi |
112 | | - - uses: marocchino/sticky-pull-request-comment@v2 |
113 | | - if: ${{ steps.fileCheck.outputs.is_unwanted_file == 'true' }} |
114 | | - with: |
115 | | - header: file-check |
116 | | - message: | |
117 | | - 👋 @${{ github.event.pull_request.user.login }} |
118 | | - Please remove unwanted files from the repo. |
119 | | - Here is the detected file path: ${{ steps.fileCheck.outputs.file_paths }} |
120 | | - Please make sure you have followed our [contributing guidelines](${{ env.GUIDELINE_REPO }}). |
121 | | -
|
122 | | - # see [reviewdog/action-detect-secrets](https://github.com/Yelp/detect-secrets) and |
123 | | - # [detect-secrets](https://github.com/Yelp/detect-secrets) |
124 | | - check-hardcoded-credentials: |
125 | | - name: Check hardcoded credentials in files |
126 | | - runs-on: ubuntu-latest |
127 | | - timeout-minutes: 10 |
128 | | - steps: |
129 | | - - name: Checkout code |
130 | | - uses: actions/checkout@v2 |
131 | | - - name: detect-secrets |
132 | | - uses: reviewdog/action-detect-secrets@master |
133 | | - with: |
134 | | - github_token: '${{ secrets.GITHUB_TOKEN }}' |
135 | | - reporter: github-pr-review |
136 | | - fail_on_error: true |
137 | | - |
138 | | - linting: |
139 | | - name: 'Linting: black, flake8' |
140 | | - runs-on: ubuntu-latest |
141 | | - timeout-minutes: 10 |
142 | | - env: |
143 | | - DOCSTRING_REPORT: output/docstring_report.txt |
144 | | - steps: |
145 | | - - uses: actions/checkout@v2 |
146 | | - - name: Set up Python 3.8 |
147 | | - uses: actions/setup-python@v2 |
148 | | - with: |
149 | | - python-version: 3.8 |
150 | | - - name: black formatting check |
151 | | - uses: reviewdog/action-black@v2 |
152 | | - with: |
153 | | - github_token: '${{ secrets.GITHUB_TOKEN }}' |
154 | | - black_args: '--config=pyproject.toml' |
155 | | - reporter: github-pr-review |
156 | | - fail_on_error: true |
157 | | - - name: flake8 lint check |
158 | | - uses: reviewdog/action-flake8@v3 |
159 | | - with: |
160 | | - github_token: '${{ secrets.GITHUB_TOKEN }}' |
161 | | - flake8_args: '--config=setup.cfg' |
162 | | - reporter: github-pr-review |
163 | | - fail_on_error: true |
164 | | - |
165 | | - interrogate: |
166 | | - name: 'Docstrings coverage check (interrogate)' |
167 | | - runs-on: ubuntu-latest |
168 | | - timeout-minutes: 10 |
169 | | - env: |
170 | | - DOCSTRING_REPORT: output/docstring_report.txt |
171 | | - steps: |
172 | | - - uses: actions/checkout@v2 |
173 | | - - name: Set up Python 3.8 |
174 | | - uses: actions/setup-python@v2 |
175 | | - with: |
176 | | - python-version: 3.8 |
177 | | - - name: Install dependencies & create output directory for reports |
178 | | - run: | |
179 | | - pip install --upgrade pip interrogate |
180 | | - mkdir -p output # for docstring report |
181 | | - - name: Generate docstring report |
182 | | - # see also https://github.com/JackMcKew/python-interrogate-check#full-example |
183 | | - # if interrogate failed, the cov will fail separately, later |
184 | | - run: | |
185 | | - interrogate -o "$DOCSTRING_REPORT" || exit 0 |
186 | | - - name: Analyze docstring report |
187 | | - id: docstringCheck |
188 | | - run: | |
189 | | - total_cov=$(grep -o 'actual: [0-9.]*' $DOCSTRING_REPORT | sed 's/actual: //') # get actual docstring coverage from docstring report file |
190 | | - echo "::set-output name=total_cov::$cov_val" |
191 | | - passed_or_failed=$(grep -o 'RESULT: \w*' $DOCSTRING_REPORT | sed 's/RESULT: //') |
192 | | - echo "::set-output name=passed_or_failed::$passed_or_failed" |
193 | | - - name: Reformat docstring report |
194 | | - run: | |
195 | | - sed -i "s!^=.*!## Docstring Coverage :memo:!" "$DOCSTRING_REPORT" |
196 | | - sed -i "s!.*-- Summary --.*!\n<details><summary>docstring coverage details</summary>\n!" "$DOCSTRING_REPORT" |
197 | | - sed -i "s!.*-- RESULT:!</details>\n\n!" "$DOCSTRING_REPORT" |
198 | | - sed -i "s!) --.*!)!" "$DOCSTRING_REPORT" |
199 | | - sed -i "s/TOTAL /**TOTAL**/" "$DOCSTRING_REPORT" |
200 | | - sed -i "s/ PASSED / **PASSED** /" "$DOCSTRING_REPORT" |
201 | | - sed -i "s/ FAILED / **FAILED** /" "$DOCSTRING_REPORT" |
202 | | - # drop second separator line; TODO: run with -vv and format nicely |
203 | | - gawk -i inplace '!/^[|]-/ || !f++' "$DOCSTRING_REPORT" |
204 | | - cat "$DOCSTRING_REPORT" |
205 | | - - name: Post docstring report as PR comment |
206 | | - uses: marocchino/sticky-pull-request-comment@v2 |
207 | | - with: |
208 | | - header: docstring-comment |
209 | | - path: ${{ env.DOCSTRING_REPORT }} |
210 | | - - name: Exit the job for docstring coverage failed |
211 | | - if: ${{ steps.docstringCheck.outputs.passed_or_failed == 'FAILED' }} |
212 | | - run: | |
213 | | - echo "Docstring coverage (interrogate): failed because coverage is low, ${{ steps.docstringCheck.outputs.total_cov }}" |
214 | | - exit 1 |
215 | | -
|
216 | | - mypy-typecheck: |
217 | | - timeout-minutes: 30 |
218 | | - runs-on: ubuntu-latest |
219 | | - name: 'Mypy Type check' |
220 | | - steps: |
221 | | - - name: Checkout code |
222 | | - uses: actions/checkout@v2 |
223 | | - - name: Set up Python 3.8 |
224 | | - uses: actions/setup-python@v2 |
225 | | - with: |
226 | | - python-version: 3.8 |
227 | | - - name: Use cache if possible |
228 | | - # see [cache](https://github.com/actions/cache) and |
229 | | - # [pip example](https://github.com/actions/cache/blob/master/examples.md#simple-example)) |
230 | | - uses: actions/cache@v2 |
231 | | - with: |
232 | | - path: ~/.cache/pip |
233 | | - key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements**.txt') }} |
234 | | - restore-keys: | |
235 | | - ${{ runner.os }}-pip- |
236 | | - - name: Install dependencies |
237 | | - run: | |
238 | | - python -m pip install --upgrade pip |
239 | | - if [ requirements.txt ]; then pip install -r requirements.txt; fi |
240 | | - if [ requirements-dev.txt ]; then pip install -r requirements-dev.txt; fi |
241 | | - - name: mypy type check |
242 | | - uses: tsuyoshicho/action-mypy@v3 |
243 | | - with: |
244 | | - github_token: '${{ secrets.GITHUB_TOKEN }}' |
245 | | - level: info |
246 | | - reporter: github-pr-review |
247 | | - # mypy_flags: '--config-file=pyproject.toml' |
248 | | - fail_on_error: true |
249 | | - |
250 | | - test-and-coverage: |
251 | | - name: 'Pytest and Coverage' |
252 | | - runs-on: ubuntu-latest |
253 | | - timeout-minutes: 30 |
254 | | - env: |
255 | | - COVERAGE_OUTPUT_PATH: output/coverage.xml |
256 | | - steps: |
257 | | - - name: Checkout code |
258 | | - uses: actions/checkout@v2 |
259 | | - - name: Set up Python 3.8 |
260 | | - uses: actions/setup-python@v2 |
261 | | - with: |
262 | | - python-version: 3.8 |
263 | | - - name: Use cache if possible |
264 | | - # see [cache](https://github.com/actions/cache) and |
265 | | - # [pip example](https://github.com/actions/cache/blob/master/examples.md#simple-example)) |
266 | | - uses: actions/cache@v2 |
267 | | - with: |
268 | | - path: ~/.cache/pip |
269 | | - key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements**.txt') }} |
270 | | - restore-keys: | |
271 | | - ${{ runner.os }}-pip- |
272 | | - - name: Install dependencies |
273 | | - run: | |
274 | | - python -m pip install --upgrade pip |
275 | | - if [ requirements.txt ]; then pip install -r requirements.txt; fi |
276 | | - if [ requirements-dev.txt ]; then pip install -r requirements-dev.txt; fi |
277 | | - - name: Test with pytest and generate cov |
278 | | - # see also https://pytest-cov.readthedocs.io/en/latest/config.html |
279 | | - run: | |
280 | | - python -m pytest --cov-report xml:$COVERAGE_OUTPUT_PATH --cov=. --cov-config=pyproject.toml \ |
281 | | - --continue-on-collection-errors --no-cov-on-fail --durations=5 |
282 | | - - name: Upload code coverage to codeclimate |
283 | | - uses: paambaati/codeclimate-action@v2.7.5 |
284 | | - env: |
285 | | - # see https://docs.codeclimate.com/docs/finding-your-test-coverage-token |
286 | | - # get from https://codeclimate.com/repos/6094b3d1a32d9010d700292e/settings/test_reporter |
287 | | - CC_TEST_REPORTER_ID: '${{ secrets.CC_TEST_REPORTER_ID }}' |
288 | | - with: |
289 | | - # see https://github.com/marketplace/actions/code-climate-coverage-action#inputs |
290 | | - coverageLocations: | |
291 | | - ${{ env.COVERAGE_OUTPUT_PATH }}:coverage.py |
292 | | - - name: Upload codecov report |
293 | | - # see https://github.com/codecov/codecov-action |
294 | | - uses: codecov/codecov-action@v1 |
295 | | - with: |
296 | | - token: ${{ secrets.CODECOV_TOKEN }} |
297 | | - files: ${{ env.COVERAGE_OUTPUT_PATH }} |
298 | | - fail_ci_if_error: true # optional (default = false) |
299 | | - verbose: true # optional (default = false) |
| 24 | + # reference: https://docs.github.com/en/actions/learn-github-actions/reusing-workflows#example-caller-workflow |
| 25 | + org-checks: |
| 26 | + uses: predictionmachine/pm-github-actions/.github/workflows/pm-gh-actions.yml@main |
| 27 | + secrets: |
| 28 | + CC_TEST_REPORTER_ID: ${{ secrets.CC_TEST_REPORTER_ID }} |
| 29 | + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} |
0 commit comments