2023-05-15 14:38:56 +00:00
name : Deploy
2023-04-21 15:01:40 +00:00
# Define when the workflow should run
on :
# Allow manual triggering of the workflow from the Actions tab
workflow_dispatch :
# Allow inputs to be passed when manually triggering the workflow from the Actions tab
inputs :
DOCKERFILE_PATH :
type : string
2023-05-19 09:02:58 +00:00
description : 'Path to the Dockerfile'
2023-04-21 15:01:40 +00:00
required : true
2023-05-16 11:03:40 +00:00
default : 'dockerfiles/debian_mini'
2023-04-21 15:01:40 +00:00
IMAGE_SIZE :
type : string
2023-05-19 09:02:58 +00:00
description : 'Image size, 950M max'
2023-04-21 15:01:40 +00:00
required : true
2023-05-17 20:47:07 +00:00
default : '600M'
2023-04-21 15:01:40 +00:00
DEPLOY_TO_GITHUB_PAGES :
type : boolean
2023-05-19 09:02:58 +00:00
description : 'Deploy to Github pages'
2023-04-21 15:01:40 +00:00
required : true
default : true
GITHUB_RELEASE :
type : boolean
2023-05-19 09:02:58 +00:00
description : 'Upload GitHub release'
2023-04-21 15:01:40 +00:00
required : true
default : false
jobs :
2023-05-23 09:32:58 +00:00
guard_clause :
runs-on : ubuntu-latest
env :
GH_TOKEN : ${{ github.token }} # As required by the GitHub-CLI
permissions :
actions : 'write' # Required in order to terminate the workflow run.
steps :
- uses : actions/checkout@v3
# Guard clause that cancels the workflow in case of an invalid DOCKERFILE_PATH and/or incorrectly configured Github Pages.
# The main reason for choosing this workaround for aborting the workflow is the fact that it does not display the workflow as successful, which can set false expectations.
- name : DOCKERFILE_PATH.
shell : bash
run : |
# We check whether the Dockerfile_path is valid.
if [ ! -f ${{ github.event.inputs.DOCKERFILE_PATH }} ]; then
echo "::error title=Invalid Dockerfile path::No file found at ${{ github.event.inputs.DOCKERFILE_PATH }}"
echo "terminate=true" >> $GITHUB_ENV
fi
- name : Github Pages config guard clause
if : ${{ github.event.inputs.DEPLOY_TO_GITHUB_PAGES == 'true' }}
run : |
# We use the Github Rest api to get information regarding pages for the Github Repository and store it into a temporary file named "pages_response".
set +e
gh api \
-H "Accept: application/vnd.github+json" \
-H "X-GitHub-Api-Version: 2022-11-28" \
/repos/${{ github.repository_owner }}/$(basename ${{ github.repository }})/pages > pages_response
# We make sure Github Pages has been enabled for this repository.
if [ "$?" -ne 0 ]; then
echo "::error title=Potential pages configuration error.::Please make sure you have enabled Github pages for the ${{ github.repository }} repository. If already enabled then Github pages might be down"
echo "terminate=true" >> $GITHUB_ENV
fi
set -e
# We make sure the Github pages build & deployment source is set to "workflow" (Github Actions). Instead of a "legacy" (branch).
if [[ "$(jq --compact-output --raw-output .build_type pages_response)" != "workflow" ]]; then
echo "Undefined behaviour, Make sure the Github Pages source is correctly configured in the Github Pages settings."
echo "::error title=Pages configuration error.::Please make sure you have correctly picked \"Github Actions\" as the build and deployment source for the Github Pages."
echo "terminate=true" >> $GITHUB_ENV
fi
rm pages_response
- name : Terminate run if error occurred.
run : |
if [[ $terminate == "true" ]]; then
gh run cancel ${{ github.run_id }}
gh run watch ${{ github.run_id }}
fi
2023-04-21 15:01:40 +00:00
build :
2023-05-23 09:32:58 +00:00
needs : guard_clause # Dependency
2023-04-21 15:01:40 +00:00
runs-on : ubuntu-latest # Image to run the worker on.
2023-05-17 15:10:22 +00:00
2023-04-21 15:01:40 +00:00
env :
TAG : "ext2-webvm-base-image" # Tag of docker image.
IMAGE_SIZE : '${{ github.event.inputs.IMAGE_SIZE }}'
DEPLOY_DIR : /webvm_deploy/ # Path to directory where we host the final image from.
2023-05-15 14:38:56 +00:00
2023-04-21 15:01:40 +00:00
permissions : # Permissions to grant the GITHUB_TOKEN.
contents : write # Required permission to make a github release.
steps :
# Checks-out our repository under $GITHUB_WORKSPACE, so our job can access it
- uses : actions/checkout@v3
2023-05-17 15:10:22 +00:00
# Setting the IMAGE_NAME variable in GITHUB_ENV to <Dockerfile name>_<date>_<run_id>.ext2.
2023-05-16 15:27:58 +00:00
- name : Generate the image_name.
id : image_name_gen
run : |
2023-05-17 15:10:22 +00:00
echo "IMAGE_NAME=$(basename ${{ github.event.inputs.DOCKERFILE_PATH }})_$(date +%Y%m%d)_${{ github.run_id }}.ext2" >> $GITHUB_ENV
2023-05-16 15:27:58 +00:00
2023-04-21 15:01:40 +00:00
# Create directory to host the image from.
- run : sudo mkdir -p $DEPLOY_DIR
# Build the i386 Dockerfile image.
- run : docker build . --tag $TAG --file ${{ github.event.inputs.DOCKERFILE_PATH }} --platform=i386
# Run the docker image so that we can export the container.
2023-05-15 08:28:02 +00:00
# Run the Docker container with the Google Public DNS nameservers: 8.8.8.8, 8.8.4.4
2023-05-22 12:19:39 +00:00
- run : |
docker run --dns 8.8.8.8 --dns 8.8.4.4 -d $TAG
echo "CONTAINER_ID=$(sudo docker ps -aq)" >> $GITHUB_ENV
# We extract the CMD, we first need to figure whether the Dockerfile uses CMD or an Entrypoint.
- name : Extracting CMD / Entrypoint and args
shell : bash
run : |
cmd=$(sudo docker inspect --format='{{json .Config.Cmd}}' $CONTAINER_ID)
entrypoint=$(sudo docker inspect --format='{{json .Config.Entrypoint}}' $CONTAINER_ID)
if [[ $entrypoint != "null" && $cmd != "null" ]]; then
echo "CMD=$( sudo docker inspect $CONTAINER_ID | jq --compact-output '.[0].Config.Entrypoint' )" >> $GITHUB_ENV
echo "ARGS=$( sudo docker inspect $CONTAINER_ID | jq --compact-output '.[0].Config.Cmd' )" >> $GITHUB_ENV
elif [[ $cmd != "null" ]]; then
echo "CMD=$( sudo docker inspect $CONTAINER_ID | jq --compact-output '.[0].Config.Cmd[:1]' )" >> $GITHUB_ENV
echo "ARGS=$( sudo docker inspect $CONTAINER_ID | jq --compact-output '.[0].Config.Cmd[1:]' )" >> $GITHUB_ENV
else
echo "CMD=$( sudo docker inspect $CONTAINER_ID | jq --compact-output '.[0].Config.Entrypoint[:1]' )" >> $GITHUB_ENV
echo "ARGS=$( sudo docker inspect $CONTAINER_ID | jq --compact-output '.[0].Config.Entrypoint[1:]' )" >> $GITHUB_ENV
fi
# We extract the ENV, CMD/Entrypoint and cwd from the Docker container with docker inspect.
- name : Extracting env, args and cwd.
shell : bash
run : |
echo "ENV=$( sudo docker inspect $CONTAINER_ID | jq --compact-output '.[0].Config.Env' )" >> $GITHUB_ENV
echo "CWD=$( sudo docker inspect $CONTAINER_ID | jq --compact-output '.[0].Config.WorkingDir' )" >> $GITHUB_ENV
2023-04-21 15:01:40 +00:00
# We create and mount the base ext2 image to extract the Docker container's filesystem its contents into.
- name : Create ext2 image.
run : |
# Preallocate space for the ext2 image
2023-05-17 20:01:53 +00:00
sudo fallocate -l $IMAGE_SIZE ${IMAGE_NAME}
2023-04-21 15:01:40 +00:00
# Format to ext2 linux kernel revision 0
2023-05-17 20:01:53 +00:00
sudo mkfs.ext2 -r 0 ${IMAGE_NAME}
2023-04-21 15:01:40 +00:00
# Mount the ext2 image to modify it
2023-05-17 20:01:53 +00:00
sudo mount -o loop -t ext2 ${IMAGE_NAME} /mnt/
2023-05-15 08:28:02 +00:00
# We opt for 'docker cp --archive' over 'docker save' since our focus is solely on the end product rather than individual layers and metadata.
# However, it's important to note that despite being specified in the documentation, the '--archive' flag does not currently preserve uid/gid information when copying files from the container to the host machine.
# Another compelling reason to use 'docker cp' is that it preserves resolv.conf.
2023-04-21 15:01:40 +00:00
- name : Export and unpack container filesystem contents into mounted ext2 image.
run : |
2023-05-22 12:19:39 +00:00
sudo docker cp -a ${CONTAINER_ID}:/ /mnt/
2023-04-21 15:01:40 +00:00
sudo umount /mnt/
# Result is an ext2 image for webvm.
2023-05-17 20:01:53 +00:00
# The .txt suffix enabled HTTP compression for free
- name : Generate image split chunks and .meta file
run : |
sudo split ${{ env.IMAGE_NAME }} ${{ env.DEPLOY_DIR }}/${{ env.IMAGE_NAME }}.c -a 6 -b 128k -x --additional-suffix=.txt
sudo bash -c "stat -c%s ${{ env.IMAGE_NAME }} > ${{ env.DEPLOY_DIR }}/${{ env.IMAGE_NAME }}.meta"
2024-10-15 09:17:07 +00:00
# This step updates the default config_github_terminal.js file by performing the following actions:
2023-05-22 12:19:39 +00:00
# 1. Replaces all occurrences of IMAGE_URL with the URL to the image.
2024-10-15 09:17:07 +00:00
# 2. Replace CMD with the Dockerfile entry command.
# 3. Replace args with the Dockerfile CMD / Entrypoint args.
# 4. Replace ENV with the container's environment values.
# 5. Replace CWD with the container's current working directory.
- name : Adjust config_github_terminal.js
2023-04-21 15:01:40 +00:00
run : |
2024-10-15 09:17:07 +00:00
sed -i 's#IMAGE_URL#"${{ env.IMAGE_NAME }}"#g' config_github_terminal.js
sed -i 's#CMD#${{ env.CMD }}#g' config_github_terminal.js
sed -i 's#ARGS#${{ env.ARGS }}#g' config_github_terminal.js
sed -i 's#ENV#${{ env.ENV }}#g' config_github_terminal.js
sed -i 's#CWD#${{ env.CWD }}#g' config_github_terminal.js
- name : Build NPM package
run : |
npm install
2024-10-15 09:22:03 +00:00
WEBVM_MODE=github npm run build
2024-10-15 09:17:07 +00:00
# Move required files for gh-pages deployment to the deployment directory $DEPLOY_DIR.
2024-10-15 17:14:04 +00:00
- name : Copy build
run : |
rm build/alpine.html
sudo mv build/* $DEPLOY_DIR/
2023-04-21 15:01:40 +00:00
# We generate index.list files for our httpfs to function properly.
- name : make index.list
shell : bash
run : |
find $DEPLOY_DIR -type d | while read -r dir;
do
index_list="$dir/index.list";
sudo rm -f "$index_list";
sudo ls "$dir" | sudo tee "$index_list" > /dev/null;
sudo chmod +rw "$index_list";
sudo echo "created $index_list";
done
# Create a gh-pages artifact in order to deploy to gh-pages.
- name : Upload GitHub Pages artifact
2023-12-20 14:33:31 +00:00
uses : actions/upload-pages-artifact@v2
2023-04-21 15:01:40 +00:00
with :
# Path of the directory containing the static assets for our gh pages deployment.
path : ${{ env.DEPLOY_DIR }} # optional, default is _site/
- name : github release # To upload our final ext2 image as a github release.
if : ${{ github.event.inputs.GITHUB_RELEASE == 'true' }}
uses : softprops/action-gh-release@v0.1.15
with :
target_commitish : ${{ github.sha }} # Last commit on the GITHUB_REF branch or tag
2023-05-19 09:04:40 +00:00
tag_name : ext2_image
2023-04-21 15:01:40 +00:00
fail_on_unmatched_files : 'true' # Fail in case of no matches with the file(s) glob(s).
files : | # Assets to upload as release.
2023-05-17 20:01:53 +00:00
${{ env.IMAGE_NAME }}
2023-04-21 15:01:40 +00:00
deploy_to_github_pages : # Job that deploys the github-pages artifact to github-pages.
if : ${{ github.event.inputs.DEPLOY_TO_GITHUB_PAGES == 'true' }}
needs : build
environment :
name : github-pages
url : ${{ steps.deployment.outputs.page_url }}
# Grant GITHUB_TOKEN the permissions required to make a Pages deployment
permissions :
pages : write # to deploy to Pages
id-token : write # to verify the deployment originates from an appropriate source
runs-on : ubuntu-latest
steps :
# Deployment to github pages
- name : Deploy GitHub Pages site
id : deployment
2023-12-20 14:33:31 +00:00
uses : actions/deploy-pages@v3