|
| 1 | +====================== |
| 2 | +LLVM CI Best Practices |
| 3 | +====================== |
| 4 | + |
| 5 | +Overview |
| 6 | +======== |
| 7 | + |
| 8 | +This document contains a list of guidelines and best practices to use when |
| 9 | +working on LLVM's CI systems. These are intended to keep our actions reliable, |
| 10 | +consistent, and secure. |
| 11 | + |
| 12 | +Github Actions Best Practices |
| 13 | +============================= |
| 14 | + |
| 15 | +This section contains information on best practices/guidelines when working on |
| 16 | +LLVM's github actions workflows. |
| 17 | + |
| 18 | +Disabling Jobs In Forks |
| 19 | +----------------------- |
| 20 | + |
| 21 | +There are many LLVM forks that exist, and we currently default to preventing |
| 22 | +actions from running outside of the LLVM organization to prevent them from |
| 23 | +running in forks. We default to this as actions running in forks are usually |
| 24 | +not desired and only run by accident. In addition, many of our workflows |
| 25 | +assume that they are operating within the main LLVM repository and break |
| 26 | +otherwise. |
| 27 | + |
| 28 | +Adhering to this best practice looks like adding the following to each of the |
| 29 | +jobs specified within a workflow: |
| 30 | + |
| 31 | +.. code-block:: yaml |
| 32 | +
|
| 33 | + jobs: |
| 34 | + <job name>: |
| 35 | + if: github.repository_owner == 'llvm' |
| 36 | +
|
| 37 | +We choose to use ``github.repository_owner`` rather than ``github.repository`` |
| 38 | +to enable these workflows to run in forks inside the LLVM organization such as |
| 39 | +the ClangIR fork. |
| 40 | + |
| 41 | +There are some exceptions to this rule where ``github.repository`` might be |
| 42 | +used when it makes sense to limit a workflow to only running in the main |
| 43 | +monorepo repository. These include things like the issue subscriber and |
| 44 | +release tasks, which should not run anywhere else. |
| 45 | + |
| 46 | +Hash Pinning Dependencies |
| 47 | +------------------------- |
| 48 | + |
| 49 | +Github Actions allows the use of actions from other repositories as steps in |
| 50 | +jobs. We take advantage of various actions for a variety of different tasks, |
| 51 | +but especially tasks like checking out the repository, and |
| 52 | +downloading/uploading build caches. These actions are typically versioned with |
| 53 | +just a release, which looks like the following: |
| 54 | + |
| 55 | +.. code-block:: yaml |
| 56 | +
|
| 57 | + steps: |
| 58 | + - name: Checkout LLVM |
| 59 | + uses: actions/checkout@v4 |
| 60 | +
|
| 61 | +However, it is best practice to specify an exact commit SHA from which to pull |
| 62 | +the action from, noting the version in a comment: |
| 63 | + |
| 64 | +We plan on revisting this reccomendation once Github's immutable actions have |
| 65 | +been rolled out as GA. |
| 66 | + |
| 67 | +.. code-block:: yaml |
| 68 | +
|
| 69 | + steps: |
| 70 | + - name: Checkout LLVM |
| 71 | + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 |
| 72 | +
|
| 73 | +This is beneficial for two reasons: reliability and security. Specifying an |
| 74 | +exact SHA rather than just a major version ensures we end up running the same |
| 75 | +action originally specified when the workflow as authored and/or updated, |
| 76 | +and that no breaking changes sneak in from new versions of a workflow being |
| 77 | +released. However, this effect could also be achieved by specifying an exact |
| 78 | +dot release. The biggest reason to prefer hash pinned dependencies is security. |
| 79 | +Release assets on Github are mutable, allowing an attacker to change the code |
| 80 | +within a specific version of an action after the fact, potentially stealing |
| 81 | +sensitive tokens and credentials. Hash pinning the dependencies prevents this |
| 82 | +as the hash would change with the code. |
| 83 | + |
| 84 | +Using Versioned Runner Images |
| 85 | +----------------------------- |
| 86 | + |
| 87 | +Github actions allows the use of either specifically versioned runner images |
| 88 | +(e.g., ``ubuntu-22.04``), or just the latest runner image |
| 89 | +(e.g., ``ubuntu-latest``). It is best practice to use explicitly versioned |
| 90 | +runner images. This prevents breakages when Github rolls the latest runner |
| 91 | +image to a new version with potentially breaking changes, instead allowing us |
| 92 | +to explicitly opt-in to using the new image when we have done sufficient |
| 93 | +testing to ensure that our existing workflows work as expected in the new |
| 94 | +environment. |
0 commit comments