Background
This weblog relies on Bit Venture’s CounselorBot, which you’ll be able to check out your self!
We at the moment have two obtainable programs:
Get began with this video tutorial or this walkthrough web page.
Overview
GitHub Actions are sometimes used for automated code operations, often automated deployments. Nevertheless, additionally they have one other handy-dandy use case: checking college students’ code submissions so that you (being lazy) do not must run them your self!
In a future tutorial, we’ll additionally speak about how output from GitHub Actions might be robotically commented on college students’ pull requests to supply suggestions on what went improper.
Outlining Our Plan
All the workflow recordsdata used as examples on this tutorial might be discovered right here.
Every “step” in our curriculum requires a unique check. When a pupil (the person) commits to the repository, we have to…
- Work out which workflow file to run
- Work out which step the scholar is on
…as a way to run the right check.
Alongside really operating the exams, we may also be utilizing GitHub Actions to find out the solutions to those two questions.
Writing the YAML File
identify: Getting Began
on:
push:
branches:
- good day
The primary part of the YAML file offers the GitHub Motion a show identify and configures when the motion ought to run. On this case, it’s going to run when a commit is pushed to the good day
department.
jobs:
construct:
runs-on: ubuntu-latest
steps:
- identify: Checkout Code
makes use of: actions/checkout@v2
- identify: Setup Node Setting
makes use of: actions/setup-node@v2
with:
node-version: '14'
- identify: Set up Dependencies
run: |
npm set up minimist
npm set up node-fetch
The subsequent part gives different steps to “arrange” the environment. We’ll primarily be utilizing node to check code; npm dependencies may also be put in if they are going to be used within the exams.
- identify: Get Rely
id: vars
run: echo ::set-output identify=rely::$(node ./.bit/scripts/getProgress.js --repo=${{github.occasion.repository.identify}} --owner=${{github.repository_owner}} )
Our first “distinctive” step on this workflow includes utilizing this script to retrieve the step that the scholar is at the moment on. This “rely” worth is an integer that correlates with steps in our curriculum.
Observe: the
echo ::set-output identify=rely::
half units the output of the file that runs to a neighborhood variable namedrely
, which will likely be accessed later withsteps.vars.outputs.rely
.
Testing Totally different Sorts Of Submissions
Now that the setting for our workflow is ready up, we are able to run totally different check recordsdata, which give suggestions on pupil code. With GitHub Actions, you might be basically simply operating instructions on a terminal. This opens up choices from operating JavaScript recordsdata to testing webpages to calling Azure Features.
All check examples used on this tutorial might be present in this listing and this listing.
Testing Program Information (JS, Python)
- identify: Step 1
if: ${{steps.vars.outputs.rely == 1 && github.occasion.head_commit.message != 'Replace progress'}}
run: |
node .bit/exams/check.1.2.js --repo=${{github.occasion.repository.identify}} --user=${{github.repository_owner}}
This step might be added onto the steps
part of the YAML file for workflow configuration. A conditional assertion is utilized to solely run this check if the “rely” worth is right. The command node .bit/exams/check.1.2.js
would then execute this check.
strive { good day = require('./../../week1/helloworld.js') }
The check first makes an attempt to import the scholar’s code within the repository.
let helloworld = good day()
let test_output = "Howdy World"
If profitable, it’s going to try to execute the imported capabilities.
await capabilities.throwError(`Acquired: '${helloworld}', was anticipating: '${test_output}'.`, person, repo)
console.log(`Acquired: "${helloworld}", was anticipating: "${test_output}".`)
course of.exit(1)
Observe: Supply code for the
capabilities.throwError()
technique might be discovered right here. It contains capabilities used to supply suggestions to college students and cut back repetition in exams.
Relying on its success, the check will present suggestions by throwing errors within the workflow.
Testing Webpages with Cypress
Cypress is a robust testing software that permits a simulation of a person’s actions on an internet site.
describe('Testing Bunnimage', () => {
it('Testing Week 4 Step 1', () => {
cy.go to('bunnimage/index.html')
cy.get('enter[type="text"]').kind('console.log("hello yall")')
cy.get('enter[type="button"]').click on()
cy.get('#output').incorporates('console.log("hello yall")❤️')
})
})
A easy instance of a check as proven right here simulates typing console.log("hello yall")
, clicking the desired button on the web page, and checking to see if the output equals console.log("hello yall")❤️
. Within the workflow’s output, suggestions from Cypress is supplied.
Testing APIs
Pupil coded endpoints may also be examined with HTTP requests run within the workflow. The important thing to this technique is asking college students so as to add “repository secrets and techniques” that may then be accessed throughout the workflow as setting variables utilizing the under syntax.
- identify: Step 12
if: ${{steps.vars.outputs.rely == 12 && github.occasion.head_commit.message != 'Replace progress'}}
env:
MORSE_ENDPOINT: ${{ secrets and techniques.MORSE_ENDPOINT }}
run: |
npm set up node-fetch
node .bit/exams/check.1.8.js --repo=${{github.occasion.repository.identify}} --user=${{github.repository_owner}}
This instance accesses the scholar’s MORSE_ENDPOINT
secret (this may be later accessed within the code with uri = course of.env.MORSE_ENDPOINT
).
strive {
const resp = await fetch(uri + "&plaintext=ilovebitproject", {
technique: 'GET'
});
var knowledge = await resp.textual content()
let check = JSON.stringify(knowledge)
capabilities.validateResponseStatus(resp, uri)
} catch (e) {
console.error("We're having hassle making a request to your endpoint. Attempt once more?")
await capabilities.throwError("We're having hassle making a request to your endpoint. Attempt once more?", person, repo)
course of.exit(1)
}
First, using the scholar’s endpoint, an HTTP GET request is made to see if the endpoint is alive.
if (knowledge.size < 3) {
console.error("No response... Attempt once more!")
await capabilities.throwError("No response... Attempt once more!", person, repo)
course of.exit(1)
} else if (knowledge == reply) {
console.data("Yay!🎉 Success - thanks for serving to us on this high secret mission. Welcome to the staff.")
console.data(`We acquired "${reply}" with the enter of ilovebitproject`)
} else {
console.error(`YIKES! We acquired "${knowledge}" as an alternative of "${reply}". Attempt once more!`)
await capabilities.throwError(`YIKES! We acquired '${knowledge}' as an alternative of '${reply}'. Attempt once more!`, person, repo)
course of.exit(1)
}
If a response is obtained, the check makes an attempt to find out if the output of the endpoint matches the right “reply.”
As demonstrated in this check proven above, a number of check instances might be without delay with suggestions returned to the scholar as output of the workflow.
Conclusion
GitHub Actions are extraordinarily versatile as they permit builders to create their very own setting, automating duties and operating scripts. Working on repositories, GitHub Actions can simply be included with different companies on GitHub: from bots, to branches, and to tug requests.
This use case demonstrates the ability of GitHub Actions past automating deployment; extending into the world of studying and training.