|  | 
|  | 1 | +# Carpentries Workflows | 
|  | 2 | + | 
|  | 3 | +This directory contains workflows to be used for Lessons using the {sandpaper} | 
|  | 4 | +lesson infrastructure. Two of these workflows require R (`sandpaper-main.yaml` | 
|  | 5 | +and `pr-recieve.yaml`) and the rest are bots to handle pull request management. | 
|  | 6 | + | 
|  | 7 | +These workflows will likely change as {sandpaper} evolves, so it is important to | 
|  | 8 | +keep them up-to-date. To do this in your lesson you can do the following in your | 
|  | 9 | +R console: | 
|  | 10 | + | 
|  | 11 | +```r | 
|  | 12 | +# Install/Update sandpaper | 
|  | 13 | +options(repos = c(carpentries = "https://carpentries.r-universe.dev/",  | 
|  | 14 | +  CRAN = "https://cloud.r-project.org")) | 
|  | 15 | +install.packages("sandpaper") | 
|  | 16 | + | 
|  | 17 | +# update the workflows in your lesson | 
|  | 18 | +library("sandpaper") | 
|  | 19 | +update_github_workflows() | 
|  | 20 | +``` | 
|  | 21 | + | 
|  | 22 | +Inside this folder, you will find a file called `sandpaper-version.txt`, which | 
|  | 23 | +will contain a version number for sandpaper. This will be used in the future to | 
|  | 24 | +alert you if a workflow update is needed. | 
|  | 25 | + | 
|  | 26 | +What follows are the descriptions of the workflow files: | 
|  | 27 | + | 
|  | 28 | +## Deployment | 
|  | 29 | + | 
|  | 30 | +### 01 Build and Deploy (sandpaper-main.yaml) | 
|  | 31 | + | 
|  | 32 | +This is the main driver that will only act on the main branch of the repository. | 
|  | 33 | +This workflow does the following: | 
|  | 34 | + | 
|  | 35 | + 1. checks out the lesson | 
|  | 36 | + 2. provisions the following resources | 
|  | 37 | +   - R | 
|  | 38 | +   - pandoc | 
|  | 39 | +   - lesson infrastructure (stored in a cache) | 
|  | 40 | +   - lesson dependencies if needed (stored in a cache) | 
|  | 41 | + 3. builds the lesson via `sandpaper:::ci_deploy()` | 
|  | 42 | + | 
|  | 43 | +#### Caching | 
|  | 44 | + | 
|  | 45 | +This workflow has two caches; one cache is for the lesson infrastructure and  | 
|  | 46 | +the other is for the the lesson dependencies if the lesson contains rendered | 
|  | 47 | +content. These caches are invalidated by new versions of the infrastructure and | 
|  | 48 | +the `renv.lock` file, respectively. If there is a problem with the cache,  | 
|  | 49 | +manual invaliation is necessary. You will need maintain access to the repository | 
|  | 50 | +and you can either go to the actions tab and [click on the caches button to find | 
|  | 51 | +and invalidate the failing cache](https://github.blog/changelog/2022-10-20-manage-caches-in-your-actions-workflows-from-web-interface/)  | 
|  | 52 | +or by setting the `CACHE_VERSION` secret to the current date (which will | 
|  | 53 | +invalidate all of the caches). | 
|  | 54 | + | 
|  | 55 | +## Updates | 
|  | 56 | + | 
|  | 57 | +### Setup Information | 
|  | 58 | + | 
|  | 59 | +These workflows run on a schedule and at the maintainer's request. Because they | 
|  | 60 | +create pull requests that update workflows/require the downstream actions to run, | 
|  | 61 | +they need a special repository/organization secret token called  | 
|  | 62 | +`SANDPAPER_WORKFLOW` and it must have the `public_repo` and `workflow` scope.  | 
|  | 63 | + | 
|  | 64 | +This can be an individual user token, OR it can be a trusted bot account. If you | 
|  | 65 | +have a repository in one of the official Carpentries accounts, then you do not | 
|  | 66 | +need to worry about this token being present because the Carpentries Core Team | 
|  | 67 | +will take care of supplying this token. | 
|  | 68 | + | 
|  | 69 | +If you want to use your personal account: you can go to  | 
|  | 70 | +<https://github.com/settings/tokens/new?scopes=public_repo,workflow&description=Sandpaper%20Token> | 
|  | 71 | +to create a token. Once you have created your token, you should copy it to your | 
|  | 72 | +clipboard and then go to your repository's settings > secrets > actions and | 
|  | 73 | +create or edit the `SANDPAPER_WORKFLOW` secret, pasting in the generated token. | 
|  | 74 | + | 
|  | 75 | +If you do not specify your token correctly, the runs will not fail and they will | 
|  | 76 | +give you instructions to provide the token for your repository.  | 
|  | 77 | + | 
|  | 78 | +### 02 Maintain: Update Workflow Files (update-workflow.yaml) | 
|  | 79 | + | 
|  | 80 | +The {sandpaper} repository was designed to do as much as possible to separate  | 
|  | 81 | +the tools from the content. For local builds, this is absolutely true, but  | 
|  | 82 | +there is a minor issue when it comes to workflow files: they must live inside  | 
|  | 83 | +the repository.  | 
|  | 84 | + | 
|  | 85 | +This workflow ensures that the workflow files are up-to-date. The way it work is | 
|  | 86 | +to download the update-workflows.sh script from GitHub and run it. The script  | 
|  | 87 | +will do the following: | 
|  | 88 | + | 
|  | 89 | +1. check the recorded version of sandpaper against the current version on github | 
|  | 90 | +2. update the files if there is a difference in versions | 
|  | 91 | + | 
|  | 92 | +After the files are updated, if there are any changes, they are pushed to a | 
|  | 93 | +branch called `update/workflows` and a pull request is created. Maintainers are | 
|  | 94 | +encouraged to review the changes and accept the pull request if the outputs | 
|  | 95 | +are okay. | 
|  | 96 | + | 
|  | 97 | +This update is run ~~weekly or~~ on demand. | 
|  | 98 | + | 
|  | 99 | +### 03 Maintain: Update Pacakge Cache (update-cache.yaml) | 
|  | 100 | + | 
|  | 101 | +For lessons that have generated content, we use {renv} to ensure that the output | 
|  | 102 | +is stable. This is controlled by a single lockfile which documents the packages | 
|  | 103 | +needed for the lesson and the version numbers. This workflow is skipped in  | 
|  | 104 | +lessons that do not have generated content. | 
|  | 105 | + | 
|  | 106 | +Because the lessons need to remain current with the package ecosystem, it's a | 
|  | 107 | +good idea to make sure these packages can be updated periodically. The  | 
|  | 108 | +update cache workflow will do this by checking for updates, applying them in a | 
|  | 109 | +branch called `updates/packages` and creating a pull request with _only the | 
|  | 110 | +lockfile changed_.  | 
|  | 111 | + | 
|  | 112 | +From here, the markdown documents will be rebuilt and you can inspect what has | 
|  | 113 | +changed based on how the packages have updated.  | 
|  | 114 | + | 
|  | 115 | +## Pull Request and Review Management | 
|  | 116 | + | 
|  | 117 | +Because our lessons execute code, pull requests are a secruity risk for any | 
|  | 118 | +lesson and thus have security measures associted with them. **Do not merge any | 
|  | 119 | +pull requests that do not pass checks and do not have bots commented on them.** | 
|  | 120 | + | 
|  | 121 | +This series of workflows all go together and are described in the following  | 
|  | 122 | +diagram and the below sections: | 
|  | 123 | + | 
|  | 124 | + | 
|  | 125 | + | 
|  | 126 | +### Pre Flight Pull Request Validation (pr-preflight.yaml) | 
|  | 127 | + | 
|  | 128 | +This workflow runs every time a pull request is created and its purpose is to | 
|  | 129 | +validate that the pull request is okay to run. This means the following things: | 
|  | 130 | + | 
|  | 131 | +1. The pull request does not contain modified workflow files | 
|  | 132 | +2. If the pull request contains modified workflow files, it does not contain  | 
|  | 133 | +   modified content files (such as a situation where @carpentries-bot will | 
|  | 134 | +   make an automated pull request) | 
|  | 135 | +3. The pull request does not contain an invalid commit hash (e.g. from a fork | 
|  | 136 | +   that was made before a lesson was transitioned from styles to use the | 
|  | 137 | +   workbench). | 
|  | 138 | + | 
|  | 139 | +Once the checks are finished, a comment is issued to the pull request, which  | 
|  | 140 | +will allow maintainers to determine if it is safe to run the  | 
|  | 141 | +"Receive Pull Request" workflow from new contributors. | 
|  | 142 | + | 
|  | 143 | +### Recieve Pull Request (pr-recieve.yaml) | 
|  | 144 | + | 
|  | 145 | +**Note of caution:** This workflow runs arbitrary code by anyone who creates a | 
|  | 146 | +pull request. GitHub has safeguarded the token used in this workflow to have no | 
|  | 147 | +priviledges in the repository, but we have taken precautions to protect against | 
|  | 148 | +spoofing. | 
|  | 149 | + | 
|  | 150 | +This workflow is triggered with every push to a pull request. If this workflow | 
|  | 151 | +is already running and a new push is sent to the pull request, the workflow | 
|  | 152 | +running from the previous push will be cancelled and a new workflow run will be | 
|  | 153 | +started. | 
|  | 154 | + | 
|  | 155 | +The first step of this workflow is to check if it is valid (e.g. that no | 
|  | 156 | +workflow files have been modified). If there are workflow files that have been | 
|  | 157 | +modified, a comment is made that indicates that the workflow is not run. If  | 
|  | 158 | +both a workflow file and lesson content is modified, an error will occurr. | 
|  | 159 | + | 
|  | 160 | +The second step (if valid) is to build the generated content from the pull | 
|  | 161 | +request. This builds the content and uploads three artifacts: | 
|  | 162 | + | 
|  | 163 | +1. The pull request number (pr) | 
|  | 164 | +2. A summary of changes after the rendering process (diff) | 
|  | 165 | +3. The rendered files (build) | 
|  | 166 | + | 
|  | 167 | +Because this workflow builds generated content, it follows the same general  | 
|  | 168 | +process as the `sandpaper-main` workflow with the same caching mechanisms. | 
|  | 169 | + | 
|  | 170 | +The artifacts produced are used by the next workflow. | 
|  | 171 | + | 
|  | 172 | +### Comment on Pull Request (pr-comment.yaml) | 
|  | 173 | + | 
|  | 174 | +This workflow is triggered if the `pr-recieve.yaml` workflow is successful. | 
|  | 175 | +The steps in this workflow are: | 
|  | 176 | + | 
|  | 177 | +1. Test if the workflow is valid and comment the validity of the workflow to the | 
|  | 178 | +   pull request. | 
|  | 179 | +2. If it is valid: create an orphan branch with two commits: the current state | 
|  | 180 | +   of the repository and the proposed changes. | 
|  | 181 | +3. If it is valid: update the pull request comment with the summary of changes | 
|  | 182 | + | 
|  | 183 | +Importantly: if the pull request is invalid, the branch is not created so any | 
|  | 184 | +malicious code is not published. | 
|  | 185 | + | 
|  | 186 | +From here, the maintainer can request changes from the author and eventually  | 
|  | 187 | +either merge or reject the PR. When this happens, if the PR was valid, the  | 
|  | 188 | +preview branch needs to be deleted.  | 
|  | 189 | + | 
|  | 190 | +### Send Close PR Signal (pr-close-signal.yaml) | 
|  | 191 | + | 
|  | 192 | +Triggered any time a pull request is closed. This emits an artifact that is the | 
|  | 193 | +pull request number for the next action | 
|  | 194 | + | 
|  | 195 | +### Remove Pull Request Branch (pr-post-remove-branch.yaml) | 
|  | 196 | + | 
|  | 197 | +Tiggered by `pr-close-signal.yaml`. This removes the temporary branch associated with | 
|  | 198 | +the pull request (if it was created). | 
0 commit comments