Repository Templates Meets GitHub Actions
On June 6, 2019, GitHub introduced Repository Templates giving users an easy way to share boilerplate for their projects. This feature is fantastic, but lacking adoption to my knowledge and opinion for one reason.
Generating a new repository from a repository template is literally only a copy of the original source repository. This however is often just half the story when creating a new repository. For instance a way to specify template variables is missing to customize the resulting repository.
Wouldn't it be helpful if you could specify the project name, version, or author which is then templated into the resulting new repository?
GitHub Actions can be much more than CI/CD
The primary usage of GitHub Actions is CI/CD, but it offers much more than that. I think of GitHub Actions as a compute service running on top of GitHub’s infrastructure. You can run a workflow on any GitHub event like push, issue creation, or a new release. This is incredibly powerful and unlocks a wide range of use cases. In combination with repository templates you can make template variables work.
Project scaffolding meets GitHub Actions
The main problem with any scaffolding tool is that you have to install it on your computer. Such tools often depend on a specific language and version which you may not have installed at all.
Wouldn't it be better to create repositories with templated values without ever leaving the browser? Not having to navigate to your terminal, installing a runtime and dependencies?
In this example, I use cookiecutter, but in theory, this works with any scaffolding tool that you can instrument without prompting questions to the user. With the --no-input
argument, cookiecutter does not prompt for user input and only uses values from the cookiecutter.json
file.
The cookiecutter-template repository contains a workflow file for GitHub Actions that runs whenever the cookiecutter.json
file is modified. After creating a new repository from the template repository, the user is asked to complete the setup by editing the cookiecutter.json
using GitHub’s file edit functionality. Once the file gets committed, the setup-repository workflow gets invoked. This workflow does a few things, but in essence, it runs cookiecutter and re-initializes the repository with the generated files. It’s worth clarifying, that the re-initialization step removes the .github/workflows/setup-repository.yml
along with the cookiecutter template files and only the actual generated project structure is left in the repository. The illustration below explains the steps involved.
Checkout the workflow file with additional comments.
Drawback
There is one limitation, if the template contains one or more GitHub Actions workflow files, the re-initializion will fail with Git Error: Refusing to allow a GitHub App to create or update workflow without workflows permission
. This is by design to prevent third-parties from adding malicious workflow files. However, with one additional step you can still make it work.
Generate a new personal access token with the workflow scope
and configure the workflow to use this token instead of the one provided by default. Depending on your use-case for template repositories you have the following options to make this work.
a) Rather than storing your workflow files as templates, store them straight in .github/workflows/
. All you have to do then is to preserve those files while re-initializing the repository. Be aware, that this means you can not template any values in these files anymore.
b) Encourage the user to create a GitHub Action secret with a personal access token with the desired workflow
permission before editing the cookiecuter.json
file. After re-initializing the repository, the workflow will remove this secret automatically by convention if the token is named REPO_SETUP_TOKEN
.
c) For repository templates shared within an organization, it’s best to create an organization action secret that contains such a personal access token.
Before you leave, there is one more thing
GitHub is currently working on Issue Forms. This opens a new exciting option to complete the setup step. The idea is to create a new issue instead of editing the cookiecutter.json
file. That way the user gets a nice-looking web form which might be less error-prone than messing with the JSON file itself. The setup-repository
workflow will then run on the issue creation event and process the user input.
To learn more about this idea, check out the Codeless Contributions with GitHub Issue Forms blog post.
See it in action
A reference implementation based on cookiecutter
, can be found on GitHub. Checkout the workflow file .github/workflows/setup-repository.yml
with additional comments.
That's it! Happy repository templating and thanks for reading.
Want to discuss?
If you have anything to add, please reply in this Twitter thread.