GitHub Learning Lab is no longer accepting new public courses from outside of GitHub.
![]() |
A course on GitHub Learning Lab can guide you through this step. |
---|
When a learner triggers a step via an event, Learning Lab will execute that step's actions. Actions are abstractions of one or more GitHub API endpoints. Currently available actions are documented in Available actions. Most API endpoints accessible by a GitHub App could be built into an action in GitHub Learning Lab.
Note: Actions in GitHub Learning Lab aren't the same as GitHub Actions.
When using an action in a step, start with the type:
key followed by the name of the action. For example:
- type: respond
with: my-response.md
Whenever possible, actions will infer context from the event that triggered the step. Sometimes, actions have additional requirements that are listed in the action documentation.
For example:
with
option pointing to the Markdown file containing the body of the response. issue
option, allowing you to specify a specific issue or pull request in which to respond. If the issue or pull request isn't supplied, the action will try to respond based on the event that triggered it. If the event that triggered the action doesn't contain an issue or a pull request (for example, in the case of a page_build
event), the action will fail and the step won't be completed.Responses are usually static content. Sometimes, you'll want to inject variable data into the response. For example, you may want to:
To pass data into the responses, include a data
object. Within the data
object, include a name and value for each variable you want to pass.
For example:
- title: Commit a file
description: Commit your file to the branch.
event: push
link: '{{ repoUrl }}/issues/2'
actions:
- type: respond
issue: Your first contribution
with: open-a-pr.md
# the data object
data:
# we're passing a variable called `branch`, it contains the ref from the payload
branch: '{{ payload.ref }}'
# we're passing a second variable called `url`, it contains the repository's URL concatenated with some additional text
url: '{{ payload.repository.html_url }}/compare/{{ payload.ref }}?expand=1'
This data will be accessible in the response file with {{ branch }}
and {{ url }}
.
When an action is executed, the response from the GitHub API is accessible to the course author, if they wish to use it.
You might want to use the response from the GitHub API for a few reasons, like:
To access the response from the GitHub API after executing an action, append an action_id
key to your action, as follows:
steps:
- title: Comment on this issue
event: issue_comment.created
actions:
- type: createIssue
title: New issue
body: an-issue.md
# Store the API response for this new issue by assigning it to an action_id
action_id: new_issue
To use the information from the action, use the '{{ actions }}'
object and dot notation with the identifier for the action, as follows:
steps:
- title: Comment on this issue
event: issue_comment.created
actions:
- type: createIssue
title: New issue
body: an-issue.md
# Store the response for this new issue by assigning an action_id
action_id: new_issue
# Respond in the issue the user just commented on
- type: respond
with: a-response.md
# Include a `data` object to provide some template variables
data:
# Reference the response of the `new_issue` action
nextIssueUrl: '{{ actions.new_issue.data.html_url }}'
Most of the time, you'll expect the action to run before a step can be marked as completed. However, there are instances when you want to run an action, but if that action fails you'd like the learner to be able to continue the course. In these cases, you can use a required
option for that action.
Here's an example:
actions:
# get the contents of a file titled index.html, store them in an action identifier called `index_file`
- type: getFileContents
filename: index.html
action_id: index_file
# check if `index_file` contains an <html> tag, store the response in an action identifier called `contains_html`. If the action fails (because, say, no <html> tag exists), don't stop the course from executing. We'll use the information to provide the learner feedback
- type: htmlContainsTag
html: '{{ actions.index_file }}'
tag: html
action_id: contains_html
required: false
# Respond to the learner conditionally using `contains_html`.
- type: gate
left: '{{ actions.contains_html }}'
else:
type: createReview
body: 03e-add-html.md
event: REQUEST_CHANGES
- type: createReview
event: COMMENT
body: 03-title-tag.md
You can store information that your steps' actions return in a key/value store that is scoped to the user's registration. You may want to use this to create an issue in step 1, then reference it in a much later step.
- type: createIssue
title: Creating this issue!
store:
first_issue_url: '{{ result.data.html_url }}'
first_issue_number: '{{ result.data.number }}'
Some important notes on what you can store:
In the store
object, you'll have access to a special result
object; this is the direct return value of the action. You can read through the actions' source code to see what those values are.
And then you can use it later on:
steps:
# In a step link
link: '{{ store.first_issue_url }}'
# Or in an action
actions:
- type: gate
left: '{{ store.first_issue_number }}'
operator: ===
right: '{{ payload.issue.number }}'
You can also use the store
object from within a markdown response template:
Check out issue number [{{ store.first_issue_number }}]({{ store.first_issue_url }})!
If an action you require isn't available, the octokit action lets you access most any GitHub API endpoint, as long as it is enabled for GitHub Apps.
In the API docs, endpoints accessible to GitHub Apps are identified by a ℹ️ icon. Here's an example of an endpoint that's enabled for GitHub Apps and an endpoint that isn't.
If you're interested in contributing to the evolution of Learning Lab's actions, we would love to collaborate with you in the open source github/learning-lab-components
repository!