These ten questions turn on GitHub 29 behaviors that catch developers who have used Actions for years: how expressions compare and quote values, what a matrix does to a number, what masking really hides, how the default shell and continue-on-error report a failure, what a skipped job does to the jobs that need it, and what the REST API and Git 1,932 's own protocol show that the web interface hides. Every answer comes from a real run on binarybehemoth/booknest with gh 2.101.0 29 and Git 2.55.0, on the ubuntu-24.04 hosted image. Write down what you expect each question to print and why, then check Appendix H, which gives the real output, the reason and the section to reread.
Save the workflow below as .github/workflows/quiz.yml in your BookNest clone. It runs only on a branch named quiz, so it cannot disturb main or any other workflow.
name: Quiz
on:
push:
branches: [quiz]
permissions:
contents: read
jobs:
quiz:
runs-on: ubuntu-24.04
env:
T: ${{ github.token }}
steps:
- name: Q1
run: >-
echo "Q1 ${{ 'BookNest' == 'BOOKNEST' }} ${{ contains('BookNest', 'NEST') }}
${{ '0' == 0 }} ${{ '' == false }}"
- name: Q2 quoted in YAML
if: 'false'
run: echo "Q2 the YAML-quoted step ran"
- name: Q2 quoted in the expression
if: "'false'"
run: echo "Q2 the expression-quoted step ran"
- name: Q4
run: echo "Q4 key=npm-${{ runner.os }}-${{ hashFiles('**/package-lock.json') }}"
- name: Q5
run: echo "Q5 $T / ${T:0:4}"
- name: Q6 default shell
run: false | true; echo "Q6 default shell ok"
- id: pipe
name: Q6 explicit bash
shell: bash
continue-on-error: true
run: false | true; echo "Q6 explicit bash ok"
- name: Q6 result
run: echo "Q6 ${{ steps.pipe.outcome }} ${{ steps.pipe.conclusion }} ${{ job.status }}"
matrix:
runs-on: ubuntu-24.04
strategy:
matrix:
node: [24.10, 22]
steps:
- run: echo "Q3 node ${{ matrix.node }}"
skipped:
if: false
runs-on: ubuntu-24.04
steps:
- run: echo "Q7 never"
after:
needs: skipped
runs-on: ubuntu-24.04
steps:
- run: echo "Q7 after ran"
always:
needs: skipped
if: always()
runs-on: ubuntu-24.04
steps:
- run: echo "Q7 always ran, skipped job result ${{ needs.skipped.result }}"# 1. Which comparisons are true? (3.9.6) 2. Which Q2 steps run? (3.9.7)
# 3. What version does the matrix pass? (3.10.1) 4. What cache key is built? (3.10.4)
# 5. What does the log show for the token? (3.11.6) 6. Which Q6 lines print? (3.9.4)
# 7. Which of the jobs after and always run? (3.9.5)
git switch -q -c quiz && git add .github/workflows/quiz.yml
git commit -q -m "Add the quiz workflow" && git push -q -u origin quiz
sleep 10; id=$(gh run list -b quiz -w quiz.yml -L 1 --json databaseId -q '.[0].databaseId')
gh run watch "$id" >/dev/null
gh run view "$id" --json jobs -q '.jobs[] | "\(.name): \(.conclusion)"'
gh run view "$id" --log | grep -oE 'Z (Q[0-9] .*|##\[error\].*)' | cut -c3-# 8. Which workflows does the API list that have no file in .github/workflows? (3.15.2, 3.15.5)
gh api 'repos/{owner}/{repo}/actions/workflows' -q '.workflows[].path' |
while read -r p; do [ -f "$p" ] || echo "$p"; done
# 9. How many items does the issues endpoint return, and are they all issues? (3.16.2)
gh api 'repos/{owner}/{repo}/issues?state=all' --paginate -q '.[] | has("pull_request")' |
sort | uniq -c
# 10. Which refs does GitHub advertise, and can you delete one? (3.8.3)
git ls-remote origin | awk '{print $2}' | sed -E 's#pull/[0-9]+#pull/N#' | sort | uniq -c
git push origin :refs/pull/1/head 2>&1 | grep rejected