From eaa5245ef4949a9f02a82c7e225ab11cc64bba85 Mon Sep 17 00:00:00 2001 From: David Binder Date: Tue, 21 Nov 2023 18:45:36 +0100 Subject: [PATCH] Finish improvements to the CI configuration for documentation changes (#9460) * Add bootstrap postjob to CI config Add a new job to the bootstrap.yml GitHub action config. This job succeeds if, and only if, all the other bootstrap jobs succeed. * Do not run bootstrap CI jobs for documentation changes The approach was already introduced in #9355 for the validate jobs. This commit introduces the same change also for the bootstrap jobs. * Also ignore CONTRIBUTING.md and README.md in CI We do not run the entire CI suite for documentation changes. Previously, only changes which were restricted to the 'docs/' subdirectory were considered to be documentation changes. With this commit we also recognize changes to README.md and CONTRIBUTING.md as documentation changes. * Document improved CI for documentation in CONTRIBUTING.md The CONTRIBUTING.md file now mentions that documentation changes do not waste expensive CI resources. * Recognize all README.md in subdirs as documentation Expensive CI jobs should not run on changes which affect only README.md files. --- .github/workflows/bootstrap.skip.yml | 39 ++++++++++++++++++++++++++++ .github/workflows/bootstrap.yml | 28 ++++++++++++++++++++ .github/workflows/validate.skip.yml | 12 ++++++--- .github/workflows/validate.yml | 10 +++++-- CONTRIBUTING.md | 6 +++++ 5 files changed, 90 insertions(+), 5 deletions(-) create mode 100644 .github/workflows/bootstrap.skip.yml diff --git a/.github/workflows/bootstrap.skip.yml b/.github/workflows/bootstrap.skip.yml new file mode 100644 index 00000000000..4a92ddaa0c6 --- /dev/null +++ b/.github/workflows/bootstrap.skip.yml @@ -0,0 +1,39 @@ +name: Bootstrap Skip + +# This Workflow is special and contains a workaround for a known limitation of GitHub CI. +# +# The problem: We don't want to run the "bootstrap" jobs on PRs which contain only changes +# to the docs, since these jobs take a long time to complete without providing any benefit. +# We therefore use path-filtering in the workflow triggers for the bootstrap jobs, namely +# "paths-ignore: doc/**". But the "Bootstrap post job" is a required job, therefore a PR cannot +# be merged unless the "Bootstrap post job" completes succesfully, which it doesn't do if we +# filter it out. +# +# The solution: We use a second job with the same name which always returns the exit code 0. +# The logic implemented for "required" workflows accepts if 1) at least one job with that name +# runs through, AND 2) If multiple jobs of that name exist, then all jobs of that name have to +# finish successfully. +on: + push: + paths: + - 'doc/**' + - '**/README.md' + - 'CONTRIBUTING.md' + branches: + - master + pull_request: + paths: + - 'doc/**' + - '**/README.md' + - 'CONTRIBUTING.md' + release: + types: + - created + +jobs: + bootstrap-post-job: + if: always() + name: Bootstrap post job + runs-on: ubuntu-latest + steps: + - run: exit 0 diff --git a/.github/workflows/bootstrap.yml b/.github/workflows/bootstrap.yml index c1734736e4c..03dafc3f59d 100644 --- a/.github/workflows/bootstrap.yml +++ b/.github/workflows/bootstrap.yml @@ -5,11 +5,22 @@ concurrency: group: ${{ github.ref }}-${{ github.workflow }} cancel-in-progress: true +# Note: This workflow file contains the required job "Bootstrap post job". We are using path filtering +# here to ignore PRs which only change documentation. This can cause a problem, see the workflow file +# "bootstrap.skip.yml" for a description of the problem and the solution provided in that file. on: push: + paths-ignore: + - 'doc/**' + - '**/README.md' + - 'CONTRIBUTING.md' branches: - master pull_request: + paths-ignore: + - 'doc/**' + - '**/README.md' + - 'CONTRIBUTING.md' release: types: - created @@ -66,3 +77,20 @@ jobs: with: name: cabal-${{ matrix.os }}-${{ matrix.ghc }}-bootstrapped path: _build/artifacts/* + + # We use this job as a summary of the workflow + # It will fail if any of the previous jobs does it + # This way we can use it exclusively in branch protection rules + # and abstract away the concrete jobs of the workflow, including their names + bootstrap-post-job: + if: always() + name: Bootstrap post job + runs-on: ubuntu-latest + # IMPORTANT! Any job added to the workflow should be added here too + needs: [bootstrap] + + steps: + - run: | + echo "jobs info: ${{ toJSON(needs) }}" + - if: contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled') + run: exit 1 diff --git a/.github/workflows/validate.skip.yml b/.github/workflows/validate.skip.yml index b67d41dd2c4..e5cd47e284a 100644 --- a/.github/workflows/validate.skip.yml +++ b/.github/workflows/validate.skip.yml @@ -5,7 +5,7 @@ name: Validate Skip # The problem: We don't want to run the "validate" jobs on PRs which contain only changes # to the docs, since these jobs take a long time to complete without providing any benefit. # We therefore use path-filtering in the workflow triggers for the validate jobs, namely -# "paths_ignore: doc/**". But the "Validate post job" is a required job, therefore a PR cannot +# "paths-ignore: doc/**". But the "Validate post job" is a required job, therefore a PR cannot # be merged unless the "Validate post job" completes succesfully, which it doesn't do if we # filter it out. # @@ -15,11 +15,17 @@ name: Validate Skip # finish successfully. on: push: - paths: 'doc/**' + paths: + - 'doc/**' + - '**/README.md' + - 'CONTRIBUTING.md' branches: - master pull_request: - paths: 'doc/**' + paths: + - 'doc/**' + - '**/README.md' + - 'CONTRIBUTING.md' release: types: - created diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml index aa6d01a128d..78652b10af7 100644 --- a/.github/workflows/validate.yml +++ b/.github/workflows/validate.yml @@ -16,11 +16,17 @@ concurrency: # "validate.skip.yml" for a description of the problem and the solution provided in that file. on: push: - paths-ignore: 'doc/**' + paths-ignore: + - 'doc/**' + - '**/README.md' + - 'CONTRIBUTING.md' branches: - master pull_request: - paths-ignore: 'doc/**' + paths-ignore: + - 'doc/**' + - '**/README.md' + - 'CONTRIBUTING.md' release: types: - created diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index c8149330eb5..cf3357a71d4 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -51,6 +51,12 @@ Some tips for using GitHub Actions effectively: sure everything is OK; otherwise, try to run relevant tests locally first. +* If you are only changing documentation in the `docs/` subdirectory, + or if you change `README.md` or `CONTRIBUTING.md`, then we only run a + small subset of the CI jobs. You can therefore open small PRs with + improvements to the documentation without feeling guilty about wasted + resources! + * Watch over your jobs on the [GitHub Actions website](http://github.org/haskell/cabal/actions). If you know a build of yours is going to fail (because one job has already failed), be nice to others and cancel the rest of the jobs,