Use Github gating (approve button) for webui-trigger workflow #3008
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# ====================================== | |
# WARNING! | |
# THIS FILE IS GENERATED FROM A TEMPLATE | |
# DO NOT EDIT THIS FILE MANUALLY! | |
# ====================================== | |
# The template is located in: build-image.yml.j2 | |
# Build a bootable image from a PR triggered by a "/build-image" comment or manually. | |
# | |
# Choose type of the image with these options: | |
# --boot.iso | |
# --live | |
# --updates.img | |
# | |
# If none of these is present, --boot-iso is assumed. | |
# If more are present at once, all variants are built. | |
# | |
# To use webui on boot.iso, add also: | |
# --webui | |
name: Build images | |
on: | |
issue_comment: | |
types: [created] | |
# be able to start this action manually from a actions tab when needed | |
workflow_dispatch: | |
permissions: | |
contents: read | |
statuses: write | |
pull-requests: write | |
jobs: | |
pr-info: | |
if: github.event_name == 'workflow_dispatch' || startsWith(github.event.comment.body, '/build-image') | |
runs-on: ubuntu-latest | |
steps: | |
- name: Query comment author repository permissions | |
if: github.event_name != 'workflow_dispatch' | |
uses: octokit/[email protected] | |
id: user_permission | |
with: | |
route: GET /repos/${{ github.repository }}/collaborators/${{ github.event.sender.login }}/permission | |
env: | |
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
# restrict this workflow to users with admin or write permission for the repository | |
# see https://docs.github.com/en/free-pro-team@latest/rest/reference/repos#get-repository-permissions-for-a-user | |
# store output if user is allowed in allowed_user job output so it has to be checked in downstream job | |
- name: Check if user does have correct permissions | |
if: github.event_name != 'workflow_dispatch' && contains('admin write', fromJson(steps.user_permission.outputs.data).permission) | |
id: check_user_perm | |
run: | | |
echo "User '${{ github.event.sender.login }}' has permission '${{ fromJson(steps.user_permission.outputs.data).permission }}' allowed values: 'admin', 'write'" | |
echo "allowed_user=true" >> $GITHUB_OUTPUT | |
- name: Get information for pull request | |
if: github.event_name != 'workflow_dispatch' | |
uses: octokit/[email protected] | |
id: pr_api | |
with: | |
route: GET /repos/${{ github.repository }}/pulls/${{ github.event.issue.number }} | |
env: | |
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
- name: Parse arguments | |
id: parse_args | |
# Do not use comment body directly in the shell command to avoid possible code injection. | |
env: | |
BODY: ${{ github.event.comment.body }} | |
run: | | |
# extract first line and cut out the "/build-image" first word | |
ARGS=$(echo "$BODY" | sed -n '1 s/^[^ ]* *//p' | sed 's/[[:space:]]*$//') | |
echo "arguments are: $ARGS" | |
if ! [[ "$ARGS" == *"--boot.iso"* || "$ARGS" == *"--live"* || "$ARGS" == *"--updates.img"* ]] ; then | |
ARGS="$ARGS --boot.iso" | |
echo "adding implicit --boot.iso, arguments now are: $ARGS" | |
fi | |
echo "args=${ARGS}" >> $GITHUB_OUTPUT | |
- name: Construct image description | |
id: image_description | |
run: | | |
set -eux | |
if [ "${{ github.event_name }}" = "workflow_dispatch" ] ; then | |
# manual run from actions page | |
branch_name="$GITHUB_REF_NAME" | |
sha="$GITHUB_SHA" | |
echo "image_description=$branch_name-$sha" >> $GITHUB_OUTPUT | |
else | |
# comment on PR | |
pr_num="${{ github.event.issue.number }}" | |
sha="${{ steps.pr_api.outcome == 'success' && fromJson(steps.pr_api.outputs.data).head.sha }}" | |
echo "image_description=pr$pr_num-$sha" >> $GITHUB_OUTPUT | |
fi | |
- name: Mark comment as seen | |
if: github.event_name != 'workflow_dispatch' | |
# https://docs.github.com/en/rest/reactions/reactions?apiVersion=2022-11-28#create-reaction-for-an-issue-comment | |
env: | |
GH_TOKEN: ${{ github.token }} | |
run: | | |
gh api \ | |
--method POST \ | |
-H "Accept: application/vnd.github+json" \ | |
-H "X-GitHub-Api-Version: 2022-11-28" \ | |
"/repos/$GITHUB_REPOSITORY/issues/comments/${{ github.event.comment.id }}/reactions" \ | |
-f content='eyes' | |
- name: Set outputs | |
id: set_outputs | |
run: | | |
set -eux | |
if [ ${{ github.event_name }} == 'workflow_dispatch' ]; then | |
echo "allowed_user=true" >> $GITHUB_OUTPUT | |
echo "sha=$GITHUB_SHA" >> $GITHUB_OUTPUT | |
else | |
echo "allowed_user=${{ steps.check_user_perm.outcome == 'success' && steps.check_user_perm.outputs.allowed_user }}" >> $GITHUB_OUTPUT | |
echo "sha=${{ steps.pr_api.outcome == 'success' && fromJson(steps.pr_api.outputs.data).head.sha }}" >> $GITHUB_OUTPUT | |
fi | |
outputs: | |
allowed_user: ${{ steps.set_outputs.outputs.allowed_user }} | |
sha: ${{ steps.set_outputs.outputs.sha }} | |
args: ${{ steps.parse_args.outputs.args }} | |
image_description: ${{ steps.image_description.outputs.image_description }} | |
boot-iso: | |
needs: pr-info | |
# only do this for Fedora for now; once we have RHEL 8/9 boot.iso builds working, also support these | |
if: needs.pr-info.outputs.allowed_user == 'true' && contains(needs.pr-info.outputs.args, '--boot.iso') | |
runs-on: [self-hosted, kstest] | |
timeout-minutes: 300 | |
env: | |
STATUS_NAME: boot-iso | |
CONTAINER_TAG: 'lorax' | |
ISO_BUILD_CONTAINER_NAME: 'quay.io/rhinstaller/anaconda-iso-creator' | |
steps: | |
# we post statuses manually as this does not run from a pull_request event | |
# https://developer.github.com/v3/repos/statuses/#create-a-status | |
- name: Create in-progress status | |
uses: octokit/[email protected] | |
with: | |
route: 'POST /repos/${{ github.repository }}/statuses/${{ needs.pr-info.outputs.sha }}' | |
context: '${{ env.STATUS_NAME }} ${{ needs.pr-info.outputs.launch_args }}' | |
state: pending | |
target_url: 'https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}' | |
env: | |
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
- name: Clone repository | |
uses: actions/checkout@v4 | |
with: | |
ref: ${{ needs.pr-info.outputs.sha }} | |
fetch-depth: 0 | |
- name: Build anaconda-iso-creator container image | |
run: | | |
# set static tag to avoid complications when looking what tag is used | |
sudo make -f ./Makefile.am anaconda-iso-creator-build CI_TAG=$CONTAINER_TAG | |
- name: Build anaconda-rpm container (for RPM build) | |
run: | | |
# set static tag to avoid complications when looking what tag is used | |
make -f ./Makefile.am anaconda-rpm-build CI_TAG=$CONTAINER_TAG | |
- name: Build Anaconda RPM files | |
run: | | |
# output of the build will be stored in ./result/build/01-rpm-build/*.rpm | |
make -f ./Makefile.am container-rpms-scratch CI_TAG=$CONTAINER_TAG | |
mkdir -p ./anaconda_rpms/ | |
cp -av ./result/build/01-rpm-build/*.rpm ./anaconda_rpms/ | |
- name: Build the ISO image | |
run: | | |
mkdir -p images | |
if [[ "${{ needs.pr-info.outputs.args }}" == *"--webui"* ]] ; then | |
WEBUI_OPTIONAL_ARG="--entrypoint /lorax-build-webui" | |
fi | |
# /var/tmp tmpfs speeds up lorax and avoids https://bugzilla.redhat.com/show_bug.cgi?id=1906364 | |
sudo podman run -i --rm --privileged \ | |
--tmpfs /var/tmp:rw,mode=1777 \ | |
-v `pwd`/anaconda_rpms:/anaconda-rpms:ro \ | |
-v `pwd`/images:/images:z \ | |
$WEBUI_OPTIONAL_ARG \ | |
$ISO_BUILD_CONTAINER_NAME:$CONTAINER_TAG | |
mv images/boot.iso "images/${{ needs.pr-info.outputs.image_description }}-boot.iso" | |
- name: Collect logs | |
if: always() | |
uses: actions/upload-artifact@v4 | |
with: | |
name: 'logs' | |
path: | | |
images/*.log | |
- name: Upload image | |
uses: actions/upload-artifact@v4 | |
with: | |
name: boot.iso image for ${{ needs.pr-info.outputs.image_description }} | |
path: | | |
images/*.iso | |
- name: Set result status | |
if: always() | |
uses: octokit/[email protected] | |
with: | |
route: 'POST /repos/${{ github.repository }}/statuses/${{ needs.pr-info.outputs.sha }}' | |
context: '${{ env.STATUS_NAME }} ${{ needs.pr-info.outputs.launch_args }}' | |
state: ${{ job.status }} | |
target_url: 'https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}' | |
env: | |
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
live-iso: | |
needs: pr-info | |
if: needs.pr-info.outputs.allowed_user == 'true' && contains(needs.pr-info.outputs.args, '--live') | |
runs-on: [self-hosted, kstest] | |
timeout-minutes: 300 | |
env: | |
STATUS_NAME: live-iso | |
CONTAINER_TAG: 'lorax' | |
ISO_BUILD_CONTAINER_NAME: 'quay.io/rhinstaller/anaconda-live-iso-creator' | |
steps: | |
# we post statuses manually as this does not run from a pull_request event | |
# https://developer.github.com/v3/repos/statuses/#create-a-status | |
- name: Create in-progress status | |
uses: octokit/[email protected] | |
with: | |
route: 'POST /repos/${{ github.repository }}/statuses/${{ needs.pr-info.outputs.sha }}' | |
context: '${{ env.STATUS_NAME }} ${{ needs.pr-info.outputs.launch_args }}' | |
state: pending | |
target_url: 'https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}' | |
env: | |
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
- name: Clone repository | |
uses: actions/checkout@v4 | |
with: | |
ref: ${{ needs.pr-info.outputs.sha }} | |
fetch-depth: 0 | |
- name: Build anaconda-rpm container (for RPM build) | |
run: | | |
# set static tag to avoid complications when looking what tag is used | |
make -f ./Makefile.am anaconda-rpm-build CI_TAG=$CONTAINER_TAG | |
- name: Build Anaconda RPM files | |
run: | | |
# output of the build will be stored in ./result/build/01-rpm-build/*.rpm | |
make -f ./Makefile.am container-rpms-scratch CI_TAG=$CONTAINER_TAG | |
- name: Build anaconda-live-iso-creator container image | |
run: | | |
# set static tag to avoid complications when looking what tag is used | |
make -f ./Makefile.am anaconda-live-iso-creator-build CI_TAG=$CONTAINER_TAG | |
- name: Build the ISO image | |
run: | | |
mkdir -p images | |
make -f Makefile.am container-live-iso-build CI_TAG=$CONTAINER_TAG | |
mv result/iso/Fedora-Workstation.iso "images/${{ needs.pr-info.outputs.image_description }}-Fedora-Workstation.iso" | |
- name: Make artefacts created by sudo cleanable | |
if: always() | |
run: | |
sudo chown -R github:github . | |
- name: Collect logs | |
if: always() | |
uses: actions/upload-artifact@v4 | |
with: | |
name: 'logs' | |
path: result/iso/logs/* | |
- name: Upload image artifacts | |
uses: actions/upload-artifact@v4 | |
with: | |
name: live image for ${{ needs.pr-info.outputs.image_description }} | |
path: | | |
images/*.iso | |
- name: Set result status | |
if: always() | |
uses: octokit/[email protected] | |
with: | |
route: 'POST /repos/${{ github.repository }}/statuses/${{ needs.pr-info.outputs.sha }}' | |
context: '${{ env.STATUS_NAME }} ${{ needs.pr-info.outputs.launch_args }}' | |
state: ${{ job.status }} | |
target_url: 'https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}' | |
env: | |
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
updates-img: | |
needs: pr-info | |
if: needs.pr-info.outputs.allowed_user == 'true' && contains(needs.pr-info.outputs.args, '--updates.img') | |
runs-on: ubuntu-latest | |
timeout-minutes: 10 | |
env: | |
STATUS_NAME: updates-img | |
steps: | |
- name: Clone repository | |
uses: actions/checkout@v4 | |
with: | |
ref: ${{ needs.pr-info.outputs.sha }} | |
fetch-depth: 0 | |
- name: Install required packages | |
run: | | |
sudo apt install -y dracut | |
- name: Create updates image | |
run: | | |
./scripts/makeupdates | |
new_name="${{ needs.pr-info.outputs.image_description }}-updates.img" | |
mv updates.img "$new_name" | |
lsinitrd "$new_name" | |
- name: Upload image | |
uses: actions/upload-artifact@v4 | |
with: | |
name: updates.img for ${{ needs.pr-info.outputs.image_description }} | |
path: | | |
*.img | |
- name: Set result status | |
if: always() | |
uses: octokit/[email protected] | |
with: | |
route: 'POST /repos/${{ github.repository }}/statuses/${{ needs.pr-info.outputs.sha }}' | |
context: '${{ env.STATUS_NAME }} ${{ needs.pr-info.outputs.launch_args }}' | |
state: ${{ job.status }} | |
target_url: 'https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}' | |
env: | |
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
finalize: | |
needs: [pr-info, boot-iso, live-iso, updates-img] | |
runs-on: ubuntu-latest | |
# needs always() to run even if builds failed | |
if: ${{ always() && !cancelled() && github.event_name != 'workflow_dispatch' && needs.pr-info.outputs.allowed_user == 'true' }} | |
steps: | |
- name: Clone repository | |
# need the repo to successfully post a comment :-/ | |
uses: actions/checkout@v4 | |
with: | |
ref: ${{ needs.pr-info.outputs.sha }} | |
fetch-depth: 1 | |
- name: Add comment with link to PR | |
env: | |
GH_TOKEN: ${{ github.token }} | |
run: | | |
sha="${{ needs.pr-info.outputs.sha }}" | |
url="https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}#artifacts" | |
echo -e -n "Images built based on commit $sha:\n" > comment.txt | |
if [[ "${{ needs.pr-info.outputs.args }}" == *"--boot.iso"* ]] ; then | |
# <job>.result can be success, failure, cancelled, or skipped | |
# https://docs.github.com/en/actions/learn-github-actions/contexts#jobs-context | |
echo -e "- \`boot.iso\`: ${{ needs.boot-iso.result }}\n" >> comment.txt | |
fi | |
if [[ "${{ needs.pr-info.outputs.args }}" == *"--live"* ]] ; then | |
echo -e "- Live: ${{ needs.live-iso.result }}\n" >> comment.txt | |
fi | |
if [[ "${{ needs.pr-info.outputs.args }}" == *"--updates.img"* ]] ; then | |
echo -e "- \`updates.img\`: ${{ needs.updates-img.result }}\n" >> comment.txt | |
fi | |
echo -e "\nDownload the images from the bottom of the [job status page]($url).\n" >> comment.txt | |
echo "Comment to be posted:" | |
cat comment.txt | |
gh pr comment \ | |
${{ github.event.issue.number }} \ | |
-F comment.txt |