diff --git a/.github/actions/expected-failure/action.yml b/.github/actions/expected-failure/action.yml new file mode 100644 index 00000000..7bf9a065 --- /dev/null +++ b/.github/actions/expected-failure/action.yml @@ -0,0 +1,39 @@ +--- + +inputs: + step-outcome: + description: 'Outcome of the step to consider' + expected-failure: + description: 'Whether a failure is expected' + +runs: + using: composite + + steps: + - if: ${{ inputs.step-outcome == 'success' + && inputs.expected-failure != 'expected-failure' }} + shell: bash + run: | + echo "The step succeeded and was planned to succeed." + exit 0 + + - if: ${{ inputs.step-outcome != 'success' + && inputs.expected-failure == 'expected-failure' }} + shell: bash + run: | + echo "The step failed and was planned to fail." + exit 0 + + - if: ${{ inputs.step-outcome == 'success' + && inputs.expected-failure == 'expected-failure' }} + shell: bash + run: | + echo "The step succeeded but was planned to fail." + exit 1 + + - if: ${{ inputs.step-outcome != 'success' + && inputs.expected-failure != 'expected-failure' }} + shell: bash + run: | + echo "The step failed but was planned to succeed." + exit 1 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 91973cdc..b672baed 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -56,10 +56,10 @@ jobs: strategy: fail-fast: false matrix: - os: - - ubuntu - - windows - - macos + include: + - {os: ubuntu} + - {os: windows, ef: expected-failure} + - {os: macos} runs-on: ${{ matrix.os }}-latest @@ -77,6 +77,11 @@ jobs: 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' @@ -89,7 +94,14 @@ jobs: 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 a smoke test + if: steps.install-topiary.outcome == 'success' run: | ## Run a tiny smoke test; checking that Topiary manages to start, ## parse a simple OCaml command and output the right thing. @@ -101,6 +113,7 @@ jobs: ## Topiary v0.1.0. These should be re-enabled in future versions. # - name: Run tests + # if: steps.install-topiary.outcome == 'success' # run: | # ## Test on OCaml implementation files (.ml) # cat topiary/tests/samples/input/ocaml.ml | opam exec -- topiary --language ocaml-implementation > ocaml.ml @@ -134,10 +147,10 @@ jobs: - name: Checkout repository uses: actions/checkout@v3 - - name: Build Docker image (see next steps for failure) + - name: Build Docker image (see next step for failure) id: build-docker-image - ## `continue-on-error` will make this step succeed no matter what. Later - ## steps will then handle the outcome of this step manually. This is + ## `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: | @@ -147,22 +160,11 @@ jobs: --file .github/workflows/ci.dockerfile \ --build-arg tag=${{matrix.tag}} - - name: Building the image succeeded and was planned to succeed - if: ${{ steps.build-docker-image.outcome == 'success' - && matrix.ef != 'expected-failure' }} - run: "true" - - name: Building the image failed and was planned to fail - if: ${{ steps.build-docker-image.outcome != 'success' - && matrix.ef == 'expected-failure' }} - run: "true" - - name: Building the image succeeded but was planned to fail - if: ${{ steps.build-docker-image.outcome == 'success' - && matrix.ef == 'expected-failure' }} - run: "false" - - name: Building the image failed but was planned to succeed - if: ${{ steps.build-docker-image.outcome == 'failure' - && matrix.ef != 'expected-failure' }} - run: "false" + - 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 a tiny smoke test if: steps.build-docker-image.outcome == 'success'