Lab session
Continuous Integration with GitHub Actions
Build a GitHub Actions workflow, diagnose a failed check from its log, and restore a green commit.
Overview¶
Continuous integration (CI) runs repository checks in a shared environment whenever the repository changes. In this lab, you will use GitHub Actions to turn a service's existing tests and static analysis into CI checks. You will then use the log from a failed run to find a source defect, repair it, and confirm that the same workflow accepts the repaired commit.
🎯 Learning Goals¶
After completing this lab, you should be able to:
- Translate repository-local check commands into a GitHub Actions workflow
- Explain the roles of workflow events, jobs, runners, and steps
- Use a failed step's log to identify the command and source finding that caused a CI run to fail
- Repair a failing check and verify that a later commit passes the same workflow
Deliverables¶
By the end of the lab, your fork should run the service's tests and static analysis in GitHub Actions on every push and pull request. Your final commit should contain the source repair identified from the first failed run and should pass the workflow. You will submit the URL of that specific commit through Canvas.
Setup¶
Fork the starter repository to your own account and open your fork in the provided devcontainer. Do not push commits to the upstream course repository. Instead, work entirely in your fork.
The starter is a small synthetic Node.js HTTP service with deterministic tests and a supplied ESLint configuration.
The .nvmrc file declares the Node.js version for both local and CI use.
You will create the missing GitHub Actions workflow; do not replace the supplied tests, linter configuration, or check script.
From the repository root, establish the starter baseline:
node --version
npm ci
npm test
Setup is complete when Node.js reports major version 22, dependency installation succeeds, and every test passes.
Tasks¶
Task 1: Turn the Local Checks into a Workflow¶
Inspect .nvmrc and the scripts object in package.json.
Together, they declare the runtime and the two project checks that CI must reproduce.
Create one YAML workflow under .github/workflows/ that:
- Runs on both pushes and pull requests
- Uses a GitHub-hosted Linux runner
- Checks out the commit being tested
- Configures the Node.js version declared by
.nvmrc - Installs the locked dependencies with
npm ci - Runs both project checks declared in
package.json
Use the official actions/checkout@v7 and actions/setup-node@v7 actions; later compatible major releases are also acceptable.
You may choose the workflow filename, names for its job and steps, and whether setup-node reads .nvmrc directly or receives its declared major version.
Keep all the checks in one job so that its steps share one checked-out workspace.
This abbreviated shape shows the GitHub Actions pieces without specifying your workflow:
name: YOUR-WORKFLOW-NAME
on: [EVENT, EVENT]
jobs:
YOUR-JOB-NAME:
runs-on: RUNNER-LABEL
steps:
- uses: ACTION
- run: COMMAND
How a workflow runs
GitHub reads a workflow from the commit being tested. An event such as a push starts the workflow, each job receives a fresh runner, and the job's steps run in order on that runner. The checkout action puts the commit on the runner, while the setup action installs the requested runtime. A command that exits nonzero fails its step and therefore fails the job.
Before pushing, predict which of the two project checks will pass and which will fail on the starter source. Commit the workflow and push it to your fork. Then open the Actions tab and enable workflows if GitHub asks you to enable them for the fork. Open the run for your commit and find the first failed step.
Check your reasoning: Why must CI install dependencies?
A GitHub-hosted job starts on a fresh runner and does not inherit the node_modules directory from your devcontainer.
npm ci reconstructs the dependency tree from the committed lockfile before the later steps use it.
Task 2: Diagnose and Repair the Failed Check¶
Expand the failed step in the Actions log. Identify the command that exited nonzero, the ESLint rule that caused that exit, and the source file and line reported by the rule.
Run the same command in the devcontainer to reproduce the result. The affected function is meant to deserialize a JSON configuration string as data. Repair that function so it parses valid JSON without evaluating the string as JavaScript. Do not disable the rule or weaken the supplied ESLint configuration.
Run both project checks locally after the repair:
npm test
npm run lint
The linter may continue to print a warning-level finding, but both commands should exit zero. Commit and push the repair, then confirm that the new workflow run is green.
A failed check is evidence, not a diagnosis
GitHub Actions decides success from each command's exit status. ESLint uses the configured severity to choose that status: an error makes this lint command exit nonzero, while warnings remain visible without failing it. The log tells you which check produced the evidence; you still have to decide whether the defect is in the workflow, its environment, or the checked source.
Check your reasoning: Why did the workflow turn green even though warnings remain?
The repair removed the error-level finding that caused ESLint to exit nonzero. The supplied lint policy reports its remaining finding at warning severity, so it is visible but does not fail the step.
Task 3: Challenge the Final Result¶
Run the supplied checker from the repository root:
./scripts/check-lab
The checker runs the project checks and verifies the repaired parser behavior. It also temporarily adds an unsafe JavaScript control and confirms that the supplied lint policy still rejects it. Finally, it inspects your workflow for the events, runner setup, and commands exercised in this lab. The checker removes its temporary control before it exits.
Your final GitHub Actions run is still the authoritative execution of the workflow on a fresh runner. If the local checker passes but that run does not, use the failed step's log to compare the runner with your local environment.
Additional Resources¶
- GitHub Actions workflow syntax: events, jobs, steps, and triggers
- Using GitHub-hosted runners: hosted runner behavior and labels
- actions/checkout: checking out the commit on a runner
- actions/setup-node: installing Node.js and enabling npm cache support
- npm ci documentation: reproducible dependency installation from a lockfile
- ESLint command-line interface: output and exit codes
Submission¶
- Commit your workflow and source repair, then push that commit to your fork.
- Confirm that
git status --shortproduces no output, run./scripts/check-labone last time, and confirm that the GitHub Actions run for the same commit is green. - Submit the URL of that exact commit—not a branch or pull request—using the Canvas link below.
This lab is graded pass/fail.