Giter Site home page Giter Site logo

coq-community / docker-coq-action Goto Github PK

View Code? Open in Web Editor NEW
12.0 5.0 4.0 261 KB

GitHub Action using Docker-Coq [maintainers=@erikmd,@Zimmi48]

License: MIT License

Dockerfile 1.22% Shell 95.47% Makefile 3.31%
docker-coq action coq opam continuous-integration container-ci docker-coq-action github-actions

docker-coq-action's Introduction

Docker-Coq GitHub Action

reviewdog Docker-Coq CI Docker-based CI Regression Test
coqorg mathcomp Example Contributing Code of Conduct

This is a GitHub Action that uses (by default) coqorg/coq Docker images, which in turn is based on coqorg/base, a Docker image with a Debian environment.

GitHub repo Type Docker Hub
docker-coq-action GitHub Action N/A
docker-coq Dockerfile coqorg/coq
docker-base Dockerfile coqorg/base
Debian Linux distro debian

For more details about these images, see the 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.

This .opam file can then serve as a basis for submitting releases in coq/opam-coq-archive, and related guidelines (including the required .opam metadata) are available in https://coq.inria.fr/opam-packaging.html.

More details can be found in the opam documentation.

Assuming the Git repository contains a folder/coq-proj.opam file, it will run (by default) the following commands:

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.

Using the GitHub Action

Using a GitHub Action 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:

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.

References

For details, see also:

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.

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.

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:

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, 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 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 section of the docker-coq wiki.

before_install

Optional

The bash snippet to run before install

Default:

startGroup "Print opam config"
  opam config list; opam repo list; opam list
endGroup

See custom_script and startGroup/endGroup for more details.

install

Optional

The bash snippet to install the opam PACKAGE dependencies.

Default:

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 variable.

See custom_script and startGroup/endGroup for more details.

after_install

Optional

The bash snippet to run after install (if successful).

Default:

startGroup "List installed packages"
  opam list
endGroup

See custom_script and startGroup/endGroup for more details.

before_script

Optional

The bash snippet to run before script.

Default: "" (empty string).

See custom_script and startGroup/endGroup for more details.

script

Optional

The bash snippet to install the opam PACKAGE.

Default:

startGroup "Build"
  opam install -y -v -j 2 $PACKAGE
  opam list
endGroup

where $PACKAGE is set from the opam_file variable.

See custom_script and startGroup/endGroup for more details.

after_script

Optional

The bash snippet to run after script (if successful).

Default: "" (empty string).

See custom_script and startGroup/endGroup for more details.

uninstall

Optional

The bash snippet to uninstall the opam PACKAGE.

Default:

startGroup "Uninstallation test"
  opam remove -y $PACKAGE
endGroup

where $PACKAGE is set from the opam_file variable.

See custom_script and startGroup/endGroup 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 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 images, we recommend to directly use keywords coq_version and ocaml_version.

If you use another registry such as that of docker-mathcomp images, you can benefit from that keyword by writing a configuration such as:

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@v3
  - 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 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 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 (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.

Here is a minimal working example of this feature:

runs-on: ubuntu-latest
steps:
  - uses: actions/checkout@v3
  - 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 environment variable is useful to run the unit tests (specified using opam's 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 and have the following features:

  • they create foldable groups in the GitHub Actions logs (see the online doc),
  • 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:

ex_var="ex_value"
# […]

startGroup "Toy example"
  echo "ex_var=$ex_var"
endGroup
  • Folded version:

    folded group

  • Unfolded version:

    unfolded group

Pitfall: do not use &&; use semicolons

Beware that the following script is buggy:

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 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 -c 'set -e; false && true; echo $?; echo this should not be run'
# → 1
# → this should not be run

bash -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:

    script: |
      startGroup "Build project"
        make -j2 ; make test ; make install
      endGroup
  • using newlines:

    script: |
      startGroup "Build project"
        make -j2
        make test
        make install
      endGroup
  • using && but within a subshell:

    script: |
      startGroup "Build project"
        ( make -j2 && make test && make install )
      endGroup

Permissions

If you use the 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).

Typically, this would lead to a workflow specification like this:

runs-on: ubuntu-latest
strategy:
  matrix:
    image:
      - 'coqorg/coq:dev'
  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'
      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 section in the docker-coq wiki.

Artifacts

The docker-coq-action and its "child" Docker image (specified by the 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@v2 in a subsequent step.

Here is an example job for this use case, which also takes into account the previously-mentioned permissions workaround:

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 pipes

            startGroup "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@v2
        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, so that "$GITHUB_ENV", "$GITHUB_OUTPUT", and "$GITHUB_STEP_SUMMARY" can be used in (parts of) the custom_script in order to pass environment variables or step outputs to the following steps, or set a Markdown summary.

Conversely, the 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:

runs-on: ubuntu-latest
strategy:
  matrix:
    image:
      - 'coqorg/coq:latest'
  fail-fast: false  # don't stop jobs if one fails
steps:
  - uses: actions/checkout@v3
  - 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 image (the default when the 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:

runs-on: ubuntu-latest
strategy:
  matrix:
    image:
      - 'coqorg/coq:dev'
  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'
      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:

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:

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

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:

    set +x
    
    #...some code with no trace...
    
    set -x

    or, to get some even less verbose output:

    { 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.
    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:

    A comprehensive example of this approach is available in PR erikmd/docker-coq-github-action-demo#12.

    For completeness, note that masking inputs involved in workflow_dispatch may require some jq-based workaround, as mentioned in issue actions/runner#643.

docker-coq-action's People

Contributors

bruno-366 avatar erikmd avatar jasongross avatar liyishuai avatar palmskog avatar zimmi48 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

docker-coq-action's Issues

New fine-grained customization does not allow groups within each section

The new value for custom_script that includes all the sections surrounds each one with a startGroup with a generic name:

startGroup before_install dependencies
  {{before_install}}
endGroup
startGroup install dependencies
  {{install}}
endGroup
startGroup after_install dependencies
  {{after_install}}
endGroup
startGroup before_script
  {{before_script}}
endGroup
startGroup script
  {{script}}
endGroup
startGroup after_script
  {{after_script}}
endGroup
startGroup uninstall
  {{uninstall}}
endGroup

Those names are a bit annoying on their own, but worse GitHub actions doesn't seem to support nested groups so they forbid adding any user groups (unless you rewrite custom_script, of course).

`git ls-files` fails with exit code 128 during `opam install --deps-only`

Of late, I've been seeing my builds fail for the following reason:

+ (script @ line 12) $ opam install --confirm-level=unsafe-yes -j 2 . --deps-only
[368](https://github.com/artagnon/bonak/actions/runs/4838247477/jobs/8622599444#step:4:373)
  Error:  Command "/usr/bin/git ls-files" failed:
[369](https://github.com/artagnon/bonak/actions/runs/4838247477/jobs/8622599444#step:4:374)
  "/usr/bin/git ls-files" exited with code 128

I wonder if this is a permissions issue.

Task: Refine the doc for PR #27

  • Related: PR #27

Posted by @Zimmi48 in #26 (comment):

Since opam_file is now optional, this means that the most simple workflow configuration corresponds to the one I wrote in my comment above (except that we can compress the on: part even more). I think that showing such a simple (complete) configuration somewhere near the top of the README would look great (to show how simple it is to use Docker-Coq-Action for simple use cases).

can docker-coq-action share a container throughout a multiple-step job? (`container: coqorg/coq`, `actions/checkout` can't)

When running actions/checking with container: coqorg/coq:dev, I see

/usr/bin/docker exec  d2f4cc80928d9913b66a607fd95b3abc47ed3b5a78234ed06151b3bcd6260342 sh -c "cat /etc/*release | grep ^ID"
node:internal/fs/sync:78
  return binding.openSync(
                 ^

Error: EACCES: permission denied, open '/__w/_temp/_runner_file_commands/save_state_e59de318-2ebd-4430-adee-f74fc8e00eb1'
    at Object.open (node:internal/fs/sync:78:18)
    at Object.openSync (node:fs:565:17)
    at Object.writeFileSync (node:fs:2288:35)
    at Object.appendFileSync (node:fs:2350:6)
    at Object.issueFileCommand (/__w/_actions/actions/checkout/v4/dist/index.js:2967:8)
    at Object.saveState (/__w/_actions/actions/checkout/v4/dist/index.js:2884:31)
    at 8647 (/__w/_actions/actions/checkout/v4/dist/index.js:2343:10)
    at __nccwpck_require__ (/__w/_actions/actions/checkout/v4/dist/index.js:18273:43)
    at 2565 (/__w/_actions/actions/checkout/v4/dist/index.js:146:34)
    at __nccwpck_require__ (/__w/_actions/actions/checkout/v4/dist/index.js:18273:43) {
  errno: -13,
  code: 'EACCES',
  syscall: 'open',
  path: '/__w/_temp/_runner_file_commands/save_state_e59de318-2ebd-4430-adee-f74fc8e00eb1'
}

Node.js v20.8.1

How do I get this image working?

Wish: Composability with other actions

It might be nice to port fiat-crypto and coq-tools to the docker coq action.

Currently fiat-crypto uses actions/setup-haskell@v1 with ghc 8.8.1 and 3.0 (and uses my ppa for Coq versions 8.12.0, 8.11.1, 8.10.2, 8.9.1, as well as the tips of master, v8.12, v8.11, v8.10, v8.9), and coq-tools uses actions/setup-python@v1 to test python versions 2.7, 3.5, 3.6, 3.7, 3.8 with Coq versions 8.11.1, 8.10.2, 8.9.1, 8.8.2, 8.7.2, 8.6.1, 8.5pl3, and the tips of the master, v8.11, v8.10, v8.9, v8.8, v8.7, v8.6, and v8.5 branches. However, I don't think docker containers are easily composable with other actions.

before_install and matrix builds

Hi,

I followed recommendations from #22 and used before_install to add opam repositories to my build.
I build for two versions of Coq, but it seems the before_install part is considered only for the second build, not the first one.
Any idea what could go wrong?

See https://github.com/Oqarina/oqarina/blob/main/.github/workflows/main.yml
and https://github.com/Oqarina/oqarina/runs/3612797755?check_suite_focus=true

For the failed log, it is apparent it did not add any additional repository
Thanks,

CI failures using docker-coq-action cause of debian download issues

Dear docker-coq-action Team,

since today we are getting in VST CI this error about the download of the debian base image:

2022-03-07T12:52:09.9644526Z Step 1/3 : FROM samueldebruyn/debian-git@sha256:6fda212f1f62ba382143c797d771dee1f4aa505520c277195de5536f2926309f
2022-03-07T12:52:10.0776585Z pull access denied for samueldebruyn/debian-git, repository does not exist or may require 'docker login': denied: requested access to the resource is denied
2022-03-07T12:52:10.0799707Z ##[warning]Docker build failed with exit code 1, back off 5.966 seconds before retry.
2022-03-07T12:52:16.0472437Z ##[command]/usr/bin/docker build -t 29a95e:708aac7d1e4e4619be905e3066757165 -f "/home/runner/work/_actions/textbook/git-checkout-submodule-action/2.1.1/Dockerfile" "/home/runner/work/_actions/textbook/git-checkout-submodule-action/2.1.1"
2022-03-07T12:52:16.0773999Z Sending build context to Docker daemon  7.168kB

I must say I don't understand how it comes to this and where the debian image is coded. Shouldn't docker-coq-action and coq-docker depend on (https://hub.docker.com/_/debian/)?

See: PrincetonUniversity/VST#550

multiline Coq error matching?

I've been toying with a fancier way of doing problem matching by piping stderr through a script that aggregates Coq warnings and errors. In particular, it would use the following criterion to identify which chunks are warnings/errors:

  • The first line must match "^(?:-\\s+)?File \"([^ \"]+)\", line (\\d+), characters (\\d+-\\d+):"
  • The second line must match "^(?:-\\s+)?(Warning|Error):\\s*(.*?)
  • If the second line ends with something matching \\[([^]]*)\\], then the error is just a two-line error
  • The multiline error is considered to end at the first line ending with something matching \\[([^]]*)\\], unless a line matching one of the following is found first, in which case we assume that the matching has gone wrong and treat only the first two lines specially:
    • We encounter another line which matches the first-line pattern for errors/warnings
    • We encounter a line matching "^(?:-\\s+)?(COQC|OCAMLC|OCAMLOPT|COQDEP) .*" (new build file, presumably we missed the end of the error)
    • We encounter a line matching "^(?:-\\s+)?[^\\s]+ \\(real: [0-9\\.]*, user: [0-9\\.]*, sys: [0-9\\.]*, mem: [0-9]* ko)" (output of make TIMED=1, we probably missed the end of the warning/error)
    • We encounter a line matching "^(?:-\\s+)?make(?:\\[[0-9]+\\]):" (we ended up back in make output)

Would the docker coq action be interested in using such a script? (via something like 2> >(./process_coq_errors_to_annotations.sh >&2), or perhaps via { normal_cmd.sh 3>&1 1>&2 2>&3 3>&- | ./process_coq_errors_to_annotations.sh; } 3>&1 1>&2 2>&3 3>&- or similar, based on https://stackoverflow.com/a/3618308/377022 and the note at https://stackoverflow.com/questions/3618078/pipe-only-stderr-through-a-filter/52575213#comment105555334_52575087 that the system may kill the substituted process before it completes, once the main process exits)

Issue: latest release `v1.1.0` is not yet in the GitHub Actions marketplace

Hi @Zimmi48, I re-checked the page https://github.com/marketplace/actions/docker-coq-action and the latest release is not there, so I opened https://github.com/coq-community/docker-coq-action/releases/edit/v1.1.0 and I see:

  • Publish this release to the GitHub Marketplace
    coq-community must accept the GitHub Marketplace Developer Agreement. Contact an org admin to accept it.

can you see if you have the rights to check that box?

Permission issues might be better solved with `sudo chmod -R a=u .`

I had some issues with permissions and artifact upload. I found that sudo chmod -R a=u . - which copies all permissions from user to group and other - works better for me than the recommended sudo chown -R coq:coq . (See ReadMe). It also has the advantage that one doesn't need to undo it later.

I would consider changing the documentation here.

export: COQ_IMAGE is ignored

Why is there no -e COQ_IMAGE despite me listing export: COQ_IMAGE?
https://github.com/mit-plv/fiat-crypto/actions/runs/9028790464/job/24809895511#step:19:44

Run coq-community/docker-coq-action@v1
  with:
    coq_version: dev
    ocaml_version: default
    export: CI ALLOW_DIFF COQCHKEXTRAFLAGS GITHUB_STEP_SUMMARY COQ_IMAGE
    custom_script: printf "'%s'\n" "${COQ_IMAGE}"
  printf "%s" "${COQ_IMAGE}" > .coqimage
  
    opam_file: .
    before_install: startGroup "Print opam config"
    opam config list; opam repo list; opam list
  endGroup
  
    install: 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
  
    after_install: startGroup "List installed packages"
    opam list
  endGroup
  
    script: startGroup "Build"
    opam install -y -v -j 2 $PACKAGE
    opam list
  endGroup
  
    uninstall: startGroup "Uninstallation test"
    opam remove -y $PACKAGE
  endGroup
  
  env:
    COQ_VERSION: master
    DOCKER_COQ_VERSION: dev
    DOCKER_OCAML_VERSION: default
    SKIP_VALIDATE: 
    COQCHKEXTRAFLAGS: -bytecode-compiler yes
    EXTRA_GH_REPORTIFY: --warnings
    ALLOW_DIFF: 1
    CI: 1
/usr/bin/docker run --name e39f5008ac7d946e449e1981db514cb3a30c6_940f15 --label 3e39f5 --workdir /github/workspace --rm -e "COQ_VERSION" -e "DOCKER_COQ_VERSION" -e "DOCKER_OCAML_VERSION" -e "SKIP_VALIDATE" -e "COQCHKEXTRAFLAGS" -e "EXTRA_GH_REPORTIFY" -e "ALLOW_DIFF" -e "CI" -e "INPUT_COQ_VERSION" -e "INPUT_OCAML_VERSION" -e "INPUT_EXPORT" -e "INPUT_CUSTOM_SCRIPT" -e "INPUT_OPAM_FILE" -e "INPUT_BEFORE_INSTALL" -e "INPUT_INSTALL" -e "INPUT_AFTER_INSTALL" -e "INPUT_BEFORE_SCRIPT" -e "INPUT_SCRIPT" -e "INPUT_AFTER_SCRIPT" -e "INPUT_UNINSTALL" -e "INPUT_CUSTOM_IMAGE" -e "HOME" -e "GITHUB_JOB" -e "GITHUB_REF" -e "GITHUB_SHA" -e "GITHUB_REPOSITORY" -e "GITHUB_REPOSITORY_OWNER" -e "GITHUB_REPOSITORY_OWNER_ID" -e "GITHUB_RUN_ID" -e "GITHUB_RUN_NUMBER" -e "GITHUB_RETENTION_DAYS" -e "GITHUB_RUN_ATTEMPT" -e "GITHUB_REPOSITORY_ID" -e "GITHUB_ACTOR_ID" -e "GITHUB_ACTOR" -e "GITHUB_TRIGGERING_ACTOR" -e "GITHUB_WORKFLOW" -e "GITHUB_HEAD_REF" -e "GITHUB_BASE_REF" -e "GITHUB_EVENT_NAME" -e "GITHUB_SERVER_URL" -e "GITHUB_API_URL" -e "GITHUB_GRAPHQL_URL" -e "GITHUB_REF_NAME" -e "GITHUB_REF_PROTECTED" -e "GITHUB_REF_TYPE" -e "GITHUB_WORKFLOW_REF" -e "GITHUB_WORKFLOW_SHA" -e "GITHUB_WORKSPACE" -e "GITHUB_ACTION" -e "GITHUB_EVENT_PATH" -e "GITHUB_ACTION_REPOSITORY" -e "GITHUB_ACTION_REF" -e "GITHUB_PATH" -e "GITHUB_ENV" -e "GITHUB_STEP_SUMMARY" -e "GITHUB_STATE" -e "GITHUB_OUTPUT" -e "RUNNER_OS" -e "RUNNER_ARCH" -e "RUNNER_NAME" -e "RUNNER_ENVIRONMENT" -e "RUNNER_TOOL_CACHE" -e "RUNNER_TEMP" -e "RUNNER_WORKSPACE" -e "ACTIONS_RUNTIME_URL" -e "ACTIONS_RUNTIME_TOKEN" -e "ACTIONS_CACHE_URL" -e "ACTIONS_RESULTS_URL" -e GITHUB_ACTIONS=true -v "/var/run/docker.sock":"/var/run/docker.sock" -v "/home/runner/work/_temp/_github_home":"/github/home" -v "/home/runner/work/_temp/_github_workflow":"/github/workflow" -v "/home/runner/work/_temp/_runner_file_commands":"/github/file_commands" -v "/home/runner/work/fiat-crypto/fiat-crypto":"/github/workspace" 3e39f5:008ac7d946e449e1981db514cb3a30c6

Problem matcher doesn't detect file if compiling without opam

With opam, an error looks like this:

  - File "./src/demo.v", line 23, characters 0-13:

While without, it looks like this:

  File "./src/demo.v", line 5, characters 7-13:

Could the regex make the leading hyphen optional so that it matches even when running CI without opam?

Git issue with coqorg/coq:dev

As discussed on Zulip, at least for MetaCoq we need to fix permissions already before the installation, otherwise installing dependencies via opam fails.

The sentence This is not an issue when relying on opam to build the Coq project. in the README might be incorrect with the newest git version. To me, it might be reasonable to run the chown by default in before_install.

Originally posted by @yforster in #85 (comment)

See also #85 (comment)

(as well as actions/checkout#766)

docs: Mention the typical header of build.yml

We should probably document in the README that a standard phrasing for .github/workflows/build.yml is:

name: Docker-Coq CI

on:
  push:
    branches:
      - master
  pull_request:
    branches:
      - '**'

jobs:
  build:
    (…)

after_script cannot contain '

Apparently something goes wrong with the shell fiddling, and you get an error like "the expanded script is empty".
Removing ' from the script solves the problem.

FTR, this reproduces the bug:

        after_script: |
          startGroup "Test HB"
            opam pin add coq-hierarchy-builder 'https://github.com/math-comp/hierarchy-builder.git' --ignore-constraints-on=coq-elpi -y -j 4
            opam list
          endGroup

[wish] running extra code after build (but before uninstall)

My use case is that I'd like to build my package, and then use my package to build other packages, to see if I break my clients.

Ideally, I'd like to be able to use actions/(upload|download)-artifact@v2 to have multiple jobs, but I've no idea if this is OK with docker.

Alternatively, I'd like to run some commands before opam remove, and today I've to override the entire script, which is not super nice.

Any thoughts?

Document how to ensure a single Coq version is used across multiple invocations of the action

Fiat Crypto has a workflow where we invoke the action multiple times, as in

    - name: deps
      uses: coq-community/docker-coq-action@v1
      with:
        coq_version: ${{ matrix.env.DOCKER_COQ_VERSION }}
        ocaml_version: ${{ matrix.env.DOCKER_OCAML_VERSION }}
        export: CI ALLOW_DIFF COQCHKEXTRAFLAGS
        custom_script: etc/ci/github-actions-docker-make.sh -j2 deps
    - name: all-except-generated
      uses: coq-community/docker-coq-action@v1
      with:
        coq_version: ${{ matrix.env.DOCKER_COQ_VERSION }}
        ocaml_version: ${{ matrix.env.DOCKER_OCAML_VERSION }}
        export: CI ALLOW_DIFF COQCHKEXTRAFLAGS
        custom_script: etc/ci/github-actions-docker-make.sh ${EXTRA_GH_REPORTIFY} -j2 all-except-generated
    - name: generated-files
      run: etc/ci/github-actions-make.sh ${EXTRA_GH_REPORTIFY} -f Makefile.examples -j2 generated-files
      if: github.event_name == 'pull_request' || ${{ matrix.env.COQ_VERSION }} != 'master'
    - run: tar -czvf generated-files.tgz fiat-*/
      if: ${{ failure() }}
    - name: upload generated files
      uses: actions/upload-artifact@v3
      with:
        name: generated-files-${{ matrix.env.COQ_VERSION }}
        path: generated-files.tgz
    - name: standalone-haskell
      run: etc/ci/github-actions-make.sh -f Makefile.standalone -j1 standalone-haskell GHCFLAGS='+RTS -M6G -RTS'
    - name: validate
      uses: coq-community/docker-coq-action@v1
      with:
        coq_version: ${{ matrix.env.DOCKER_COQ_VERSION }}
        ocaml_version: ${{ matrix.env.DOCKER_OCAML_VERSION }}
        export: CI ALLOW_DIFF COQCHKEXTRAFLAGS
        custom_script: etc/ci/github-actions-docker-make.sh TIMED=1 validate COQCHKFLAGS="-o ${COQCHKEXTRAFLAGS}"
      if: env.SKIP_VALIDATE == '' && github.event_name != 'pull_request'

This has a couple advantages:

  • we can order steps the way we want, which is not possible if we can only invoke the docker action once (unless I want to figure out how to hand-code a replacement for actions/upload-artifact from inside docker, which I don't)
  • we can make use of other actions, like installing Haskell and uploading artifacts
  • we get more readable logs because we can make separate steps

However, there's a big downside, which is that sometimes "coq.dev" changes meaning between one step and the next, and this causes our CI to do duplicative work or fail outright.

I'd like to be able to somehow record the particular commit of Coq or docker image or something in a file or GitHub environment variable (I think one step can persistently modify the environment for subsequent steps by writing to a file), but I'm not sure how to get the relevant information from inside docker, nor how to tell the next step to use the same version. How can I set up my script to do this?

Inconsistency with Opam repository?

I run this action against a projects that installs just fine locally with opam install ., but via CI fails with this error:

Error:  Package conflict!
    * Missing dependency:
      - coq-pact-model -> coq-hammer-tactics >= 1.3.2 -> coq < 8.11~
      not available because the package is pinned to version 8.15.2
    * Missing dependency:
      - coq-pact-model -> coq-hammer-tactics >= 1.3.2 -> coq < 8.12~
      not available because the package is pinned to version 8.15.2
    * Missing dependency:
      - coq-pact-model -> coq-hammer-tactics >= 1.3.2 -> coq < 8.13~
      not available because the package is pinned to version 8.15.2
    * Missing dependency:
      - coq-pact-model -> coq-hammer-tactics >= 1.3.2 -> coq < 8.14~
      not available because the package is pinned to version 8.15.2
    * Missing dependency:
      - coq-pact-model -> coq-hammer-tactics >= 1.3.2 -> coq < 8.15~
      not available because the package is pinned to version 8.15.2

My ci.yml file is:

name: CI

on: [push, pull_request]

jobs:
  build:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        coq_version:
          - '8.16'
          - '8.15'
          - '8.14'
          - dev
        ocaml_version: ['default']
      fail-fast: false
    steps:
      - uses: actions/checkout@v2
      - uses: coq-community/docker-coq-action@v1
        with:
          opam_file: 'coq-pact-model.opam'
          coq_version: ${{ matrix.coq_version }}
          ocaml_version: ${{ matrix.ocaml_version }}

And my opam file is:

opam-version: "2.0"
maintainer: "[email protected]"

homepage: "https://github.com/jwiegley/pact-model"
dev-repo: "git+https://github.com/jwiegley/pact-model.git"
bug-reports: "https://github.com/jwiegley/pact-model/issues"
license: "BSD-3-Clause"

synopsis: "Formal model of the Pact Smart Contracts language"
description: """
Formal model of the Pact Smart Contracts language.
"""

build: [make "-j%{jobs}%" ]
install: [make "install"]
depends: [
  "coq" {(>= "8.14" & < "8.17~") | (= "dev")}
  "coq-equations" {(>= "1.2" & < "1.4~") | (= "dev")}
  "coq-hammer" {(>= "1.3.2") | (= "dev")}
  "coq-hammer-tactics" {(>= "1.3.2") | (= "dev")}
  "coq-haskell" {(>= "1.1") | (= "dev")}
  "coq-category-theory" {(>= "1.0") | (= "dev")}
]

tags: [
]
authors: [
  "John Wiegley"
]

I've confirmed in the Coq Package List that coq-hammer has a version 1.3.2+8.15 that works fine with my build, but for some reason docker-coq-action doesn't see it as available?

Problem Matcher should be disableable

If I use this action without a custom script to test a development against multiple versions of Coq, I get duplicates of the warnings annotations. Please add a configuration option that allows disabling echo "::add-matcher::$HOME/coq.json"

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.