borg/.github/workflows/canary.yml
Thomas Waldmann 70fc87ec1b
CI: do not persist the checkout credentials where they are not needed
actions/checkout leaves the job token behind in .git/config, so anything
that later archives the workspace also archives the credential (zizmor's
artipacked audit).  None of these workflows push with it - release.yml
authenticates gh via GH_TOKEN, and peter-evans/create-pull-request uses
its own token input - so they can all opt out.

backport.yml is the exception and keeps the credentials: korthout/backport-action
pushes the backport branch with a plain `git push`, which only works with
what actions/checkout left in .git/config.  Marked accordingly.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-29 22:37:28 +02:00

182 lines
6.6 KiB
YAML

name: Canary (Unlocked Requirements)
on:
schedule:
- cron: '0 7 * * *' # Run at 07:00 UTC
workflow_dispatch: # Allow manual trigger
permissions:
contents: read
env:
# Force colored tox and pytest output even without a tty - the GitHub
# Actions log viewer renders ANSI colors. tox passes both vars through
# to pytest (pass_env = ["*"]).
PY_COLORS: "1" # pytest
TOX_COLORED: "yes" # tox's own output
jobs:
canary_tests:
name: Canary (${{ matrix.os }}, ${{ matrix.python-version }}, ${{ matrix.toxenv }})
runs-on: ${{ matrix.os }}
timeout-minutes: 360
strategy:
fail-fast: false
matrix:
include:
# A representative subset of environments
- os: ubuntu-26.04
python-version: '3.11'
toxenv: py311-llfuse
- os: ubuntu-26.04
python-version: '3.12'
toxenv: py312-pyfuse3
- os: ubuntu-26.04
python-version: '3.14'
toxenv: py314-mfusepy
- os: ubuntu-26.04
# 3.15 is not released yet - fail-fast is off, so a broken prerelease
# python (or a dependency without 3.15 wheels) only reddens this entry.
python-version: '3.15-dev'
toxenv: py315-mfusepy
- os: macos-15
python-version: '3.14'
toxenv: py314-none
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
fetch-depth: 0
fetch-tags: true
persist-credentials: false
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
with:
python-version: ${{ matrix.python-version }}
- name: Install Linux packages
if: ${{ runner.os == 'Linux' }}
shell: bash
run: |
sudo apt-get update
sudo apt-get install -y pkg-config build-essential
sudo apt-get install -y libssl-dev libacl1-dev liblz4-dev
if [[ "${{ matrix.toxenv }}" == *"llfuse"* ]]; then
sudo apt-get install -y libfuse-dev fuse
elif [[ "${{ matrix.toxenv }}" == *"pyfuse3"* || "${{ matrix.toxenv }}" == *"mfusepy"* ]]; then
sudo apt-get install -y libfuse3-dev fuse3
fi
- name: Install macOS packages
if: ${{ runner.os == 'macOS' }}
shell: bash
run: |
brew bundle install || true
# unresolvable .local runner hostname = ~35s resolver timeout per borg process, see #9470
sudo scutil --set HostName borg-ci-mac
echo "127.0.0.1 borg-ci-mac" | sudo tee -a /etc/hosts
- name: Install Python requirements (UNLOCKED)
shell: bash
run: |
python -m pip install --upgrade pip setuptools wheel
# Use UNLOCKED requirements to catch upstream breakages
pip install -r requirements.d/development.txt
- name: Install borgbackup
shell: bash
run: |
if [[ "${{ matrix.toxenv }}" == *"llfuse"* ]]; then
pip install -e ".[llfuse,cockpit]"
elif [[ "${{ matrix.toxenv }}" == *"pyfuse3"* ]]; then
pip install -e ".[pyfuse3,cockpit]"
elif [[ "${{ matrix.toxenv }}" == *"mfusepy"* ]]; then
pip install -e ".[mfusepy,cockpit]"
else
pip install -e ".[cockpit]"
fi
- name: Run tests (Canary)
shell: bash
run: |
if [[ "${{ matrix.toxenv }}" == *"-windows" ]]; then
python -m pytest -n4 --benchmark-skip -vv -rs -k "not remote" --cov=borg --cov-config=pyproject.toml --cov-report=xml --junitxml=test-results.xml
else
# Force tox to use the unlocked requirements in its environment creation
# by overriding the deps if possible, or just trusting it uses development.txt
# which we already installed in the root. Actually tox creates its own venv.
# We need to tell tox to use the unlocked file.
tox -e ${{ matrix.toxenv }} --override "env_run_base.deps=[-rrequirements.d/development.txt]"
fi
windows_canary:
if: true # can be used to temporarily disable the build
name: Canary (Windows)
runs-on: windows-latest
timeout-minutes: 180
env:
MSYS2_ARG_CONV_EXCL: "*"
MSYS2_ENV_CONV_EXCL: "*"
# see the "Cache pip-built wheels" step. MSYS2_ENV_CONV_EXCL above keeps
# this a Windows path when it enters the msys2 shell.
PIP_CACHE_DIR: ${{ github.workspace }}\.pip-cache
defaults:
run:
shell: msys2 {0}
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
fetch-depth: 0
persist-credentials: false
# Same as the "Cache pip-built wheels" step in ci.yml (MSYS2's mingw
# Python cannot use PyPI's win_amd64 wheels). Own key, because the
# unlocked requirements may resolve to different versions; falls back
# to (and gets picked up by) the ci.yml cache via the shared prefix.
- name: Cache pip-built wheels
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
with:
path: .pip-cache
key: windows-msys2-pip-canary-${{ hashFiles('pyproject.toml', 'requirements.d/pyinstaller.txt') }}
restore-keys: |
windows-msys2-pip-
- uses: msys2/setup-msys2@66cd2cce69caa17b53920067426061ca1de3a884 # v2.32.0
with:
msystem: UCRT64
update: true
- name: Install system packages
run: ./scripts/msys2-install-deps development
- name: Build python venv
run: |
# building some packages in the venv fails, so we try to use the system packages
python -m venv --system-site-packages env
. env/bin/activate
# python -m pip install --upgrade pip
# pip install --upgrade setuptools build wheel
pip install -r requirements.d/pyinstaller.txt
- name: Build
run: |
# build borg.exe
. env/bin/activate
pip install -e ".[cockpit,s3,sftp,rclone]"
mkdir -p dist/binary
pyinstaller -y --clean --distpath=dist/binary scripts/borg.exe.spec
# build sdist and wheel in dist/...
python -m build
- name: Run tests
run: |
# Ensure locally built binary in ./dist/binary/borg-dir is found during tests
export PATH="$GITHUB_WORKSPACE/dist/binary/borg-dir:$PATH"
borg.exe -V
. env/bin/activate
python -m pytest -n4 --benchmark-skip -vv -rs -k "not remote" --cov=borg --cov-config=pyproject.toml --cov-report=xml --junitxml=test-results.xml