Goal: Reinforce GitHub Actions understanding through three progressively challenging drills, culminating in setting up a workflow to trigger Jest tests.
By the end of this lab, students will have all the skills needed to complete Assignment 4 and the Final Project.
Lab Structure
Overview
Section 1: Basic GitHub Actions Workflow – Echo Commands Section 2: Automating Code Linting with GitHub Actions Section 3: Running Jest Tests with GitHub Actions Each section includes:
Entry Point (Learning Outcome): What students will learn. Checklist Instructions: Step-by-step micro-tasks. Exit Point (Accomplishment): What students will have achieved. Condensed Version:
Section 1: Basic GitHub Actions Workflow
Entry Point (Learning Outcome):
Understand the basic structure of a GitHub Actions workflow by creating a simple workflow that echoes commands to the console.
Following the earlier lab work from last week: You have:
Create a GITHUB cloud repository. Clone this to a local repository. → In this local clone directory: you put whatever files you want into this directory. (Sublime is the preferred text editor for working here, due to handling .git GIT PUSH syncs local files up to Cloud. Once that YAML File in in Git HUB REPO: it will start doing its job. To repeat the process of Creating a GITHUB REPO and cloning it to the local file system: see this Lab Book:
Checklist Instructions:
In your local repository: mkdir -p .github/workflows
touch .github/workflows/basic.yml
If the .github directory does not exist, you can easily create it manually. Here's how to proceed:
Creating the .github Directory and workflows Subdirectory
Step-by-Step Instructions:
Manually Create the Directory: In your terminal or PowerShell, run the following commands to create the necessary directories: mkdir .github/workflows {this is where our YAML file will go} If you're on Windows and encounter syntax issues, you can split it into two steps: Verify the Directory Structure: Run the following command to ensure the directories were created: A directory named workflows should appear under .github. now → To create the basic.yml file in the workflows directory, follow these simple steps:
Creating basic.yml in the workflows Directory
Step-by-Step Instructions:
Navigate to the workflows Directory: Use the following command in your terminal or PowerShell: Use Sublime to create the file: Add Workflow Content to basic.yml: Open the file in the editor and paste the following content: Save the changes and close the editor. Check the directory for the basic.yml file: You should see basic.yml listed. Commit and Push the Workflow: Add the file to Git and commit the changes: git add basic.yml {adds unstaged changes to local git repo staging area} git commit -m "Added basic GitHub Actions workflow" {push staged file to a commited level} Result:
You have successfully created the basic.yml file in the workflows directory, and it is now part of your repository.
The gh command-line tool focuses on GitHub-specific actions like managing repositories, issues, pull requests, etc. For basic Git operations (e.g., git add, git commit, git push), you still use the standard git commands.
The commands in your workflow (git add, git commit, git push) do not need to change, even though you authenticated with gh auth login.
Why Keep Using git for These Commands?
git add: Stages files for commit locally. git commit: Commits changes locally. git push: Pushes changes from the local repository to GitHub. The gh CLI is not designed to replace these fundamental Git commands but to enhance interactions with GitHub-specific features.
When to Use gh Instead?
Cloning repositories: gh repo clone Creating repositories: gh repo create Viewing or managing pull requests: gh pr Authenticating: gh auth login Continue using git for core Git operations, such as adding files, committing changes, and pushing/pulling updates. Result:
The listed commands (git add, git commit, git push) are correct and do not need to change when using gh auth login. Would you like additional examples to clarify how gh complements git?
Add the following content to basic.yml:
name: Basic Workflow
on:
push:
branches: [main]
jobs:
echo_job:
runs-on: ubuntu-latest
steps:
- name: Checkout Code
uses: actions/checkout@v2
- name: Echo Command
run: echo "Hello, GitHub Actions!"
For yml, indentation matters! You can get a run failure due to incorrect indention:
Fix the Indentation
Here’s how your workflow file should look with proper formatting:
yaml
name: Basic Workflow
on:
push:
branches: [main]
jobs:
echo_job:
runs-on: ubuntu-latest
steps:
- name: Checkout Code
uses: actions/checkout@v2
- name: Echo Command
run: echo "Hello, GitHub Actions!"
Key Points:
The steps block must be indented under jobs.echo_job. Each - name and uses/run pair must align correctly under the steps block. Ensure uses: actions/checkout@v2 is aligned under name: Checkout Code. Adjust all indentation levels to match the example above. How to Fix It Locally
Open the file (basic.yml) in your editor. Apply the corrected formatting as shown above. Save the File and Commit Changes: git add .github/workflows/basic.yml
git commit -m "Fix YAML syntax in workflow file"
git push
Trigger the Workflow Again: Make any small change to the repository (e.g., modify README.md), commit, and push to trigger the workflow. Verifying the Fix
Go to the Actions tab in your GitHub repository. Look for the new workflow run. If the syntax is correct, the workflow will execute successfully. Commit and push the workflow:
git add .github/workflows/basic.yml
git commit -m "Add basic GitHub Actions workflow"
git push
Run git status and git diff --cached after staging files (git add ...) and before committing (git commit), or after committing and before pushing (git push).
IF before doing this, you made changes directly on GitHub, a divergence occurred because your remote branch (origin/main) now contains commits that are not in your local branch (main). Here's how to sync your local branch with the remote one and push your changes safely:
Steps to Resolve Divergence
1. Pull the Remote Changes
You need to fetch and merge the changes from GitHub into your local branch. Run:
git pull origin main
This will bring the changes you made directly on GitHub into your local repository. If there are no conflicts, Git will merge the changes automatically. 2. Handle Merge Conflicts (If Any)
If there are conflicting changes between your local and remote commits, Git will stop the merge and display a list of files with conflicts. Here’s how to resolve them:
Open the conflicting files and manually resolve the conflicts. Look for markers like this: Keep the desired changes and remove the conflict markers (<<<<<<<, =======, >>>>>>>). Mark the conflicts as resolved by running:
Complete the merge with:
git commit -m "Resolved merge conflicts"
3. Push Your Changes
After resolving conflicts (if any), push your local changes back to GitHub:
git push origin main
Quick Explanation
Why git pull is necessary: It ensures your local branch contains the commits from GitHub before adding your own changes. Why conflicts might happen: Both the remote and local branches modified the same lines in the same files. Pro Tip for Future Workflows
If you plan to work on the repository both locally and directly on GitHub, follow these best practices to avoid divergence:
Always pull the latest changes from GitHub before starting local work: Avoid making changes directly on GitHub when collaborating with local work.
Test the Workflow:
Make a small code change to trigger the workflow:
echo "// Minor edit" >> index.js
git add .
git commit -m "Trigger basic workflow"
git push
Go to the Actions tab on GitHub to observe the workflow execution. Exit Point (Accomplishment):
Students have created and tested a simple GitHub Actions workflow that runs on every push to the main branch.
You observed the Action in the GIT Actions Panel of the GitHub Repository.
Section 2: Automating Code Linting
Entry Point (Learning Outcome):
Learn how to automate linting using GitHub Actions to ensure code quality.
Checklist Instructions:
In your project directory: npm -init
npm install eslint --save-dev
npx eslint --init
Follow the prompts to configure ESLint. Create a Linting Workflow: touch .github/workflows/lint.yml
Add the following content to lint.yml: yaml
name: Lint Workflow
on:
push:
branches: [main]
jobs:
lint_job:
runs-on: ubuntu-latest
steps:
- name: Checkout Code
uses: actions/checkout@v2
- name: Setup Node.js
uses: actions/setup-node@v2
with:
node-version: '16'
- name: Install Dependencies
run: npm install
- name: Run ESLint
run: npx eslint . --ext .js
Commit and push the workflow: git add .github/workflows/lint.yml
git commit -m "Add linting workflow"
git push
Introduce a linting error (e.g., remove a semicolon in index.js) and push: echo console.log('Lint error') >> index.js // cmd line generate a small file
git add .
git commit -m "Test linting workflow"
git push
Check the Actions tab for linting results.
Exit Point (Accomplishment):
Students have automated linting using GitHub Actions and understand how to enforce code quality standards.
add a .gitignore file to exclude the node_modules directory (or any other files/directories) from being pushed to the repository.
Here's how to do it:
Steps to Add .gitignore for node_modules
Create a .gitignore File: If you don’t already have a .gitignore file in your repository, create one: Edit the .gitignore File: Open the .gitignore file in a text editor and add the following line: This tells Git to ignore the node_modules directory. Remove node_modules from Tracking (If Already Added): If node_modules is already being tracked by Git, you need to remove it from the Git index: git rm -r --cached node_modules This removes the directory from tracking but leaves it intact locally. Stage and commit the .gitignore file and the changes to stop tracking node_modules: git commit -m "Add .gitignore to exclude node_modules" Push the Changes to GitHub: Push the changes to the remote repository: Verify the .gitignore is Working
After making these changes, any files in the node_modules directory will no longer appear in git status, and they won’t be pushed to the remote repository. Best Practices
It’s a good practice to always include node_modules in .gitignore for JavaScript/Node.js projects to avoid unnecessary large file uploads and ensure the repository stays clean. now → Section 3: Running Jest Tests with GitHub Actions
Entry Point (Learning Outcome):
Master how to automate running Jest tests with GitHub Actions.
Checklist Instructions:
Verify Jest Tests Are Ready: Confirm your __tests__/example.test.js exists and works locally: Create a Testing Workflow: Add another workflow file: touch .github/workflows/test.yml
Add the following content to test.yml: yaml
name: Jest Tests
on:
push:
branches: [main]
jobs:
test_job:
runs-on: ubuntu-latest
steps:
- name: Checkout Code
uses: actions/checkout@v2
- name: Setup Node.js
uses: actions/setup-node@v2
with:
node-version: '16'
- name: Install Dependencies
run: npm install
- name: Run Jest Tests
run: npx jest
Commit and push the workflow: git add .github/workflows/test.yml
git commit -m "Add Jest testing workflow"
git push
Make a small code change and push: echo "// Test Jest workflow" >> index.js
git add .
git commit -m "Testing Jest workflow"
git push
Go to the Actions tab and review the test results. Exit Point (Accomplishment):
Students can automate Jest tests, ensuring each commit triggers tests and provides pass/fail results in GitHub Actions.
Key Outcomes for Students:
Section 1: Basic GitHub Actions workflow understanding. Section 2: Automation of code linting for quality assurance. Section 3: Running Jest tests with GitHub Actions for CI/CD. By completing this lab, students will have mastered GitHub Actions and be fully prepared for Assignment 4 and the Final Project.
Let’s run a JEST testing workflow sequence
Lab: Running Jest Tests with GitHub Actions for a TypeScript Program
Objective
Students will create a simple TypeScript program that adds two numbers, write a Jest test to verify the functionality, and automate testing using GitHub Actions.
This lab will guide students step-by-step through writing, testing, and pushing the program, while ensuring they can observe test results in the GitHub Actions log.
Checklist Instructions
1. Create a TypeScript Program
Initialize the TypeScript Project: In the project folder, initialize the project with: npm init -y
npm install typescript jest ts-jest @types/jest --save-dev
npx tsc --init
Write the TypeScript Program: Create a file named add.ts: Add the following content: export function add(a: number, b: number): number {
return a + b;
}
Compile the TypeScript Program: Compile to JavaScript with: 2. Write Jest Tests
Create a Jest configuration file: Create a test file named add.test.ts in the __tests__ directory: mkdir __tests__
touch __tests__/add.test.ts
import { add } from '../add';
test('adds 1 + 2 to equal 3', () => {
expect(add(1, 2)).toBe(3);
});
test('adds -1 + -1 to equal -2', () => {
expect(add(-1, -1)).toBe(-2);
});
Verify that tests pass locally: 3. Set Up GitHub Actions
mkdir -p .github/workflows
touch .github/workflows/test.yml
Add the Workflow Configuration: Add the following content to test.yml: name: Jest Tests
on:
push:
branches: [main]
jobs:
test_job:
runs-on: ubuntu-latest