You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
GitHub actions are an almost endless source of features that will allow you to trigger on any kind of event that happens on GitHub. The trigger is executed in a container injected with your source code. GitHub actions are extensions which are effectively repos on GitHub. You can then use them from the workflow (.yml file).
Some actions are officially published but you and your team can just create your own actions and store them on GitHub and use then directly from there - no official release is required for it to be available.
The actions that trigger are defined in a workflow file - and since the runtime environment for the execution is a linux based container you can literally runanything that you can script - either embedded in the workflow file or in a separate script you call from the the workflow.
The runtime environment in which the action is triggered is default pre-authenticated (you can turn it off) so it can access the GitHub eco-system with the same credentials as yourself.
GitHub has a full fledged API that allows you to do access all GitHub features. But it's tedious and verbose to use an API like that from a shell script. So in January 2020 GitHub released the first version of the GitHub CLI gh. Although it it doesn't (yet) cover all features it's amazingly comprehensive. It gives you command line access to 'all' GitHub features - from the terminal. Which means that your actions can do anything.
In this issue:
Understand the workflow yaml file; on, env, permissions, jobs, usesand run.
See the gh CLI in action
Use the GitHub REST API for additional stuff gh doesn't support (yet)
Log messages to the action execution using different log levels
Use the GitHub web interface to create new workflows from 100's of predefined templates
Let's examine the workflow that was triggered on repo-creation - when you pushed "Use this template".
Here's the context:
Problem
Solution
Value
When I do tutorials and training materials in GitHub I want to present the material and exercises as issues. But both forks and templates on GitHub ignores the GitHub issues from the source repo — they are simply not copied over in the new repo.
Use GitHub Actions to start a workflow that triggers on the creation of a repo based on using another repo as a template. In that workflow use the GitHub CLI gh to reach back into the source repo, read the issues there and recreate them in the copy.
Issues from the source are now conceptually part of the template. From the perspective of didactics it has the advantage that meta data is kept out from cluttering the git filesystem. Rather they are stored in the same place at developers would naturally have that kind of meta data. Learners get to familiarize themselves with GitHub issues too and they'll have a natural place to record notes on their individual earning process.
👉 Go to the ▶️ Actions panel and open the workflow that just ran on "Initial commit" 👈
You will see something similar to this. Each section is expandable/collapsable and gives you exact details on what happened during the workflow execution.
👉 Open the worflow file that ran this particular workflow" 👈
In the left panel you'll find a read-only reference to the workflow file, in the version as it looked in the actual commit that triggered the workflow.
👉 Find the original workflow file in the git repo at /.github/worflows/template.yml and open that in the web editor 👈
You'll see the same file, but in the editable version from masterbranch. Since you are now in a genuine VS Code IDE you'll the IntelliSense support you expect.
As an example, if you hover on: you'll get instant access to a tool-tip box on this particular keyword. Apparently VS Code has built in support for GitHub Actions Workflow files.
👉 Hover over the keywords in the worflow file and see how much you'll learn about GitHub Actions 👈
A rundown on what goes on in this particular workflow:
In the reminder of this particular issue I'll not throw exercises at you, but rater walk you through some of the finer details in this flow. If you are already familiar with the semantics of the workflow files you may skip it - and then again; It does take you through some special cases, that serves to clarify the point, that a lot can be done with small means, by standing on the shoulders of other's general abstractions: Fight software complexity with more software!
name is optional, it serves as a heading in the workflow execution. on- defines what should trigger this workflow. Since there is not an actual event for creating a new repo the hack is to use '**' this will make the trigger fire on any branch.
env is the section that defines environment variables. Setting GITHUB_TOKEN is the standard way of authenticating the GitHub CLI. GitHub actions support secrets and GitHub automatically generate the a token when strating a workflow, it's stored in the secrets so this becomes that standard way of using the automatic token authentications
permissions is used to change the permission if you need anything other than the default permissions. For this particular run I had to add explicit write permissions to actions (as you'll see later I'll disable this flow as soon as it has run once) and issues so the workflow can create new issues.
jobs is where the action happens - the section defines all the jobs that the workflow knows of. Each job has it's on tag (you define the name yourself) in this case I only have one job and I came up with the clever name cpissues.
runs-on specifies the runner and image that this workflow will run in. I only need to do small bits in the terminal, so I'm happy with the default latest Ubuntu But even though runs-on is just a small clause it has a huge impact and by defining your own runners and images you can open up a complete customized world to Platform Engineering and Internal Development Platforms where you can configure the actions to support anything as code - quite literally "anything"! I will point you to a an example of using a customized docker container in a bit, but the finder details of the world that opens up underneath runs-on is beyond the scope of this tutorial. So go and explore yourself.
steps defined the different steps executed in this workflow. Each that becomes an expandable/collabsable setting in the job execution log you saw earlier, so this is how tiy add abit of readbility to your workflows. The rest of the this workflow happens in the context of these steps but before the workflow continues and if statement is used to fix the inconvenient fact that there is not dedicated event that fires on repository creation only that this workflow then fires on everything; The steps are simply ignored, unless the commit message of the commit spells exactly 'Initial commit'. Because this is exactly the commit message the GitHub always uses when it creates new repos off of templates.
uses i referring to actions so -apparently - the workflow somehow has access to to a GitHub Action called actions/checkout which is executed with no additional parameters in version 3.
As hinted earlier the access is simply that this is a Github repo called checkout under the GitHub user or organisations with handle actions. Consequently there should be somthing of interest at:
There is! The user actions is controlled by GitHub self, so you know that if an action is located here it's considered GitHub standard. Almost every workflow will call this particular action as the first - It makes sure, that the rest of the workflow execution has access to the content of the repo.
...
if$(gh workflow disable template.yml);thenecho ::notice title=Workflow successfully disabled::This also works as a raised semaphore - parallel workflow runs will see it and cancel
elseecho"::warning title=Another job got here first::This room is crowded - I'm outta here!"
curl -X POST \
-H "Accept: application/vnd.github.v3+json" \
-H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \
https://api.github.com/repos/${{ github.repository }}/actions/runs/${{ github.run_id }}/cancel
exit 1
fi
run is similar to uses but where uses calls a predefined action, run executes native shell commands. Starting the run clause with a pipe | followed by a new-line is a notation used to make the rest of the clause - a shell script.
The first thing that happens is that the workflow template.ymlis disabled. The is done simply by using the gh cli The command will raise an error if it doesn't succeed - like if it's already disabled.
The else clause runs if we didn't succeed to disable the workflow - as the message states, another job got here first. This is a precaution that deals with the occasional abnormality that sometimes GitHub fires the workflow twice on the same catch-all '**' branch pattern. When that is the case, I'd rather have this workflow cancelled, that having the record of a failed workflow. But cancelling a running instance of a workflow is is not supported from the gh CLI. It is hover supported by a webhook on the GitHub REST API.
Consequently this worflow now works as intended: It runs once - and only once, and only on the initial commit. And it doesn't take up any polling resources after, because it's effectively disabled.
run executes the script I provided in this repo at /.github/template/cpissues.sh In large; It starts by reading settings from a local gitconfig file (lines #3-7) and it then uses gh to generate a json output of all issues in the source repo that has the designated label template (line #18). It then iterates over this json and uses an unholy mix of jq, base64 and sed - which are all standard linux commands - to capture the title of the issue (lines #22-26) and then, checks if an issue with the same title doesn't already exit (line #28) if not it pipes the issue body into a temporary file and uses a special flag on on the gh cli to create an issue from the file (lines #30-35)
This bit uses run to replace the README.md in the root with the one that's designed, to be shown in the copy. This needs to be committed and pushed, and in order to do that we need to verify to git who we are by name and email.
This creates a new commit - If you go and take a look, your repo already has two commits, but also notice that you only have one job execution - despite that the workflow subscribes to any branch '**'; the disablement of the job works as intended.
The text was updated successfully, but these errors were encountered:
GitHub actions
GitHub actions are an almost endless source of features that will allow you to trigger on any kind of event that happens on GitHub. The trigger is executed in a container injected with your source code. GitHub actions are extensions which are effectively repos on GitHub. You can then
use
them from the workflow (.yml
file).Some actions are officially published but you and your team can just create your own actions and store them on GitHub and
use
then directly from there - no official release is required for it to be available.The actions that trigger are defined in a workflow file - and since the runtime environment for the execution is a linux based container you can literally
run
anything that you can script - either embedded in the workflow file or in a separate script you call from the the workflow.The runtime environment in which the action is triggered is default pre-authenticated (you can turn it off) so it can access the GitHub eco-system with the same credentials as yourself.
GitHub has a full fledged API that allows you to do access all GitHub features. But it's tedious and verbose to use an API like that from a shell script. So in January 2020 GitHub released the first version of the GitHub CLI
gh
. Although it it doesn't (yet) cover all features it's amazingly comprehensive. It gives you command line access to 'all' GitHub features - from the terminal. Which means that your actions can do anything.In this issue:
on
,env
,permissions
,jobs
,uses
andrun
.gh
CLI in actiongh
doesn't support (yet)Let's examine the workflow that was triggered on repo-creation - when you pushed "Use this template".
Here's the context:
forks
andtemplates
on GitHub ignores the GitHub issues from the source repo — they are simply not copied over in the new repo.template
. In that workflow use the GitHub CLIgh
to reach back into the source repo, read the issues there and recreate them in the copy.template
. From the perspective of didactics it has the advantage that meta data is kept out from cluttering the git filesystem. Rather they are stored in the same place at developers would naturally have that kind of meta data. Learners get to familiarize themselves with GitHub issues too and they'll have a natural place to record notes on their individual earning process.▶️ Actions
panel and open the workflow that just ran on "Initial commit" 👈You will see something similar to this. Each section is expandable/collapsable and gives you exact details on what happened during the workflow execution.
In the left panel you'll find a read-only reference to the workflow file, in the version as it looked in the actual commit that triggered the workflow.
/.github/worflows/template.yml
and open that in the web editor 👈You'll see the same file, but in the editable version from
master
branch. Since you are now in a genuine VS Code IDE you'll the IntelliSense support you expect.As an example, if you hover
on:
you'll get instant access to a tool-tip box on this particular keyword. Apparently VS Code has built in support for GitHub Actions Workflow files.A rundown on what goes on in this particular workflow:
In the reminder of this particular issue I'll not throw exercises at you, but rater walk you through some of the finer details in this flow. If you are already familiar with the semantics of the workflow files you may skip it - and then again; It does take you through some special cases, that serves to clarify the point, that a lot can be done with small means, by standing on the shoulders of other's general abstractions: Fight software complexity with more software!
Workflow:
/.github/worflows/template.yml
Lines 1-6
name
is optional, it serves as a heading in the workflow execution.on
- defines what should trigger this workflow. Since there is not an actual event for creating a new repo the hack is to use'**'
this will make the trigger fire on any branch.Lines 8-9
env
is the section that defines environment variables. SettingGITHUB_TOKEN
is the standard way of authenticating the GitHub CLI. GitHub actions support secrets and GitHub automatically generate the a token when strating a workflow, it's stored in the secrets so this becomes that standard way of using the automatic token authenticationsLines 11-15
permissions
is used to change the permission if you need anything other than the default permissions. For this particular run I had to add explicit write permissions toactions
(as you'll see later I'll disable this flow as soon as it has run once) andissues
so the workflow can create new issues.Lines 17-20
jobs
is where the action happens - the section defines all the jobs that the workflow knows of. Each job has it's on tag (you define the name yourself) in this case I only have one job and I came up with the clever namecpissues
.runs-on
specifies the runner and image that this workflow will run in. I only need to do small bits in the terminal, so I'm happy with the default latest Ubuntu But even thoughruns-on
is just a small clause it has a huge impact and by defining your own runners and images you can open up a complete customized world to Platform Engineering and Internal Development Platforms where you can configure the actions to support anything as code - quite literally "anything"! I will point you to a an example of using a customized docker container in a bit, but the finder details of the world that opens up underneathruns-on
is beyond the scope of this tutorial. So go and explore yourself.Lines 21-25
steps
defined the different steps executed in this workflow. Each that becomes an expandable/collabsable setting in the job execution log you saw earlier, so this is how tiy add abit of readbility to your workflows. The rest of the this workflow happens in the context of thesesteps
but before the workflow continues andif
statement is used to fix the inconvenient fact that there is not dedicated event that fires on repository creation only that this workflow then fires on everything; The steps are simply ignored, unless the commit message of the commit spells exactly'Initial commit'
. Because this is exactly the commit message the GitHub always uses when it creates new repos off of templates.uses
i referring to actions so -apparently - the workflow somehow has access to to a GitHub Action calledactions/checkout
which is executed with no additional parameters in version3
.As hinted earlier the access is simply that this is a Github repo called
checkout
under the GitHub user or organisations with handleactions
. Consequently there should be somthing of interest at:https://github.com/actions/checkout
There is! The user
actions
is controlled by GitHub self, so you know that if an action is located here it's considered GitHub standard. Almost every workflow will call this particular action as the first - It makes sure, that the rest of the workflow execution has access to the content of the repo.Lines 25-38
run
is similar touses
but whereuses
calls a predefined action,run
executes native shell commands. Starting therun
clause with a pipe|
followed by a new-line is a notation used to make the rest of the clause - a shell script.The first thing that happens is that the workflow
template.yml
is disabled. The is done simply by using thegh
cli The command will raise an error if it doesn't succeed - like if it's already disabled.The next line demonstrate how to use simple
echo
statements to create messages in the workflow execution log four levels are supported:debug
,notice
,warning
anderror
. You already saw the output from this earlier, when you browsed the content on the▶️ Actions
panel.The
else
clause runs if we didn't succeed to disable the workflow - as the message states, another job got here first. This is a precaution that deals with the occasional abnormality that sometimes GitHub fires the workflow twice on the same catch-all'**'
branch pattern. When that is the case, I'd rather have this workflow cancelled, that having the record of a failed workflow. But cancelling a running instance of a workflow is is not supported from thegh
CLI. It is hover supported by a webhook on the GitHub REST API.Consequently this worflow now works as intended: It runs once - and only once, and only on the initial commit. And it doesn't take up any polling resources after, because it's effectively disabled.
Lines 39-41
run
executes the script I provided in this repo at/.github/template/cpissues.sh
In large; It starts by reading settings from a localgitconfig
file (lines #3-7) and it then usesgh
to generate ajson
output of all issues in the source repo that has the designated labeltemplate
(line #18). It then iterates over thisjson
and uses an unholy mix ofjq
,base64
andsed
- which are all standard linux commands - to capture the title of the issue (lines #22-26) and then, checks if an issue with the same title doesn't already exit (line #28) if not it pipes the issue body into a temporary file and uses a special flag on on thegh
cli to create an issue from the file (lines #30-35)Lines 42-49
This bit uses
run
to replace theREADME.md
in the root with the one that's designed, to be shown in the copy. This needs to be committed and pushed, and in order to do that we need to verify to git who we are byname
andemail
.This creates a new commit - If you go and take a look, your repo already has two commits, but also notice that you only have one job execution - despite that the workflow subscribes to any branch
'**'
; the disablement of the job works as intended.The text was updated successfully, but these errors were encountered: