Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/coq-community/docker-coq-action
GitHub Action using Docker-Coq [maintainers=@erikmd,@Zimmi48]
https://github.com/coq-community/docker-coq-action
action container-ci continuous-integration coq docker-coq docker-coq-action github-actions opam
Last synced: 3 months ago
JSON representation
GitHub Action using Docker-Coq [maintainers=@erikmd,@Zimmi48]
- Host: GitHub
- URL: https://github.com/coq-community/docker-coq-action
- Owner: coq-community
- License: mit
- Created: 2020-03-25T18:07:29.000Z (almost 5 years ago)
- Default Branch: master
- Last Pushed: 2024-07-14T21:50:15.000Z (6 months ago)
- Last Synced: 2024-09-30T20:52:24.259Z (4 months ago)
- Topics: action, container-ci, continuous-integration, coq, docker-coq, docker-coq-action, github-actions, opam
- Language: Shell
- Homepage:
- Size: 268 KB
- Stars: 12
- Watchers: 4
- Forks: 4
- Open Issues: 21
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# Docker-Coq GitHub Action
[![reviewdog][reviewdog-badge]][reviewdog-link]
[![Docker-Coq CI][docker-coq-ci-badge]][docker-coq-ci-link]
[![Docker-based CI][python-ci-badge]][python-ci-link]
[![Regression Test][rt-ci-badge]][rt-ci-link]
[![coqorg][coqorg-shield]][coqorg-link]
[![mathcomp][mathcomp-shield]][mathcomp-link]
[![Example][example-shield]][example-link]
[![Contributing][contributing-shield]][contributing-link]
[![Code of Conduct][conduct-shield]][conduct-link][reviewdog-badge]: https://github.com/coq-community/docker-coq-action/actions/workflows/reviewdog.yml/badge.svg?branch=master
[docker-coq-ci-badge]: https://github.com/coq-community/docker-coq-action/actions/workflows/coq-demo.yml/badge.svg?branch=master
[python-ci-badge]: https://github.com/coq-community/docker-coq-action/actions/workflows/python-demo.yml/badge.svg?branch=master
[rt-ci-badge]: https://github.com/coq-community/docker-coq-action/actions/workflows/gha-rt.yml/badge.svg?branch=master
[reviewdog-link]:https://github.com/coq-community/docker-coq-action/actions/workflows/reviewdog.yml
[docker-coq-ci-link]:https://github.com/coq-community/docker-coq-action/actions/workflows/coq-demo.yml
[python-ci-link]:https://github.com/coq-community/docker-coq-action/actions/workflows/python-demo.yml
[rt-ci-link]:https://github.com/coq-community/docker-coq-action/actions/workflows/gha-rt.yml[coqorg-shield]: https://img.shields.io/badge/depends%20on-coqorg%2Fcoq-blue.svg
[coqorg-link]: https://hub.docker.com/r/coqorg/coq[mathcomp-shield]: https://img.shields.io/badge/see%20also-mathcomp%2Fmathcomp-blue.svg
[mathcomp-link]: https://hub.docker.com/r/mathcomp/mathcomp[example-shield]: https://img.shields.io/badge/see%20also-example-brightgreen.svg
[example-link]: https://github.com/erikmd/docker-coq-github-action-demo[contributing-shield]: https://img.shields.io/badge/contributions-welcome-%23f7931e.svg
[contributing-link]: https://github.com/coq-community/manifesto/blob/master/CONTRIBUTING.md[conduct-shield]: https://img.shields.io/badge/%E2%9D%A4-code%20of%20conduct-%23f15a24.svg
[conduct-link]: https://github.com/coq-community/manifesto/blob/master/CODE_OF_CONDUCT.mdThis is a GitHub Action that uses (by default)
[coqorg/coq](https://hub.docker.com/r/coqorg/coq/) Docker images,
which in turn is based on [coqorg/base](https://hub.docker.com/r/coqorg/base/),
a Docker image with a Debian environment.| | GitHub repo | Type | Docker Hub |
|---|-------------------------------------------------------------------------|---------------|--------------------------------------------------------|
| ⊙ | [docker-coq-action](https://github.com/coq-community/docker-coq-action) | GitHub Action | N/A |
| ↳ | [docker-coq](https://github.com/coq-community/docker-coq) | Dockerfile | [`coqorg/coq`](https://hub.docker.com/r/coqorg/coq/) |
| ↳ | [docker-base](https://github.com/coq-community/docker-base) | Dockerfile | [`coqorg/base`](https://hub.docker.com/r/coqorg/base/) |
| ↳ | Debian | Linux distro | [`debian`](https://hub.docker.com/_/debian/) |For more details about these images, see the
[docker-coq wiki](https://github.com/coq-community/docker-coq/wiki).## OPAM
The `docker-coq-action` provides built-in support for `opam` builds.
`coq` is built on-top of `ocaml` and so `coq` projects use `ocaml`'s
package manager (`opam`) to build themselves.
This GitHub Action supports `opam` out of the box.
If your project does not already have a `coq-….opam` file, you might
generate one such file by using the corresponding template gathered in
[coq-community/templates](https://github.com/coq-community/templates#readme).This `.opam` file can then serve as a basis for submitting releases in
[coq/opam-coq-archive](https://github.com/coq/opam-coq-archive), and
related guidelines (including the required **`.opam` metadata**) are
available in .More details can be found in the
[opam documentation](https://opam.ocaml.org/doc/Packaging.html#The-file-format-in-more-detail).Assuming the Git repository contains a `folder/coq-proj.opam` file,
it will run (by default) the following commands:```bash
opam config list; opam repo list; opam list
sudo apt-get update -y -q
opam pin add -n -y -k path coq-proj folder
opam update -y
opam install --confirm-level=unsafe-yes -j 2 coq-proj --deps-only
opam list
opam install -y -v -j 2 coq-proj
opam list
opam remove -y coq-proj
```The `apt-get` command and the `--confirm-level=unsafe-yes` opam option
are necessary for automatic installation of system packages
that may be required by `coq-proj.opam`, as described in the
[opam 2.1 release notes](https://opam.ocaml.org/blog/opam-2-1-0/#Seamless-integration-of-System-dependencies-handling-a-k-a-quot-depexts-quot).## Using the GitHub Action
Using a [GitHub Action](https://docs.github.com/en/actions)
in your GitHub repository amounts to committing a file `.github/workflows/your-workflow-name.yml`,
e.g. `.github/workflows/build.yml`, containing (among others), a snippet such as:```yaml
runs-on: ubuntu-latest # container actions require GNU/Linux
strategy:
matrix:
coq_version:
- '8.16'
- dev
ocaml_version: ['default']
fail-fast: false # don't stop jobs if one fails
steps:
- uses: actions/checkout@v3
- uses: coq-community/docker-coq-action@v1
with:
opam_file: 'folder/coq-proj.opam'
coq_version: ${{ matrix.coq_version }}
ocaml_version: ${{ matrix.ocaml_version }}
```Each field can be customized, see below
for the documentation of those specific to the docker-coq-action,
or the GitHub Actions official documentation for the
[standard fields involved in workflows](https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions).### References
For details, see also:
* the [action.yml](./action.yml) file (containing the metadata processed by the GitHub Actions platform itself, as well as some comments, albeit more terse than the [documentation below](#inputs));
* the accompanying [`coq-demo` example repo](https://github.com/erikmd/docker-coq-github-action-demo);
* the two workflows [coq-demo.yml](./.github/workflows/coq-demo.yml) and [python-demo.yml](./.github/workflows/python-demo.yml) that both serve as `docker-coq-action`'s CI test-suite and provide some examples of use.### Versioning
The Git repo of `docker-coq-action` uses `master` as developing branch
and `v1` as release branch; and the corresponding tags `v1.x.y` follow
[semantic versioning](https://semver.org/).We develop `docker-coq-action` with a special focus on backward
compatibility, so that if your workflow just uses
**`coq-community/docker-coq-action@v1`**, you will be able to benefit
from new features, while expecting no breaking change.However, we recall that the version of any GitHub Action can just as
well be [referenced by a tag or a commit SHA](https://docs.github.com/en/actions/learn-github-actions/finding-and-customizing-actions#using-release-management-for-your-custom-actions).Contrary to some custom practice of GitHub Actions maintainers, we do not change to which commit a tag points once it is published.
As a result, the latest stable version denoted by the short Git reference `v1` is implemented as a *release branch*, not as a tag.
Anyway, if you do not trust the maintainers of a given GitHub Action, it is always safer to reference a *commit SHA*.### Inputs
#### `opam_file`
*Optional*
The path of the `.opam` file (or a directory), relative to the repo root.
Default: `"."` (if the argument is omitted or an empty string).
*Note-1:* relying on the value of this `INPUT_OPAM_FILE` variable, the
following two variables are exported when running the `custom_script`:```bash
if [ -z "$INPUT_OPAM_FILE" ] || [ -d "$INPUT_OPAM_FILE" ]; then
WORKDIR=""
PACKAGE=${INPUT_OPAM_FILE:-.}
else
WORKDIR=$(dirname "$INPUT_OPAM_FILE")
PACKAGE=$(basename "$INPUT_OPAM_FILE" .opam)
fi
```*Note-2:* if this value is a directory (e.g., `.`), relying on the
[`custom_script` default value](#custom_script), the action will
install all the `*.opam` packages stored in this directory.#### `coq_version`
*Optional*
The version of Coq. E.g., `"8.10"`.
Default: `"latest"` (= latest stable version).
Append the `-native` suffix if the version is `>= 8.13` (or `dev`)
*and* you are interested in the image that contains the
[`coq-native`](https://opam.ocaml.org/packages/coq-native/) package.
E.g., `"8.13-native"`, `"latest-native"`, `"dev-native"`.If the `coq_version` value contains the `-native` suffix,
the `ocaml_version` value is ignored (as `coq-native` images only come with a single OCaml version).
Still, a warning is raised if `ocaml_version` is nonempty and different from `"default"`.#### `ocaml_version`
*Optional*
The version of OCaml.
Default: `"default"` (= Docker-Coq's default OCaml version for the given Coq version).
Among `"default"`, `"4.02"`, `"4.05"`, `"4.07-flambda"`, `"4.08-flambda"`, `"4.09-flambda"`, `"4.10-flambda"`, `"4.11-flambda"`, `"4.12-flambda"`, `"4.13-flambda"`, `"4.14-flambda"`…
**Warning!** not all OCaml versions are available with all Coq versions.
The supported compilers w.r.t. each version of Coq are documented in the
[OCaml-versions policy](https://github.com/coq-community/docker-coq/wiki#ocaml-versions-policy) section of the `docker-coq` wiki.#### `before_install`
*Optional*
The bash snippet to run before `install`
Default:
```bash
startGroup "Print opam config"
opam config list; opam repo list; opam list
endGroup
```See [`custom_script`](#custom_script) and [startGroup/endGroup](#startGroupendGroup) for more details.
#### `install`
*Optional*
The bash snippet to install the `opam` `PACKAGE` dependencies.
Default:
```bash
startGroup "Install dependencies"
sudo apt-get update -y -q
opam pin add -n -y -k path $PACKAGE $WORKDIR
opam update -y
opam install --confirm-level=unsafe-yes -j 2 $PACKAGE --deps-only
endGroup
```where `$PACKAGE` and `$WORKDIR` are set from the [`opam_file`](#opam_file) variable.
See [`custom_script`](#custom_script) and [startGroup/endGroup](#startGroupendGroup) for more details.
#### `after_install`
*Optional*
The bash snippet to run after `install` (if successful).
Default:
```bash
startGroup "List installed packages"
opam list
endGroup
```See [`custom_script`](#custom_script) and [startGroup/endGroup](#startGroupendGroup) for more details.
#### `before_script`
*Optional*
The bash snippet to run before `script`.
Default: `""` (empty string).
See [`custom_script`](#custom_script) and [startGroup/endGroup](#startGroupendGroup) for more details.
#### `script`
*Optional*
The bash snippet to install the `opam` `PACKAGE`.
Default:
```bash
startGroup "Build"
opam install -y -v -j 2 $PACKAGE
opam list
endGroup
```where `$PACKAGE` is set from the [`opam_file`](#opam_file) variable.
See [`custom_script`](#custom_script) and [startGroup/endGroup](#startGroupendGroup) for more details.
#### `after_script`
*Optional*
The bash snippet to run after `script` (if successful).
Default: `""` (empty string).
See [`custom_script`](#custom_script) and [startGroup/endGroup](#startGroupendGroup) for more details.
#### `uninstall`
*Optional*
The bash snippet to uninstall the `opam` `PACKAGE`.
Default:
```bash
startGroup "Uninstallation test"
opam remove -y $PACKAGE
endGroup
```where `$PACKAGE` is set from the [`opam_file`](#opam_file) variable.
See [`custom_script`](#custom_script) and [startGroup/endGroup](#startGroupendGroup) for more details.
#### `custom_script`
*Optional*
The main script run in the container; may be overridden; but overriding more specific parts of the script is preferred.
Default:
```
{{before_install}}
{{install}}
{{after_install}}
{{before_script}}
{{script}}
{{after_script}}
{{uninstall}}
```*Note-1:* the semantics of this variable is a *standard Bash script*,
that is evaluated within the workflow container after replacing the
"mustache" placeholders with the value of their variable counterpart.
For example, `{{uninstall}}` will be replaced with the value of the
[`uninstall`](#uninstall) variable (the default value of which being
the string `opam remove -y $PACKAGE`).*Note-2:* this option is named `custom_script` rather than `run` or so
to **discourage changing its recommended, default value** for building
a regular `opam` project, while keeping the flexibility to be able to
change it.*Note-3:* if you decide to override the `custom_script` value anyway,
you can just as well rely on the "mustache interpolation" of
`{{before_install}}` … `{{uninstall}}`, and customize the underlying
values.#### `custom_image`
*Optional*
The name of the Docker image to pull.
Default: unset
If this variable is unset, its value is computed from the values of
keywords `coq_version` and `ocaml_version`.If you use the standard
[`docker-coq`](https://github.com/coq-community/docker-coq) images, we
recommend to directly use keywords `coq_version` and `ocaml_version`.If you use another registry such as that of
[`docker-mathcomp`](https://github.com/math-comp/docker-mathcomp)
images, you can benefit from that keyword by writing a configuration
such as:```yaml
runs-on: ubuntu-latest
strategy:
matrix:
image:
- mathcomp/mathcomp:1.10.0-coq-8.10
- mathcomp/mathcomp:1.10.0-coq-8.11
- mathcomp/mathcomp:1.11.0-coq-dev
- mathcomp/mathcomp-dev:coq-dev
fail-fast: false # don't stop jobs if one fails
steps:
- uses: actions/checkout@v4
- uses: coq-community/docker-coq-action@v1
with:
opam_file: 'folder/coq-proj.opam'
custom_image: ${{ matrix.image }}
```If ever you want to retrieve the Docker image name within the CI script, you can
use the [`export`](#export) keyword to expose the `COQ_IMAGE` internal variable.#### `export`
*Optional*
A space-separated list of `env` variables to export to the `custom_script`.
Default: `""`, i.e., no additional variable is exported.
*Note-1:* The values of the variables to export may be defined by using the
[`env`](https://docs.github.com/en/actions/reference/environment-variables)
keyword.*Note-2:* Regarding the naming of these variables:
* Only use ASCII letters, `_` and digits, i.e., matching the `[a-zA-Z_][a-zA-Z0-9_]*` regexp.
* Avoid [reserved identifiers](https://docs.github.com/en/actions/reference/environment-variables#default-environment-variables) (namely: `HOME`, `CI`, and strings starting with `GITHUB_`, `ACTIONS_`, `RUNNER_`, or `INPUT_`).
* The `docker-coq-action` internally sets a `COQ_IMAGE` environment variable that contains the full name of the Docker image used. Use `export: 'COQ_IMAGE'` to make this variable available within the [script](#custom_script).Here is a minimal working example of this feature:
```yaml
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: coq-community/docker-coq-action@v1
with:
opam_file: 'folder/coq-proj.opam'
coq_version: 'dev'
ocaml_version: 'default'
export: 'OPAMWITHTEST' # space-separated list of variables
env:
OPAMWITHTEST: 'true'
```Here, setting the [`OPAMWITHTEST`](https://opam.ocaml.org/doc/man/opam-install.html#lbAG)
environment variable is useful to run the unit tests
(specified using `opam`'s [`with-test`](https://opam.ocaml.org/doc/Manual.html#pkgvar-with-test)
clause) after the package build.## Remarks
### startGroup/endGroup
The default value of fields `{{before_install}}`, `{{install}}`,
`{{after_install}}`, `{{script}}`, and `{{uninstall}}` involves the bash
functions `startGroup` (taking 1 argument: `startGroup "Group title"`)
and `endGroup`.These bash functions are defined in [timegroup.sh](./timegroup.sh) and have the following features:
* they create foldable groups in the GitHub Actions logs
(see the [online doc](https://github.com/actions/toolkit/blob/master/docs/commands.md#group-and-ungroup-log-lines)),
* and they compute the elapsed time for the considered group;
* these groups cannot be nested,
* and if an `endGroup` has been forgotten, it is implicitly and
automatically inserted at the next `startGroup` (albeit it is better
to make each `endGroup` explicit, for readability).Here is an example of script along with the output log so obtained:
```bash
ex_var="ex_value"
# […]startGroup "Toy example"
echo "ex_var=$ex_var"
endGroup
```* Folded version:
[![folded group](./images/2021-08-11_ex_log_folded.png)](./images/2021-08-11_ex_log_folded.png)
* Unfolded version:
[![unfolded group](./images/2021-08-11_ex_log_unfolded.png)](./images/2021-08-11_ex_log_unfolded.png)
### Pitfall: do not use `&&`; use semicolons
Beware that the following script is *buggy*:
```yaml
script: |
startGroup "Build project"
make -j2 && make test && make install
endGroup
```Because if `make test` fails, it won't make the CI fail.
(Explanation)
This is a typical pitfall that occur *in any shell-based CI platform*
where the [`set -e`](
https://manpages.ubuntu.com/manpages/hirsute/en/man1/set.1posix.html#description)
option is implied: the early-exit associated to this option is
disabled if the failing command is followed by `&&` or `||`.See e.g., the output of the following three commands:
```bash
bash -c 'set -e; false && true; echo $?; echo this should not be run'
# → 1
# → this should not be runbash -c 'set -e; false; true; echo $?; echo this should not be run'
# (no output)bash -c 'set -e; ( false && true ); echo $?; echo this should not be run'
# (no output)
```Instead, you should write one of the following variants:
* using semicolons:
```yaml
script: |
startGroup "Build project"
make -j2 ; make test ; make install
endGroup
```* using newlines:
```yaml
script: |
startGroup "Build project"
make -j2
make test
make install
endGroup
```* using `&&` but within a subshell:
```yaml
script: |
startGroup "Build project"
( make -j2 && make test && make install )
endGroup
```### Permissions
If you use the
[`docker-coq`](https://github.com/coq-community/docker-coq) images,
the container user has UID=GID=1000 while the GitHub Actions workdir
has (UID=1001, GID=116).
This is not an issue when relying on `opam` to build the Coq project.
Otherwise, you may want to use `sudo` in the container to change the
permissions. You may also install additional Debian packages
(see the [dedicated section below](#install-debian-packages)).Typically, this would lead to a workflow specification like this:
```yaml
runs-on: ubuntu-latest
strategy:
matrix:
image:
- 'coqorg/coq:dev'
fail-fast: false # don't stop jobs if one fails
steps:
- uses: actions/checkout@v4
- uses: coq-community/docker-coq-action@v1
with:
opam_file: 'folder/coq-proj.opam'
custom_image: ${{ matrix.image }}
before_script: |
startGroup "Workaround permission issue"
sudo chown -R coq:coq . # <--
endGroup
script: |
startGroup "Build project"
make -j2
endGroup
uninstall: |
startGroup "Clean project"
make clean
endGroup
- name: Revert permissions
# to avoid a warning at cleanup time
if: ${{ always() }}
run: sudo chown -R 1001:116 . # <--
```For more details, see the
[CI setup / Remarks](https://github.com/coq-community/docker-coq/wiki/CI-setup#remarks)
section in the `docker-coq` wiki.### Artifacts
The `docker-coq-action` and its "child" Docker image (specified by the
[`custom_image`](#custom_image) field) run inside a container, which
implies the associated filesystem is isolated from the runner.However, the GitHub workspace directory is made available in the
container (using a so-called bind-mount) and set as the current
working directory.As a result:
* all the files installed outside of this GitHub workspace directory
(such as `opam` packages installed in `/home/coq/.opam`) are "lost"
when `docker-coq-action` terminates;
* all the files put in the GitHub workspace directory (or in a
sub-directory) are kept;
so it is possible to create artifacts, then use an action such as
[`actions/upload-artifact@v4`](https://github.com/actions/upload-artifact)
in a subsequent step.Here is an example job for this use case, which also takes into
account the previously-mentioned [permissions workaround](#permissions):```yaml
runs-on: ubuntu-latest
strategy:
matrix:
image:
- 'coqorg/coq:dev'
fail-fast: false # don't stop jobs if one fails
steps:
- uses: coq-community/docker-coq-action@v1
with:
opam_file: 'folder/coq-proj.opam'
custom_image: ${{ matrix.image }}
before_script: |
startGroup "Workaround permission issue"
sudo chown -R coq:coq .
endGroup
script: |
startGroup "Build project"
coq_makefile -f _CoqProject -o Makefile
make -j2
endGroup
after_script: |
set -o pipefail # recommended if the script uses pipesstartGroup "Build artifacts"
mkdir -v -p artifacts
opam list > artifacts/opam_list.txt
make test 2>&1 | tee artifacts/make_test.txt
endGroup
uninstall: ''
- name: Revert permissions
# to avoid a warning at cleanup time
if: ${{ always() }}
run: sudo chown -R 1001:116 .
- uses: actions/upload-artifact@v4
with:
name: example-artifact
path: artifacts/
if-no-files-found: error # 'warn' or 'ignore' are also available, defaults to `warn`
retention-days: 8
```### GitHub Actions environment files
Recall that `docker-coq-action` runs your CI script in a Docker container,
the filesystem of which being isolated from the GitHub runner.Still, `docker-coq-action` bind-mounts some special paths for
[GitHub Actions environment files](https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#environment-files),
so that `"$GITHUB_ENV"`, `"$GITHUB_OUTPUT"`, and `"$GITHUB_STEP_SUMMARY"` can be used
in (parts of) the [`custom_script`](#custom_script) in order to pass environment
variables or step outputs to the following steps, or set a Markdown summary.Conversely, the [`export`](#export) keyword can be used to pass variables
from the previous step to `docker-coq-action`.Here is an example of script that uses `GITHUB_ENV` and `GITHUB_OUTPUT`:
```yaml
runs-on: ubuntu-latest
strategy:
matrix:
image:
- 'coqorg/coq:latest'
fail-fast: false # don't stop jobs if one fails
steps:
- uses: actions/checkout@v4
- uses: coq-community/docker-coq-action@v1
id: docker-coq-action # needed to get step outputs
with:
opam_file: 'folder/coq-proj.opam'
custom_image: ${{ matrix.image }}
after_script: |
# Pass values to upcoming steps in two different ways
echo "coq_version_var=$(opam var coq:version)" >> "$GITHUB_ENV"
echo "coq_version_out=$(opam var coq:version)" >> "$GITHUB_OUTPUT"
- name: Next step
env:
coq_version_var2: ${{ steps.docker-coq-action.outputs.coq_version_out }}
run: |
: Summary
echo "Previous step used: coq_version=$coq_version_var"
echo "Previous step used: coq_version=$coq_version_var2 (same)"
```### Install Debian packages
If you use `docker-coq-action` with a
[Docker-Coq](https://github.com/coq-community/docker-coq) image (the
default when the [`custom_image`](#custom_image) field is omitted),
the image is based on Debian stable and the container user
(UID=GID=1000) has `sudo` rights, so you can rely on `apt-get` to
install additional Debian packages.This use case is illustrated by the following job that installs
the `emacs` and `tree` packages:```yaml
runs-on: ubuntu-latest
strategy:
matrix:
image:
- 'coqorg/coq:dev'
fail-fast: false # don't stop jobs if one fails
steps:
- uses: actions/checkout@v4
- uses: coq-community/docker-coq-action@v1
with:
opam_file: 'folder/coq-proj.opam'
custom_image: ${{ matrix.image }}
before_script: |
startGroup "Install APT dependencies"
cat /etc/os-release # Print the Debian OS version
# sudo apt-get update -y -q # this mandatory command is already run in install step by default
sudo DEBIAN_FRONTEND=noninteractive apt-get install -y -q --no-install-recommends \
emacs \
tree # for instance
# Alphabetical order is recommended for long package lists to ease review and update
endGroup
after_script: |
startGroup "Post-test"
emacs --version
tree
endGroup
```### Verbose output and Variable leaking
The code run in the `docker-coq-action` container relies on the
following invocation to display a customized prompt before each
command:```bash
export PS4='+ \e[33;1m($0 @ line $LINENO) \$\e[0m '; set -ex
```As a result, due to the `set -x` option, the value of each variable is
exposed in the log.For example, the script:
```bash
startGroup "Risky example"
TOKEN=$(uuidgen -r)
curl -fsS -X POST -F token="$TOKEN" https://example.com >/dev/null
endGroup
```will produce a log such as:
[![verbose log](./images/2021-08-11_too_verbose_log.png)](./images/2021-08-11_too_verbose_log.png)
Hence the following two remarks:
1. If need be, it is possible to temporarily disable the trace feature
in your script, surrounding the lines at stake by (`set +x`, `set -x`).
Your script would thus look like:```bash
set +x#...some code with no trace...
set -x
```or, to get some even less verbose output:
```bash
{ set +x; } 2>/dev/null#...some code with no trace...
set -x
```2. Fortunately, this trace feature cannot make repository secrets
`${{ secrets.STH }}` leak, as
[GitHub Actions automatically redact them in the log](https://docs.github.com/en/actions/reference/encrypted-secrets#accessing-your-secrets).
Regarding secrets obtained by other means, e.g. from a command-line
program, it is recommended to perform the three actions below **in a
previous `run:` step**:* store the "locally-created secret" in an environment variable:
```bash
SOME_TOKEN="..."
```* immediately [mark the variable as masked](https://docs.github.com/en/actions/reference/workflow-commands-for-github-actions#masking-a-value-in-log):
```bash
echo "::add-mask::$SOME_TOKEN"
```* register the variable to [make it available for subsequent steps](https://docs.github.com/en/actions/reference/workflow-commands-for-github-actions#setting-an-environment-variable):
```bash
printf "%s\n" "SOME_TOKEN=$(printf "%q" "$SOME_TOKEN")" >> $GITHUB_ENV
```A comprehensive example of this approach is available in PR [erikmd/docker-coq-github-action-demo#12](https://github.com/erikmd/docker-coq-github-action-demo/pull/12).
For completeness, note that masking inputs involved in `workflow_dispatch` may require some `jq`-based workaround, as mentioned in issue [actions/runner#643](https://github.com/actions/runner/issues/643).