# SPDX-License-Identifier: LGPL-2.1-or-later # *************************************************************************** # * * # * Copyright (c) 2023 0penBrain. * # * * # * This file is part of FreeCAD. * # * * # * FreeCAD is free software: you can redistribute it and/or modify it * # * under the terms of the GNU Lesser General Public License as * # * published by the Free Software Foundation, either version 2.1 of the * # * License, or (at your option) any later version. * # * * # * FreeCAD is distributed in the hope that it will be useful, but * # * WITHOUT ANY WARRANTY; without even the implied warranty of * # * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * # * Lesser General Public License for more details. * # * * # * You should have received a copy of the GNU Lesser General Public * # * License along with FreeCAD. If not, see * # * . * # * * # *************************************************************************** # This is the pre-check workflow for CI of FreeCAD. # It aims at running some basic checks about the workflow run ... # ... and gathering some data needed for the next steps. name: Prepare on: workflow_call: inputs: artifactBasename: type: string required: true dontFailOnOldRebase: default: true type: boolean required: false maxRebaseHours: default: "48" type: string required: false outputs: reportFile: value: ${{ jobs.Prepare.outputs.reportFile }} changedFiles: value: ${{ jobs.Prepare.outputs.changedFiles }} changedLines: value: ${{ jobs.Prepare.outputs.changedLines }} changedPythonFiles: value: ${{ jobs.Prepare.outputs.changedPythonFiles }} changedPythonLines: value: ${{ jobs.Prepare.outputs.changedPythonLines }} changedCppFiles: value: ${{ jobs.Prepare.outputs.changedCppFiles }} changedCppLines: value: ${{ jobs.Prepare.outputs.changedCppLines }} jobs: Prepare: env: isPR: ${{ github.event_name == 'pull_request' }} isPush: ${{ github.event_name == 'push' }} logdir: /tmp/logs/ reportdir: /tmp/report/ reportfilename: ${{ inputs.artifactBasename }}-report.md runs-on: ubuntu-latest defaults: run: shell: bash outputs: reportFile: ${{ steps.Init.outputs.reportFile }} changedFiles: ${{ steps.Output.outputs.changedFiles }} changedLines: ${{ steps.Output.outputs.changedLines }} changedPythonFiles: ${{ steps.Output.outputs.changedPythonFiles }} changedPythonLines: ${{ steps.Output.outputs.changedPythonLines }} changedCppFiles: ${{ steps.Output.outputs.changedCppFiles }} changedCppLines: ${{ steps.Output.outputs.changedCppLines }} steps: - name: Harden the runner (Audit all outbound calls) uses: step-security/harden-runner@5ef0c079ce82195b2a36a210272d6b661572d83e # v2.14.2 with: egress-policy: audit - name: Make needed directories, files and initializations id: Init run: | mkdir -p ${{ env.logdir }} mkdir -p ${{ env.reportdir }} commitCnt=0 touch ${{ env.logdir }}changedFiles.lst ${{ env.logdir }}changedCppFiles.lst ${{ env.logdir }}changedPythonFiles.lst echo "reportFile=${{ env.reportfilename }}" >> $GITHUB_OUTPUT - name: Check out code uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: submodules: true - name: Determine base and head SHA in case of PR if: env.isPR == 'true' run: | baseSha=${{ github.event.pull_request.base.sha }} headSha=${{ github.event.pull_request.head.sha }} echo "baseSha=$baseSha" >> $GITHUB_ENV echo "headSha=$headSha" >> $GITHUB_ENV echo "This CI run is performed on a Pull Request" | tee -a ${{env.reportdir}}${{ env.reportfilename }} echo "Base SHA is $baseSha, Head SHA is $headSha" | tee -a ${{env.reportdir}}${{ env.reportfilename }} - name: Check if PR has been recently rebased if: env.isPR == 'true' continue-on-error: ${{ inputs.dontFailOnOldRebase }} run: | baseDate=$(curl -H "Accept: application/vnd.github+json" -H "authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" $GITHUB_API_URL/repos/$GITHUB_REPOSITORY/commits/$baseSha | jq -r '.commit.committer.date') dateDiff=$(( ( $(date +%s) - $(date -d $baseDate +%s) ) / 3600 )) echo "Pull request is based on a $dateDiff hour-old commit" | tee -a ${{env.reportdir}}${{ env.reportfilename }} # Exit the step with appropriate code if [ $dateDiff -gt ${{ inputs.maxRebaseHours }} ] then echo -n ":warning: Pull request should be rebased" | tee -a ${{env.reportdir}}${{ env.reportfilename }} exit 1 fi - name: Determine base and head SHA in case of push if: env.isPush == 'true' run: | baseSha=${{ github.event.before }} headSha=${{ github.event.after }} echo "headSha=$headSha" >> $GITHUB_ENV if [ $baseSha -eq 0 ] then echo "This CI run is performed on a Push that created a new branch : files changed will be ignored" | tee -a ${{env.reportdir}}${{ env.reportfilename }} echo "Head SHA is $headSha" | tee -a ${{env.reportdir}}${{ env.reportfilename }} echo "isPush='false'" >> $GITHUB_ENV else echo "This CI run is performed on a Push" | tee -a ${{env.reportdir}}${{ env.reportfilename }} echo "Base SHA is $baseSha, Head SHA is $headSha" | tee -a ${{env.reportdir}}${{ env.reportfilename }} echo "baseSha=$baseSha" >> $GITHUB_ENV fi - name: Get compare between head and base if: env.isPR == 'true' || env.isPush == 'true' run: | echo "$GITHUB_API_URL/repos/$GITHUB_REPOSITORY/compare/$baseSha...$headSha" curl -H "Accept: application/vnd.github+json" -H "authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" $GITHUB_API_URL/repos/$GITHUB_REPOSITORY/compare/$baseSha...$headSha > ${{ env.logdir }}compare.json - name: Get number of commits in the changeset if: env.isPR == 'true' || env.isPush == 'true' run: | commitCnt=$(jq -re '.ahead_by' ${{ env.logdir }}compare.json) echo "Changeset is composed of $commitCnt commit(s)" | tee -a ${{env.reportdir}}${{ env.reportfilename }} - name: Get files modified in changeset #TODO check what happens with deleted file in the subsequent process if: env.isPR == 'true' env: API_URL: ${{ github.api_url }} TOKEN: ${{ github.token }} REPO: ${{ github.repository }} REF: ${{ github.ref_name }} PR: ${{ github.event.number }} run: | # could reduce this to a single python3 tools/lint/changed_lines.py --api-url ${API_URL} --token ${TOKEN} --repo ${REPO} --ref=${REF} --pr=${PR} > ${{ env.logdir }}changedLines.lst cat ${{ env.logdir }}changedLines.lst | jq '.[].name' > ${{ env.logdir }}changedFiles.lst python3 tools/lint/changed_lines.py --api-url ${API_URL} --token ${TOKEN} --repo ${REPO} --ref=${REF} --pr=${PR} --file-filter '.py, .pyi' > ${{ env.logdir }}changedPythonLines.lst cat ${{ env.logdir }}changedPythonLines.lst | jq '.[].name' > ${{ env.logdir }}changedPythonFiles.lst python3 tools/lint/changed_lines.py --api-url ${API_URL} --token ${TOKEN} --repo ${REPO} --ref=${REF} --pr=${PR} --file-filter '.c, .cc, .cu, .cuh, .c++, .cpp, .cxx, .h, .hh, .h++, .hpp, .hxx' > ${{ env.logdir }}changedCppLines.lst cat ${{ env.logdir }}changedCppLines.lst | jq '.[].name' > ${{ env.logdir }}changedCppFiles.lst # Write the report echo "::group::Modified files in changeset (removed files are ignored) :" ; cat ${{ env.logdir }}changedFiles.lst ; echo "::endgroup::" echo "
Modified files (removed files are ignored):" >> ${{env.reportdir}}${{ env.reportfilename }} cat ${{ env.logdir }}changedFiles.lst >> ${{env.reportdir}}${{ env.reportfilename }} echo "
" >> ${{env.reportdir}}${{ env.reportfilename }} echo "" >> ${{env.reportdir}}${{ env.reportfilename }} - name: Transmitting outputs id: Output run: | echo "changedFiles=$(cat ${{ env.logdir }}changedFiles.lst | tr '\n' ' ')" >> $GITHUB_OUTPUT echo "changedLines=$(cat ${{ env.logdir }}changedLines.lst | tr '\n' ' ')" >> $GITHUB_OUTPUT echo "changedPythonFiles=$(cat ${{ env.logdir }}changedPythonFiles.lst | tr '\n' ' ')" >> $GITHUB_OUTPUT echo "changedPythonLines=$(cat ${{ env.logdir }}changedPythonLines.lst | tr '\n' ' ')" >> $GITHUB_OUTPUT echo "changedCppFiles=$(cat ${{ env.logdir }}changedCppFiles.lst | tr '\n' ' ')" >> $GITHUB_OUTPUT echo "changedCppLines=$(cat ${{ env.logdir }}changedCppLines.lst | tr '\n' ' ')" >> $GITHUB_OUTPUT echo "" >> $GITHUB_OUTPUT - name: Upload logs if: always() uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 with: name: ${{ inputs.artifactBasename }}-Logs path: | ${{ env.logdir }} - name: Upload report if: always() uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 with: name: ${{ env.reportfilename }} path: | ${{env.reportdir}}${{ env.reportfilename }}