-
Notifications
You must be signed in to change notification settings - Fork 0
182 lines (158 loc) · 5.98 KB
/
ci.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
name: ci
on:
push:
branches:
- main
tags:
- '*'
pull_request:
workflow_dispatch:
schedule:
- cron: '0 0 * * 2'
## We specify a concurrency group with automated cancellation. This means that
## other pushes on the same `github.ref` (eg. other pushes to the same pull
## request) cancel previous occurrences of the CI.
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
## Our CI consists in two kind of jobs: the `docker-based` ones and the
## `github-hosted` ones. Both come with their upsides and downsides.
##
## - `docker-based` jobs rely on the `ocaml/opam` Docker images [1]. These come
## with a variety of tags allowing to selected between various versions of
## OCaml and, more importantly for us, between various OSs (several Linux
## distributions as well as some Windows images). However, OPAM's sandboxing
## mechanism, based on `bubblewrap` [2], does not behave well in Docker and it
## is unavailable in those images [3].
##
## - `github-hosted` jobs rely on the default GitHub Actions runners and the
## `ocaml/setup-ocaml` action [4]. This offers more limited OSes (limited to
## Ubuntu, Windows and macOS) but it is compatible with OPAM's sandboxing
## mechanism.
##
## We need to test that our package behaves well with the OPAM sandboxing
## because Cargo does use network to build by default, which will not be
## available in the sandbox, and which we therefore need to catch in CI.
## Therefore, we need to include these `github-hosted` jobs.
##
## However, we also want to test that our package installs fine on a variety of
## distributions because it depends heavily on detecting external dependencies
## (namely Cargo and Rustc) and installing them correctly. Therefore, we also
## need to include these `docker-based` jobs.
##
## [1]: https://hub.docker.com/r/ocaml/opam
## [2]: https://github.com/containers/bubblewrap
## [3]: https://github.com/ocurrent/docker-base-images/issues/229
## [4]: https://github.com/ocaml/setup-ocaml
jobs:
github-hosted:
name: github-hosted
strategy:
fail-fast: false
matrix:
include:
- {os: ubuntu}
- {os: windows, ef: expected-failure}
- {os: macos}
runs-on: ${{ matrix.os }}-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
submodules: true
## Set up OCaml, pin Topiay and install its system dependencies.
- name: Set-up OCaml 4.14
uses: ocaml/setup-ocaml@v2
with:
ocaml-compiler: 4.14.x
opam-pin: true ## this is the default; set here explicitly
opam-depext: true ## this is the default; set here explicitly
- name: Install Topiary
id: install-topiary
## `continue-on-error` will make this step succeed no matter what. The
## next step will then handle the outcome of this step manually. This is
## what allows us to emulate an expected CI failure.
continue-on-error: true
run: |
## Install Topiary then report where it is and in which version.
echo '::group::Install Topiary'
opam install topiary
echo '::endgroup::'
echo '::group::Where is Topiary and in which version?'
printf 'Topiary is: '
opam exec -- sh -c 'command -v topiary'
printf 'in version: '
opam exec -- topiary --version
echo '::endgroup::'
- name: Check the outcome of the build
uses: ./.github/actions/expected-failure
with:
step-outcome: ${{ steps.install-topiary.outcome }}
expected-failure: ${{ matrix.ef }}
- name: Run tests
if: steps.install-topiary.outcome == 'success'
uses: ./.github/actions/run-tests
with:
topiary: opam exec -- topiary
samples: topiary/topiary/tests/samples
docker-based:
name: docker-based
strategy:
fail-fast: false
matrix:
include:
- {tag: alpine}
- {tag: archlinux}
- {tag: centos, ef: expected-failure}
- {tag: debian, ef: expected-failure}
- {tag: debian-testing}
- {tag: debian-unstable}
- {tag: fedora}
- {tag: oraclelinux}
- {tag: opensuse, ef: expected-failure}
- {tag: opensuse-tumbleweed}
- {tag: ubuntu}
- {tag: ubuntu-lts}
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
submodules: true
- name: Build Docker image (see next step for failure)
id: build-docker-image
## `continue-on-error` will make this step succeed no matter what. The
## next step will then handle the outcome of this step manually. This is
## what allows us to emulate an expected CI failure.
continue-on-error: true
run: |
docker build \
. \
--tag topiary \
--file .github/workflows/ci.dockerfile \
--build-arg tag=${{matrix.tag}}
- name: Check the outcome of the build
uses: ./.github/actions/expected-failure
with:
step-outcome: ${{ steps.build-docker-image.outcome }}
expected-failure: ${{ matrix.ef }}
- name: Run tests
if: steps.build-docker-image.outcome == 'success'
uses: ./.github/actions/run-tests
with:
topiary: docker run --interactive topiary
samples: topiary/topiary/tests/samples
flake-checks:
name: flake-checks
runs-on: ubuntu-latest
steps:
- name: Check out repository code.
uses: actions/checkout@v4
- name: Install Nix
uses: cachix/install-nix-action@v25
with:
extra_nix_config: |
## Access token to avoid triggering GitHub's rate limiting.
access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}
- name: Run flake checks
run: nix flake check --print-build-logs