mirror of
https://github.com/zotero/zotero.git
synced 2026-08-28 05:25:31 +00:00
The apt mirrors regularly hang for many minutes, which was taking out random jobs until the job timeout.
427 lines
15 KiB
YAML
427 lines
15 KiB
YAML
name: CI
|
|
on:
|
|
push:
|
|
pull_request:
|
|
workflow_dispatch:
|
|
schedule:
|
|
# Monthly, to catch runner image and OS changes
|
|
- cron: '0 6 1 * *'
|
|
concurrency:
|
|
group: ${{ github.ref }}
|
|
cancel-in-progress: true
|
|
jobs:
|
|
# Decide whether to run the network-filesystem tests: always for manual and scheduled
|
|
# runs, and otherwise only when the changes touch the Gecko version or the files
|
|
# responsible for network-filesystem database handling
|
|
changes:
|
|
name: Detect changes
|
|
runs-on: ubuntu-latest
|
|
if: >
|
|
github.event_name != 'pull_request'
|
|
|| github.event.pull_request.head.repo.full_name != github.repository
|
|
outputs:
|
|
network: ${{ steps.check.outputs.network }}
|
|
steps:
|
|
- name: Check for network-filesystem-related changes
|
|
id: check
|
|
env:
|
|
EVENT: ${{ github.event_name }}
|
|
REPO: ${{ github.repository }}
|
|
SHA: ${{ github.sha }}
|
|
BEFORE: ${{ github.event.before }}
|
|
BASE: ${{ github.event.pull_request.base.sha }}
|
|
run: |
|
|
network=false
|
|
if [[ "$EVENT" == "workflow_dispatch" || "$EVENT" == "schedule" ]]; then
|
|
network=true
|
|
else
|
|
base="$BASE"
|
|
[[ -z "$base" ]] && base="$BEFORE"
|
|
git init -q repo && cd repo
|
|
git remote add origin "https://github.com/$REPO"
|
|
git fetch -q --depth 1 origin "$SHA"
|
|
# Run the tests if the base of the change can't be determined (e.g., a new
|
|
# branch or an unfetchable pre-force-push commit)
|
|
if [[ -z "$base" || "$base" == 0000000000000000000000000000000000000000 ]] \
|
|
|| ! git fetch -q --depth 1 origin "$base" 2>/dev/null; then
|
|
network=true
|
|
elif git diff --name-only "$base" "$SHA" \
|
|
| grep -qE '^(app/config\.sh|chrome/content/zotero/xpcom/(db|file)\.js|\.github/workflows/ci\.yml)$'; then
|
|
network=true
|
|
fi
|
|
fi
|
|
echo "network=$network" >> "$GITHUB_OUTPUT"
|
|
|
|
test:
|
|
name: Test (${{ matrix.shard }})
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 30
|
|
needs: changes
|
|
# Same-repo PRs are covered by the push run, so run pull_request jobs only for forks
|
|
if: >
|
|
github.event_name != 'pull_request'
|
|
|| github.event.pull_request.head.repo.full_name != github.repository
|
|
strategy:
|
|
matrix:
|
|
# Numbered shards split the full suite. 'smb' and 'nfs' run the db and file tests
|
|
# with the test data directory on a loopback CIFS or NFS mount, so that connection
|
|
# initialization itself runs against a network filesystem, which is where
|
|
# network-filesystem failures (startup crashes and hangs) occur. The network shards
|
|
# run only when the 'changes' job detects relevant changes.
|
|
shard: ${{ fromJSON(needs.changes.outputs.network == 'true'
|
|
&& '["1", "2", "3", "4", "smb", "nfs"]'
|
|
|| '["1", "2", "3", "4"]') }}
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
with:
|
|
submodules: recursive
|
|
lfs: true
|
|
|
|
- name: Install Node
|
|
uses: actions/setup-node@v4
|
|
with:
|
|
node-version: 24
|
|
#cache: npm
|
|
|
|
# Local via act
|
|
- name: Install packages for act
|
|
if: env.ACT == 'true'
|
|
run: apt update && apt install -y zstd xvfb dbus-x11 libgtk-3-0 libx11-xcb1 libdbus-glib-1-2 libxt6
|
|
|
|
- name: Cache xulrunner
|
|
id: xulrunner-cache
|
|
uses: actions/cache@v4
|
|
with:
|
|
path: app/xulrunner/firefox-x86_64
|
|
key: xulrunner-${{ hashFiles('app/config.sh', 'app/scripts/fetch_xulrunner') }}
|
|
|
|
- name: Fetch xulrunner
|
|
if: steps.xulrunner-cache.outputs.cache-hit != 'true'
|
|
run: app/scripts/fetch_xulrunner -p l
|
|
|
|
- name: Cache Node modules
|
|
id: node-cache
|
|
uses: actions/cache@v4
|
|
with:
|
|
path: node_modules
|
|
key: node-modules-24-${{ hashFiles('package-lock.json') }}
|
|
|
|
- name: Install Node modules
|
|
if: steps.node-cache.outputs.cache-hit != 'true'
|
|
run: npm install
|
|
|
|
- name: Build Zotero
|
|
run: npm run build
|
|
# Currently necessary for document-worker Webpack: https://stackoverflow.com/a/69746937
|
|
env:
|
|
NODE_OPTIONS: --openssl-legacy-provider
|
|
|
|
# Create deployment ZIP from the build output, then replace build/ with the
|
|
# unzipped contents so that tests run against the same artifact that gets
|
|
# deployed. This catches problems that only manifest after a zip round-trip
|
|
# (e.g., resolved symlinks, missing files).
|
|
- name: Create deployment ZIP
|
|
run: |
|
|
cd build
|
|
zip -r ../build.zip *
|
|
cd ..
|
|
|
|
- name: Replace build with ZIP contents
|
|
run: |
|
|
rm -rf build
|
|
mkdir build
|
|
cd build
|
|
unzip ../build.zip
|
|
|
|
- name: Set up SMB share
|
|
if: matrix.shard == 'smb'
|
|
timeout-minutes: 10
|
|
run: |
|
|
sudo apt install -y --no-install-recommends samba cifs-utils
|
|
sudo mkdir -p /srv/zotero-smb /mnt/zotero-smb
|
|
sudo chown $(whoami) /srv/zotero-smb
|
|
sudo tee -a /etc/samba/smb.conf > /dev/null <<EOF
|
|
[ztest]
|
|
path = /srv/zotero-smb
|
|
read only = no
|
|
EOF
|
|
(echo smbtestpass; echo smbtestpass) | sudo smbpasswd -s -a $(whoami)
|
|
sudo systemctl restart smbd
|
|
sudo mount -t cifs //127.0.0.1/ztest /mnt/zotero-smb \
|
|
-o user=$(whoami),pass=smbtestpass,vers=3.0,uid=$(id -u),gid=$(id -g)
|
|
|
|
- name: Set up NFS share
|
|
if: matrix.shard == 'nfs'
|
|
timeout-minutes: 10
|
|
run: |
|
|
sudo apt install -y --no-install-recommends nfs-kernel-server
|
|
sudo mkdir -p /srv/zotero-nfs /mnt/zotero-nfs
|
|
sudo chown $(whoami) /srv/zotero-nfs
|
|
echo "/srv/zotero-nfs localhost(rw,no_subtree_check,insecure)" | sudo tee -a /etc/exports
|
|
sudo exportfs -ra
|
|
sudo mount -t nfs4 localhost:/srv/zotero-nfs /mnt/zotero-nfs
|
|
|
|
- name: Run tests
|
|
if: matrix.shard != 'smb' && matrix.shard != 'nfs'
|
|
run: xvfb-run test/runtests.sh -f -r 3 -p ${{ matrix.shard }}/4
|
|
|
|
# The step timeout turns a startup hang into a failure
|
|
- name: Run tests on network share
|
|
if: matrix.shard == 'smb' || matrix.shard == 'nfs'
|
|
timeout-minutes: 10
|
|
run: TMPDIR=/mnt/zotero-${{ matrix.shard }} xvfb-run test/runtests.sh -f -r 3 -b db file
|
|
|
|
# Run the db and file tests on macOS with the test data directory on a loopback NFS
|
|
# mount. On macOS, SQLite selects locking methods without shared-memory support on
|
|
# network filesystems, which is what the network-filesystem database handling has to
|
|
# detect and handle, so this runs the real code path that crashed on SMB/NFS/sshfs
|
|
# data directories.
|
|
test-mac:
|
|
name: Test (macOS NFS)
|
|
runs-on: macos-15
|
|
timeout-minutes: 30
|
|
needs: changes
|
|
if: >
|
|
needs.changes.outputs.network == 'true'
|
|
&& (github.event_name != 'pull_request'
|
|
|| github.event.pull_request.head.repo.full_name != github.repository)
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
with:
|
|
submodules: recursive
|
|
lfs: true
|
|
|
|
- name: Install Node
|
|
uses: actions/setup-node@v4
|
|
with:
|
|
node-version: 24
|
|
|
|
- name: Cache xulrunner
|
|
id: xulrunner-cache
|
|
uses: actions/cache@v4
|
|
with:
|
|
path: app/xulrunner/Firefox.app
|
|
key: xulrunner-mac-${{ hashFiles('app/config.sh', 'app/scripts/fetch_xulrunner') }}
|
|
|
|
- name: Fetch xulrunner
|
|
if: steps.xulrunner-cache.outputs.cache-hit != 'true'
|
|
run: app/scripts/fetch_xulrunner -p m
|
|
|
|
- name: Cache Node modules
|
|
id: node-cache
|
|
uses: actions/cache@v4
|
|
with:
|
|
path: node_modules
|
|
key: node-modules-mac-24-${{ hashFiles('package-lock.json') }}
|
|
|
|
- name: Install Node modules
|
|
if: steps.node-cache.outputs.cache-hit != 'true'
|
|
run: npm install
|
|
|
|
- name: Build Zotero
|
|
run: npm run build
|
|
# Currently necessary for document-worker Webpack: https://stackoverflow.com/a/69746937
|
|
env:
|
|
NODE_OPTIONS: --openssl-legacy-provider
|
|
|
|
- name: Set up NFS share
|
|
run: |
|
|
sudo mkdir -p /private/var/zotero-nfs
|
|
sudo chown $(whoami) /private/var/zotero-nfs
|
|
echo "/private/var/zotero-nfs -mapall=$(whoami) localhost" | sudo tee /etc/exports
|
|
sudo nfsd enable || sudo nfsd start
|
|
sleep 2
|
|
showmount -e localhost
|
|
mkdir -p "$HOME/zotero-nfs"
|
|
sudo mount_nfs -o vers=3 localhost:/private/var/zotero-nfs "$HOME/zotero-nfs"
|
|
|
|
# The step timeout turns a startup hang into a failure
|
|
- name: Run tests on network share
|
|
timeout-minutes: 10
|
|
run: TMPDIR="$HOME/zotero-nfs" test/runtests.sh -f -r 3 -b db file
|
|
|
|
# Boot the Windows build -- which uses custom-built Firefox components (xul.dll) rather
|
|
# than stock Mozilla binaries -- and run the db and file tests. A Gecko bump commit
|
|
# updates the custom-component hashes in config.sh along with the version, so this
|
|
# tests each new set of custom components.
|
|
test-win:
|
|
name: Test (Windows ${{ matrix.arch }})
|
|
runs-on: ${{ matrix.os }}
|
|
timeout-minutes: 40
|
|
needs: changes
|
|
if: >
|
|
needs.changes.outputs.network == 'true'
|
|
&& (github.event_name != 'pull_request'
|
|
|| github.event.pull_request.head.repo.full_name != github.repository)
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
include:
|
|
- arch: x64
|
|
os: windows-latest
|
|
- arch: arm64
|
|
os: windows-11-arm
|
|
defaults:
|
|
run:
|
|
shell: bash
|
|
steps:
|
|
# The repository contains symlinks, which Git checks out as plain files on Windows
|
|
# by default, breaking the build
|
|
- name: Enable symlinks
|
|
run: git config --global core.symlinks true
|
|
|
|
- uses: actions/checkout@v4
|
|
with:
|
|
submodules: recursive
|
|
lfs: true
|
|
|
|
- name: Install Node
|
|
uses: actions/setup-node@v4
|
|
with:
|
|
node-version: 24
|
|
|
|
# Git Bash has unzip but not zip, which fetch_xulrunner needs to repack omni.ja
|
|
- name: Install zip
|
|
run: choco install zip --no-progress -y
|
|
|
|
- name: Cache xulrunner
|
|
id: xulrunner-cache
|
|
uses: actions/cache@v4
|
|
with:
|
|
path: app/xulrunner/firefox-win-${{ matrix.arch }}
|
|
key: xulrunner-win-${{ matrix.arch }}-${{ hashFiles('app/config.sh', 'app/scripts/fetch_xulrunner') }}
|
|
|
|
- name: Fetch xulrunner
|
|
if: steps.xulrunner-cache.outputs.cache-hit != 'true'
|
|
run: app/scripts/fetch_xulrunner -p w -a ${{ matrix.arch }}
|
|
|
|
- name: Cache Node modules
|
|
id: node-cache
|
|
uses: actions/cache@v4
|
|
with:
|
|
path: node_modules
|
|
key: node-modules-win-24-${{ hashFiles('package-lock.json') }}
|
|
|
|
- name: Install Node modules
|
|
if: steps.node-cache.outputs.cache-hit != 'true'
|
|
run: npm install
|
|
|
|
# Committed symlinks point into node_modules, which doesn't exist at checkout time,
|
|
# so Git creates the directory ones with the wrong symlink type on Windows. Recreate
|
|
# them now that the targets exist.
|
|
- name: Recreate symlinks
|
|
run: |
|
|
git ls-files -s | awk '$1 == 120000 { print $4 }' | xargs rm
|
|
git checkout -- .
|
|
|
|
- name: Build Zotero
|
|
run: npm run build
|
|
# Currently necessary for document-worker Webpack: https://stackoverflow.com/a/69746937
|
|
env:
|
|
NODE_OPTIONS: --openssl-legacy-provider
|
|
|
|
# The step timeout turns a startup hang into a failure
|
|
- name: Run tests
|
|
timeout-minutes: 15
|
|
run: test/runtests.sh -f -r 3 -b -x app/staging/Zotero_win-${{ matrix.arch }}/zotero.exe db file
|
|
|
|
utilities:
|
|
name: Utilities Tests
|
|
runs-on: ubuntu-latest
|
|
if: >
|
|
github.event_name != 'pull_request'
|
|
|| github.event.pull_request.head.repo.full_name != github.repository
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
with:
|
|
submodules: recursive
|
|
|
|
- name: Install Node
|
|
uses: actions/setup-node@v4
|
|
with:
|
|
node-version: 24
|
|
|
|
- name: Cache utilities Node modules
|
|
id: utilities-node-cache
|
|
uses: actions/cache@v4
|
|
with:
|
|
path: chrome/content/zotero/xpcom/utilities/node_modules
|
|
key: utilities-node-modules-24-${{ hashFiles('chrome/content/zotero/xpcom/utilities/package-lock.json') }}
|
|
|
|
- name: Install utilities Node modules
|
|
if: steps.utilities-node-cache.outputs.cache-hit != 'true'
|
|
run: npm install --prefix chrome/content/zotero/xpcom/utilities
|
|
|
|
- name: Run utilities tests
|
|
run: |
|
|
npm test --prefix chrome/content/zotero/xpcom/utilities -- -j resource/schema/global/schema.json
|
|
|
|
# Build deployment ZIPs from main, version branches (e.g., 9.0, 10.0), and *-hotfix branches
|
|
deploy:
|
|
name: Build, Upload
|
|
runs-on: ubuntu-latest
|
|
if: github.event_name == 'push' && github.repository == 'zotero/zotero'
|
|
steps:
|
|
- name: Check if deployment branch
|
|
id: check-deploy
|
|
if: env.ACT != 'true'
|
|
run: |
|
|
branch="${GITHUB_REF#refs/heads/}"
|
|
if [[ "$branch" == "main" || "$branch" =~ ^[0-9]+\.[0-9]+$ || "$branch" == *-hotfix ]]; then
|
|
echo "deploy=true" >> "$GITHUB_OUTPUT"
|
|
fi
|
|
|
|
- uses: actions/checkout@v4
|
|
if: steps.check-deploy.outputs.deploy == 'true'
|
|
with:
|
|
submodules: recursive
|
|
lfs: true
|
|
|
|
- name: Install Node
|
|
if: steps.check-deploy.outputs.deploy == 'true'
|
|
uses: actions/setup-node@v4
|
|
with:
|
|
node-version: 24
|
|
|
|
- name: Cache Node modules
|
|
id: node-cache
|
|
if: steps.check-deploy.outputs.deploy == 'true'
|
|
uses: actions/cache@v4
|
|
with:
|
|
path: node_modules
|
|
key: node-modules-24-${{ hashFiles('package-lock.json') }}
|
|
|
|
- name: Install Node modules
|
|
if: steps.check-deploy.outputs.deploy == 'true' && steps.node-cache.outputs.cache-hit != 'true'
|
|
run: npm install
|
|
|
|
- name: Build Zotero
|
|
if: steps.check-deploy.outputs.deploy == 'true'
|
|
run: npm run build
|
|
# Currently necessary for document-worker Webpack: https://stackoverflow.com/a/69746937
|
|
env:
|
|
NODE_OPTIONS: --openssl-legacy-provider
|
|
|
|
- name: Create deployment ZIP
|
|
if: steps.check-deploy.outputs.deploy == 'true'
|
|
run: |
|
|
cd build
|
|
zip -r ../build.zip *
|
|
cd ..
|
|
|
|
- uses: ruby/setup-ruby@v1
|
|
if: steps.check-deploy.outputs.deploy == 'true'
|
|
with:
|
|
ruby-version: '3.3'
|
|
bundler-cache: true # runs 'bundle install' and caches installed gems automatically
|
|
|
|
- name: Upload deployment ZIP
|
|
if: steps.check-deploy.outputs.deploy == 'true'
|
|
env:
|
|
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
|
|
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
|
|
run: |
|
|
mkdir build-zip
|
|
cp build.zip build-zip/$GITHUB_SHA.zip
|
|
gem install --no-document dpl -v '>= 2.0'
|
|
dpl s3 --bucket zotero-download --local_dir build-zip --upload_dir ci/client --acl public_read
|