File: continuous-integration-workflow.yml

package info (click to toggle)
fpdf2 2.8.7-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 114,352 kB
  • sloc: python: 50,410; sh: 133; makefile: 12
file content (290 lines) | stat: -rw-r--r-- 13,160 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
name: build

on:  # cf. https://github.community/t/how-to-trigger-an-action-on-push-or-pull-request-but-not-both/16662
  push:
    branches:
    - master
  pull_request:
    branches:
    - master

jobs:
  check-reference-pdf-files:
    runs-on: ubuntu-latest
    permissions: {}
    steps:
      - name: Checkout πŸ›ŽοΈ
        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
        with:
          persist-credentials: false
      - name: Set up Python 3.14 πŸ”§
        uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
        with:
          python-version: 3.14
      - name: Install system dependencies βš™οΈ
        run: sudo apt-get update --allow-releaseinfo-change && sudo apt-get install qpdf
      - name: Check all PDF reference files used in tests β˜‘
        run: |
          # Using qpdf
          find . -name '*.pdf' | xargs -n 1 sh -c 'qpdf --check --password=fpdf2 $0 || exit 255'
          export PYTHONPATH=$PWD
          # Using Datalogics PDF Checker:
          scripts/install-pdfchecker.sh
          time scripts/pdfchecker.py --process-all-test-pdf-files
          scripts/pdfchecker.py --print-aggregated-report
          # Using VeraPDF:
          scripts/install-verapdf.sh
          time scripts/verapdf.py --process-all-test-pdf-files
          scripts/verapdf.py --print-aggregated-report
          scripts/check-PDF-A-with-verapdf.sh
  lint:
    runs-on: ubuntu-24.04
    permissions:
      security-events: write  # for zizmor
    steps:
      - name: Checkout πŸ›ŽοΈ
        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
        with:
          persist-credentials: false
      - name: Set up Python 3.13 πŸ”§
        uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
        with:
          python-version: 3.13 # guarddog / pygit2 still have issues with 3.14
      - name: Install Python dependencies βš™οΈ
        run: |
          python -m pip install --upgrade pip setuptools wheel
          pip install --upgrade .[dev,test]
      # Running zizmor 1st, because it is blocking PR merge
      - name: Run zizmor 🌈
        run: zizmor --format=sarif . > results.sarif
        env:
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
      - name: Upload SARIF file
        uses: github/codeql-action/upload-sarif@89a39a4e59826350b863aa6b6252a07ad50cf83e # v4.32.4
        with:
          sarif_file: results.sarif
          category: zizmor
      - name: Run linters πŸ”Ž
        run: |
          black --check .
          pylint fpdf test tutorial/tuto*.py
          bandit -c .banditrc.yml -r contributors/ fpdf/ tutorial/
          semgrep scan --config auto --error --strict --exclude-rule=python.lang.security.insecure-hash-function.insecure-hash-function fpdf
      - name: Run type checkers πŸ”Ž
        run: |
          mypy
          pyright
      - name: Scan project with grype πŸ”Ž
        uses: anchore/scan-action@7037fa011853d5a11690026fb85feee79f4c946c # v7.3.2
        with:
          path: "."
          fail-build: true
      - name: Scan project dependencies with guarddog 🐢
        # GuardDog is very slow, we only execute it on the master branch:
        if: github.ref == 'refs/heads/master'
        run: |
          pip install guarddog
          python scripts/generate-dependencies-list.py pyproject.toml fpdf2-full-requirements.txt
          time guarddog pypi verify fpdf2-full-requirements.txt
          time guarddog pypi verify contributors/requirements.txt
      - name: Spell Check Repo ✍️
        uses: crate-ci/typos@631208b7aac2daa8b707f55e7331f9112b0e062d # v1.44.0
  test:
    strategy:
      matrix:
        python-version: ['3.10', '3.11', '3.12', '3.13', '3.14']
        platform: [ubuntu-latest, windows-latest, macos-latest]
    runs-on: ${{ matrix.platform }}
    permissions: {}
    steps:
      - name: Checkout πŸ›ŽοΈ
        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
        with:
          persist-credentials: false
      - name: Set up Python ${{ matrix.python-version }} πŸ”§
        uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
        with:
          python-version: ${{ matrix.python-version }}
      - name: Install system dependencies βš™οΈ
        if: ${{ startsWith(matrix.platform, 'ubuntu') }}
        # Ghostscript is needed for test/table/test_table_extraction.py
        run: sudo apt-get update --allow-releaseinfo-change && sudo apt-get install ghostscript
      - name: Install qpdf βš™οΈ
        # We run the unit tests WITHOUT qpdf for a single parallel execution / Python version:
        if: ${{ startsWith(matrix.platform, 'ubuntu') && matrix.python-version != '3.13' }}
        run: sudo apt-get update --allow-releaseinfo-change && sudo apt-get install qpdf
      - name: Install qpdf on Windows
        if: startsWith(matrix.platform, 'windows')
        shell: pwsh
        run: |
          choco install qpdf -y
          qpdf --version
      - name: Install Python dependencies βš™οΈ
        # Temporarily writing a constraints file to make sure numpy 2.3.3 is used
        # for python 3.14
        shell: bash
        run: |
          python -m pip install --upgrade pip setuptools wheel
          # --- Create constraints file ---
          # For Python 3.14 only - temporary solution while camelot-py
          # update its dependencies
          CONSTRAINTS_FILE="constraints.txt"
          if [[ "${{ matrix.python-version }}" == "3.14" ]]; then
            echo "numpy>=2.3.3" > "$CONSTRAINTS_FILE"
            echo "Added numpy>=2.3.3 to $CONSTRAINTS_FILE"
          else
            : > "$CONSTRAINTS_FILE"   # create empty file
            echo "Created empty $CONSTRAINTS_FILE"
          fi
          # --- Install dependencies respecting constraints ---
          pip install --upgrade .[dev,test] -c "$CONSTRAINTS_FILE"
      - name: Run tests β˜‘
        shell: bash
        env:
          CHECK_EXEC_TIME: ${{ matrix.python-version == '3.10' && 'test-enabled' || '' }}
          CHECK_RSS_MEMORY: ${{ matrix.python-version == '3.14' && 'test-enabled' || '' }}
        run: |
          # Ensuring there is no `generate=True` left remaining in calls to assert_pdf_equal:
          grep -IRF generate=True test/ && exit 1
          # Executing all tests:
          if [[ "${{ matrix.platform }}" == "ubuntu-latest" ]]; then
          echo "Running with --trace-memory-usage (Ubuntu)"
            pytest -vv --trace-memory-usage
          else
            echo "Running without trace-memory-usage (${{ matrix.platform }})"
            pytest -vv
          fi
      - name: Upload coverage report to codecov.io β˜‘
        # We only upload coverage ONCE, for a single parallel execution / Python version:
        if: ${{ startsWith(matrix.platform, 'ubuntu') && matrix.python-version == '3.13' }}
        run: bash <(curl -s https://codecov.io/bash)
      - name: Run tests with the minimal versions of fpdf2 direct dependencies β˜‘
        if: ${{ startsWith(matrix.platform, 'ubuntu') && matrix.python-version == '3.10' }}
        run: |
          # Ensuring that those minimal versions remain compatible:
          sed -i '/requires-python/s/>=/~=/' pyproject.toml
          sed -i 's/>=/==/' pyproject.toml
          # Removing field not supported in pyproject.toml at the time (prevent this: ValueError - invalid pyproject.toml config):
          sed -i '/license.*=/d' pyproject.toml
          pip install .
          # Targeting only a subset of tests because: A) it's faster and B) some tests are dependant on a specific version of fonttools or Pillow
          # Deselect test involving TTF fonts due to differences with old fonttools version.
          pytest -vv test/barcodes test/drawing test/errors test/image/test_load_image.py test/metadata test/shapes test/signing test/text_region test/utils --deselect test/drawing/test_drawing_text.py::test_text_ttf_transforms
  doc:
    runs-on: ubuntu-latest
    permissions:
      # required to deploy doc, by pushing commits to branch gh-pages:
      contents: write
      pages: write
    steps:
      - name: Harden Runner
        # Security hardening because this is a sensitive job,
        # where extra care should be taken NOT to leak any secret
        uses: step-security/harden-runner@a90bcbc6539c36a85cdfeb73f7e2f433735f215b # v2.15.0
        with:
          egress-policy: block
          allowed-endpoints:
            github.com:443
            api.github.com:443
            *.githubusercontent.com:443
            pypi.org:443
            files.pythonhosted.org:443
            registry.npmjs.org:443
            api.star-history.com:443
            cdnjs.cloudflare.com:443
            colab.research.google.com:443
            fonts.googleapis.com:443
            fonts.gstatic.com:443
            img.shields.io:443
            unpkg.com:443
            borbpdf.com:443
          # Starting from api.star-history.com, the endpoints whitelist reason is the mkdocs privacy plugin
      - name: Checkout πŸ›ŽοΈ
        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
        with:
          persist-credentials: false
          # Required for mkdocs git-revision-date-localized plugin:
          fetch-depth: 0
      - name: Set up Python 3.14 πŸ”§
        uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
        with:
          python-version: 3.14
      - name: Install Python dependencies βš™οΈ
        run: |
          python -m pip install --upgrade pip setuptools wheel
          pip install --upgrade .[docs] -r contributors/requirements.txt
      - name: Generate HTML documentation πŸ—οΈ
        run: |
          mkdir -p public/
          # Setting PDF manual version:
          VERSION=$(python -c "import importlib.metadata; print(importlib.metadata.version('fpdf2'))")
          sed -i "s/author:.*/author: v$VERSION/" mkdocs.yml
          cp tutorial/notebook.ipynb docs/
          python -m mkdocs build
          pdoc --html -o public/ fpdf --template-dir docs/pdoc
          scripts/add_pdoc_to_search_index.py
      - name: Build contributors map πŸ—ΊοΈ
        # As build_contributors_html_page.py can hang due to GitHub rate-limiting, we only execute this on master for now
        if: github.ref == 'refs/heads/master'
        env:
          # Needed by contributors/build_contributors_html_page.py:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          PYTHONUNBUFFERED: 1
        run: |
          cd contributors/
          npm ci
          ./build_contributors_html_page.py py-pdf/fpdf2
          cp -t ../public/ contributors.html contributors-map-small.png
      - name: Deploy documentation πŸš€
        if: github.ref == 'refs/heads/master'
        uses: peaceiris/actions-gh-pages@4f9cc6602d3f66b9c108549d475ec49e8ef4d45e # v4.0.0
        with:
          github_token: ${{ secrets.GITHUB_TOKEN }}
          publish_dir: public/
  publish:
    if: github.ref == 'refs/heads/master'
    runs-on: ubuntu-latest
    environment:
      name: pypi
      url: https://pypi.org/p/fpdf2
    permissions:
      # Trusted publishing configured there: https://pypi.org/manage/project/fpdf2/settings/publishing/
      id-token: write
    steps:
      - name: Harden Runner
        # Security hardening because this is a sensitive job,
        # where extra care should be taken NOT to leak any secret
        uses: step-security/harden-runner@a90bcbc6539c36a85cdfeb73f7e2f433735f215b # v2.15.0
        with:
          egress-policy: block
          allowed-endpoints:
            ghcr.io:443
            github.com:443
            *.githubusercontent.com:443
            pypi.org:443
            files.pythonhosted.org:443
            *.sigstore.dev:443
            upload.pypi.org:443
      - name: Checkout πŸ›ŽοΈ
        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
        with:
          persist-credentials: false
      - name: Set up Python 3.14 πŸ”§
        uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
        with:
          python-version: '3.14'
      - name: Build distributions for Pypi πŸ—οΈ
        id: build
        run: |
          echo Versions already released on Pypi: $(curl -Ls 'https://pypi.org/pypi/fpdf2/json' | jq -r '.releases|keys[]')
          pip install --upgrade build twine .
          VERSION=$(python -c "import importlib.metadata; print(importlib.metadata.version('fpdf2'))")
          echo Current code version: $VERSION
          # Checking if current code version has already been released:
          if ! curl -Ls 'https://pypi.org/pypi/fpdf2/json' | jq -r '.releases|keys[]' | grep "^$VERSION\$"; then echo publish=yes >> "$GITHUB_OUTPUT"; python -m build; twine check dist/*; fi
      - name: Publish package distributions to PyPI πŸš€
        if: steps.build.outputs.publish == 'yes'
        uses: pypa/gh-action-pypi-publish@ed0c53931b1dc9bd32cbe73a98c7f6766f8a527e # v1.13.0
        # Doc: https://github.com/marketplace/actions/pypi-publish
        with:
          print-hash: true