diff --git a/.github/workflows/meet.yml b/.github/workflows/build-and-test.yml similarity index 82% rename from .github/workflows/meet.yml rename to .github/workflows/build-and-test.yml index e7572b68c9..244b25e6c9 100644 --- a/.github/workflows/meet.yml +++ b/.github/workflows/build-and-test.yml @@ -1,4 +1,4 @@ -name: meet Workflow +name: build and test on: push: @@ -11,63 +11,6 @@ permissions: contents: read jobs: - lint-git: - runs-on: ubuntu-latest - if: github.event_name == 'pull_request' # Makes sense only for pull requests - permissions: - contents: read - steps: - - name: Checkout repository - uses: actions/checkout@v6 - with: - fetch-depth: 0 - - name: show - run: git log - - name: Enforce absence of print statements in code - if: always() - run: | - ! git diff origin/${{ github.event.pull_request.base.ref }}..HEAD -- . ':(exclude)**/meet.yml' | grep "print(" - - name: Check absence of fixup commits - if: always() - run: | - ! git log | grep 'fixup!' - - name: Install gitlint - if: always() - run: pip install --user requests gitlint - - name: Lint commit messages added to main - if: always() - run: ~/.local/bin/gitlint --commits origin/${{ github.event.pull_request.base.ref }}..HEAD - - check-changelog: - runs-on: ubuntu-latest - if: | - contains(github.event.pull_request.labels.*.name, 'noChangeLog') == false && - github.event_name == 'pull_request' - permissions: - contents: read - steps: - - name: Checkout repository - uses: actions/checkout@v6 - with: - fetch-depth: 50 - - name: Check that the CHANGELOG has been modified in the current branch - run: git diff --name-only ${{ github.event.pull_request.base.sha }} ${{ github.event.after }} | grep 'CHANGELOG.md' - - lint-changelog: - runs-on: ubuntu-latest - permissions: - contents: read - steps: - - name: Checkout repository - uses: actions/checkout@v6 - - name: Check CHANGELOG max line length - run: | - max_line_length=$(cat CHANGELOG.md | grep -Ev "^\[.*\]: https://github.com" | wc -L) - if [ $max_line_length -ge 80 ]; then - echo "ERROR: CHANGELOG has lines longer than 80 characters." - exit 1 - fi - build-mails: runs-on: ubuntu-latest permissions: @@ -353,9 +296,6 @@ jobs: - name: Check linting run: cd src/frontend/ && npm run lint - - name: Check format - run: cd src/frontend/ && npm run check - lint-sdk: runs-on: ubuntu-latest permissions: diff --git a/.github/workflows/static-checks.yml b/.github/workflows/static-checks.yml new file mode 100644 index 0000000000..cdfa8111e0 --- /dev/null +++ b/.github/workflows/static-checks.yml @@ -0,0 +1,139 @@ +name: static checks + +# The checks that read a branch rather than execute it. They live here, and not +# in build-and-test.yml, so they report on a pull request from a first-time +# contributor, whose pull_request run waits for a maintainer to approve it. On +# a push to main, the two that read a commit rather than a pull request run +# over what was pushed. +# +# pull_request_target runs with this repository's token, so nothing the branch +# controls may be installed, imported or executed here. Do not add a step that +# builds or tests it: that needs pull_request, and the wait that comes with it. +# https://securitylab.github.com/resources/github-actions-preventing-pwn-requests/ + +on: + push: + branches: + - main + pull_request_target: + types: + - opened + - reopened + - synchronize + - labeled + - unlabeled + +# every job below grants itself what it needs, so a job added without a block +# gets nothing rather than the repository default +permissions: {} + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +env: + HEAD_REF: refs/pull/${{ github.event.pull_request.number }}/head + +jobs: + check-format: + runs-on: ubuntu-latest + permissions: + contents: read + steps: + # persist-credentials keeps this repository's token out of .git/config, + # which the branch's own files land beside + - name: Checkout repository + uses: actions/checkout@v6 + with: + persist-credentials: false + - uses: actions/setup-node@v6 + with: + node-version: "22" + cache: npm + cache-dependency-path: src/frontend/package-lock.json + - name: Install dependencies + run: cd src/frontend/ && npm ci --ignore-scripts + - name: Read the branch's sources as data + if: github.event_name == 'pull_request_target' + run: | + git fetch --no-tags --depth 1 origin "$HEAD_REF" + rm -rf src/frontend/src + git checkout FETCH_HEAD -- src/frontend/src + # without --config prettier loads one the branch left among its own files, + # and without --no-editorconfig an .editorconfig left there moves printWidth + # and tabWidth, which .prettierrc does not set and so cannot override + - name: Check format + run: cd src/frontend/ && npm run check -- --config .prettierrc --no-editorconfig + + lint-changelog: + runs-on: ubuntu-latest + permissions: + contents: read + steps: + - name: Read the branch's changelog as data + env: + GH_TOKEN: ${{ github.token }} + REF: ${{ github.event.pull_request.head.sha || github.sha }} + run: | + gh api -H 'Accept: application/vnd.github.raw' \ + "repos/${{ github.repository }}/contents/CHANGELOG.md?ref=$REF" \ + > CHANGELOG.md + - name: Check CHANGELOG max line length + run: | + max_line_length=$(cat CHANGELOG.md | grep -Ev "^\[.*\]: https://github.com" | wc -L) + if [ $max_line_length -ge 80 ]; then + echo "ERROR: CHANGELOG has lines longer than 80 characters." + exit 1 + fi + + check-changelog: + if: | + github.event_name == 'pull_request_target' && + contains(github.event.pull_request.labels.*.name, 'noChangelog') == false + runs-on: ubuntu-latest + permissions: + contents: read + pull-requests: read + steps: + # unanchored, so a path ending in CHANGELOG.md anywhere counts + - name: Check that the CHANGELOG has been modified in the current branch + env: + GH_TOKEN: ${{ github.token }} + run: | + gh api --paginate \ + "repos/${{ github.repository }}/pulls/${{ github.event.pull_request.number }}/files" \ + --jq '.[].filename' | grep 'CHANGELOG.md' + + lint-git: + if: github.event_name == 'pull_request_target' + runs-on: ubuntu-latest + permissions: + contents: read + env: + BASE_REF: ${{ github.event.pull_request.base.ref }} + steps: + - name: Checkout repository + uses: actions/checkout@v6 + with: + fetch-depth: 0 + filter: blob:none + persist-credentials: false + - name: Read the branch's commits as data + run: git fetch --no-tags origin "$HEAD_REF" + # added lines only, since deleting a print is not a violation, and the + # pattern is spelled so that this line does not match itself + - name: Enforce absence of print statements in code + if: always() + run: | + ! git diff "origin/$BASE_REF...FETCH_HEAD" | grep '^+.*print[(]' + - name: Check absence of fixup commits + if: always() + run: | + ! git log "origin/$BASE_REF..FETCH_HEAD" | grep 'fixup!' + - name: Install gitlint + if: always() + run: "pip install --user --only-binary=:all: requests==2.34.2 gitlint==0.18.0" + # gitlint imports gitlint/, so those rules must come from this checkout + - name: Lint commit messages added to main + if: always() + run: ~/.local/bin/gitlint --commits "origin/$BASE_REF..FETCH_HEAD"