|
1 |
| -name: Test |
2 |
| - |
3 |
| -on: pull_request |
4 |
| - |
| 1 | +# Limitations of GitHub Actions: |
| 2 | +# Fedora: https://github.com/actions/runner-images/issues/10802 |
| 3 | +# on.pull_request.paths: https://github.com/actions/runner/issues/2324 |
| 4 | +# jobs.<job_id>.continue-on-error: https://github.com/orgs/community/discussions/15452 |
| 5 | +# etc: https://fusectore.dev/2022/09/25/github-actions-pitfalls.html |
| 6 | +name: Portability Testing |
| 7 | +on: |
| 8 | + push: |
| 9 | + paths: |
| 10 | + - '!**' |
| 11 | + - '.github/workflows/test.yml' |
| 12 | + - 'updater.sh' |
| 13 | + - 'prefsCleaner.sh' |
5 | 14 | jobs:
|
6 |
| - test: |
| 15 | + sh: |
| 16 | + defaults: |
| 17 | + run: |
| 18 | + shell: sh {0} |
7 | 19 | strategy:
|
| 20 | + fail-fast: false |
8 | 21 | matrix:
|
9 |
| - os: [ubuntu-latest] # TODO Add macos-latest and windows-latest |
10 |
| - shell: [bash, busybox, dash, ksh, mksh, yash, zsh] # TODO Add ksh88, osh, pbosh, posh |
| 22 | + script: [ updater.sh, prefsCleaner.sh ] |
| 23 | + shell: [ bash, busybox, dash, ksh, mksh, posh, yash, zsh ] |
| 24 | + os: [ ubuntu-latest ] |
| 25 | + include: |
| 26 | + - script: updater.sh |
| 27 | + shell: bash |
| 28 | + os: macos-latest |
| 29 | + - script: prefsCleaner.sh |
| 30 | + shell: bash |
| 31 | + os: macos-latest |
11 | 32 | runs-on: ${{ matrix.os }}
|
12 | 33 | steps:
|
13 | 34 | - uses: actions/checkout@v4
|
14 |
| - - name: Install esoteric shell |
15 |
| - if: ${{ contains(fromJSON('["busybox", "ksh", "mksh", "yash", "zsh"]'), matrix.shell) }} |
| 35 | + - name: Install POSIX compliant shell from the Ubuntu repositories |
| 36 | + if: ${{ startsWith(matrix.os, 'ubuntu-') }} |
| 37 | + timeout-minutes: 3 |
16 | 38 | run: |
|
17 |
| - sudo apt update -y |
18 |
| - sudo apt install ${{ matrix.shell }} -y |
19 |
| - - name: Set shell |
20 |
| - if: ${{ matrix.os == 'ubuntu-latest' }} |
21 |
| - run: sudo ln -sf /usr/bin/${{ matrix.shell }} /bin/sh |
22 |
| - - name: Check exit status definitions |
| 39 | + sudo apt update -y && |
| 40 | + sudo apt install -y ${{ matrix.shell }} || |
| 41 | + exit |
| 42 | + - name: Point `/bin/sh` at the newly installed shell |
| 43 | + if: ${{ runner.os == 'Linux' }} |
| 44 | + run: sudo ln -sf /usr/bin/${{ matrix.shell }} /bin/sh || exit |
| 45 | + - name: Test dot sourcing and obtain exit status definitions |
| 46 | + timeout-minutes: 1 |
23 | 47 | run: |
|
24 |
| - . ./updater.sh 2>/dev/null |
25 |
| -
|
26 |
| - while IFS='=' read -r name code; do |
27 |
| - # "When reporting the exit status with the special parameter '?', |
28 |
| - # the shell shall report the full eight bits of exit status available." |
29 |
| - # ―https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_08_02 |
30 |
| - # "exit [n]: If n is specified, but its value is not between 0 and 255 |
31 |
| - # inclusively, the exit status is undefined." |
32 |
| - # ―https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_21 |
33 |
| - [ "$code" -ge 0 ] && [ "$code" -le 255 ] || { |
34 |
| - printf '%s %s\n' 'Undefined exit status in the definition:' \ |
35 |
| - "$name=$code." >&2 |
36 |
| - exit 70 # Internal software error. |
37 |
| - } |
38 |
| - done <<EOF |
39 |
| - $(exit_status_definitions) |
| 48 | + case ${{ matrix.shell }} in |
| 49 | + busybox) |
| 50 | + shell='busybox ash' |
| 51 | + ;; |
| 52 | + *) |
| 53 | + shell=${{ matrix.shell }} |
| 54 | + ;; |
| 55 | + esac && |
| 56 | + eval "$shell" <<'EOF' |
| 57 | + case ${{ matrix.shell }} in |
| 58 | + zsh) |
| 59 | + emulate sh |
| 60 | + ;; |
| 61 | + esac |
| 62 | + . ./${{ matrix.script }} |
| 63 | + [ "$?" -eq "$_EX_OK" ] || |
| 64 | + echo '::error file=${{ matrix.script }}::Dot sourcing failed' |
| 65 | + exit_status_definitions | tr -d ' ' >>"$GITHUB_ENV" |
40 | 66 | EOF
|
41 |
| - - name: Tests setup |
| 67 | + [ "$?" -eq 0 ] || exit |
| 68 | + - name: Test the `-h` option |
| 69 | + timeout-minutes: 1 |
| 70 | + run: ./${{ matrix.script }} -h |
| 71 | + - name: Test passing an unsupported option to the script |
| 72 | + timeout-minutes: 1 |
42 | 73 | run: |
|
43 |
| - set +e |
44 |
| - . ./updater.sh && exit_status_definitions >> $GITHUB_ENV |
45 |
| - - name: Check that running as root returns EX_USAGE |
46 |
| - run: sudo ./updater.sh -x 2>/dev/null || { [ "$?" -eq $_EX_USAGE ] && exit 0; } |
47 |
| - - name: Check that passing a wrong option returns EX_USAGE |
48 |
| - run: ./updater.sh -x 2>/dev/null || { [ "$?" -eq $_EX_USAGE ] && exit 0; } |
49 |
| - - name: Check that --help returns EX_OK and not EX__BASE |
50 |
| - run: ./updater.sh -h > /dev/null |
51 |
| - - name: Check that if the profile doesn't have at least d-wx permissions, returns EX_UNAVAILABLE |
| 74 | + ./${{ matrix.script }} -9 |
| 75 | + [ "$?" -eq "$_EX_USAGE" ] |
| 76 | + - name: Test nonexistent profiles.ini |
| 77 | + timeout-minutes: 1 |
52 | 78 | run: |
|
53 |
| - unxable_temp_dir=$(mktemp -d) |
54 |
| - chmod 444 $unxable_temp_dir |
55 |
| - ./updater.sh -p $unxable_temp_dir > /dev/null 2>&1 || { [ "$?" -ne $_EX_UNAVAILABLE ] && exit 1; } |
56 |
| - unwable_temp_dir=$(mktemp -d) |
57 |
| - chmod 111 $unwable_temp_dir |
58 |
| - ./updater.sh -p $unwable_temp_dir > /dev/null 2>&1 || { [ "$?" -ne $_EX_UNAVAILABLE ] && exit 1; } |
59 |
| - exit 0 |
60 |
| - - name: Check that if the profiles.ini doesn't exist, returns EX_NOINPUT |
| 79 | + (HOME=/nosuchdir ./${{ matrix.script }} -sl) |
| 80 | + [ "$?" -eq "$_EX_NOINPUT" ] |
| 81 | + - name: Test profile directory missing write or search permissions |
| 82 | + timeout-minutes: 1 |
61 | 83 | run: |
|
62 |
| - temp_dir=$(mktemp -d) |
63 |
| - chmod 777 $temp_dir |
64 |
| - ./updater.sh -l > /dev/null 2>&1 || { [ "$?" -ne $_EX_NOINPUT ] && exit 1; } |
65 |
| - exit 0 |
66 |
| - - name: Check that if the profile requires root privileges, returns EX_CONFIG |
| 84 | + unwritable_dir=$(mktemp -d) && |
| 85 | + chmod a-w "$unwritable_dir" && |
| 86 | + ./${{ matrix.script }} -sp "$unwritable_dir" |
| 87 | + unwritable_status=$? |
| 88 | + unsearchable_dir=$(mktemp -d) && |
| 89 | + chmod a-x "$unsearchable_dir" && |
| 90 | + ./${{ matrix.script }} -sp "$unsearchable_dir" |
| 91 | + unsearchable_status=$? |
| 92 | + [ "$unwritable_status" -eq "$_EX_UNAVAILABLE" ] && |
| 93 | + { |
| 94 | + [ "$unsearchable_status" -eq "$_EX_UNAVAILABLE" ] || |
| 95 | + [ "$unsearchable_status" -eq "$_EX_FAIL" ] # readlinkf failed. |
| 96 | + } |
| 97 | + - name: Test running as root |
| 98 | + timeout-minutes: 1 |
67 | 99 | run: |
|
68 |
| - temp_dir=$(mktemp -d) |
69 |
| - sudo chmod 777 $temp_dir |
70 |
| - sudo touch $temp_dir/user.js |
71 |
| - ./updater.sh -p $temp_dir > /dev/null 2>&1 || { [ "$?" -ne $_EX_CONFIG ] && exit 1; } |
72 |
| - exit 0 |
73 |
| - - name: Check that the profile contains something after execution |
| 100 | + sudo ./${{ matrix.script }} |
| 101 | + [ "$?" -eq "$_EX_USAGE" ] |
| 102 | + - name: Test profile directory containing certain root owned files |
| 103 | + if: ${{ matrix.script == 'updater.sh' }} |
| 104 | + timeout-minutes: 1 |
74 | 105 | run: |
|
75 |
| - temp_dir=$(mktemp -d) |
76 |
| - echo "temp_dir=$temp_dir" >> $GITHUB_ENV |
77 |
| - touch $temp_dir/user.js |
78 |
| - yes | ./updater.sh -p $temp_dir |
79 |
| - [ -s $temp_dir/user.js ] || exit 1 |
80 |
| - - name: Check that the profile contains the most recent user.js after execution |
| 106 | + temp_dir=$(mktemp -d) && |
| 107 | + sudo touch "$temp_dir/user.js" && |
| 108 | + ./${{ matrix.script }} -p "$temp_dir" |
| 109 | + [ "$?" -eq "$_EX_CONFIG" ] |
| 110 | + - name: Test noninteractive run |
| 111 | + timeout-minutes: 2 |
81 | 112 | run: |
|
82 |
| - wget -qO user.js https://raw.githubusercontent.com/arkenfox/user.js/refs/heads/master/user.js |
83 |
| - diff user.js $temp_dir/user.js |
| 113 | + temp_dir=$(mktemp -d) && |
| 114 | + cp ./${{ matrix.script }} ./user.js "$temp_dir" && ( |
| 115 | + cd "$temp_dir" && |
| 116 | + ln -s 127.0.0.2:999 .parentlock && |
| 117 | + ln -s 127.0.0.2:999 lock && |
| 118 | + echo 'user_pref("app.installation.timestamp", "0");' >prefs.js && |
| 119 | + # yes | tr -d '\n' | ./${{ matrix.script }} -ds hangs on macOS. |
| 120 | + printf '%s' 'yyyyyyyyy' | ./${{ matrix.script }} -ds |
| 121 | + ) |
0 commit comments