Skip to content

Commit ce9e8eb

Browse files
kwankyualice
authored and
alice
committed
Update files for Binder
0 parents  commit ce9e8eb

11 files changed

+2665
-0
lines changed

.github/Dockerfile

+57
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
# Multi-stage Dockerfile for slim Sage
2+
# https://docs.docker.com/build/building/multi-stage
3+
4+
FROM ghcr.io/sagemath/sage/sage-ubuntu-jammy-minimal-with-targets:10.6 AS target
5+
6+
# Resolve symbolic links to recreate them later
7+
RUN readlink /sage/prefix >> /sage/prefix_link
8+
RUN readlink /sage/venv >> /sage/venv_link
9+
10+
WORKDIR /sage
11+
12+
# Strip executables in /sage
13+
RUN LC_ALL=C find local src pkgs -type f -exec strip '{}' ';' 2>&1 | grep -v "file format not recognized" || true
14+
15+
# Clean up before copying in the next stage
16+
RUN rm -rf local/share/doc local/share/*/doc local/share/*/examples local/share/singular/html
17+
18+
# Remove all __pycache__ directories
19+
RUN find /sage -type d -name "__pycache__" -exec rm -rf {} +
20+
# Remove all .c .cpp files corresponding to .pyx files
21+
RUN find /sage -name "*.pyx" | sed 's/\(.*\)[.]pyx$/\1.c \1.cpp/' | xargs rm -f +
22+
23+
FROM ghcr.io/sagemath/sage/sage-ubuntu-jammy-minimal-with-system-packages:10.6
24+
25+
USER root
26+
27+
# Remove warnings
28+
ENV DEBIAN_FRONTEND noninteractive
29+
ENV DEBCONF_NOWARNINGS="yes"
30+
31+
# Install JupyterLab to the system
32+
RUN apt-get update
33+
RUN apt-get install -y --no-install-recommends python3-pip
34+
RUN python3 -m pip install --no-warn-script-location --no-cache-dir notebook jupyterlab ipywidgets
35+
36+
# Disable annoying popup for Jupyter news
37+
RUN jupyter labextension disable "@jupyterlab/apputils-extension:announcements"
38+
39+
# Install /sage from target
40+
COPY --from=target /sage/local /sage/local
41+
COPY --from=target /sage/src/bin /sage/src/bin
42+
COPY --from=target /sage/src/sage /sage/src/sage
43+
COPY --from=target /sage/sage /sage/sage
44+
COPY --from=target /sage/pkgs/sage-conf /sage/pkgs/sage-conf
45+
46+
# Recreate symbolic links
47+
COPY --from=target /sage/prefix_link /sage/prefix_link
48+
COPY --from=target /sage/venv_link /sage/venv_link
49+
RUN ln -s $(cat /sage/prefix_link) /sage/prefix && rm /sage/prefix_link
50+
RUN ln -s $(cat /sage/venv_link) /sage/venv && rm /sage/venv_link
51+
52+
# Configure Sage library
53+
RUN /sage/sage -pip install --root-user-action=ignore /sage/pkgs/sage-conf
54+
55+
# Remove problematic lines!
56+
RUN sed -i '/^__requires__/d' /sage/venv/bin/sage-venv-config
57+
RUN sed -i '/^__import__/d' /sage/venv/bin/sage-venv-config

.github/icons/blue.ico

35.4 KB
Binary file not shown.

.github/icons/orange.ico

35.9 KB
Binary file not shown.
+311
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,311 @@
1+
name: Build docker image and export for WSL
2+
3+
on:
4+
schedule:
5+
- cron: '0 2 * * *' # Run every day
6+
workflow_dispatch:
7+
8+
jobs:
9+
build-and-export:
10+
runs-on: ubuntu-latest
11+
outputs:
12+
upload_url: ${{ steps.create_release.outputs.upload_url }}
13+
version: ${{ steps.extract_version.outputs.version }}
14+
steps:
15+
16+
# Create WSL export (a tar file) of the minimal Sage install
17+
18+
- name: Prepare Dockerfile
19+
run: |
20+
curl -o Dockerfile https://raw.githubusercontent.com/sagemath/sage-binder-env/master/Dockerfile
21+
sed -i '/COPY notebooks/d' Dockerfile # remove the line from Dockerfile
22+
23+
- name: Extract version from Dockerfile
24+
id: extract_version
25+
run: |
26+
VERSION=$(grep '^FROM ghcr.io/sagemath/sage-binder-env:' Dockerfile | sed 's/^FROM ghcr.io\/sagemath\/sage-binder-env://')
27+
echo "VERSION=$VERSION" >> $GITHUB_ENV
28+
echo "version=$VERSION" >> $GITHUB_OUTPUT
29+
30+
- name: Build and export Docker image
31+
run: |
32+
docker build -t sagemath-container .
33+
export CONTAINER_ID=$(docker create sagemath-container)
34+
docker export $CONTAINER_ID -o sagemath-$VERSION-wsl.tar
35+
36+
- name: Upload tar file as artifact
37+
id: upload-artifact
38+
uses: actions/upload-artifact@v4
39+
with:
40+
name: sagemath-${{ env.VERSION }}-wsl
41+
path: sagemath-${{ env.VERSION }}-wsl.tar
42+
43+
# Make a release
44+
45+
- name: Get latest release version
46+
id: get_latest_release
47+
run: |
48+
LATEST_VERSION=$(curl -s https://api.github.com/repos/${{ github.repository }}/releases/latest | jq -r '.tag_name // "0.0.0"' | sed 's/v//')
49+
echo "LATEST_VERSION=$LATEST_VERSION" >> $GITHUB_ENV
50+
51+
- name: Zip the tar file
52+
if: ${{ env.VERSION != env.LATEST_VERSION }}
53+
run: |
54+
zip sagemath-${{ env.VERSION }}-wsl.zip sagemath-${{ env.VERSION }}-wsl.tar
55+
56+
- name: Create GitHub Release
57+
if: ${{ env.VERSION != env.LATEST_VERSION }}
58+
id: create_release
59+
uses: actions/create-release@v1
60+
env:
61+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
62+
with:
63+
tag_name: v${{ env.VERSION }}
64+
release_name: Run SageMath ${{ env.VERSION }} on WSL
65+
body: |
66+
We recommend you check if WSL is enabled before running the installer.
67+
68+
The .ps1 installer downloads the .zip file and imports a minimized SageMath ${{ env.VERSION }} into WSL.
69+
70+
After downloading the installer, right-click it to open the context menu and run it with PowerShell.
71+
You may also open the installer as a text file, and copy and paste all lines into a PowerShell window.
72+
73+
The installer should create two shortcuts on your desktop: one for launching SageMath
74+
and another to start the Jupyter server for SageMath.
75+
76+
The minimized SageMath is the same as the one used in the Binder environment, meaning no bells and whistles.
77+
Notably the Sage build system is not included.
78+
draft: false
79+
prerelease: false
80+
81+
- name: Upload release asset
82+
if: ${{ env.VERSION != env.LATEST_VERSION }}
83+
uses: actions/upload-release-asset@v1
84+
env:
85+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
86+
with:
87+
upload_url: ${{ steps.create_release.outputs.upload_url }}
88+
asset_path: ./sagemath-${{ env.VERSION }}-wsl.zip
89+
asset_name: sagemath-${{ env.VERSION }}-wsl.zip
90+
asset_content_type: application/zip
91+
92+
# Generate a Windows PowerShell script
93+
94+
- name: Checkout repo
95+
uses: actions/checkout@v3
96+
97+
- name: Generate PowerShell Script
98+
run: |
99+
cat << EOF > download_and_import_sagemath_to_wsl.ps1
100+
# ----------------------------------------------------
101+
# Copy and paste all lines into the Windows PowerShell
102+
# ----------------------------------------------------
103+
104+
[Console]::OutputEncoding = [System.Text.Encoding]::UTF8
105+
try {
106+
Write-Host "Checking WSL installation."
107+
wsl --install --no-distribution
108+
if (\$LASTEXITCODE -ne 0) {
109+
Write-Host "WSL installation failed."
110+
Read-Host -Prompt "Press any key to exit"; exit
111+
}
112+
} catch {
113+
Write-Host "Could not check WSL installation, proceeding with fingers crossed."
114+
}
115+
# Check if SageMath already exists in WSL
116+
\$sagemathWSL = "SageMath-$VERSION"
117+
if ((wsl -l -q) -contains \$sagemathWSL) {
118+
# Ask user if they want to reinstall SageMath
119+
\$response = Read-Host "\$sagemathWSL is already installed. Do you want to reinstall it? (y/n)"
120+
if (\$response -eq "y") {
121+
Write-Host "Uninstalling \$sagemathWSL."
122+
# Unregister the existing SageMath WSL distribution
123+
wsl --unregister \$sagemathWSL
124+
} else {
125+
Read-Host "OK. Press any key to exit"; exit
126+
}
127+
}
128+
\$artifactUrl = "https://github.com/sagemath/sage-binder-env/releases/download/v$VERSION/sagemath-$VERSION-wsl.zip"
129+
\$zipFilePath = "\$PWD\\artifact.zip"
130+
\$dataPath = "\$HOME\\AppData\\Local\\SageMath"
131+
\$tarFilePath = "\$dataPath\\sagemath-$VERSION-wsl.tar"
132+
# Ensure the path exists
133+
if (-Not (Test-Path \$dataPath)) { New-Item -Path \$dataPath -ItemType Directory > \$null }
134+
# Skip downloading and extracting if the tar file already exists
135+
if (-Not (Test-Path \$tarFilePath)) {
136+
Write-Host "Downloading \$sagemathWSL..."
137+
Start-BitsTransfer -Source \$artifactUrl -Destination \$zipFilePath
138+
Write-Host "Extracting..."
139+
Expand-Archive -Path \$zipFilePath -DestinationPath \$dataPath -Force
140+
if (Test-Path \$tarFilePath) { Remove-Item \$zipFilePath }
141+
} else {
142+
Write-Host "\$sagemathWSL was already downloaded."
143+
}
144+
# Import the WSL image
145+
Write-Host "Start importing..."
146+
wsl --import SageMath-$VERSION \$dataPath \$tarFilePath
147+
# Check if importing succeeded
148+
if (-Not ((wsl -l -q) -contains \$sagemathWSL)) {
149+
Write-Host "Importing \$sagemathWSL into WSL failed."
150+
Write-Host "If WSL was freshly installed by this installer, try again after rebooting the computer."
151+
Read-Host "Press any key to exit"; exit
152+
}
153+
Write-Host "Creating shortcults at:"
154+
# Download icons for shortcuts
155+
\$iconUrlOrange = "https://raw.githubusercontent.com/sagemath/sage-binder-env/refs/heads/master/.github/icons/orange.ico"
156+
\$iconUrlBlue = "https://raw.githubusercontent.com/sagemath/sage-binder-env/refs/heads/master/.github/icons/blue.ico"
157+
\$iconPathOrange = "\$dataPath\\orange.ico"
158+
\$iconPathBlue = "\$dataPath\\blue.ico"
159+
# Download the icon if it doesn't exist
160+
if (-Not (Test-Path \$iconPathBlue)) {
161+
Start-BitsTransfer -Source \$iconUrlBlue -Destination \$iconPathBlue
162+
}
163+
if (-Not (Test-Path \$iconPathOrange)) {
164+
Start-BitsTransfer -Source \$iconUrlOrange -Destination \$iconPathOrange
165+
}
166+
# Create shortcuts
167+
\$ShortcutFile = "\$([Environment]::GetFolderPath('Desktop'))\\Run Sage.lnk"
168+
\$TargetPath = "C:\\Windows\\System32\\wsl.exe"
169+
\$Arguments = "-d \$sagemathWSL --user user --cd ~ /sage/sage"
170+
\$WScriptShell = New-Object -ComObject WScript.Shell
171+
\$Shortcut = \$WScriptShell.CreateShortcut(\$ShortcutFile)
172+
\$Shortcut.TargetPath = \$TargetPath
173+
\$Shortcut.Arguments = \$Arguments
174+
\$Shortcut.IconLocation = \$iconPathBlue
175+
\$Shortcut.Save()
176+
Write-Host "\$ShortcutFile"
177+
# Create a shortcut that starts Jupyter on Desktop
178+
\$ShortcutFile = "\$([Environment]::GetFolderPath('Desktop'))\\Run Jupyter.lnk"
179+
\$TargetPath = "C:\\Windows\\System32\\wsl.exe"
180+
\$Arguments = "-d \$sagemathWSL --user user --cd ~ jupyter lab --no-browser"
181+
\$WScriptShell = New-Object -ComObject WScript.Shell
182+
\$Shortcut = \$WScriptShell.CreateShortcut(\$ShortcutFile)
183+
\$Shortcut.TargetPath = \$TargetPath
184+
\$Shortcut.Arguments = \$Arguments
185+
\$Shortcut.IconLocation = \$iconPathOrange
186+
\$Shortcut.Save()
187+
Write-Host "\$ShortcutFile"
188+
Read-Host "\`n\$sagemathWSL installation succeeded!\`nPress any key to exit"
189+
EOF
190+
cat << EOF > remove_sagemath_from_wsl.ps1
191+
# ----------------------------------------------------
192+
# Copy and paste all lines into the Windows PowerShell
193+
# ----------------------------------------------------
194+
195+
[Console]::OutputEncoding = [System.Text.Encoding]::UTF8
196+
try {
197+
Write-Host "Checking WSL installation."
198+
wsl --install --no-distribution
199+
if (\$LASTEXITCODE -ne 0) {
200+
Write-Host "WSL installation failed."
201+
Read-Host -Prompt "Press any key to exit"; exit
202+
}
203+
} catch {
204+
Write-Host "Could not check WSL installation, proceeding with fingers crossed."
205+
}
206+
# Check if SageMath already exists in WSL
207+
\$sagemathWSL = "SageMath-$VERSION"
208+
\$dataPath = "\$HOME\\AppData\\Local\\SageMath"
209+
\$iconPathOrange = "\$dataPath\\orange.ico"
210+
\$iconPathBlue = "\$dataPath\\blue.ico"
211+
if ((wsl -l -q) -contains \$sagemathWSL) {
212+
# Ask user if they want to reinstall SageMath
213+
\$response = Read-Host "Do you want to uninstall \$(\$sagemathWSL) from WSL? (y/n)"
214+
if (\$response -eq "y") {
215+
Write-Host "Uninstalling \$sagemathWSL..."
216+
try {
217+
wsl --unregister \$sagemathWSL
218+
} catch {
219+
Write-Host "Failed: wsl --unregister \$sagemathWSL"
220+
}
221+
try {
222+
rm -recurse \$dataPath
223+
} catch {
224+
Write-Host "Failed: rm -recurse \$dataPath"
225+
}
226+
try {
227+
\$ShortcutFile = "\$([Environment]::GetFolderPath('Desktop'))\\Run Sage.lnk"
228+
rm \$ShortcutFile
229+
} catch {
230+
Write-Host "Failed: rm \$ShortcutFile"
231+
}
232+
try {
233+
\$ShortcutFile = "\$([Environment]::GetFolderPath('Desktop'))\\Run Jupyter.lnk"
234+
rm \$ShortcutFile
235+
} catch {
236+
Write-Host "Failed: rm \$ShortcutFile"
237+
}
238+
} else {
239+
Read-Host "OK. Press any key to exit"; exit
240+
}
241+
} else {
242+
Write-Host "\$sagemathWSL is not found."
243+
Read-Host -Prompt "Press any key to exit"; exit
244+
}
245+
Read-Host "\`n\$sagemathWSL uninstallation succeeded!\`nPress any key to exit"
246+
EOF
247+
shell: bash
248+
249+
- name: Upload installation script as artifact
250+
uses: actions/upload-artifact@v4
251+
with:
252+
name: download_and_import_sagemath_to_wsl
253+
path: download_and_import_sagemath_to_wsl.ps1
254+
255+
- name: Upload uninstallation script as artifact
256+
uses: actions/upload-artifact@v4
257+
with:
258+
name: remove_sagemath_from_wsl
259+
path: remove_sagemath_from_wsl.ps1
260+
261+
- name: Upload installation script as release asset
262+
if: ${{ env.VERSION != env.LATEST_VERSION }}
263+
uses: actions/upload-release-asset@v1
264+
env:
265+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
266+
with:
267+
upload_url: ${{ steps.create_release.outputs.upload_url }}
268+
asset_path: ./download_and_import_sagemath_to_wsl.ps1
269+
asset_name: sagemath-${{ env.VERSION }}-wsl-installer.ps1
270+
asset_content_type: application/octet-stream
271+
272+
- name: Upload uninstallation script as release asset
273+
if: ${{ env.VERSION != env.LATEST_VERSION }}
274+
uses: actions/upload-release-asset@v1
275+
env:
276+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
277+
with:
278+
upload_url: ${{ steps.create_release.outputs.upload_url }}
279+
asset_path: ./remove_sagemath_from_wsl.ps1
280+
asset_name: sagemath-${{ env.VERSION }}-wsl-uninstaller.ps1
281+
asset_content_type: application/octet-stream
282+
283+
# build-exe:
284+
# runs-on: windows-latest
285+
# needs: build-and-export
286+
# if: ${{ contains(needs.build-and-export.outputs.upload_url || '', 'http') }}
287+
# steps:
288+
# - name: Checkout repository
289+
# uses: actions/checkout@v3
290+
#
291+
# - name: Download PowerShell Script artifact
292+
# uses: actions/download-artifact@v4
293+
# with:
294+
# name: download_and_import_sagemath_to_wsl
295+
#
296+
# - name: Install PS2EXE
297+
# run: |
298+
# Install-Module -Name ps2exe -Force
299+
# Import-Module ps2exe
300+
# Invoke-ps2exe -inputFile .\download_and_import_sagemath_to_wsl.ps1 -outputFile .\sagemath_installer.exe
301+
# shell: powershell
302+
#
303+
# - name: Upload EXE to GitHub Release
304+
# uses: actions/upload-release-asset@v1
305+
# env:
306+
# GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
307+
# with:
308+
# upload_url: ${{ needs.build-and-export.outputs.upload_url }}
309+
# asset_path: ./sagemath_installer.exe
310+
# asset_name: sagemath-${{ needs.build-and-export.outputs.version }}-wsl-installer.exe
311+
# asset_content_type: application/octet-stream

0 commit comments

Comments
 (0)