Skip to content

docs: Add guide how to debug/develop GH workflows #1883

docs: Add guide how to debug/develop GH workflows

docs: Add guide how to debug/develop GH workflows #1883

Workflow file for this run

# ======================================
# 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/request-action@v2.x
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/request-action@v2.x
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/request-action@v2.x
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/request-action@v2.x
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/request-action@v2.x
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"
mv result/iso/logs images/
- 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: |
images/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/request-action@v2.x
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/request-action@v2.x
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