DRAFT DOCUMENT - Best Practices for Automated Pipelines

Protect code branches. In GitHub settings “Branch protection rules” select:

GitHub Actions is the preferred CI platform to implement checks. Create a test pipeline, consider required checks for:

  • DCO (required)
https://github.com/apps/dco
  • Linters
Linting GitHub Action workflow .yaml Files: https://github.com/rhysd/actionlint
  • Unit tests

  • Integration tests

  • Code coverage

  • Documentation

Example - ReadTheDocs webhook:

https://docs.readthedocs.io/en/stable/integrations.html

  • Static analysis aka Static Application Security Testing (SAST)

Example - CodeQL:

https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/about-code-scanning-with-codeql

Example - Snyk:

https://docs.snyk.io/integrations/git-repository-scm-integrations/github-integration

  • Software Composition Analysis dependency scans
  • And/or setup Dependabot in Settings/Security

Dependabot:

https://docs.github.com/en/code-security/dependabot/dependabot-security-updates/configuring-dependabot-security-updates

Trivy: 

https://github.com/aquasecurity/trivy

It supports pom.xml files but not build.gradle files. If you have a Gradle project you can use the Maven Publish Gradle plugin to generate an equivalent pom.xml file.

  • Note: use Reusable GitHub actions to reduce the number of top-level checks

https://docs.github.com/en/actions/using-workflows/reusing-workflows

Use GitHub Actions efficiently and reduce unnecessary runner usage:

  • Use cancel-in-progress to suppress multiple jobs for multiple pushes to the same pull request
https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#example-using-concurrency-to-cancel-any-in-progress-job-or-run
  • Uncheck branch protection rule “Require branches to be up to date before merging” to reduce number of runs
    • Potentially add a scheduled run if you are concerned about incompatible PRs getting merged

Via built-in GitHub YAML syntax:

https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/defining-the-mergeability-of-pull-requests/about-protected-branches#require-status-checks-before-merging


Via third-party GitHub Action: https://github.com/dorny/paths-filter

  • Use filters to eliminate unnecessary runs
    • Documentation PRs shouldn’t require building and testing code.
https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#filter-pattern-cheat-sheet
  • Consider custom docker images for CI with pre-installed and pre-configured dependencies

  • Consider running some jobs on schedule (nightly) rather than on each pull request (e.g. full matrix of platform tests, expensive security scans, code coverage)

  • Inspect Github Actions run results on your own fork prior to opening Pull Request
The simplest way to do this is to simply open the pull request for your own fork's main branch the same way as you would open it for the upstream repository's.
  • Contact Hyperledger staff for the possibility of dedicated paid runners

  • Consider using development container images which come pre-installed with all the dependencies a contributor need to get started with writing code on the project.
https://code.visualstudio.com/docs/devcontainers/containers
  • Consider leveraging pre-commit hooks via tools like husky (NodeJS) and lint-staged which can run arbitrary scripts at the time of you making a git commit.

Where appropriate, implement pre-commit rules (Stephen Curran can you clarify?) - Peter: I've added an item above for what I think this means. (If it's not a match, we can add more/different items of course)

Encourage developers to run tests locally before opening a pull request.

If due to technical constraints it is not possible to run the tests locally at all, the next best thing to encourage contributors is to run the CI on their personal fork (submit a PR against their their personal fork's main branch first while drafting the PR). Once the tests are passing on their fork's CI, they are ready to open the PR for review on the upstream repository.

  • Document how to run tests locally

  • Document how to run individual failing tests

  • Document how to add tests of all types.