AICODEAgentic Programming · 67723 · 2026-7

Week 6 · video 5 of 6 · transcript

CI and GitHub Actions

0:00

A local check gives fast feedback while you work. A shared project also needs checks on changes arriving from other machines. We will follow a change pushed to GitHub through a failing check and a correction, and read the GitHub Actions workflow that runs the check.

0:18

People can contribute from different environments. One person uses our configured agent, another uses a different tool, and someone makes a small change in the browser. The project needs a way to check those changes that does not depend on each contributor having the same local hook.

0:35

Continuous integration, or CI, means integrating changes into a shared codebase frequently, and using automated builds and checks to find problems early. A shared checking service supports that practice. It shows the result together with the change, so the team can see which version was checked and investigate a failure.

0:55

This changes how a team works. Imagine several developers working separately for weeks, then bringing all their changes together for a large release. When something breaks, they have many changes to investigate, and they may discover that their code relies on incompatible assumptions.

1:12

With continuous integration, we bring small changes into the shared codebase throughout development. Automated builds and tests give us feedback on each change, while the work is still fresh and there is less code to investigate. We can fix a problem before more work builds on it. Continuous delivery extends this idea to keeping the software ready to release. The team can release smaller updates as they are ready, without saving all the integration and testing for a large release at the end. Integrating a change does not mean we must immediately release it to users. Let's follow one small change through the checks that support this way of working.

1:50

Before we try this, what does it cost? GitHub calls the machines that execute our jobs runners. Standard GitHub-hosted runners are free for public repositories. For private repositories, GitHub Free currently includes two thousand minutes each month, shared across the repository owner's private repositories. Other plans have different allowances. This free allowance is useful for small personal projects. Larger runners and usage beyond the allowance cost extra.

2:19

Suppose we're updating a small Python project that adds up item counts. The function should return the sum, but our change accidentally replaces it with zero. For the list containing two and three, we should get five. Let's see what happens if we commit this mistake and push it to GitHub. We've configured the repository to run the project checks whenever we push to "main".

2:42

We commit the changed file and push it to "main". GitHub Actions starts a workflow run for the pushed commit. In the repository's Actions tab, we can open that run and see the steps and their output. That gives everyone on the project access to the same check result.

3:00

The workflow runs the project's check command. The test expects five and receives zero, so it fails. That failure is attached to the pushed commit. We can see the command and its output without asking the contributor to copy a message from their terminal.

3:16

What started this check? A workflow file in the repository tells GitHub Actions when to run and what to execute. Let's read the file that runs our project checks.

3:27

A workflow describes the automation. It contains jobs, and each job contains steps. Our first workflow has one job. Its steps obtain the code, prepare Python, install the dependencies and run the project check.

3:43

A runner is the machine that executes a job. In this example, GitHub supplies a fresh hosted runner, and the job's steps run there in sequence. Each step either runs a shell command or uses an action. An action is reusable code for a task such as checking out the repository or setting up Python.

4:03

This is a YAML file. A key followed by a colon introduces a value or a nested section, and the indentation shows what belongs inside it. The name identifies the workflow. The on section selects the events that start it. Here, "pull request" means that GitHub runs the workflow on every pull request, before it can be merged. "Push" means that it also runs when we push code, and the branches entry limits that to "main". The workflow file must be committed and pushed along with the project. Each subsequent push to "main" starts another run.

4:39

The permissions entry gives the workflow's repository token read access to the contents. Under jobs, checks names our job, and runs on selects a hosted Ubuntu runner. Inside that job, we list the steps that prepare the machine and run our checks.

4:56

The steps continue the same file, inside the checks job. Each dash begins another step in the list. Uses names an action. Checkout obtains the repository files, and setup dash python installs Python three point twelve, the version we chose for the local example as well. The number after the at sign is the action's own version, not the Python version.

5:21

Run executes a shell command on the runner. First we install the development dependencies from requirements dev dot txt. Then we run the same checking script that we use locally. If a checker fails, the script exits with a failure status. That makes this step fail, and GitHub reports the job as failed.

5:41

The runner checks out the repository and follows the workflow's setup instructions. It does not copy your laptop's working directory or its installed packages. So if your program needs the uncommitted data dot csv shown here, that file will be missing. A package you installed locally also needs to be included in the runner's setup.

6:03

Before changing the code, read what failed. On GitHub, open the repository's Actions tab, then the failed run, then the failed step, to see its output. If dependency installation failed, the project checks never started. If a test reports a failed assertion, it ran but got an unexpected result. The GitHub command line tool can print the same output in a terminal. That also lets the agent read it for you.

6:30

In our example, the test ran successfully but found the wrong answer. Two plus three should produce five, and the function returned zero. We reproduce the failure locally, change the function to return the sum, and run the checks again. Review the diff as well, so you can see what made the test pass.

6:49

Commit the correction and push it to "main". This push starts a new workflow run on the corrected code.

6:57

Notice the order here. GitHub accepts our push, then runs the checks. A failed run reports a problem, but it does not remove the commit or undo the push. In this example, we respond by investigating the failure and pushing a correction. Running checks locally first helps us catch mistakes before they reach the shared branch.

7:19

Checking locally depends on each contributor. To keep a failing change away from the people who use the repository, the check has to pass before the change reaches main. On GitHub, a ruleset for main can require a pull request and require the project checks to pass before merging. With that rule, a direct push to main is refused. The change goes through a pull request, and its merge stays blocked while the required check fails. Main keeps only commits that passed, so anyone who clones it gets code that passed the checks.

7:52

We also need to maintain what these checks cover. If a change removes a test or weakens the checking script, the job can pass without checking something the team still needs. Review changes to the workflow, checking script and tests along with changes to the application code.

8:09

Local feedback helps you correct a mistake quickly, while the relevant code is still in front of you. The GitHub workflow checks the pushed code in its configured environment. It can repeat checks you already ran locally. That repetition is useful, because the shared result does not depend on a report from one laptop.

8:28

Alongside checks triggered by the agent, you can run a local check whenever someone makes a Git commit. Git has its own hooks for operations like this. A pre-commit hook runs before Git creates the commit, whether an agent or a person runs the command. The diagram separates these Git hooks from the agent harness's session hooks.

8:48

"Git commit dash dash no-verify" skips the pre-commit hook. Either a person or an agent can use that option. A hook in the agent session can reject a command it recognizes, but it only covers that session. When we push to "main", GitHub runs the workflow checks even if the local check was skipped.

9:09

After the checks pass, a project may also prepare a release. This is where continuous delivery and continuous deployment fit. Continuous delivery keeps validated changes ready to release, while leaving the release itself as a separate decision. A release workflow can enforce the same order. It publishes a version only in a job that needs the checks job to pass.

9:32

Continuous deployment releases changes automatically after the pipeline passes. The team also needs to monitor the running software and recover from problems. Our example stops at checking the pushed code.

9:46

You can now run project checks on GitHub after a push and use the results to investigate a failure. The CI runner has the memory of a goldfish and the standards of a tough, relentless sergeant major. See you in the next video.

10:00 of video · 1,584 words · 29 slides← Back to the video