Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CI Build: Build a docker image incrementally, then test, docbuild, ... in separate jobs #36459

Closed
wants to merge 52 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
3332a89
build/sage_bootstrap/download/mirror_list.py: Remove sagepad.org
mkoeppe Oct 9, 2023
dd939ff
sage_bootstrap.{tarball, download.mirror_list}: Lower layout of the m…
mkoeppe Oct 9, 2023
2dfe081
sage_bootstrap.download.mirror_list: Delay downloading/reading/rankin…
mkoeppe Oct 9, 2023
a37f4fd
sage_bootstrap.download.mirror_list: Use master list of download sour…
mkoeppe Oct 9, 2023
2323480
src/bin/sage-update-version: Update .upstream.d/20-gh.neting.cc-sagemat…
mkoeppe Oct 9, 2023
7e65260
sage_bootstrap.download.mirror_list: Skip empty lines earlier
mkoeppe Oct 9, 2023
371be50
src/bin/sage-update-version: Also commit
mkoeppe Oct 9, 2023
423e48a
build/bin/write-dockerfile.sh: ADD .upstream.d
mkoeppe Oct 9, 2023
f429993
.ci/retrofit-worktree.sh: New, factored out from .github/workflows/bu…
mkoeppe Oct 10, 2023
47f6a98
src/tox.ini (pyright): Remove old version pin, do not rely on global …
mkoeppe Oct 10, 2023
47e2783
.github/workflows/build.yml: Simplify use of pyright by going through…
mkoeppe Oct 10, 2023
94c8b88
Fixup
mkoeppe Oct 11, 2023
8bf3bcb
src/tox.ini (pyright): Do not restrict to subdirectories by default
mkoeppe Oct 11, 2023
81e1afa
src/tox.ini (pyright): Pin to 1.1.331 (latest)
mkoeppe Oct 11, 2023
18458bf
Rename spkg-piprm-requirements.txt to just spkg-requirements.txt
mkoeppe Oct 11, 2023
4a4810e
build/make/Makefile.in (SCRIPT_PACKAGE_templ): Set more variables set…
mkoeppe Oct 11, 2023
952405f
build/bin/sage-dist-helpers (sdh_store_[and_pip_install_]wheel): Reco…
mkoeppe Oct 11, 2023
f8b93c7
build/bin/sage-spkg: Remove unused code for packages without spkg-ins…
mkoeppe Oct 11, 2023
91b0b83
build/bin/sage-spkg: Adjust to spkg-requirements.txt being installed …
mkoeppe Oct 11, 2023
f91c20b
build/make/Makefile.in (SCRIPT_PACKAGE_templ): Remove script dir befo…
mkoeppe Oct 11, 2023
0aaf02e
build/make/Makefile.in (SCRIPT_PACKAGE_templ) [SAGE_CHECK=yes]: Call …
mkoeppe Oct 11, 2023
417de39
build/pkgs/sagemath_*/spkg-postinstcheck: Break out from spkg-install
mkoeppe Oct 11, 2023
3c2939a
Rename spkg-postinstcheck -> spkg-check
mkoeppe Oct 11, 2023
af6d0ad
build/pkgs/sage_sws2rst/spkg-install: Do not call spkg-check from her…
mkoeppe Oct 11, 2023
22b101f
build/make/Makefile.in (pypi-wheels-check): New target
mkoeppe Oct 12, 2023
3838613
.github/workflows/build.yml: Separate build and test
mkoeppe Oct 12, 2023
8224cb0
.github/workflows/build.yml: Fix 'if' of some steps
mkoeppe Oct 12, 2023
e3dce3f
conda: Do not pin setuptools, instead add legacy editable to install …
mkoeppe Oct 12, 2023
c60de9a
build/pkgs/setuptools_wheel: Make distros a symlink too
mkoeppe Sep 27, 2023
756e5c4
src/doc/en/installation/conda.rst: Restore 'bootstrap' in instruction…
mkoeppe Oct 11, 2023
ddbbdc5
pkgs/sage-conf_conda/setup.py: Always run configure
mkoeppe Oct 11, 2023
d0cae80
pkgs/sage-conf_conda/setup.py: Remove 'reusing configured SAGE_ROOT' …
mkoeppe Oct 12, 2023
c555723
Merge branch 'tox_pyright_update' into ci_streamline
mkoeppe Oct 12, 2023
19f029b
Merge branch 'conda_legacy_editable' into ci_streamline
mkoeppe Oct 12, 2023
68e9997
Merge branch 'bootstrap_conda_refactor' into ci_streamline
mkoeppe Oct 12, 2023
66a8be4
Merge branch 'gh_actions_release' into ci_streamline
mkoeppe Oct 12, 2023
2e11b0f
Merge branch 'ci_refactor_build' into ci_streamline
mkoeppe Oct 12, 2023
0bfb487
build/bin/write-dockerfile.sh, tox.ini (docker-incremental): Make inc…
mkoeppe Oct 11, 2023
8e25cbd
.github/workflows/build.yml: Merge doc-build.yml, doc-build-pdf.yml
mkoeppe Oct 11, 2023
459da44
.github/workflows/build.yml: Merge ci-linux-incremental.yml
mkoeppe Oct 11, 2023
4e847e3
Merge branch 'wheel_requirements' into ci_streamline_share_build
mkoeppe Oct 13, 2023
c85851e
Merge branch 'ci_streamline' into ci_streamline_share_build
mkoeppe Oct 13, 2023
30aa592
.github/workflows/build.yml: Create image, parallelize modularized tests
mkoeppe Oct 12, 2023
8499265
WIP export
mkoeppe Oct 12, 2023
7d8466c
WIP
mkoeppe Oct 13, 2023
49d62ff
Merge branch 'ci_disk_space' into ci_streamline_share_build
mkoeppe Oct 13, 2023
2e962b3
Snar it, then tar it
mkoeppe Oct 13, 2023
aada134
build/bin/write-dockerfile.sh: Only unminimize once
mkoeppe Oct 13, 2023
43b57d5
snar to root
mkoeppe Oct 13, 2023
eb61f5c
build/bin/write-dockerfile.sh: Only unminimize once (fixup)
mkoeppe Oct 13, 2023
f158d60
Merge tag '10.2.beta7' into ci_streamline_share_build
mkoeppe Oct 17, 2023
ad15def
WIP
mkoeppe Oct 17, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions .ci/retrofit-worktree.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#!/bin/sh
if [ $# != 2 ]; then
echo >&2 "usage: $0 WORKTREE_NAME WORKTREE_DIRECTORY"
echo >&2 "Ensures that the current working directory is a git repository,"
echo >&2 "then makes WORKTREE_DIRECTORY a git worktree named WORKTREE_NAME."
fi
WORKTREE_NAME="$1"
WORKTREE_DIRECTORY="$2"

export GIT_AUTHOR_NAME="ci-sage workflow"
export GIT_AUTHOR_EMAIL="ci-sage@example.com"
export GIT_COMMITTER_NAME="$GIT_AUTHOR_NAME"
export GIT_COMMITTER_EMAIL="$GIT_AUTHOR_EMAIL"

set -ex

# If actions/checkout downloaded our source tree using the GitHub REST API
# instead of with git (because do not have git installed in our image),
# we first make the source tree a repo.
if [ ! -d .git ]; then git init && git add -A && git commit --quiet -m "new"; fi

# Tag this state of the source tree "new". This is what we want to build and test.
git tag -f new

# Our container image contains a source tree in $WORKTREE_DIRECTORY with a full build of Sage.
# But $WORKTREE_DIRECTORY is not a git repository.
# We make $WORKTREE_DIRECTORY a worktree whose index is at tag "new".
# We then commit the current sources and set the tag "old". (This keeps all mtimes unchanged.)
# Then we update worktree and index with "git reset --hard new".
# (This keeps mtimes of unchanged files unchanged and mtimes of changed files newer than unchanged files.)
# Finally we reset the index to "old". (This keeps all mtimes unchanged.)
# The changed files now show up as uncommitted changes.
# The final "git add -N" makes sure that files that were added in "new" do not show
# as untracked files, which would be removed by "git clean -fx".
git worktree add --detach $WORKTREE_NAME
rm -rf $WORKTREE_DIRECTORY/.git && mv $WORKTREE_NAME/.git $WORKTREE_DIRECTORY/
rm -rf $WORKTREE_NAME && ln -s $WORKTREE_DIRECTORY $WORKTREE_NAME
if [ ! -f $WORKTREE_NAME/.gitignore ]; then cp .gitignore $WORKTREE_NAME/; fi
(cd $WORKTREE_NAME && git add -A && git commit --quiet --allow-empty -m "old" -a && git tag -f old && git reset --hard new && git reset --quiet old && git add -N . && git status)
215 changes: 57 additions & 158 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,11 @@ on:
platform:
description: 'Platform'
required: true
default: 'ubuntu-focal-standard'
default: 'ubuntu-focal'
packages:
description: 'Platform'
required: true
default: 'standard'
docker_tag:
description: 'Docker tag'
required: true
Expand All @@ -27,171 +31,66 @@ concurrency:
cancel-in-progress: true

jobs:
get_ci_fixes:
changed_files:
runs-on: ubuntu-latest
name: List changed packages
outputs:
uninstall_targets: ${{ steps.build-targets.outputs.uninstall_targets }}
build_targets: ${{ steps.build-targets.outputs.build_targets }}
steps:
- name: Checkout
id: checkout
uses: actions/checkout@v4
- name: Merge CI fixes from sagemath/sage
run: |
.ci/merge-fixes.sh
env:
GH_TOKEN: ${{ github.token }}
- name: Store CI fixes in upstream artifact
run: |
mkdir -p upstream
if git format-patch --stdout test_base > ci_fixes.patch; then
cp ci_fixes.patch upstream/
fi
- uses: actions/upload-artifact@v3
- uses: actions/checkout@v4
- name: Get all packages that have changed
id: changed-packages
uses: tj-actions/changed-files@v38
with:
path: upstream
name: upstream
files_yaml: |
configures:
- 'build/pkgs/*/spkg-configure.m4'
pkgs:
- 'build/pkgs/**'
- 'pkgs/**'
- name: Determine targets to build
id: build-targets
run: |
echo "uninstall_targets=$(echo $(for a in '' ${{ steps.changed-packages.outputs.configures_all_changed_files }}; do echo $a | sed -E 's,build/pkgs/([_.a-z0-9]*)/spkg-configure[.]m4 *,\1-uninstall,'; done | sort -u))" >> $GITHUB_OUTPUT
echo "build_targets=$(echo $(for a in '' ${{ steps.changed-packages.outputs.pkgs_all_changed_files }}; do echo $a | sed -E 's,-,_,g;s,(build/)?pkgs/([-_.a-z0-9]*)/[^ ]* *,\2-ensure,;'; done | sort -u))" >> $GITHUB_OUTPUT
cat $GITHUB_OUTPUT

build:
uses: ./.github/workflows/docker.yml
with:
# Build incrementally from published Docker image
incremental: true
free_disk_space: true
from_docker_repository: ghcr.io/sagemath/sage/
from_docker_target: "with-targets"
from_docker_tag: "dev"
docker_targets: "with-targets"
targets: "SAGE_CHECK=no build pypi-wheels"
tox_system_factors: >-
["${{ github.event.inputs.platform || 'ubuntu-focal' }}"]
tox_packages_factors: >-
["${{ github.event.inputs.packages || 'standard' }}"]
image_artifact: image

test-modularized:
runs-on: ubuntu-latest
container: ghcr.io/sagemath/sage/sage-${{ github.event.inputs.platform || 'ubuntu-focal-standard' }}-with-targets:${{ github.event.inputs.docker_tag || 'dev'}}
needs: [get_ci_fixes]
container: ghcr.io/${{ github.repository }}/sage-${{ github.event.inputs.platform || 'ubuntu-focal' }}-${{ github.event.inputs.packages || 'packages' }}-with-targets:${{ github.sha }}
needs: [build]
strategy:
fail-fast: false
matrix:
distribution: ${{ fromJson('["sagemath_repl", "sagemath_categories"]') }}
env:
IMAGE_ARTIFACT_NAME: image-commit-${{ github.sha }}-tox-docker-ubuntu-focal-standard
steps:
- name: Checkout
id: checkout
uses: actions/checkout@v4

- name: Update system packages
id: prepare
run: |
export PATH="build/bin:$PATH"
eval $(sage-print-system-package-command auto update)
eval $(sage-print-system-package-command auto --spkg --yes --no-install-recommends install git)

- name: Add prebuilt tree as a worktree
id: worktree
run: |
set -ex
git config --global user.email "ci-sage@example.com"
git config --global user.name "Build & Test workflow"
git config --global --add safe.directory $(pwd)
# If actions/checkout downloaded our source tree using the GitHub REST API
# instead of with git (because do not have git installed in our image),
# we first make the source tree a repo.
if [ ! -d .git ]; then git init && git add -A && git commit --quiet -m "new"; fi
# Tag this state of the source tree "new". This is what we want to build and test.
git tag -f new
# Our container image contains a source tree in /sage with a full build of Sage.
# But /sage is not a git repository.
# We make /sage a worktree whose index is at tag "new".
# We then commit the current sources and set the tag "old". (This keeps all mtimes unchanged.)
# Then we update worktree and index with "git reset --hard new".
# (This keeps mtimes of unchanged files unchanged and mtimes of changed files newer than unchanged files.)
# Finally we reset the index to "old". (This keeps all mtimes unchanged.)
# The changed files now show up as uncommitted changes.
# The final "git add -N" makes sure that files that were added in "new" do not show
# as untracked files, which would be removed by "git clean -fx".
git worktree add --detach worktree-image
rm -rf /sage/.git && mv worktree-image/.git /sage/
rm -rf worktree-image && ln -s /sage worktree-image
if [ ! -f worktree-image/.gitignore ]; then cp .gitignore worktree-image/; fi
(cd worktree-image && git add -A && git commit --quiet --allow-empty -m "old" -a && git tag -f old && git reset --hard new && git reset --quiet old && git add -N . && git status)

- name: Download upstream artifact
- name: Download incremental tar archive artifact
uses: actions/download-artifact@v3
with:
path: upstream
name: upstream

- name: Apply CI fixes from sagemath/sage
# After applying the fixes, make sure all changes are marked as uncommitted changes.
name: ${{ env.IMAGE_ARTIFACT_NAME }}
- name: Update from incremental tar archive
run: |
if [ -r upstream/ci_fixes.patch ]; then
(cd worktree-image && git commit -q -m "current changes" --allow-empty -a && git am; git reset --quiet old; git add -N .) < upstream/ci_fixes.patch
fi

- name: Incremental build, test changed files (sage -t --new)
id: incremental
(cd / && tar xf -) < *-incremental.tar
- name: Test
run: |
# Now re-bootstrap and build. The build is incremental because we were careful with the timestamps.
# We run tests with "sage -t --new"; this only tests the uncommitted changes.
./bootstrap && make build && ./sage -t --new -p2
working-directory: ./worktree-image
env:
MAKE: make -j2 --output-sync=recurse
SAGE_NUM_THREADS: 2

- name: Build and test modularized distributions
if: always() && steps.worktree.outcome == 'success'
run: make V=0 tox && make pypi-wheels
working-directory: ./worktree-image
env:
MAKE: make -j2 --output-sync=recurse
SAGE_NUM_THREADS: 2

- name: Set up node to install pyright
if: always() && steps.worktree.outcome == 'success'
uses: actions/setup-node@v3
with:
node-version: '12'

- name: Install pyright
if: always() && steps.worktree.outcome == 'success'
# Fix to v232 due to bug https://github.com/microsoft/pyright/issues/3239
run: npm install -g pyright@1.1.232

- name: Static code check with pyright
if: always() && steps.worktree.outcome == 'success'
run: pyright
working-directory: ./worktree-image

- name: Clean (fallback to non-incremental)
id: clean
if: always() && steps.worktree.outcome == 'success' && steps.incremental.outcome != 'success'
run: |
set -ex
./bootstrap && make doc-clean doc-uninstall sagelib-clean && git clean -fx src/sage && ./config.status
working-directory: ./worktree-image
env:
MAKE: make -j2
SAGE_NUM_THREADS: 2

- name: Build
# This step is needed because building the modularized distributions installs some optional packages,
# so the editable install of sagelib needs to build the corresponding optional extension modules.
id: build
if: always() && (steps.incremental.outcome == 'success' || steps.clean.outcome == 'success')
run: |
make build
working-directory: ./worktree-image
env:
MAKE: make -j2 --output-sync=recurse
SAGE_NUM_THREADS: 2

- name: Pytest
if: contains(github.ref, 'pytest')
run: |
../sage -python -m pip install coverage pytest-xdist
../sage -python -m coverage run -m pytest -c tox.ini --doctest-modules || true
working-directory: ./worktree-image/src
env:
# Increase the length of the lines in the "short summary"
COLUMNS: 120

- name: Test all files (sage -t --all --long)
if: always() && steps.build.outcome == 'success'
run: |
../sage -python -m pip install coverage
../sage -python -m coverage run ./bin/sage-runtests --all --long -p2 --random-seed=286735480429121101562228604801325644303
working-directory: ./worktree-image/src

- name: Prepare coverage results
if: always() && steps.build.outcome == 'success'
run: |
./venv/bin/python3 -m coverage combine src/.coverage/
./venv/bin/python3 -m coverage xml
find . -name *coverage*
working-directory: ./worktree-image

- name: Upload coverage to codecov
if: always() && steps.build.outcome == 'success'
uses: codecov/codecov-action@v3
with:
files: ./worktree-image/coverage.xml
make -j2 V=0 tox-ensure && make -j2 ${{ matrix.distribution }}-check"
2 changes: 1 addition & 1 deletion .github/workflows/ci-conda.yml
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ jobs:
run: |
# Use --no-deps and pip check below to verify that all necessary dependencies are installed via conda.
pip install --no-build-isolation --no-deps -v -v -e ./pkgs/sage-conf ./pkgs/sage-setup
pip install --no-build-isolation --no-deps -v -v -e ./src
pip install --no-build-isolation --no-deps --config-settings editable_mode=compat -v -v -e ./src
env:
SAGE_NUM_THREADS: 2

Expand Down
Loading
Loading