Skip to content

Commit 0aa9b0e

Browse files
committed
Updated and fleshed out ci exercise
1 parent 664d3d6 commit 0aa9b0e

File tree

3 files changed

+151
-16
lines changed

3 files changed

+151
-16
lines changed

content/guided-workshop/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ Ready to get started? Let's go! The workshop scenario imagines you as a develope
3232
1. [Enable Code Scanning](exercises/1-code-scanning.md) to ensure new code is secure
3333
2. [Create an issue](exercises/2-issues.md) to document a feature request
3434
3. [Create a codespace](exercises/3-codespaces.md) to start writing code
35-
4. [Implement continuous integration](exercises/4-ci.md) to test new code
35+
4. [Implement testing](exercises/4-testing.md) to supplement continuous integration
3636
5. [Add a new feature](exercises/5-coding.md) to implement the feature
3737
6. [Create a pull request](exercises/6-pull-request.md) to begin a code review
3838
7. [Add automation](exercises/7-automation.md) to create a deployment environment

content/guided-workshop/exercises/4-ci.md

Lines changed: 0 additions & 15 deletions
This file was deleted.
Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
# Continuous integration and testing
2+
3+
Chances are you've heard the abbreviation CI/CD, which stands for continuous integration and continuous delivery (or sometimes continuous deployment). CI is centered on incorporating new code into the existing codebase, and typically includes running tests and performing builds. CD focuses on the next logical step, taking the now validated code and generating the necessary outputs to be pushed to the cloud or other destinations. This is probably the most focused upon component of DevOps.
4+
5+
CI/CD fosters a culture of rapid development, collaboration, and continuous improvement, allowing organizations to deliver software updates and new features more reliably and quickly. It ensures consistency, and allows developers to focus on writing code rather than performing manual processes.
6+
7+
[GitHub Actions](https://github.com/features/actions) is an automation platform upon which you can build your CI/CD process. It can also be used to automate other tasks, such as resizing images and validating machine learning models.
8+
9+
## Scenario
10+
11+
A couple of front-end tests have already been defined for the project using [Cypress](https://www.cypress.io/), a popular framework for testing. One of the tests includes checking for the component you'll be adding in a later exercise. To implement CI, you want to run these tests whenever new code is suggested or merged into the **main** branch of the project.
12+
13+
> **IMPORTANT:** Because the test will look for a component you have not yet created, it will fail when it runs for the first time. In an upcoming exercise you will add the code for the test to pass.
14+
15+
## Exploring the test
16+
17+
Let's take a look at the tests defined for the project.
18+
19+
> **NOTE:** There are only two tests defined for this project. Many projects will have hundreds or thousands of tests to ensure reliability.
20+
21+
1. Return to your codespace, or reopen it by navigating to your repository and selecting **Code** > **Codespaces** and the name of your codespace.
22+
1. In **Explorer**, navigate to **src** > **cypress** > **e2e**, and open **app.cy.ts**.
23+
1. Note the following test, which looks for an element with an id of `hours` and ensures the name of today is displayed:
24+
25+
```typescript
26+
it('should display todays day', () => {
27+
// start from the index page
28+
cy.visit('http://localhost:3000/')
29+
30+
// get today's long day name
31+
const today = new Date().toLocaleDateString('en-US', { weekday: 'long' })
32+
33+
// confirm div with id of hours has today's day
34+
cy.get('#hours').contains(today)
35+
})
36+
```
37+
38+
## Creating the workflow
39+
40+
To run the tests, we'll need to perform a couple of steps. We need to create an environment in which the tests can run, to checkout the code, then run the tests with the appropriate configuration.
41+
42+
As you might expect, performing these types of actions is something numerous organizations need to do as part of their DevOps processes. To support these organizations, there is a [marketplace](https://github.com/marketplace?type=actions) hosted by GitHub containing actions for these and many other tasks. You can then create workflows which build upon these actions.
43+
44+
Workflows are defined as [YAML (or YML)](https://en.wikipedia.org/wiki/YAML) files, and stored as part of the project in a special folder named **.github/workflows**. By being part of the repository, they are subject to the exact same source controls as all other code. It also makes it easier to manage as everything you need is right there in the repository.
45+
46+
Let's create a workflow to implement testing.
47+
48+
1. In the root of your project in the **Explorer** window, navigate to **.github**.
49+
1. Select the **New Folder** button in the **Explorer** window, and name it **workflows**.
50+
1. Create a new file in the **workflows** folder by selecting **New File** in the **Explorer** window and name it **e2e.yml**.
51+
1. In the new file, copy the following YML to create the workflow (we'll describe it in below this step):
52+
53+
```yml
54+
name: End-to-end tests
55+
on:
56+
push:
57+
branches: ["main"]
58+
pull_request:
59+
branches: ["main"]
60+
jobs:
61+
cypress-run:
62+
runs-on: ubuntu-20.04
63+
steps:
64+
- name: Checkout
65+
uses: actions/checkout@v3
66+
# Install NPM dependencies, cache them correctly
67+
# and run all Cypress tests
68+
- name: Cypress run
69+
uses: cypress-io/github-action@v5
70+
with:
71+
build: npm run build
72+
start: npm run start
73+
project: ./source
74+
env:
75+
MONGODB_URI: test
76+
```
77+
78+
> **IMPORTANT:** YML is sensitive to tab/space levels. Ensure the tabbing is as displayed above.
79+
80+
### Explaining the workflow
81+
82+
To make this exercise easier, we provided the full YML for the workflow. Let's breakdown what's happening.
83+
84+
- `name`: Provides a name for the workflow, which will display in the logs.
85+
- `on`: Defines when the workflow will run. In our case, it will run whenever new code is pushed (or merged) into `main`, or a pull request is made to `main`.
86+
- `jobs`: Defines a series of jobs for this workflow. Each job is considered a unit of work.
87+
- `runs-on`: Where the operations for the job will be performed.
88+
- `steps`: The operations to be performed.
89+
90+
The `steps` section is broken down into two steps, each calling an action from the marketplace. The first is [checkout](https://github.com/marketplace/actions/checkout), which as the name implies, checks out your code. The trailing **@v3** pins the version of the action being used.
91+
92+
Next is [Cypress](https://github.com/marketplace/actions/cypress-io), which will run the tests. Note there are a couple of configuration options which need to be set:
93+
94+
- `build`: The build command for the project.
95+
- `start`: The command to start the website.
96+
- `project`: The location of the source code so Cypress can find the tests.
97+
- `MONGODB_URI`: The location of the backend database to use for the project.
98+
99+
> **NOTE:** The application is configured to use [MongoDB In-Memory Server](https://github.com/nodkz/mongodb-memory-server) when `MONGODB_URI` is set to **test**. For sensitive values, you can create [encrypted secrets](https://docs.github.com/en/actions/security-guides/encrypted-secrets) for the repository.
100+
101+
## Push the workflow to the repository
102+
103+
With the workflow created, let's push it to the repository. Typically you would create a [pull request](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/about-pull-requests) for any new code (which this is). To streamline the process, we're going to push straight to main as we'll be exploring pull requests and the [GitHub flow](https://docs.github.com/en/get-started/quickstart/github-flow) in a later exercise. You'll start by obtaining the number of the [issue you created earlier](./2-issues.md), creating a commit for the new code, then pushing it to main.
104+
105+
1. Open a terminal window in your codespace by pressing <kbd>Ctl</kbd> + <kbd>`</kbd>.
106+
1. List all issues for the repository by entering the following command in the terminal window and pressing <kbd>Enter</kbd> (or <kbd>Return</kbd> on a Mac):
107+
108+
```bash
109+
gh issue list
110+
```
111+
112+
1. Note the issue number for the one titled **Implement testing**.
113+
1. Stage all files by entering the following command in the terminal window and pressing <kbd>Enter</kbd> (or <kbd>Return</kbd> on a Mac):
114+
115+
```bash
116+
git add .
117+
```
118+
119+
1. Commit all changes with a message by entering the following command in the terminal window and pressing <kbd>Enter</kbd> (or <kbd>Return</kbd> on a Mac), replacing **<ISSUE_NUMBER>** with the number for the **Implement testing** issue:
120+
121+
```bash
122+
git commit -m "Resolves #<ISSUE_NUMBER>"
123+
```
124+
125+
1. Push all changes to the repository by entering the following command in the terminal window and pressing <kbd>Enter</kbd> (or <kbd>Return</kbd> on a Mac):
126+
127+
```bash
128+
git push
129+
```
130+
131+
Congratulations! You've now implemented testing, a core component of continuous integration (CI)!
132+
133+
## Seeing the workflow in action
134+
135+
Pushing the workflow definition to the repository counts as a push to `main`, meaning the workflow will be triggered. You can see the workflow in action by navigating to the **Actions** tab in your repository.
136+
137+
> **IMPORTANT:** The workflow **WILL FAIL** on the first run. This is expected. In the next exercise you will add the code to ensure the test passes.
138+
139+
1. Return to your repository.
140+
1. Select the **Actions** tab.
141+
1. Select the name of the action on the left side.
142+
1. Note the test running (and eventually failing). You can click the name of the action to see the individual steps, and the logs provided by those steps.
143+
144+
## Summary and next steps
145+
146+
Implementing continuous integration and continuous deployment is critical to successful DevOps. Automating these processes ensures consistency and reduces the workload required for developers and administrators. You have created a workflow to run tests on any new code for your codebase.
147+
148+
Let's turn our attention to [adding code to our project](./5-coding.md).
149+
150+
### Resources

0 commit comments

Comments
 (0)