Add a event to trigger a workflow if a Template Repository is instantiated
Describe the enhancement
Provide a new event like these https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows that is triggered if a Repository is created from a Template Repository.
This would allow a Template author to automate initialization of a Repository. The workflow should run in the newly create Repository, not in the Template Repository.
Example when this would be useful
- I have a Template named "standard-nuget-package". Within this repository, there are files and folders named like "standard-nuget-package.csproj". This Template includes a workflow triggered on instantiation (maybe
template_instantiated), that renames files, folders and replaces file contents to replace "standard-nuget-package" with the name of the newly created Repository, and commits the changes. - Another user creates a new Repository named "MyCoolPackage"
- The workflow triggers and performs rename / replace operations, and commits these changes
- The new Repository is ready to go
I can image more of such initialization workflows that would benefit from this event.
I think this would be a really big deal—it would supercharge GitHub's "template repository" concept, and use GitHub Actions to make it easier for people to "consume" a template repository, lowering the friction to use them.
I used a workflow like this in my use case.
# this file should only be editted from (insert your template repo name here)
name: Cookiecutter format
on:
# I have found this event triggers on initial creation of new repository from github template
push:
branches:
- '**'
jobs:
cookiecutter:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
# This is my application specific use case,
# I am formatting the code here using Cookiecutter
# In the reader's case, they should modify the code however they want to do it.
- name: Cookiecutter format
uses: ./.github/actions/self-initialize-cookiecutter
with:
repo_name: ${{ github.event.repository.name }}
- name: Create Pull Request
# My repository that is a template repository includes the string "cookiecutter"
if: ${{ ! contains(github.event.repository.name, 'cookiecutter') }}
uses: peter-evans/create-pull-request@v3
with:
commit-message: "Cookiecutter format with repo_name as ${{ github.event.repository.name }}"
title: Cookiecutter format
body: |
# Cookiecutter format PR
Cookiecutter format with repo_name as ${{ github.event.repository.name }}
branch: cookiecutter-format
If you happen to want the action.yaml I'm using for cookiecutter, here it is.
name: "self-initialize-cookiecutter"
description: "Replace the code in this repository by formatting a cookiecutter template"
author: Steven Miller
inputs:
repo_name:
description: "What to use in the cookiecutter template for repository name?"
required: true
runs:
using: composite
steps:
- name: Check repo_name
shell: bash
run: |
REGEX_REPO_NAME='^[a-z][a-z0-9-]{0,38}[a-z0-9]$'
if [[ ! ${{ inputs.repo_name }} =~ ${REGEX_REPO_NAME} ]]; then
echo "'repo_name' must match regex ${REGEX_REPO_NAME}"
exit 1
fi
- name: Install tree
shell: bash
run: |
sudo apt-get install -y tree
- name: Install Cookiecutter and other pip modules
shell: bash
run: |
pip3 install -r requirements.txt
- name: Format with cookiecutter
shell: bash
run: |
set -xe
printf '${{ inputs.repo_name }}\n' | cookiecutter .
ls -ltrah
- name: Replace content with subdirectory's content
shell: bash
run: |
set -xe
# Delete everything except the rendered content
find . -mindepth 1 ! -regex '\.\/${{ inputs.repo_name }}\/.*' ! -regex '^\./\.git\/.*' ! -name .git ! -name ${{ inputs.repo_name }} -delete
ls -ltrah
- name: Copy the rendered content to the top level of this repository
shell: bash
run: |
set -xe
cp -R ./${{ inputs.repo_name }}/* .
ls -ltrah
- name: Delete subdirectory
shell: bash
run: |
set -xe
rm -rf ./${{ inputs.repo_name }}
ls -ltrah
- name: Show results
shell: bash
run: |
set -xe
echo "===================="
echo "===================="
echo "===================="
tree -a .
So in our organization the workflow is like a developer will click "use template" then as a result a formatted cookiecutter PR will open on the new repository they have created.
@sjmiller609 this looks quite interesting! Thank you
@sjmiller609 Yes, that's exactly the use case, man, you're AWESOME!!! 🙌🏻 🤪
That's a really terrific trick...
Do you have a public example of this in action?
@sjmiller609 will this github action be triggered on pushes from all branches? Or only once upon repository instantiation.
@svenvanderburg Look here for an example of what you are trying to do (I think):
https://github.com/jlumbroso/hugo-theme-bootstrap-skeleton
@jlumbroso this is the same solution as @sjmiller609 proposed right? By specifying:
on:
push:
branches:
- '**'
I tested this, and it does trigger on initialization. But it also triggers on all following commits... This last behavior is not what I want.
Here is a workaround. Basically, you disable the workflow after it has run.
A fully working, but untested solution would be:
name: Execute workflow only upon repository initialisation
on:
push:
branches:
- '**'
jobs:
- name: Disable this workflow
shell: bash
run: |
gh workflow disable -R $GITHUB_REPOSITORY "${{ github.workflow }}"
env:
GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
I stumbled upon the following github action that setup everything once the template is cloned https://github.com/laucia/cookiecutter-pypackage/blob/main/.github/workflows/template_baking.yaml
This would allow a Template author to automate initialization of a Repository. The workflow should run in the newly create Repository, not in the Template Repository.
The following's my approach to triggering a workflow if a repository is created using my template repository. The workflow runs upon branch/tag creation as well, but it gets canceled because of the conditional expression.
I've already tested it a lot with a scrapped project. Hope it helps!
name: Setup repository
on:
create
jobs:
create_issue:
if: github.event.ref == github.event.master_branch
name: Create issue
runs-on: ubuntu-latest
permissions:
issues: write
steps:
- uses: imjohnbo/issue-bot@v3
with:
title: "Test issue"
The workflow should run in the newly create Repository, not in the Template Repository.
It would actually be great if the event fired in both locations, so if for example the "source" repo wanted to update a README.md w/ a list of repos that use this template (mainly useful for internal template repos in orgs).
would be nice to have a template-create event to make things cleaner