|
1 | 1 | name: Setup Linux dependencies |
2 | | -description: Install and cache the system packages required to build ReScript. |
| 2 | +description: Install the system packages required to build ReScript. |
3 | 3 |
|
4 | 4 | runs: |
5 | 5 | using: composite |
6 | 6 | steps: |
7 | | - # This is a small, repository-specific version of the filesystem cache used |
8 | | - # by awalsh128/cache-apt-pkgs-action@v1.4.3. Restoring the installed files is |
9 | | - # considerably faster than downloading and installing the .deb files again. |
10 | | - - name: Resolve package versions |
11 | | - id: packages |
| 7 | + # Installed with apt, so that dpkg knows them: opam checks system |
| 8 | + # packages with dpkg, and an earlier cache that unpacked these files |
| 9 | + # without dpkg made opam take them for missing. musl-tools is needed for |
| 10 | + # the static builds; bubblewrap and rsync for opam builds in a restored |
| 11 | + # environment, such as coverage's bisect_ppx pin; cmake for OPAM. |
| 12 | + # ocaml/setup-ocaml installs its own packages, such as the multilib ones, |
| 13 | + # when it builds an environment. |
| 14 | + - name: Install system dependencies |
12 | 15 | shell: bash |
13 | | - env: |
14 | | - # Dependencies required by setup-ocaml, plus cmake for OPAM. The |
15 | | - # multilib packages are only available on x64 runners. |
16 | | - PACKAGES: >- |
17 | | - bubblewrap musl-tools rsync cmake |
18 | | - ${{ runner.arch == 'X64' && 'g++-multilib gcc-multilib' || '' }} |
19 | | - CACHE_VERSION: v5 |
20 | 16 | run: | |
21 | | - set -euo pipefail |
22 | | -
|
23 | | - read -ra packages <<< "$PACKAGES" |
24 | | - mapfile -t packages < <(printf '%s\n' "${packages[@]}" | sort -u) |
25 | | -
|
26 | | - candidate() { |
27 | | - local output |
28 | | - output="$(apt-cache policy "$1" 2>&1)" || { |
29 | | - echo "apt-cache policy $1 failed with exit code $?:" >&2 |
30 | | - printf '%s\n' "$output" >&2 |
31 | | - return 1 |
32 | | - } |
33 | | - awk '/Candidate:/ { print $2; exit }' <<< "$output" |
34 | | - } |
35 | | -
|
36 | | - # A runner image may ship without package lists, in which case no |
37 | | - # candidate resolves until the lists are fetched. |
38 | | - updated=false |
39 | | - resolved_packages=() |
40 | | - for package in "${packages[@]}"; do |
41 | | - version="$(candidate "$package")" || version="" |
42 | | - if [[ ( -z "$version" || "$version" == "(none)" ) && "$updated" == false ]]; then |
43 | | - sudo apt-get update |
44 | | - updated=true |
45 | | - version="$(candidate "$package")" || version="" |
46 | | - fi |
47 | | - if [[ -z "$version" || "$version" == "(none)" ]]; then |
48 | | - echo "Unable to resolve an APT candidate for $package" >&2 |
49 | | - exit 1 |
50 | | - fi |
51 | | - resolved_packages+=("$package=$version") |
52 | | - done |
53 | | -
|
54 | | - cache_key="$({ |
55 | | - printf '%s\n' "$CACHE_VERSION" |
56 | | - (. /etc/os-release; printf '%s\n' "$ID" "$VERSION_ID") |
57 | | - dpkg --print-architecture |
58 | | - printf '%s\n' "${resolved_packages[@]}" |
59 | | - } | sha256sum | cut -d' ' -f1)" |
60 | | -
|
61 | | - cache_dir="$RUNNER_TEMP/cache-apt-pkgs" |
62 | | - mkdir -p "$cache_dir" |
63 | | - printf '%s\n' "${resolved_packages[@]}" > "$cache_dir/requested-packages.txt" |
64 | | - echo "cache-dir=$cache_dir" >> "$GITHUB_OUTPUT" |
65 | | - echo "cache-key=$cache_key" >> "$GITHUB_OUTPUT" |
66 | | -
|
67 | | - - name: Restore system dependencies |
68 | | - id: cache |
69 | | - uses: actions/cache/restore@v6 |
70 | | - with: |
71 | | - path: ${{ steps.packages.outputs.cache-dir }} |
72 | | - key: cache-apt-pkgs-${{ runner.os }}-${{ steps.packages.outputs.cache-key }} |
73 | | - |
74 | | - - name: Restore cached system dependencies |
75 | | - if: steps.cache.outputs.cache-hit == 'true' |
76 | | - shell: bash |
77 | | - env: |
78 | | - CACHE_DIR: ${{ steps.packages.outputs.cache-dir }} |
79 | | - run: sudo tar -xf "$CACHE_DIR/packages.tar" -C / |
80 | | - |
81 | | - - name: Install and cache system dependencies |
82 | | - if: steps.cache.outputs.cache-hit != 'true' |
83 | | - shell: bash |
84 | | - env: |
85 | | - CACHE_DIR: ${{ steps.packages.outputs.cache-dir }} |
86 | | - run: | |
87 | | - set -euo pipefail |
88 | | -
|
89 | | - sudo apt-get update |
90 | | - mapfile -t packages < <(cut -d= -f1 "$CACHE_DIR/requested-packages.txt") |
91 | | - sudo DEBIAN_FRONTEND=noninteractive apt-get install --yes \ |
| 17 | + sudo apt-get update -qq |
| 18 | + sudo DEBIAN_FRONTEND=noninteractive apt-get install --yes -qq \ |
92 | 19 | --no-install-recommends --no-upgrade \ |
93 | | - "${packages[@]}" \ |
94 | | - | tee "$CACHE_DIR/install.log" |
95 | | -
|
96 | | - sed -nE 's/^Unpacking ([^ :]+)(:[^ ]+)? .*\(([^ )]+).*/\1\2/p' \ |
97 | | - "$CACHE_DIR/install.log" \ |
98 | | - | sort -u \ |
99 | | - > "$CACHE_DIR/installed-packages.txt" |
100 | | -
|
101 | | - if [[ -s "$CACHE_DIR/installed-packages.txt" ]]; then |
102 | | - while IFS= read -r package; do |
103 | | - dpkg-query --listfiles "$package" |
104 | | - done < "$CACHE_DIR/installed-packages.txt" \ |
105 | | - | sort -u \ |
106 | | - | while IFS= read -r path; do |
107 | | - if [[ -f "$path" || -L "$path" ]]; then |
108 | | - printf '%s\n' "${path#/}" |
109 | | - fi |
110 | | - done \ |
111 | | - | sudo tar -cf "$CACHE_DIR/packages.tar" -C / -T - |
112 | | - else |
113 | | - # A newer runner image may already contain every requested package. |
114 | | - sudo tar -cf "$CACHE_DIR/packages.tar" -T /dev/null |
115 | | - fi |
116 | | -
|
117 | | - - name: Save system dependencies |
118 | | - if: steps.cache.outputs.cache-hit != 'true' |
119 | | - uses: actions/cache/save@v6 |
120 | | - with: |
121 | | - path: ${{ steps.packages.outputs.cache-dir }} |
122 | | - key: ${{ steps.cache.outputs.cache-primary-key }} |
123 | | - |
124 | | - - name: Clean up system dependency cache |
125 | | - if: always() |
126 | | - shell: bash |
127 | | - env: |
128 | | - CACHE_DIR: ${{ steps.packages.outputs.cache-dir }} |
129 | | - run: rm -rf "$CACHE_DIR" |
| 20 | + bubblewrap musl-tools rsync cmake |
0 commit comments