|
| 1 | +# Introduction & Your First CI Workflow |
| 2 | + |
| 3 | +| [← GitHub Actions: From CI to CD][walkthrough-previous] | [Next: The Marketplace & Caching →][walkthrough-next] | |
| 4 | +|:-----------------------------------|------------------------------------------:| |
| 5 | + |
| 6 | +**Estimated time: 25 minutes** |
| 7 | + |
| 8 | +[GitHub Actions][github-actions] is an automation platform built into GitHub that lets you build, test, and deploy your code directly from your repository. While it's most commonly used for CI/CD, it can automate just about any task in your development workflow — from labeling issues to resizing images. |
| 9 | + |
| 10 | +Before diving in, here are the key terms you'll encounter: |
| 11 | + |
| 12 | +- **Workflow**: An automated process defined in a YAML file, stored in `.github/workflows/`. |
| 13 | +- **Event**: A trigger that starts a workflow, such as a `push`, `pull_request`, or `workflow_dispatch`. |
| 14 | +- **Job**: A set of steps that run on the same runner. Jobs run in parallel by default. |
| 15 | +- **Step**: An individual task within a job — either a shell command (`run`) or a reusable action (`uses`). |
| 16 | +- **Runner**: The virtual machine that executes your jobs (e.g., `ubuntu-latest`). |
| 17 | +- **Action**: A reusable unit of code that performs a specific task, published on the [Actions Marketplace][actions-marketplace]. |
| 18 | + |
| 19 | +## Scenario |
| 20 | + |
| 21 | +The shelter has built its application — a Flask API and Astro frontend — and now needs to automate testing to catch issues before they reach production. The goal is to ensure tests run on every push and pull request so that broken code never makes it to the main branch unnoticed. |
| 22 | + |
| 23 | +## Understanding GitHub Actions |
| 24 | + |
| 25 | +A workflow file is written in YAML and lives in the `.github/workflows/` directory. Here are the core sections you'll work with: |
| 26 | + |
| 27 | +- `name`: A human-readable name for the workflow, displayed in the **Actions** tab. |
| 28 | +- `on`: Defines the events that trigger the workflow (e.g., `push`, `pull_request`). |
| 29 | +- `jobs`: Contains one or more jobs, each with a unique identifier. |
| 30 | + - `runs-on`: Specifies the runner environment (e.g., `ubuntu-latest`). |
| 31 | + - `steps`: An ordered list of tasks the job performs. |
| 32 | + - `uses`: References a reusable action (e.g., `actions/checkout@v4`). |
| 33 | + - `run`: Executes a shell command. |
| 34 | + |
| 35 | +## Create the CI workflow |
| 36 | + |
| 37 | +Let's create your first workflow to run the API tests automatically. |
| 38 | + |
| 39 | +> [!TIP] |
| 40 | +> If you have GitHub Copilot, try asking it to generate a GitHub Actions workflow for running Python tests. You can compare its output with the steps below! |
| 41 | +
|
| 42 | +1. In your repository, create the folder `.github/workflows/` if it doesn't already exist. |
| 43 | +2. Create a new file named `.github/workflows/ci.yml`. |
| 44 | +3. Add the following content: |
| 45 | + |
| 46 | + ```yaml |
| 47 | + name: CI |
| 48 | + |
| 49 | + on: |
| 50 | + push: |
| 51 | + branches: [main] |
| 52 | + pull_request: |
| 53 | + branches: [main] |
| 54 | + |
| 55 | + jobs: |
| 56 | + test-api: |
| 57 | + runs-on: ubuntu-latest |
| 58 | + |
| 59 | + steps: |
| 60 | + - uses: actions/checkout@v4 |
| 61 | + |
| 62 | + - name: Set up Python |
| 63 | + uses: actions/setup-python@v5 |
| 64 | + with: |
| 65 | + python-version: '3.12' |
| 66 | + |
| 67 | + - name: Install dependencies |
| 68 | + run: | |
| 69 | + python -m pip install --upgrade pip |
| 70 | + pip install -r server/requirements.txt |
| 71 | + pip install pytest |
| 72 | +
|
| 73 | + - name: Run tests |
| 74 | + working-directory: ./server |
| 75 | + run: | |
| 76 | + python -m pytest test_app.py -v |
| 77 | + ``` |
| 78 | +
|
| 79 | +4. Save the file. |
| 80 | +
|
| 81 | +> [!NOTE] |
| 82 | +> The workflow triggers on both `push` to main and `pull_request` targeting main. This ensures tests run whether you push directly or open a PR. |
| 83 | + |
| 84 | +## Push and explore |
| 85 | + |
| 86 | +Now let's push the workflow and see it in action. |
| 87 | + |
| 88 | +1. Stage and commit your changes: |
| 89 | + |
| 90 | + ```bash |
| 91 | + git add .github/workflows/ci.yml |
| 92 | + git commit -m "Add CI workflow" |
| 93 | + ``` |
| 94 | + |
| 95 | +2. Push to your repository: |
| 96 | + |
| 97 | + ```bash |
| 98 | + git push |
| 99 | + ``` |
| 100 | + |
| 101 | +3. Navigate to your repository on GitHub and select the **Actions** tab. |
| 102 | +4. You should see the **CI** workflow running. Select it to view the details. |
| 103 | +5. Select the **test-api** job to explore the logs for each step — you'll see the checkout, Python setup, dependency installation, and test results. |
| 104 | + |
| 105 | +## Add a build job |
| 106 | + |
| 107 | +With the API tests passing, let's add a job to build the frontend client. |
| 108 | + |
| 109 | +1. Open `.github/workflows/ci.yml` and add the following job below `test-api`: |
| 110 | + |
| 111 | + ```yaml |
| 112 | + build-client: |
| 113 | + runs-on: ubuntu-latest |
| 114 | + needs: test-api |
| 115 | +
|
| 116 | + steps: |
| 117 | + - uses: actions/checkout@v4 |
| 118 | +
|
| 119 | + - name: Set up Node.js |
| 120 | + uses: actions/setup-node@v4 |
| 121 | + with: |
| 122 | + node-version: '20' |
| 123 | +
|
| 124 | + - name: Install dependencies |
| 125 | + working-directory: ./client |
| 126 | + run: npm ci |
| 127 | +
|
| 128 | + - name: Build client |
| 129 | + working-directory: ./client |
| 130 | + run: npm run build |
| 131 | + ``` |
| 132 | + |
| 133 | + > [!NOTE] |
| 134 | + > The `needs: test-api` line creates a dependency — `build-client` will only run after `test-api` completes successfully. Remove this line if you'd prefer both jobs to run in parallel. |
| 135 | + |
| 136 | +2. Save the file. |
| 137 | +3. Stage, commit, and push: |
| 138 | + |
| 139 | + ```bash |
| 140 | + git add .github/workflows/ci.yml |
| 141 | + git commit -m "Add client build job to CI workflow" |
| 142 | + git push |
| 143 | + ``` |
| 144 | + |
| 145 | +4. Return to the **Actions** tab and observe both jobs. If you used `needs`, you'll see them run sequentially; otherwise they'll run in parallel. |
| 146 | + |
| 147 | +## Summary and next steps |
| 148 | + |
| 149 | +Congratulations! You've created your first CI workflow with GitHub Actions. Tests now run automatically on every push and pull request, and the client is built to verify there are no build errors. This is the foundation of continuous integration — catching problems early so they don't reach production. |
| 150 | + |
| 151 | +Next, we'll explore the [Actions Marketplace][walkthrough-next] to discover pre-built actions and speed up our workflow with caching. |
| 152 | + |
| 153 | +### Resources |
| 154 | + |
| 155 | +- [GitHub Actions documentation][github-actions-docs] |
| 156 | +- [Workflow syntax for GitHub Actions][workflow-syntax] |
| 157 | +- [Events that trigger workflows][workflow-triggers] |
| 158 | +- [Understanding GitHub Actions][understanding-actions] |
| 159 | + |
| 160 | +| [← GitHub Actions: From CI to CD][walkthrough-previous] | [Next: The Marketplace & Caching →][walkthrough-next] | |
| 161 | +|:-----------------------------------|------------------------------------------:| |
| 162 | + |
| 163 | +[actions-marketplace]: https://github.com/marketplace?type=actions |
| 164 | +[github-actions]: https://github.com/features/actions |
| 165 | +[github-actions-docs]: https://docs.github.com/en/actions |
| 166 | +[understanding-actions]: https://docs.github.com/en/actions/about-github-actions/understanding-github-actions |
| 167 | +[workflow-syntax]: https://docs.github.com/en/actions/writing-workflows/workflow-syntax-for-github-actions |
| 168 | +[workflow-triggers]: https://docs.github.com/en/actions/writing-workflows/choosing-when-your-workflow-runs/events-that-trigger-workflows |
| 169 | +[walkthrough-previous]: README.md |
| 170 | +[walkthrough-next]: 1-marketplace-and-caching.md |
0 commit comments