Skip to content

Release 3.1.0

Release 3.1.0 #24

name: Pre-release (web)
on:
pull_request:
title:
- "Release *.*.*"
- "Release *.*.*b*"
branches: main
paths-ignore:
- ".github/**"
- "**.md"
# cf https://github.com/actions/runner/issues/2324, paths-ignore will only be respected at PR creation
# all new commits then added in the PR will trigger the workflow
env:
# intermediary registry in which architecture-specific images must be pushed
DOCKER_BUILD_REPO: "nwodtuhs/exegol-builds"
# final registry target, in which arch-specific images must be aggregated
DOCKER_TARGET_REPO: "nwodtuhs/exegol-preprod"
IMAGE_BASE_NAME: "web"
DOCKERFILE: "web.dockerfile"
jobs:
# https://github.com/orgs/community/discussions/26671, "can’t pass ENV variables to the reusable workflow"
varset:
name: Initialize variables
runs-on: self-hosted
outputs:
DOCKER_BUILD_REPO: ${{ steps.varset.outputs.DOCKER_BUILD_REPO }}
DOCKER_TARGET_REPO: ${{ steps.varset.outputs.DOCKER_TARGET_REPO }}
IMAGE_BASE_NAME: ${{ steps.varset.outputs.IMAGE_BASE_NAME }}
DOCKERFILE: ${{ steps.varset.outputs.DOCKERFILE }}
IMAGE_VERSION: ${{ steps.varset.outputs.IMAGE_VERSION }}
steps:
- name: Passing workflow env vars to reusable workflows
id: varset
run: |
echo "DOCKER_BUILD_REPO=${DOCKER_BUILD_REPO}" >> $GITHUB_OUTPUT
echo "DOCKER_TARGET_REPO=${DOCKER_TARGET_REPO}" >> $GITHUB_OUTPUT
echo "IMAGE_BASE_NAME=${IMAGE_BASE_NAME}" >> $GITHUB_OUTPUT
echo "DOCKERFILE=${DOCKERFILE}" >> $GITHUB_OUTPUT
echo "IMAGE_VERSION=$(echo ${{ github.event.pull_request.title }} | cut -d ' ' -f 2)"
echo "IMAGE_VERSION=$(echo ${{ github.event.pull_request.title }} | cut -d ' ' -f 2)" >> $GITHUB_OUTPUT
build_belt:
name: Build belt
needs: varset
strategy:
fail-fast: false
matrix:
arch: [arm64, amd64]
uses: ./.github/workflows/sub_build_belt.yml
with:
DOCKER_BUILD_REPO: ${{ needs.varset.outputs.DOCKER_BUILD_REPO }}
DOCKER_TARGET_REPO: ${{ needs.varset.outputs.DOCKER_TARGET_REPO }}
IMAGE_BASE_NAME: ${{ needs.varset.outputs.IMAGE_BASE_NAME }}
DOCKERFILE: ${{ needs.varset.outputs.DOCKERFILE }}
IMAGE_VERSION: ${{ needs.varset.outputs.IMAGE_VERSION }}
ARCH: ${{ matrix.arch }}
secrets:
DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }}
DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }}
publish:
name: Publish
timeout-minutes: 60
needs:
- varset
- build_belt
runs-on: self-hosted
# only publishing if the tests were a success (implicit by the success of build_belt).
if: needs.build_belt.result == 'success'
steps:
- name: Login to Dockerhub
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Create and push manifest
if: success()
run: |
echo "Create manifest"
docker manifest create ${DOCKER_TARGET_REPO}:${IMAGE_BASE_NAME} ${DOCKER_BUILD_REPO}:${IMAGE_BASE_NAME}-arm64 ${DOCKER_BUILD_REPO}:${IMAGE_BASE_NAME}-amd64
docker manifest push ${DOCKER_TARGET_REPO}:${IMAGE_BASE_NAME}
docker manifest rm ${DOCKER_TARGET_REPO}:${IMAGE_BASE_NAME}
- name: Create and push version manifest
env:
IMAGE_VERSION: ${{ needs.varset.outputs.IMAGE_VERSION }}
if: success() && env.IMAGE_VERSION != ''
run: |
echo "Create version manifest"
docker manifest create ${DOCKER_TARGET_REPO}:${IMAGE_BASE_NAME}-${IMAGE_VERSION} ${DOCKER_BUILD_REPO}:${IMAGE_BASE_NAME}-arm64 ${DOCKER_BUILD_REPO}:${IMAGE_BASE_NAME}-amd64
docker manifest push ${DOCKER_TARGET_REPO}:${IMAGE_BASE_NAME}-${IMAGE_VERSION}
docker manifest rm ${DOCKER_TARGET_REPO}:${IMAGE_BASE_NAME}-${IMAGE_VERSION}
tools_list:
name: Export tools list
needs:
- varset
- publish
- build_belt
# only exporting tools list if publish was a success AND the tests were a success
if: always() && ( needs.publish.result == 'success' && !contains(needs.build_belt.outputs.build, 'failure'))
strategy:
fail-fast: false
# only 1 job at a time, else there will be a conflict. Runner 2 will pull exegol-docs before runner 1 pushes changes.
max-parallel: 1
matrix:
arch: [ arm64, amd64 ]
runs-on:
- self-hosted
- builder
- ${{ matrix.arch }}
steps:
- name: Checkout Exegol-images
uses: actions/checkout@v3
- name: Prepare image version
id: prepare
run: |
COMMIT_ID=$(git rev-parse "$GITHUB_SHA")
if [ "$IMAGE_VERSION" == "" ]; then
IMAGE_VERSION=${COMMIT_ID:0:8}
fi
echo "image_version=${IMAGE_VERSION}"
echo "image_version=${IMAGE_VERSION}" >> $GITHUB_OUTPUT
- name: Checkout Exegol-docs
uses: actions/checkout@v3
with:
repository: 'ThePorgs/Exegol-docs'
ref: 'dev-images'
- name: Inspect the built image
run: docker inspect ${{ needs.varset.outputs.DOCKER_BUILD_REPO }}:${{ needs.varset.outputs.IMAGE_BASE_NAME }}-${{ matrix.arch }}
- name: Create a container from the built image
run: |
docker run --name exegol-${{ needs.varset.outputs.IMAGE_BASE_NAME }}-${{ matrix.arch }} --rm -t -d ${{ needs.varset.outputs.DOCKER_BUILD_REPO }}:${{ needs.varset.outputs.IMAGE_BASE_NAME }}-${{ matrix.arch }} endless
- name: Export the tools list
if: success()
run: |
docker cp exegol-${{ needs.varset.outputs.IMAGE_BASE_NAME }}-${{ matrix.arch }}:/.exegol/installed_tools.csv installed_tools.csv
- name: Debug print installed_tools.csv
id: list_exists
run: cat installed_tools.csv
- name: Sanity check for installed_tools.csv
if: success()
run: |
grep -qE '([^,]*,[^,]*){3,}' installed_tools.csv \
&& (echo '[-] Wrong number of columns on the following lines' \
&& grep -oE '([^,]*,[^,]*){3,}' installed_tools.csv || exit 1) \
|| (echo '[+] List contains right number of columns' && exit 0)
- name: Stop the container
if: always()
run: docker stop exegol-${{ needs.varset.outputs.IMAGE_BASE_NAME }}-${{ matrix.arch }}
- name: Adding list to repo and tables
if: always() && steps.list_exists.outcome == 'success'
run: |
mkdir -p source/assets/installed_tools/lists
echo '[*] Moving tools list to imagetag_version_arch.csv'
mv installed_tools.csv source/assets/installed_tools/lists/${{ needs.varset.outputs.IMAGE_BASE_NAME }}_${{ steps.prepare.outputs.image_version }}_${{ matrix.arch }}.csv
echo '[*] Changing lists.csv so that new tools list appears'
echo '[*] [SHOULD BE RELEASES ONLY] Removing occurences of image,version,arch. This is because this workflow runs in the prerelease pipeline, meaning that there is a possibility tools list is pushed to exegol-docs even if the images are not released for some reasons (e.g. imageA prerelease works but not for imageB). Doing this grep -v will ensure that lists.csv does not have duplicates to the same tag, same version and same arch'
(head -n 1 source/assets/installed_tools/lists.csv; \
echo "${{ needs.varset.outputs.IMAGE_BASE_NAME }},${{ steps.prepare.outputs.image_version }},${{ matrix.arch }},$(date -u +"%Y-%m-%dT%H:%M:%SZ"),:download:\`${{ needs.varset.outputs.IMAGE_BASE_NAME }}_${{ steps.prepare.outputs.image_version }}_${{ matrix.arch }}.csv \
</assets/installed_tools/lists/${{ needs.varset.outputs.IMAGE_BASE_NAME }}_${{ steps.prepare.outputs.image_version }}_${{ matrix.arch }}.csv>\`"; \
( \
tail -n +2 source/assets/installed_tools/lists.csv | grep -Ev "${{ needs.varset.outputs.IMAGE_BASE_NAME }},${{ steps.prepare.outputs.image_version }},${{ matrix.arch }}" \
) \
) | tee source/assets/installed_tools/new_lists.csv
mv source/assets/installed_tools/new_lists.csv source/assets/installed_tools/lists.csv
- name: Debug print lists.csv
if: always()
id: final_list_exists
run: cat source/assets/installed_tools/lists.csv
- name: Push Exegol-docs
if: always() && steps.final_list_exists.outcome == 'success'
env:
SSH_DEPLOY_KEY: ${{ secrets.EXEGOL_DOCS_SSH_DEPLOY_KEY }}
run: |
echo '[*] Setting up git env for SSH use'
mkdir -p "$HOME/.ssh"
DEPLOY_KEY_FILE="$HOME/.ssh/deploy_key"
echo "${SSH_DEPLOY_KEY}" > "$DEPLOY_KEY_FILE"
chmod 600 "$DEPLOY_KEY_FILE"
SSH_KNOWN_HOSTS_FILE="$HOME/.ssh/known_hosts"
ssh-keyscan -H github.com > "$SSH_KNOWN_HOSTS_FILE"
export GIT_SSH_COMMAND="ssh -i "$DEPLOY_KEY_FILE" -o UserKnownHostsFile=$SSH_KNOWN_HOSTS_FILE"
GIT_CMD_REPOSITORY="[email protected]:ThePorgs/Exegol-docs.git"
echo '[*] Setting git config'
git config --global user.name "exegol-images[pipeline]"
git config --global user.email "[email protected]"
echo '[*] Staging changes'
git add --verbose source/assets/installed_tools/lists/${{ needs.varset.outputs.IMAGE_BASE_NAME }}_${{ steps.prepare.outputs.image_version }}_${{ matrix.arch }}.csv
git add --verbose source/assets/installed_tools/lists.csv
echo '[*] Commiting changes'
git commit --verbose -m "PIPELINE: tools list for ${{ needs.varset.outputs.IMAGE_BASE_NAME }}_${{ steps.prepare.outputs.image_version }}_${{ matrix.arch }}"
echo '[*] Pushing changes'
git push --verbose "$GIT_CMD_REPOSITORY"
clean_runners:
name: Clean runner
needs:
- tools_list
- publish
- build_belt
# clean runners, if publish was a success, or at least if build succeeded
if: always() && ( needs.publish.result == 'success' || !contains(needs.build_belt.outputs.build, 'failure'))
strategy:
fail-fast: false
matrix:
arch: [ arm64, amd64 ]
runs-on:
- self-hosted
- builder
- ${{ matrix.arch }}
steps:
- name: Remove image built for ${{ matrix.arch }}
run: |
image_name=${DOCKER_BUILD_REPO}:${IMAGE_BASE_NAME}-${{ matrix.arch }}
echo "Removing $image_name"
docker image inspect $image_name || exit 0 && docker rmi $image_name
clean_registry:
name: Clean intermediate registry
needs: publish
runs-on: self-hosted
# only cleaning if publish was a success. And publish requires that tests were a success. If tests were a success, there's no need for debugging the images, they can be removed from the exegol-builds registry
if: needs.publish.result == 'success'
steps:
- name: Remove arch-specific images on intermediate registry
run: |
HUB_TOKEN=$(curl -s -H "Content-Type: application/json" -X POST -d "{\"username\": \"${{ secrets.DOCKER_USERNAME }}\", \"password\": \"${{ secrets.DOCKER_PASSWORD }}\"}" https://hub.docker.com/v2/users/login/ | jq -r .token)
curl -i -X DELETE -H "Accept: application/json" -H "Authorization: JWT $HUB_TOKEN" https://hub.docker.com/v2/repositories/${DOCKER_BUILD_REPO}/tags/${IMAGE_BASE_NAME}-arm64/
curl -i -X DELETE -H "Accept: application/json" -H "Authorization: JWT $HUB_TOKEN" https://hub.docker.com/v2/repositories/${DOCKER_BUILD_REPO}/tags/${IMAGE_BASE_NAME}-amd64/