{"id":18684849,"url":"https://github.com/j-sephb-lt-n/python-github-ci-pipeline","last_synced_at":"2026-04-13T13:32:23.492Z","repository":{"id":208581983,"uuid":"721986198","full_name":"J-sephB-lt-n/python-github-ci-pipeline","owner":"J-sephB-lt-n","description":"Example continuous-integration pipeline for a python project using GitHub actions and GitHub branch protection","archived":false,"fork":false,"pushed_at":"2024-01-18T20:34:33.000Z","size":2228,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-05-26T19:54:17.164Z","etag":null,"topics":["ci-cd","ci-cd-pipeline","cicd","github","github-actions","mkdocs","mkdocstrings","mypy","pylint","pytest","python","ruff"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/J-sephB-lt-n.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-11-22T07:39:52.000Z","updated_at":"2023-11-23T20:23:42.000Z","dependencies_parsed_at":"2024-01-18T21:39:05.610Z","dependency_job_id":null,"html_url":"https://github.com/J-sephB-lt-n/python-github-ci-pipeline","commit_stats":null,"previous_names":["j-sephb-lt-n/python-github-ci-pipeline","j-sephb-lt-n/python-github-ci-cd-pipeline"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/J-sephB-lt-n/python-github-ci-pipeline","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/J-sephB-lt-n%2Fpython-github-ci-pipeline","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/J-sephB-lt-n%2Fpython-github-ci-pipeline/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/J-sephB-lt-n%2Fpython-github-ci-pipeline/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/J-sephB-lt-n%2Fpython-github-ci-pipeline/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/J-sephB-lt-n","download_url":"https://codeload.github.com/J-sephB-lt-n/python-github-ci-pipeline/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/J-sephB-lt-n%2Fpython-github-ci-pipeline/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31754914,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-13T13:27:56.013Z","status":"ssl_error","status_checked_at":"2026-04-13T13:21:23.512Z","response_time":93,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: 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":["ci-cd","ci-cd-pipeline","cicd","github","github-actions","mkdocs","mkdocstrings","mypy","pylint","pytest","python","ruff"],"created_at":"2024-11-07T10:19:31.616Z","updated_at":"2026-04-13T13:32:23.465Z","avatar_url":"https://github.com/J-sephB-lt-n.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# python-github-ci-pipeline\n\nThis [GitHub](https://github.com) repo holds an example [Continuous Integration (CI)](https://en.wikipedia.org/wiki/Continuous_integration) pipeline for a python project, built using [GitHub actions](https://github.com/features/actions) and [GitHub branch protection rules](https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/managing-protected-branches/about-protected-branches). A tutorial blog post explaining this repo in detail can be found [here](./blog_post/tutorial.md).\n\nThe python project code in this repo is an implementation of the original \n[Diffie-Hellman-Merkle Key Exchange](https://en.wikipedia.org/wiki/Diffie-Hellman_key_exchange#Cryptographic_explanation) \nalgorithm. You can see the project documentation [here](https://J-sephB-lt-n.github.io/python-github-ci-pipeline/) (this documentation is automatically built by the [CI](https://en.wikipedia.org/wiki/Continuous_integration) pipeline when a pull request to main branch is accepted).\n\n\u003c\u003c **this repo is still under construction** \u003e\u003e\n\nThis flowchart illustrates the [CI](https://en.wikipedia.org/wiki/Continuous_integration) pipeline implemented in this git repo:\n\n```mermaid\n---\ntitle: Continuous Integration Pipeline\n---\nflowchart TD;\n    A[\"Production codebase \u003cbr\u003e(git main branch)\"] -. \"developer makes a local copy\u003cbr\u003e of the production code\u003cbr\u003e(git pull)\" .-\u003e B[\"Local copy of production codebase \u003cbr\u003e(git feature branch)\"]\n    B -. \"developer writes new code\" .-\u003e C[\"Local copy of production codebase\u003cbr\u003ewith new code\u003cbr\u003e(git feature branch)\"]\n    C -. \"developer attempts to merge new\u003cbr\u003ecode into production codebase\u003cbr\u003e(git push origin main)\u003cbr\u003e(github pull request)\" .-\u003e D{\"System checks for\u003cbr\u003emerge conflicts and\u003cbr\u003eruns all tests\u003cbr\u003e(github actions)\"}\n    D -- \"all tests pass\" --\u003e E{System accepts \u003cbr\u003emerge}\n    E -. \"code merged into\u003cbr\u003eproduction codebase \" .-\u003e A\n    D -- \"1 or more tests fail\" --\u003e F{System rejects \u003cbr\u003emerge}\n    F -. \"developer adapts their code\u003cbr\u003eto make the tests pass\" .-\u003e C\n```\n\nParts of the [CI](https://en.wikipedia.org/wiki/Continuous_integration) pipeline can be run locally using the [Makefile](./Makefile) in terminal using the following commands: \n\n```bash\n# install all of the python packages required in order to contribute to this python project #\nmake install_dev_dependencies\n\n# install all of the python packages required in order to use this python project (i.e. as an end-user) #\nmake install_prod_dependencies\n\n# run all tests (unit, integration, end-to-end, test coverage, linter, type-checking, docstring examples) #\nmake run_all_tests\n\n# quantify test coverage #\nmake test_coverage\n\n# run all unit tests # \nmake unit_tests\n\n# run all integration tests #\nmake integration_tests\n\n# run all end-to-end tests #\nmake end_to_end_tests\n\n# run code linter (static code analysis) #\nmake linter\n\n# run type-checks (static code type-checking) #\nmake type_checks\n\n# verify python code examples in function/method docstrings #\nmake check_docstring_example_code\n\n# automatically format all scripts (uses Ruff) #\nmake auto_format_full_codebase\n\n# locally host the project documentation #\nmake view_docs_local\n\n# locally build the documentation and push it to GitHub pages #\nmake deploy_docs_to_github\n```\n\nThe project code consists of a toy implementation of the original [Diffie-Hellman-Merkle Key Exchange](https://en.wikipedia.org/wiki/Diffie–Hellman_key_exchange) algorithm (which is used to securely communicate a secret key across an insecure public communication channel).  \n\nThis [CI](https://en.wikipedia.org/wiki/Continuous_integration) pipeline works as follows (joe TODO: references in text below are stale after last refactor):\n\n* The pipeline is set up as a single GitHub action (I've labelled the action \"**ci**\" on the GitHub repo).\n\n* Users are not allowed to push directly the **main** branch of the repository - they must merge a feature branch into **main** using a [pull request](https://en.wikipedia.org/wiki/Distributed_version_control#Pull_requests).\n\n* [Pull requests](https://en.wikipedia.org/wiki/Distributed_version_control#Pull_requests) to **main** branch trigger the **ci** GitHub action to run, and the merge to **main** is rejected if any one of the steps in **ci** reports an error. \n\n* You can read the code defining the **ci** pipeline GitHub action in this repo here: [.github/workflows/ci.yml](./.github/workflows/ci.yml)\n\nImplemented so far:\n\n| Task                        | Location                | How to Run This Task\n|-----------------------------|-------------------------|-----------------------------\n| Auto-format all code scripts (uses [Ruff](https://github.com/astral-sh/ruff)) | local github repo | run in terminal (from project root folder):\u003cbr\u003e \u003ccode\u003emake auto_format_code\u003c/code\u003e\n| Auto-format all code scripts (uses [Ruff](https://github.com/astral-sh/ruff)) | remote github repo      | task runs automatically (using github action) whenever code is pushed to remote main branch\n| Install development dependencies (required to run tests, build documentation etc.) | local github repo | run in terminal (from project root folder):\u003cbr\u003e \u003ccode\u003emake install_dev_dependencies\u003c/code\u003e\n| Install production dependencies (required to use the package) | local github repo | run in terminal (from project root folder):\u003cbr\u003e \u003ccode\u003emake install_prod_dependencies\u003c/code\u003e\n| Measure test coverage (uses [pytest-cov](https://github.com/pytest-dev/pytest-cov)) | local github repo | run in terminal (from project root folder):\u003cbr\u003e \u003ccode\u003emake test_coverage\u003c/code\u003e\n| Run all tests (unit, integration, end-to-end, test coverage, linter, type-checking) | local github repo | run in terminal (from project root folder):\u003cbr\u003e \u003ccode\u003emake run_all_tests\u003c/code\u003e\n| Run all unit tests | local github repo | run in terminal (from project root folder):\u003cbr\u003e \u003ccode\u003emake unit_tests\u003c/code\u003e\n| Run all integration tests | local github repo | run in terminal (from project root folder):\u003cbr\u003e \u003ccode\u003emake integration_tests\u003c/code\u003e\n| Run all end-to-end tests | local github repo | run in terminal (from project root folder):\u003cbr\u003e \u003ccode\u003emake end_to_end_tests\u003c/code\u003e\n| Run code linting on core scripts in [/diffie_hellman_merkle/](./diffie_hellman_merkle/) folder (uses [Pylint](https://github.com/pylint-dev/pylint)) | local github repo | run in terminal (from project root folder):\u003cbr\u003e \u003ccode\u003emake linter\u003c/code\u003e\n| Run static type checking on core scripts in [/diffie_hellman_merkle/](./diffie_hellman_merkle/) folder (uses [my[py]](https://github.com/python/mypy)) | local github repo | run in terminal (from project root folder):\u003cbr\u003e \u003ccode\u003emake type_checks\u003c/code\u003e\n\n# GitHub Actions and Branch Protection Rules\n\n* Branch protection is set up on the main branch (on the GitHub website UI under *Settings\u003e\u003eCode and automation\u003e\u003eBranches\u003e\u003eBranch protection rules*) as follows:\n\n    - Branch name pattern: *main*\n    \n    - ☑ Require status checks to pass before merging: **ci**\n\n    - ☑ Do not allow bypassing the above settings (i.e. repository administrators must follow the rules too)\n\n# Setup Notes\n\n* In order for GitHub actions to be able to write to the repository (e.g. to automatically format code, and then commit and push the changed code), you need to enable \"Read and write permissions\" for GitHub actions in the GitHub website UI (this is under *Settings\u003e\u003eActions\u003e\u003eGeneral*).\n\n# Other Notes\n\n* Remote rejections can be pre-empted by developers using [pre-commit](https://github.com/pre-commit/pre-commit) locally, which will cause commits of insufficient quality (e.g. mypy errors, pylint score too low etc.) to be rejected locally when a local \u003ccode\u003egit commit\u003c/code\u003e is attempted (i.e. before attempting communication with the remote github repository). However, this puts the onus on individual developers to be principled with their local environment, which is why I used GitHub branch protection rules on the remote repository instead (so that the remote main branch is automatically protected).\n\n# Some Useful Resources \n\n* https://www.wolframalpha.com (for finding large prime numbers, and finding/verifying primitive roots)\n\n* https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-python\n\n* https://github.com/marketplace/actions/github-push\n\n* https://www.math.stonybrook.edu/~sorin/311-2006/hw8.pdf\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fj-sephb-lt-n%2Fpython-github-ci-pipeline","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fj-sephb-lt-n%2Fpython-github-ci-pipeline","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fj-sephb-lt-n%2Fpython-github-ci-pipeline/lists"}