{"id":15640799,"url":"https://github.com/timja/training-continuous-integration","last_synced_at":"2026-03-18T03:56:31.575Z","repository":{"id":85475387,"uuid":"601696625","full_name":"timja/training-continuous-integration","owner":"timja","description":null,"archived":false,"fork":false,"pushed_at":"2023-06-01T06:58:02.000Z","size":36,"stargazers_count":0,"open_issues_count":1,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-02-10T06:56:02.528Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"cc-by-4.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/timja.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-02-14T16:14:05.000Z","updated_at":"2023-02-14T16:14:07.000Z","dependencies_parsed_at":null,"dependency_job_id":"197b0317-147a-4360-b7b3-aa01ce198986","html_url":"https://github.com/timja/training-continuous-integration","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":"skills/test-with-actions","purl":"pkg:github/timja/training-continuous-integration","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/timja%2Ftraining-continuous-integration","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/timja%2Ftraining-continuous-integration/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/timja%2Ftraining-continuous-integration/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/timja%2Ftraining-continuous-integration/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/timja","download_url":"https://codeload.github.com/timja/training-continuous-integration/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/timja%2Ftraining-continuous-integration/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30646256,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-18T02:48:56.676Z","status":"ssl_error","status_checked_at":"2026-03-18T02:48:55.747Z","response_time":104,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-03T11:40:19.837Z","updated_at":"2026-03-18T03:56:31.557Z","avatar_url":"https://github.com/timja.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003c!--\n  \u003c\u003c\u003c Author notes: Header of the course \u003e\u003e\u003e\n  Include a 1280×640 image, course title in sentence case, and a concise description in emphasis.\n  In your repository settings: enable template repository, add your 1280×640 social image, auto delete head branches.\n  Add your open source license, GitHub uses Creative Commons Attribution 4.0 International.\n--\u003e\n\n# Continuous Integration\n\n_Create workflows that enable you to use Continuous Integration (CI) for your projects._\n\n\u003c!--\n  \u003c\u003c\u003c Author notes: Start of the course \u003e\u003e\u003e\n  Include start button, a note about Actions minutes,\n  and tell the learner why they should take the course.\n  Each step should be wrapped in \u003cdetails\u003e/\u003csummary\u003e, with an `id` set.\n  The start \u003cdetails\u003e should have `open` as well.\n  Do not use quotes on the \u003cdetails\u003e tag attributes.\n--\u003e\n\n\u003c!--step0\n\n[Continuous integration](https://en.wikipedia.org/wiki/Continuous_integration) can help you stick to your team’s quality standards by running tests and reporting the results on GitHub. CI tools run builds and tests, triggered by commits. The results post back to GitHub in the pull request. The goal is fewer issues in `main` and faster feedback as you work.\n\n- **Who is this for**: Developers, DevOps Engineers, new GitHub users, students, teams.\n- **What you'll learn**: What continuous integration is, how to use GitHub Actions for CI, how to create a workflow that runs tests and produces test reports.\n- **What you'll build**: We'll use [remark-lint](https://github.com/remarkjs/remark-lint) to check the consistency of Markdown files.\n- **Prerequisites**: We assume you've completed [Hello GitHub Actions](https://github.com/skills/hello-github-actions) first.\n- **How long**: This course is five steps long and takes less than two hours to complete.\n\n## How to start this course\n\n1. Above these instructions, right-click **Use this template** and open the link in a new tab.\n   ![Use this template](https://user-images.githubusercontent.com/1221423/169618716-fb17528d-f332-4fc5-a11a-eaa23562665e.png)\n2. In the new tab, follow the prompts to create a new repository.\n   - For owner, choose your personal account or an organization to host the repository.\n   - We recommend creating a public repository—private repositories will [use Actions minutes](https://docs.github.com/en/billing/managing-billing-for-github-actions/about-billing-for-github-actions).\n   ![Create a new repository](https://user-images.githubusercontent.com/1221423/169618722-406dc508-add4-4074-83f0-c7a7ad87f6f3.png)\n3. After your new repository is created, wait about 20 seconds, then refresh the page. Follow the step-by-step instructions in the new repository's README.\n\nendstep0--\u003e\n\n\u003c!--\n  \u003c\u003c\u003c Author notes: Step 1 \u003e\u003e\u003e\n  Choose 3-5 steps for your course.\n  The first step is always the hardest, so pick something easy!\n  Link to docs.github.com for further explanations.\n  Encourage users to open new tabs for steps!\n--\u003e\n\n\u003cdetails id=1\u003e\n\u003csummary\u003e\u003ch2\u003eStep 1: Add a test workflow\u003c/h2\u003e\u003c/summary\u003e\n\n_Welcome to \"GitHub Actions: Continuous Integration\"! :wave:_\n\n**What is _continuous integration_?**: [Continuous integration](https://en.wikipedia.org/wiki/Continuous_integration) can help you stick to your team’s quality standards by running tests and reporting the results on GitHub. CI tools run builds and tests, triggered by commits. The results post back to GitHub in the pull request. The goal is fewer issues in `main` and faster feedback as you work.\n\n![An illustration split in two. On the left: illustration of how GitHub Actions terms are encapsulated. At the highest level: workflows and event triggers. Inside of workflows: jobs and definition of the build environment. Inside jobs: steps. Inside steps: a call to an action. On the right: the sequence: workflows, job, step, action.](https://user-images.githubusercontent.com/6351798/88589835-f5ce0900-d016-11ea-8c8a-0e7d7907c713.png)\n\n- **Workflow**: A workflow is a unit of automation from start to finish, including the definition of what triggers the automation, what environment or other aspects should be taken into account during the automation, and what should happen as a result of the trigger.\n- **Job**: A job is a section of the workflow, and is made up of one or more steps. In this section of our workflow, the template defines the steps that make up the `build` job.\n- **Step**: A step represents one _effect_ of the automation. A step could be defined as a GitHub Action, or another unit, like printing something to the console.\n- **Action**: An action is a piece of automation written in a way that is compatible with workflows. Actions can be written by GitHub, by the open source community, or you can write them yourself!\n\nTo learn more, check out \"[Workflow syntax for GitHub Actions](https://docs.github.com/actions/using-workflows/workflow-syntax-for-github-actions)\" in the GitHub Docs.\n\nFirst, let's add a workflow to lint our Markdown files in this repository.\n\n### :keyboard: Activity: Add a test workflow\n\n1. Open a new browser tab, and work on the steps in your second tab while you read the instructions in this tab\n1. Go to the **Actions tab**.\n1. Click **New workflow**.\n1. Search for \"Simple workflow\" and click **Configure**.\n1. Name your workflow `ci.yml`.\n1. Update the workflow to remove all steps other than the \"checkout\" step.\n1. Add the following step to your workflow:\n   ```yaml\n      - name: Run markdown lint\n        run: |\n          npm install remark-cli remark-preset-lint-consistent\n          npx remark . --use remark-preset-lint-consistent --frail\n   ```\n   \u003e We expect this to create a error build. We'll fix this in the next step.\n1. Click **Start commit**, and choose to make a new branch named `ci`.\n1. Click **Propose a new file**.\n1. Click **Create pull request**.\n1. Wait about 20 seconds then refresh this page for the next step\n\n\u003c/details\u003e\n\n\u003c!--\n  \u003c\u003c\u003c Author notes: Step 2 \u003e\u003e\u003e\n  Start this step by acknowledging the previous step.\n  Define terms and link to docs.github.com.\n--\u003e\n\n\u003cdetails id=2\u003e\n\u003csummary\u003e\u003ch2\u003eStep 2: Fix the test\u003c/h2\u003e\u003c/summary\u003e\n\n_Great job adding the templated workflow! :tada:_\n\nAdding that file to this branch is enough for GitHub Actions to begin running CI on your repository.\n\nWhen a GitHub Actions workflow is running, you should see some checks in progress, like the screenshot below.\n\n\u003cimg alt=\"checks in progress in a merge box\" src=https://user-images.githubusercontent.com/16547949/66080348-ecc5f580-e533-11e9-909e-c213b08790eb.png width=400 /\u003e\n\nYou can follow along as GitHub Actions runs your job by going to the **Actions** tab or by clicking on \"Details\" in the merge box below.\n\nWhen the tests finish, you'll see a red X :x: or a green check mark :heavy_check_mark: in the merge box. At that point, you'll have access to logs for the build job and its associated steps.\n\n\u003c!-- Note here: Learners -- yup, you found the error! Course maintainers -- leave the italics with * instead of _ for the error case. --\u003e\n\n_By looking at the logs, can you identify which tests failed?_ To find it, go to one of the failed builds and scrolling through the log. Look for a section that lists all the unit tests. We're looking for the name of the test with an \"x\".\n\n\u003cimg alt=\"screenshot of a sample build log with the names of the tests blurred out\" src=https://user-images.githubusercontent.com/16547949/65922013-e740a200-e3b1-11e9-8151-faf52c30201e.png width=400 /\u003e\n\nIf the checks don't appear or if the checks are stuck in progress, there's a few things you can do to try and trigger them:\n\n- Refresh the page, it's possible the workflow ran and the page just hasn't been updated with that change.\n- Try making a commit on this branch. Our workflow is triggered with a `push` event, and committing to this branch will result in a new `push`.\n- Edit the workflow file on GitHub and ensure there are no red lines indicating a syntax problem.\n\n### :keyboard: Activity: Fix the test\n\n1. Update the code in the `ci` branch to get the test to pass. You need to look something like this:\n   ```markdown\n   _underscore_\n   ```\n1. **Commit changes**.\n1. Wait about 20 seconds then refresh this page for the next step.\n\n\u003c/details\u003e\n\n\u003c!--\n  \u003c\u003c\u003c Author notes: Step 3 \u003e\u003e\u003e\n  Start this step by acknowledging the previous step.\n  Define terms and link to docs.github.com.\n--\u003e\n\n\u003cdetails id=3\u003e\n\u003csummary\u003e\u003ch2\u003eStep 3: Upload test reports\u003c/h2\u003e\u003c/summary\u003e\n\n_The workflow has finished running! :sparkles:_\n\nSo what do we do when we need the work product of one job in another? We can use the built-in [artifact storage](https://docs.github.com/en/actions/advanced-guides/storing-workflow-data-as-artifacts) to save artifacts created from one job to be used in another job within the same workflow.\n\nTo upload artifacts to the artifact storage, we can use an action built by GitHub: [`actions/upload-artifacts`](https://github.com/actions/upload-artifact).\n\n### :keyboard: Activity: Upload test reports\n\n1. Edit your workflow file.\n1. Add a step to your `build` job that uses the `upload-artifacts` action.\n   ```yaml\n     build:\n       runs-on: ubuntu-latest\n       steps:\n         - uses: actions/checkout@v3\n\n         - name: Run markdown lint\n           run: |\n             npm install remark-cli remark-preset-lint-consistent\n             npx remark . --use remark-preset-lint-consistent --frail\n\n         - uses: actions/upload-artifact@v3\n           with:\n             name: remark-lint-report\n             path: public/\n   ```\n1. Commit your change to this branch.\n1. Wait about 20 seconds then refresh this page for the next step.\n\nSimilar to the upload action to send artifacts to the storage, you can use another action built by GitHub to download these previously uploaded artifacts from the `build` job: [`actions/download-artifact`](https://github.com/actions/download-artifact). To save you time, we'll skip that step for this course.\n\n\u003c/details\u003e\n\n\u003c!--\n  \u003c\u003c\u003c Author notes: Step 4 \u003e\u003e\u003e\n  Start this step by acknowledging the previous step.\n  Define terms and link to docs.github.com.\n--\u003e\n\n\u003cdetails id=4 open\u003e\n\u003csummary\u003e\u003ch2\u003eStep 4: Add branch protections\u003c/h2\u003e\u003c/summary\u003e\n\n_Great job uploading test reports! :partying_face:_\n\nTake a look at the merge box, you'll notice you can merge this even though the review process hasn't been met.\n\nProtected branches ensure that collaborators on your repository cannot make irrevocable changes to branches. Enabling protected branches also allows you to enable other optional checks and requirements, like required status checks and required reviews.\n\n### :keyboard: Activity: Add branch protections\n\n1. Go to **Branches** settings. You can navigate to that page manually by clicking on the right-most tab in the top of the repository called **Settings** and then clicking on **Branches**.\n1. Click on **Add rule** under \"Branch protection rules\".\n1. Type `main` in **Branch name pattern**.\n1. Check **Require pull request reviews before merging**.\n1. Check **Require status checks to pass before merging**.\n1. Check all build and test jobs that you'd like to see in the newly visible gray box.\n1. Click **Create**.\n1. _Once you turn on branch protection, Actions can no longer push directly to `main`. You'll need to open the next step on your own._\n\n\u003c!-- Wait about 20 seconds then refresh this page for the next step. --\u003e\n\n\u003c/details\u003e\n\n\u003c!--\n  \u003c\u003c\u003c Author notes: Step 5 \u003e\u003e\u003e\n  Start this step by acknowledging the previous step.\n  Define terms and link to docs.github.com.\n--\u003e\n\n\u003cdetails id=5\u003e\n\u003csummary\u003e\u003ch2\u003eStep 5: Merge your pull request\u003c/h2\u003e\u003c/summary\u003e\n\n_Almost there! :heart:_\n\nYou can now [merge](https://docs.github.com/en/get-started/quickstart/github-glossary#merge) your pull request!\n\n### :keyboard: Activity: Merge your pull request\n\n1. Click **Merge pull request**.\n1. Delete the branch `ci` (optional).\n1. _Once you turn on branch protection, Actions can no longer push directly to `main`. You'll need to open the \"finish\" on your own._\n\n\u003c!-- Wait about 20 seconds then refresh this page for the next step. --\u003e\n\n\u003c/details\u003e\n\n\u003c!--\n  \u003c\u003c\u003c Author notes: Finish \u003e\u003e\u003e\n  Review what we learned, ask for feedback, provide next steps.\n--\u003e\n\n\u003cdetails id=X\u003e\n\u003csummary\u003e\u003ch2\u003eFinish\u003c/h2\u003e\u003c/summary\u003e\n\n_Congratulations friend, you've completed this course!_\n\n\u003cimg src=https://octodex.github.com/images/Fintechtocat.png alt=celebrate width=300 align=right\u003e\n\nHere's a recap of all the tasks you've accomplished in your repository:\n\n- We created an Actions workflow to lint our Markdown files.\n- You caught an issue in a file and fixed the issue before it could make it to `main`.\n- You learned how to use build artifacts for test reports.\n- You enabled branch protections to require the workflow to pass before merging.\n\n### What's next?\n\n- Get more ideas of what you can do with [awesome actions](https://github.com/sdras/awesome-actions).\n- We'd love to hear what you thought of this course [in our discussion board](https://github.com/skills/.github/discussions).\n- [Take another GitHub Skills course](https://github.com/skills).\n- [Read the GitHub Getting Started docs](https://docs.github.com/en/get-started).\n- To find projects to contribute to, check out [GitHub Explore](https://github.com/explore).\n\n\u003c/details\u003e\n\n\u003c!--\n  \u003c\u003c\u003c Author notes: Footer \u003e\u003e\u003e\n  Add a link to get support, GitHub status page, code of conduct, license link.\n--\u003e\n\n---\n\nGet help: [Post in our discussion board](https://github.com/skills/.github/discussions) \u0026bull; [Review the GitHub status page](https://www.githubstatus.com/)\n\n\u0026copy; 2022 GitHub \u0026bull; [Code of Conduct](https://www.contributor-covenant.org/version/2/1/code_of_conduct/code_of_conduct.md) \u0026bull; [CC-BY-4.0 License](https://creativecommons.org/licenses/by/4.0/legalcode)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftimja%2Ftraining-continuous-integration","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftimja%2Ftraining-continuous-integration","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftimja%2Ftraining-continuous-integration/lists"}