diff --git a/.config/dictionaries/project.dic b/.config/dictionaries/project.dic index 248d860a5..635063eb6 100644 --- a/.config/dictionaries/project.dic +++ b/.config/dictionaries/project.dic @@ -1,13 +1,16 @@ aarch buildkit camelcase +cowsay cytopia devenv dind Earthfile Earthfiles errchkjson +extldflags ginkgolinter +gitops glightbox gofmt golangci @@ -22,17 +25,31 @@ gosec graphviz Kroki kubeconfig +ldflags markdownlint +mattn mdlint mkdocs modcache +mozallowfullscreen multirepo nilnil nixos nixpkgs onsi pkgs +projectcatalyst +pymdownx PYTHONDONTWRITEBYTECODE +rivo +runewidth +subproject +subprojects +superfences testpackage +transpiling UDCs +uniseg +webkitallowfullscreen WORKDIR +xerrors \ No newline at end of file diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index f8109d014..2f1402a48 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -1,3 +1,5 @@ +# WARNING: If you modify this workflow, please update the documentation + on: workflow_call: inputs: diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml new file mode 100644 index 000000000..158f57d24 --- /dev/null +++ b/.github/workflows/docs.yml @@ -0,0 +1,24 @@ +name: Docs + +on: + push: + paths: + - "docs/**" + +permissions: + id-token: write + contents: write + packages: write + +jobs: + ci: + uses: ./.github/workflows/pages.yml + with: + aws_role_arn: arn:aws:iam::332405224602:role/ci + aws_region: eu-central-1 + ci_cli_version: 1.3.1 + earthfile: ./docs + target: docs + secrets: + earthly_runner_address: ${{ secrets.EARTHLY_SATELLITE_ADDRESS }} + earthly_runner_secret: ${{ secrets.EARTHLY_RUNNER_SECRET }} \ No newline at end of file diff --git a/.github/workflows/check.yml b/.github/workflows/pages.yml similarity index 57% rename from .github/workflows/check.yml rename to .github/workflows/pages.yml index eab2abdc4..ec82a0a76 100644 --- a/.github/workflows/check.yml +++ b/.github/workflows/pages.yml @@ -1,15 +1,22 @@ +# WARNING: If you modify this workflow, please update the documentation + on: workflow_call: inputs: + earthfile: + description: | + The path to the folder containing the Earthfile that will be built. + This path should be relative to the repository root. + required: true + type: string target: description: | - The target used to mark check builds. This target should be unique - across all Earthly files in the repository. The target should perform - all required checks to validate an artifact: linting, formatting, and - unit tests are common examples. + The target that will be used to build docs. The target should always + produce one artifact which is the static site that will be deployed to + GitHub Pages. required: false type: string - default: check + default: docs aws_role_arn: description: | The ARN of the AWS role that will be assumed by the workflow. Only @@ -37,7 +44,7 @@ on: earthly_runner_address: description: | The address of the Earthly runner that will be used to build the - Earthly files. + Earthfile. required: false earthly_runner_secret: description: | @@ -48,40 +55,8 @@ on: required: false jobs: - discover: + run: runs-on: ubuntu-latest - outputs: - json: ${{ steps.check.outputs.json }} - steps: - - uses: actions/checkout@v3 - - name: Setup CI - uses: input-output-hk/catalyst-ci/actions/setup@master - with: - cli_version: ${{ inputs.ci_cli_version }} - earthly_skip_install: "true" - - name: Discover Earthly files - uses: input-output-hk/catalyst-ci/actions/discover@master - id: discover - with: - targets: ${{ inputs.target }} - - name: Check for empty output - id: check - run: | - output=$(echo '${{ steps.discover.outputs.json }}' | jq -rc) - if [ "$output" == "null" ]; then - echo "json=[]" >> $GITHUB_OUTPUT - else - echo "json=$output" >> $GITHUB_OUTPUT - fi - - build: - runs-on: ubuntu-latest - needs: [discover] - if: needs.discover.outputs.json != '[]' - strategy: - fail-fast: false - matrix: - earthfile: ${{ fromJson(needs.discover.outputs.json) }} steps: - uses: actions/checkout@v3 - name: Setup CI @@ -92,10 +67,17 @@ jobs: cli_version: ${{ inputs.ci_cli_version }} earthly_version: ${{ inputs.earthly_version }} earthly_runner_secret: ${{ secrets.earthly_runner_secret }} - - name: Check + - name: Build docs uses: input-output-hk/catalyst-ci/actions/run@master id: build with: - earthfile: ${{ matrix.earthfile }} + earthfile: ${{ inputs.earthfile }} target: ${{ inputs.target }} - runner_address: ${{ secrets.earthly_runner_address }} \ No newline at end of file + runner_address: ${{ secrets.earthly_runner_address }} + artifact: "true" + - name: Publish docs + uses: JamesIves/github-pages-deploy-action@v4.4.3 + if: github.ref == format('refs/heads/{0}', github.event.repository.default_branch) + with: + branch: gh-pages + folder: ${{ steps.build.outputs.artifact }} \ No newline at end of file diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index f0db73125..014c174a7 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -1,3 +1,5 @@ +# WARNING: If you modify this workflow, please update the documentation + on: workflow_call: inputs: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 2fdfbf6b1..30239e67d 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,3 +1,5 @@ +# WARNING: If you modify this workflow, please update the documentation + on: workflow_call: inputs: diff --git a/actions/setup/Earthfile b/actions/setup/Earthfile deleted file mode 100644 index 28b42648e..000000000 --- a/actions/setup/Earthfile +++ /dev/null @@ -1,5 +0,0 @@ -VERSION 0.7 - -docs: - FROM node:16-alpine3.17 - DO ../+DOCS \ No newline at end of file diff --git a/docs/Earthfile b/docs/Earthfile new file mode 100644 index 000000000..33e5a01e0 --- /dev/null +++ b/docs/Earthfile @@ -0,0 +1,16 @@ +VERSION 0.7 + +deps: + FROM python:3.11-bullseye + DO ../earthly/python+POETRY_SETUP + +src: + FROM +deps + + COPY --dir src mkdocs.yml . + +docs: + FROM +src + + RUN poetry run mkdocs build --strict + SAVE ARTIFACT site/* \ No newline at end of file diff --git a/docs/mkdocs.yml b/docs/mkdocs.yml new file mode 100644 index 000000000..9059cbed6 --- /dev/null +++ b/docs/mkdocs.yml @@ -0,0 +1,29 @@ +site_name: Catalyst CI Documentation +docs_dir: src +theme: + name: material + features: + - navigation.indexes + - navigation.tracking +nav: + - Introduction: index.md + - Onboarding: onboarding/index.md + - Style Guide: style.md + - Reference: + - reference/index.md + - Actions: reference/actions.md + - Targets: reference/targets.md + - Workflows: reference/workflows.md + - UDCs: reference/udc.md + - Appendix: + - Earthly: appendix/earthly.md +markdown_extensions: + - admonition + - pymdownx.details + - pymdownx.superfences: + custom_fences: + - name: mermaid + class: mermaid + format: !!python/name:pymdownx.superfences.fence_code_format + - pymdownx.tabbed: + alternate_style: true diff --git a/docs/poetry.lock b/docs/poetry.lock new file mode 100644 index 000000000..1c71f2931 --- /dev/null +++ b/docs/poetry.lock @@ -0,0 +1,716 @@ +# This file is automatically @generated by Poetry 1.6.1 and should not be changed by hand. + +[[package]] +name = "babel" +version = "2.13.0" +description = "Internationalization utilities" +optional = false +python-versions = ">=3.7" +files = [ + {file = "Babel-2.13.0-py3-none-any.whl", hash = "sha256:fbfcae1575ff78e26c7449136f1abbefc3c13ce542eeb13d43d50d8b047216ec"}, + {file = "Babel-2.13.0.tar.gz", hash = "sha256:04c3e2d28d2b7681644508f836be388ae49e0cfe91465095340395b60d00f210"}, +] + +[package.extras] +dev = ["freezegun (>=1.0,<2.0)", "pytest (>=6.0)", "pytest-cov"] + +[[package]] +name = "certifi" +version = "2023.7.22" +description = "Python package for providing Mozilla's CA Bundle." +optional = false +python-versions = ">=3.6" +files = [ + {file = "certifi-2023.7.22-py3-none-any.whl", hash = "sha256:92d6037539857d8206b8f6ae472e8b77db8058fec5937a1ef3f54304089edbb9"}, + {file = "certifi-2023.7.22.tar.gz", hash = "sha256:539cc1d13202e33ca466e88b2807e29f4c13049d6d87031a3c110744495cb082"}, +] + +[[package]] +name = "charset-normalizer" +version = "3.3.0" +description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." +optional = false +python-versions = ">=3.7.0" +files = [ + {file = "charset-normalizer-3.3.0.tar.gz", hash = "sha256:63563193aec44bce707e0c5ca64ff69fa72ed7cf34ce6e11d5127555756fd2f6"}, + {file = "charset_normalizer-3.3.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:effe5406c9bd748a871dbcaf3ac69167c38d72db8c9baf3ff954c344f31c4cbe"}, + {file = "charset_normalizer-3.3.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:4162918ef3098851fcd8a628bf9b6a98d10c380725df9e04caf5ca6dd48c847a"}, + {file = "charset_normalizer-3.3.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:0570d21da019941634a531444364f2482e8db0b3425fcd5ac0c36565a64142c8"}, + {file = "charset_normalizer-3.3.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5707a746c6083a3a74b46b3a631d78d129edab06195a92a8ece755aac25a3f3d"}, + {file = "charset_normalizer-3.3.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:278c296c6f96fa686d74eb449ea1697f3c03dc28b75f873b65b5201806346a69"}, + {file = "charset_normalizer-3.3.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a4b71f4d1765639372a3b32d2638197f5cd5221b19531f9245fcc9ee62d38f56"}, + {file = "charset_normalizer-3.3.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5969baeaea61c97efa706b9b107dcba02784b1601c74ac84f2a532ea079403e"}, + {file = "charset_normalizer-3.3.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a3f93dab657839dfa61025056606600a11d0b696d79386f974e459a3fbc568ec"}, + {file = "charset_normalizer-3.3.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:db756e48f9c5c607b5e33dd36b1d5872d0422e960145b08ab0ec7fd420e9d649"}, + {file = "charset_normalizer-3.3.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:232ac332403e37e4a03d209a3f92ed9071f7d3dbda70e2a5e9cff1c4ba9f0678"}, + {file = "charset_normalizer-3.3.0-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:e5c1502d4ace69a179305abb3f0bb6141cbe4714bc9b31d427329a95acfc8bdd"}, + {file = "charset_normalizer-3.3.0-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:2502dd2a736c879c0f0d3e2161e74d9907231e25d35794584b1ca5284e43f596"}, + {file = "charset_normalizer-3.3.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:23e8565ab7ff33218530bc817922fae827420f143479b753104ab801145b1d5b"}, + {file = "charset_normalizer-3.3.0-cp310-cp310-win32.whl", hash = "sha256:1872d01ac8c618a8da634e232f24793883d6e456a66593135aeafe3784b0848d"}, + {file = "charset_normalizer-3.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:557b21a44ceac6c6b9773bc65aa1b4cc3e248a5ad2f5b914b91579a32e22204d"}, + {file = "charset_normalizer-3.3.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:d7eff0f27edc5afa9e405f7165f85a6d782d308f3b6b9d96016c010597958e63"}, + {file = "charset_normalizer-3.3.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6a685067d05e46641d5d1623d7c7fdf15a357546cbb2f71b0ebde91b175ffc3e"}, + {file = "charset_normalizer-3.3.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:0d3d5b7db9ed8a2b11a774db2bbea7ba1884430a205dbd54a32d61d7c2a190fa"}, + {file = "charset_normalizer-3.3.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2935ffc78db9645cb2086c2f8f4cfd23d9b73cc0dc80334bc30aac6f03f68f8c"}, + {file = "charset_normalizer-3.3.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9fe359b2e3a7729010060fbca442ca225280c16e923b37db0e955ac2a2b72a05"}, + {file = "charset_normalizer-3.3.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:380c4bde80bce25c6e4f77b19386f5ec9db230df9f2f2ac1e5ad7af2caa70459"}, + {file = "charset_normalizer-3.3.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f0d1e3732768fecb052d90d62b220af62ead5748ac51ef61e7b32c266cac9293"}, + {file = "charset_normalizer-3.3.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1b2919306936ac6efb3aed1fbf81039f7087ddadb3160882a57ee2ff74fd2382"}, + {file = "charset_normalizer-3.3.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:f8888e31e3a85943743f8fc15e71536bda1c81d5aa36d014a3c0c44481d7db6e"}, + {file = "charset_normalizer-3.3.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:82eb849f085624f6a607538ee7b83a6d8126df6d2f7d3b319cb837b289123078"}, + {file = "charset_normalizer-3.3.0-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:7b8b8bf1189b3ba9b8de5c8db4d541b406611a71a955bbbd7385bbc45fcb786c"}, + {file = "charset_normalizer-3.3.0-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:5adf257bd58c1b8632046bbe43ee38c04e1038e9d37de9c57a94d6bd6ce5da34"}, + {file = "charset_normalizer-3.3.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:c350354efb159b8767a6244c166f66e67506e06c8924ed74669b2c70bc8735b1"}, + {file = "charset_normalizer-3.3.0-cp311-cp311-win32.whl", hash = "sha256:02af06682e3590ab952599fbadac535ede5d60d78848e555aa58d0c0abbde786"}, + {file = "charset_normalizer-3.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:86d1f65ac145e2c9ed71d8ffb1905e9bba3a91ae29ba55b4c46ae6fc31d7c0d4"}, + {file = "charset_normalizer-3.3.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:3b447982ad46348c02cb90d230b75ac34e9886273df3a93eec0539308a6296d7"}, + {file = "charset_normalizer-3.3.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:abf0d9f45ea5fb95051c8bfe43cb40cda383772f7e5023a83cc481ca2604d74e"}, + {file = "charset_normalizer-3.3.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b09719a17a2301178fac4470d54b1680b18a5048b481cb8890e1ef820cb80455"}, + {file = "charset_normalizer-3.3.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b3d9b48ee6e3967b7901c052b670c7dda6deb812c309439adaffdec55c6d7b78"}, + {file = "charset_normalizer-3.3.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:edfe077ab09442d4ef3c52cb1f9dab89bff02f4524afc0acf2d46be17dc479f5"}, + {file = "charset_normalizer-3.3.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3debd1150027933210c2fc321527c2299118aa929c2f5a0a80ab6953e3bd1908"}, + {file = "charset_normalizer-3.3.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:86f63face3a527284f7bb8a9d4f78988e3c06823f7bea2bd6f0e0e9298ca0403"}, + {file = "charset_normalizer-3.3.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:24817cb02cbef7cd499f7c9a2735286b4782bd47a5b3516a0e84c50eab44b98e"}, + {file = "charset_normalizer-3.3.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:c71f16da1ed8949774ef79f4a0260d28b83b3a50c6576f8f4f0288d109777989"}, + {file = "charset_normalizer-3.3.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:9cf3126b85822c4e53aa28c7ec9869b924d6fcfb76e77a45c44b83d91afd74f9"}, + {file = "charset_normalizer-3.3.0-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:b3b2316b25644b23b54a6f6401074cebcecd1244c0b8e80111c9a3f1c8e83d65"}, + {file = "charset_normalizer-3.3.0-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:03680bb39035fbcffe828eae9c3f8afc0428c91d38e7d61aa992ef7a59fb120e"}, + {file = "charset_normalizer-3.3.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4cc152c5dd831641e995764f9f0b6589519f6f5123258ccaca8c6d34572fefa8"}, + {file = "charset_normalizer-3.3.0-cp312-cp312-win32.whl", hash = "sha256:b8f3307af845803fb0b060ab76cf6dd3a13adc15b6b451f54281d25911eb92df"}, + {file = "charset_normalizer-3.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:8eaf82f0eccd1505cf39a45a6bd0a8cf1c70dcfc30dba338207a969d91b965c0"}, + {file = "charset_normalizer-3.3.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:dc45229747b67ffc441b3de2f3ae5e62877a282ea828a5bdb67883c4ee4a8810"}, + {file = "charset_normalizer-3.3.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2f4a0033ce9a76e391542c182f0d48d084855b5fcba5010f707c8e8c34663d77"}, + {file = "charset_normalizer-3.3.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ada214c6fa40f8d800e575de6b91a40d0548139e5dc457d2ebb61470abf50186"}, + {file = "charset_normalizer-3.3.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b1121de0e9d6e6ca08289583d7491e7fcb18a439305b34a30b20d8215922d43c"}, + {file = "charset_normalizer-3.3.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1063da2c85b95f2d1a430f1c33b55c9c17ffaf5e612e10aeaad641c55a9e2b9d"}, + {file = "charset_normalizer-3.3.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:70f1d09c0d7748b73290b29219e854b3207aea922f839437870d8cc2168e31cc"}, + {file = "charset_normalizer-3.3.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:250c9eb0f4600361dd80d46112213dff2286231d92d3e52af1e5a6083d10cad9"}, + {file = "charset_normalizer-3.3.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:750b446b2ffce1739e8578576092179160f6d26bd5e23eb1789c4d64d5af7dc7"}, + {file = "charset_normalizer-3.3.0-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:fc52b79d83a3fe3a360902d3f5d79073a993597d48114c29485e9431092905d8"}, + {file = "charset_normalizer-3.3.0-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:588245972aca710b5b68802c8cad9edaa98589b1b42ad2b53accd6910dad3545"}, + {file = "charset_normalizer-3.3.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:e39c7eb31e3f5b1f88caff88bcff1b7f8334975b46f6ac6e9fc725d829bc35d4"}, + {file = "charset_normalizer-3.3.0-cp37-cp37m-win32.whl", hash = "sha256:abecce40dfebbfa6abf8e324e1860092eeca6f7375c8c4e655a8afb61af58f2c"}, + {file = "charset_normalizer-3.3.0-cp37-cp37m-win_amd64.whl", hash = "sha256:24a91a981f185721542a0b7c92e9054b7ab4fea0508a795846bc5b0abf8118d4"}, + {file = "charset_normalizer-3.3.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:67b8cc9574bb518ec76dc8e705d4c39ae78bb96237cb533edac149352c1f39fe"}, + {file = "charset_normalizer-3.3.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:ac71b2977fb90c35d41c9453116e283fac47bb9096ad917b8819ca8b943abecd"}, + {file = "charset_normalizer-3.3.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:3ae38d325b512f63f8da31f826e6cb6c367336f95e418137286ba362925c877e"}, + {file = "charset_normalizer-3.3.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:542da1178c1c6af8873e143910e2269add130a299c9106eef2594e15dae5e482"}, + {file = "charset_normalizer-3.3.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:30a85aed0b864ac88309b7d94be09f6046c834ef60762a8833b660139cfbad13"}, + {file = "charset_normalizer-3.3.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:aae32c93e0f64469f74ccc730a7cb21c7610af3a775157e50bbd38f816536b38"}, + {file = "charset_normalizer-3.3.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15b26ddf78d57f1d143bdf32e820fd8935d36abe8a25eb9ec0b5a71c82eb3895"}, + {file = "charset_normalizer-3.3.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7f5d10bae5d78e4551b7be7a9b29643a95aded9d0f602aa2ba584f0388e7a557"}, + {file = "charset_normalizer-3.3.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:249c6470a2b60935bafd1d1d13cd613f8cd8388d53461c67397ee6a0f5dce741"}, + {file = "charset_normalizer-3.3.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:c5a74c359b2d47d26cdbbc7845e9662d6b08a1e915eb015d044729e92e7050b7"}, + {file = "charset_normalizer-3.3.0-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:b5bcf60a228acae568e9911f410f9d9e0d43197d030ae5799e20dca8df588287"}, + {file = "charset_normalizer-3.3.0-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:187d18082694a29005ba2944c882344b6748d5be69e3a89bf3cc9d878e548d5a"}, + {file = "charset_normalizer-3.3.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:81bf654678e575403736b85ba3a7867e31c2c30a69bc57fe88e3ace52fb17b89"}, + {file = "charset_normalizer-3.3.0-cp38-cp38-win32.whl", hash = "sha256:85a32721ddde63c9df9ebb0d2045b9691d9750cb139c161c80e500d210f5e26e"}, + {file = "charset_normalizer-3.3.0-cp38-cp38-win_amd64.whl", hash = "sha256:468d2a840567b13a590e67dd276c570f8de00ed767ecc611994c301d0f8c014f"}, + {file = "charset_normalizer-3.3.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:e0fc42822278451bc13a2e8626cf2218ba570f27856b536e00cfa53099724828"}, + {file = "charset_normalizer-3.3.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:09c77f964f351a7369cc343911e0df63e762e42bac24cd7d18525961c81754f4"}, + {file = "charset_normalizer-3.3.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:12ebea541c44fdc88ccb794a13fe861cc5e35d64ed689513a5c03d05b53b7c82"}, + {file = "charset_normalizer-3.3.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:805dfea4ca10411a5296bcc75638017215a93ffb584c9e344731eef0dcfb026a"}, + {file = "charset_normalizer-3.3.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:96c2b49eb6a72c0e4991d62406e365d87067ca14c1a729a870d22354e6f68115"}, + {file = "charset_normalizer-3.3.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:aaf7b34c5bc56b38c931a54f7952f1ff0ae77a2e82496583b247f7c969eb1479"}, + {file = "charset_normalizer-3.3.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:619d1c96099be5823db34fe89e2582b336b5b074a7f47f819d6b3a57ff7bdb86"}, + {file = "charset_normalizer-3.3.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a0ac5e7015a5920cfce654c06618ec40c33e12801711da6b4258af59a8eff00a"}, + {file = "charset_normalizer-3.3.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:93aa7eef6ee71c629b51ef873991d6911b906d7312c6e8e99790c0f33c576f89"}, + {file = "charset_normalizer-3.3.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7966951325782121e67c81299a031f4c115615e68046f79b85856b86ebffc4cd"}, + {file = "charset_normalizer-3.3.0-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:02673e456dc5ab13659f85196c534dc596d4ef260e4d86e856c3b2773ce09843"}, + {file = "charset_normalizer-3.3.0-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:c2af80fb58f0f24b3f3adcb9148e6203fa67dd3f61c4af146ecad033024dde43"}, + {file = "charset_normalizer-3.3.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:153e7b6e724761741e0974fc4dcd406d35ba70b92bfe3fedcb497226c93b9da7"}, + {file = "charset_normalizer-3.3.0-cp39-cp39-win32.whl", hash = "sha256:d47ecf253780c90ee181d4d871cd655a789da937454045b17b5798da9393901a"}, + {file = "charset_normalizer-3.3.0-cp39-cp39-win_amd64.whl", hash = "sha256:d97d85fa63f315a8bdaba2af9a6a686e0eceab77b3089af45133252618e70884"}, + {file = "charset_normalizer-3.3.0-py3-none-any.whl", hash = "sha256:e46cd37076971c1040fc8c41273a8b3e2c624ce4f2be3f5dfcb7a430c1d3acc2"}, +] + +[[package]] +name = "click" +version = "8.1.7" +description = "Composable command line interface toolkit" +optional = false +python-versions = ">=3.7" +files = [ + {file = "click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28"}, + {file = "click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"}, +] + +[package.dependencies] +colorama = {version = "*", markers = "platform_system == \"Windows\""} + +[[package]] +name = "colorama" +version = "0.4.6" +description = "Cross-platform colored terminal text." +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" +files = [ + {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, + {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, +] + +[[package]] +name = "ghp-import" +version = "2.1.0" +description = "Copy your docs directly to the gh-pages branch." +optional = false +python-versions = "*" +files = [ + {file = "ghp-import-2.1.0.tar.gz", hash = "sha256:9c535c4c61193c2df8871222567d7fd7e5014d835f97dc7b7439069e2413d343"}, + {file = "ghp_import-2.1.0-py3-none-any.whl", hash = "sha256:8337dd7b50877f163d4c0289bc1f1c7f127550241988d568c1db512c4324a619"}, +] + +[package.dependencies] +python-dateutil = ">=2.8.1" + +[package.extras] +dev = ["flake8", "markdown", "twine", "wheel"] + +[[package]] +name = "idna" +version = "3.4" +description = "Internationalized Domain Names in Applications (IDNA)" +optional = false +python-versions = ">=3.5" +files = [ + {file = "idna-3.4-py3-none-any.whl", hash = "sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2"}, + {file = "idna-3.4.tar.gz", hash = "sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4"}, +] + +[[package]] +name = "jinja2" +version = "3.1.2" +description = "A very fast and expressive template engine." +optional = false +python-versions = ">=3.7" +files = [ + {file = "Jinja2-3.1.2-py3-none-any.whl", hash = "sha256:6088930bfe239f0e6710546ab9c19c9ef35e29792895fed6e6e31a023a182a61"}, + {file = "Jinja2-3.1.2.tar.gz", hash = "sha256:31351a702a408a9e7595a8fc6150fc3f43bb6bf7e319770cbc0db9df9437e852"}, +] + +[package.dependencies] +MarkupSafe = ">=2.0" + +[package.extras] +i18n = ["Babel (>=2.7)"] + +[[package]] +name = "markdown" +version = "3.5" +description = "Python implementation of John Gruber's Markdown." +optional = false +python-versions = ">=3.8" +files = [ + {file = "Markdown-3.5-py3-none-any.whl", hash = "sha256:4afb124395ce5fc34e6d9886dab977fd9ae987fc6e85689f08278cf0c69d4bf3"}, + {file = "Markdown-3.5.tar.gz", hash = "sha256:a807eb2e4778d9156c8f07876c6e4d50b5494c5665c4834f67b06459dfd877b3"}, +] + +[package.extras] +docs = ["mdx-gh-links (>=0.2)", "mkdocs (>=1.5)", "mkdocs-gen-files", "mkdocs-literate-nav", "mkdocs-nature (>=0.6)", "mkdocs-section-index", "mkdocstrings[python]"] +testing = ["coverage", "pyyaml"] + +[[package]] +name = "markupsafe" +version = "2.1.3" +description = "Safely add untrusted strings to HTML/XML markup." +optional = false +python-versions = ">=3.7" +files = [ + {file = "MarkupSafe-2.1.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:cd0f502fe016460680cd20aaa5a76d241d6f35a1c3350c474bac1273803893fa"}, + {file = "MarkupSafe-2.1.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e09031c87a1e51556fdcb46e5bd4f59dfb743061cf93c4d6831bf894f125eb57"}, + {file = "MarkupSafe-2.1.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:68e78619a61ecf91e76aa3e6e8e33fc4894a2bebe93410754bd28fce0a8a4f9f"}, + {file = "MarkupSafe-2.1.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:65c1a9bcdadc6c28eecee2c119465aebff8f7a584dd719facdd9e825ec61ab52"}, + {file = "MarkupSafe-2.1.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:525808b8019e36eb524b8c68acdd63a37e75714eac50e988180b169d64480a00"}, + {file = "MarkupSafe-2.1.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:962f82a3086483f5e5f64dbad880d31038b698494799b097bc59c2edf392fce6"}, + {file = "MarkupSafe-2.1.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:aa7bd130efab1c280bed0f45501b7c8795f9fdbeb02e965371bbef3523627779"}, + {file = "MarkupSafe-2.1.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c9c804664ebe8f83a211cace637506669e7890fec1b4195b505c214e50dd4eb7"}, + {file = "MarkupSafe-2.1.3-cp310-cp310-win32.whl", hash = "sha256:10bbfe99883db80bdbaff2dcf681dfc6533a614f700da1287707e8a5d78a8431"}, + {file = "MarkupSafe-2.1.3-cp310-cp310-win_amd64.whl", hash = "sha256:1577735524cdad32f9f694208aa75e422adba74f1baee7551620e43a3141f559"}, + {file = "MarkupSafe-2.1.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:ad9e82fb8f09ade1c3e1b996a6337afac2b8b9e365f926f5a61aacc71adc5b3c"}, + {file = "MarkupSafe-2.1.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3c0fae6c3be832a0a0473ac912810b2877c8cb9d76ca48de1ed31e1c68386575"}, + {file = "MarkupSafe-2.1.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b076b6226fb84157e3f7c971a47ff3a679d837cf338547532ab866c57930dbee"}, + {file = "MarkupSafe-2.1.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bfce63a9e7834b12b87c64d6b155fdd9b3b96191b6bd334bf37db7ff1fe457f2"}, + {file = "MarkupSafe-2.1.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:338ae27d6b8745585f87218a3f23f1512dbf52c26c28e322dbe54bcede54ccb9"}, + {file = "MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e4dd52d80b8c83fdce44e12478ad2e85c64ea965e75d66dbeafb0a3e77308fcc"}, + {file = "MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:df0be2b576a7abbf737b1575f048c23fb1d769f267ec4358296f31c2479db8f9"}, + {file = "MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:5bbe06f8eeafd38e5d0a4894ffec89378b6c6a625ff57e3028921f8ff59318ac"}, + {file = "MarkupSafe-2.1.3-cp311-cp311-win32.whl", hash = "sha256:dd15ff04ffd7e05ffcb7fe79f1b98041b8ea30ae9234aed2a9168b5797c3effb"}, + {file = "MarkupSafe-2.1.3-cp311-cp311-win_amd64.whl", hash = "sha256:134da1eca9ec0ae528110ccc9e48041e0828d79f24121a1a146161103c76e686"}, + {file = "MarkupSafe-2.1.3-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:f698de3fd0c4e6972b92290a45bd9b1536bffe8c6759c62471efaa8acb4c37bc"}, + {file = "MarkupSafe-2.1.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:aa57bd9cf8ae831a362185ee444e15a93ecb2e344c8e52e4d721ea3ab6ef1823"}, + {file = "MarkupSafe-2.1.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ffcc3f7c66b5f5b7931a5aa68fc9cecc51e685ef90282f4a82f0f5e9b704ad11"}, + {file = "MarkupSafe-2.1.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:47d4f1c5f80fc62fdd7777d0d40a2e9dda0a05883ab11374334f6c4de38adffd"}, + {file = "MarkupSafe-2.1.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1f67c7038d560d92149c060157d623c542173016c4babc0c1913cca0564b9939"}, + {file = "MarkupSafe-2.1.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:9aad3c1755095ce347e26488214ef77e0485a3c34a50c5a5e2471dff60b9dd9c"}, + {file = "MarkupSafe-2.1.3-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:14ff806850827afd6b07a5f32bd917fb7f45b046ba40c57abdb636674a8b559c"}, + {file = "MarkupSafe-2.1.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8f9293864fe09b8149f0cc42ce56e3f0e54de883a9de90cd427f191c346eb2e1"}, + {file = "MarkupSafe-2.1.3-cp312-cp312-win32.whl", hash = "sha256:715d3562f79d540f251b99ebd6d8baa547118974341db04f5ad06d5ea3eb8007"}, + {file = "MarkupSafe-2.1.3-cp312-cp312-win_amd64.whl", hash = "sha256:1b8dd8c3fd14349433c79fa8abeb573a55fc0fdd769133baac1f5e07abf54aeb"}, + {file = "MarkupSafe-2.1.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:8e254ae696c88d98da6555f5ace2279cf7cd5b3f52be2b5cf97feafe883b58d2"}, + {file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cb0932dc158471523c9637e807d9bfb93e06a95cbf010f1a38b98623b929ef2b"}, + {file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9402b03f1a1b4dc4c19845e5c749e3ab82d5078d16a2a4c2cd2df62d57bb0707"}, + {file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ca379055a47383d02a5400cb0d110cef0a776fc644cda797db0c5696cfd7e18e"}, + {file = "MarkupSafe-2.1.3-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:b7ff0f54cb4ff66dd38bebd335a38e2c22c41a8ee45aa608efc890ac3e3931bc"}, + {file = "MarkupSafe-2.1.3-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c011a4149cfbcf9f03994ec2edffcb8b1dc2d2aede7ca243746df97a5d41ce48"}, + {file = "MarkupSafe-2.1.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:56d9f2ecac662ca1611d183feb03a3fa4406469dafe241673d521dd5ae92a155"}, + {file = "MarkupSafe-2.1.3-cp37-cp37m-win32.whl", hash = "sha256:8758846a7e80910096950b67071243da3e5a20ed2546e6392603c096778d48e0"}, + {file = "MarkupSafe-2.1.3-cp37-cp37m-win_amd64.whl", hash = "sha256:787003c0ddb00500e49a10f2844fac87aa6ce977b90b0feaaf9de23c22508b24"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:2ef12179d3a291be237280175b542c07a36e7f60718296278d8593d21ca937d4"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2c1b19b3aaacc6e57b7e25710ff571c24d6c3613a45e905b1fde04d691b98ee0"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8afafd99945ead6e075b973fefa56379c5b5c53fd8937dad92c662da5d8fd5ee"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8c41976a29d078bb235fea9b2ecd3da465df42a562910f9022f1a03107bd02be"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d080e0a5eb2529460b30190fcfcc4199bd7f827663f858a226a81bc27beaa97e"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:69c0f17e9f5a7afdf2cc9fb2d1ce6aabdb3bafb7f38017c0b77862bcec2bbad8"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:504b320cd4b7eff6f968eddf81127112db685e81f7e36e75f9f84f0df46041c3"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:42de32b22b6b804f42c5d98be4f7e5e977ecdd9ee9b660fda1a3edf03b11792d"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-win32.whl", hash = "sha256:ceb01949af7121f9fc39f7d27f91be8546f3fb112c608bc4029aef0bab86a2a5"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-win_amd64.whl", hash = "sha256:1b40069d487e7edb2676d3fbdb2b0829ffa2cd63a2ec26c4938b2d34391b4ecc"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:8023faf4e01efadfa183e863fefde0046de576c6f14659e8782065bcece22198"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6b2b56950d93e41f33b4223ead100ea0fe11f8e6ee5f641eb753ce4b77a7042b"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9dcdfd0eaf283af041973bff14a2e143b8bd64e069f4c383416ecd79a81aab58"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:05fb21170423db021895e1ea1e1f3ab3adb85d1c2333cbc2310f2a26bc77272e"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:282c2cb35b5b673bbcadb33a585408104df04f14b2d9b01d4c345a3b92861c2c"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:ab4a0df41e7c16a1392727727e7998a467472d0ad65f3ad5e6e765015df08636"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7ef3cb2ebbf91e330e3bb937efada0edd9003683db6b57bb108c4001f37a02ea"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:0a4e4a1aff6c7ac4cd55792abf96c915634c2b97e3cc1c7129578aa68ebd754e"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-win32.whl", hash = "sha256:fec21693218efe39aa7f8599346e90c705afa52c5b31ae019b2e57e8f6542bb2"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-win_amd64.whl", hash = "sha256:3fd4abcb888d15a94f32b75d8fd18ee162ca0c064f35b11134be77050296d6ba"}, + {file = "MarkupSafe-2.1.3.tar.gz", hash = "sha256:af598ed32d6ae86f1b747b82783958b1a4ab8f617b06fe68795c7f026abbdcad"}, +] + +[[package]] +name = "mergedeep" +version = "1.3.4" +description = "A deep merge function for 🐍." +optional = false +python-versions = ">=3.6" +files = [ + {file = "mergedeep-1.3.4-py3-none-any.whl", hash = "sha256:70775750742b25c0d8f36c55aed03d24c3384d17c951b3175d898bd778ef0307"}, + {file = "mergedeep-1.3.4.tar.gz", hash = "sha256:0096d52e9dad9939c3d975a774666af186eda617e6ca84df4c94dec30004f2a8"}, +] + +[[package]] +name = "mkdocs" +version = "1.5.3" +description = "Project documentation with Markdown." +optional = false +python-versions = ">=3.7" +files = [ + {file = "mkdocs-1.5.3-py3-none-any.whl", hash = "sha256:3b3a78e736b31158d64dbb2f8ba29bd46a379d0c6e324c2246c3bc3d2189cfc1"}, + {file = "mkdocs-1.5.3.tar.gz", hash = "sha256:eb7c99214dcb945313ba30426c2451b735992c73c2e10838f76d09e39ff4d0e2"}, +] + +[package.dependencies] +click = ">=7.0" +colorama = {version = ">=0.4", markers = "platform_system == \"Windows\""} +ghp-import = ">=1.0" +jinja2 = ">=2.11.1" +markdown = ">=3.2.1" +markupsafe = ">=2.0.1" +mergedeep = ">=1.3.4" +packaging = ">=20.5" +pathspec = ">=0.11.1" +platformdirs = ">=2.2.0" +pyyaml = ">=5.1" +pyyaml-env-tag = ">=0.1" +watchdog = ">=2.0" + +[package.extras] +i18n = ["babel (>=2.9.0)"] +min-versions = ["babel (==2.9.0)", "click (==7.0)", "colorama (==0.4)", "ghp-import (==1.0)", "importlib-metadata (==4.3)", "jinja2 (==2.11.1)", "markdown (==3.2.1)", "markupsafe (==2.0.1)", "mergedeep (==1.3.4)", "packaging (==20.5)", "pathspec (==0.11.1)", "platformdirs (==2.2.0)", "pyyaml (==5.1)", "pyyaml-env-tag (==0.1)", "typing-extensions (==3.10)", "watchdog (==2.0)"] + +[[package]] +name = "mkdocs-material" +version = "9.4.6" +description = "Documentation that simply works" +optional = false +python-versions = ">=3.8" +files = [ + {file = "mkdocs_material-9.4.6-py3-none-any.whl", hash = "sha256:78802035d5768a78139c84ad7dce0c6493e8f7dc4861727d36ed91d1520a54da"}, + {file = "mkdocs_material-9.4.6.tar.gz", hash = "sha256:09665e60df7ee9e5ff3a54af173f6d45be718b1ee7dd962bcff3102b81fb0c14"}, +] + +[package.dependencies] +babel = ">=2.10,<3.0" +colorama = ">=0.4,<1.0" +jinja2 = ">=3.0,<4.0" +markdown = ">=3.2,<4.0" +mkdocs = ">=1.5.3,<2.0" +mkdocs-material-extensions = ">=1.2,<2.0" +paginate = ">=0.5,<1.0" +pygments = ">=2.16,<3.0" +pymdown-extensions = ">=10.2,<11.0" +regex = ">=2022.4" +requests = ">=2.26,<3.0" + +[package.extras] +git = ["mkdocs-git-committers-plugin-2 (>=1.1,<2.0)", "mkdocs-git-revision-date-localized-plugin (>=1.2,<2.0)"] +imaging = ["cairosvg (>=2.6,<3.0)", "pillow (>=9.4,<10.0)"] +recommended = ["mkdocs-minify-plugin (>=0.7,<1.0)", "mkdocs-redirects (>=1.2,<2.0)", "mkdocs-rss-plugin (>=1.6,<2.0)"] + +[[package]] +name = "mkdocs-material-extensions" +version = "1.3" +description = "Extension pack for Python Markdown and MkDocs Material." +optional = false +python-versions = ">=3.8" +files = [ + {file = "mkdocs_material_extensions-1.3-py3-none-any.whl", hash = "sha256:0297cc48ba68a9fdd1ef3780a3b41b534b0d0df1d1181a44676fda5f464eeadc"}, + {file = "mkdocs_material_extensions-1.3.tar.gz", hash = "sha256:f0446091503acb110a7cab9349cbc90eeac51b58d1caa92a704a81ca1e24ddbd"}, +] + +[[package]] +name = "packaging" +version = "23.2" +description = "Core utilities for Python packages" +optional = false +python-versions = ">=3.7" +files = [ + {file = "packaging-23.2-py3-none-any.whl", hash = "sha256:8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7"}, + {file = "packaging-23.2.tar.gz", hash = "sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5"}, +] + +[[package]] +name = "paginate" +version = "0.5.6" +description = "Divides large result sets into pages for easier browsing" +optional = false +python-versions = "*" +files = [ + {file = "paginate-0.5.6.tar.gz", hash = "sha256:5e6007b6a9398177a7e1648d04fdd9f8c9766a1a945bceac82f1929e8c78af2d"}, +] + +[[package]] +name = "pathspec" +version = "0.11.2" +description = "Utility library for gitignore style pattern matching of file paths." +optional = false +python-versions = ">=3.7" +files = [ + {file = "pathspec-0.11.2-py3-none-any.whl", hash = "sha256:1d6ed233af05e679efb96b1851550ea95bbb64b7c490b0f5aa52996c11e92a20"}, + {file = "pathspec-0.11.2.tar.gz", hash = "sha256:e0d8d0ac2f12da61956eb2306b69f9469b42f4deb0f3cb6ed47b9cce9996ced3"}, +] + +[[package]] +name = "platformdirs" +version = "3.11.0" +description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." +optional = false +python-versions = ">=3.7" +files = [ + {file = "platformdirs-3.11.0-py3-none-any.whl", hash = "sha256:e9d171d00af68be50e9202731309c4e658fd8bc76f55c11c7dd760d023bda68e"}, + {file = "platformdirs-3.11.0.tar.gz", hash = "sha256:cf8ee52a3afdb965072dcc652433e0c7e3e40cf5ea1477cd4b3b1d2eb75495b3"}, +] + +[package.extras] +docs = ["furo (>=2023.7.26)", "proselint (>=0.13)", "sphinx (>=7.1.1)", "sphinx-autodoc-typehints (>=1.24)"] +test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4)", "pytest-cov (>=4.1)", "pytest-mock (>=3.11.1)"] + +[[package]] +name = "pygments" +version = "2.16.1" +description = "Pygments is a syntax highlighting package written in Python." +optional = false +python-versions = ">=3.7" +files = [ + {file = "Pygments-2.16.1-py3-none-any.whl", hash = "sha256:13fc09fa63bc8d8671a6d247e1eb303c4b343eaee81d861f3404db2935653692"}, + {file = "Pygments-2.16.1.tar.gz", hash = "sha256:1daff0494820c69bc8941e407aa20f577374ee88364ee10a98fdbe0aece96e29"}, +] + +[package.extras] +plugins = ["importlib-metadata"] + +[[package]] +name = "pymdown-extensions" +version = "10.3.1" +description = "Extension pack for Python Markdown." +optional = false +python-versions = ">=3.8" +files = [ + {file = "pymdown_extensions-10.3.1-py3-none-any.whl", hash = "sha256:8cba67beb2a1318cdaf742d09dff7c0fc4cafcc290147ade0f8fb7b71522711a"}, + {file = "pymdown_extensions-10.3.1.tar.gz", hash = "sha256:f6c79941498a458852853872e379e7bab63888361ba20992fc8b4f8a9b61735e"}, +] + +[package.dependencies] +markdown = ">=3.2" +pyyaml = "*" + +[package.extras] +extra = ["pygments (>=2.12)"] + +[[package]] +name = "python-dateutil" +version = "2.8.2" +description = "Extensions to the standard Python datetime module" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" +files = [ + {file = "python-dateutil-2.8.2.tar.gz", hash = "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86"}, + {file = "python_dateutil-2.8.2-py2.py3-none-any.whl", hash = "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9"}, +] + +[package.dependencies] +six = ">=1.5" + +[[package]] +name = "pyyaml" +version = "6.0.1" +description = "YAML parser and emitter for Python" +optional = false +python-versions = ">=3.6" +files = [ + {file = "PyYAML-6.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d858aa552c999bc8a8d57426ed01e40bef403cd8ccdd0fc5f6f04a00414cac2a"}, + {file = "PyYAML-6.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f"}, + {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938"}, + {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d"}, + {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515"}, + {file = "PyYAML-6.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:326c013efe8048858a6d312ddd31d56e468118ad4cdeda36c719bf5bb6192290"}, + {file = "PyYAML-6.0.1-cp310-cp310-win32.whl", hash = "sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924"}, + {file = "PyYAML-6.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d"}, + {file = "PyYAML-6.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007"}, + {file = "PyYAML-6.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f003ed9ad21d6a4713f0a9b5a7a0a79e08dd0f221aff4525a2be4c346ee60aab"}, + {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d"}, + {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc"}, + {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673"}, + {file = "PyYAML-6.0.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b"}, + {file = "PyYAML-6.0.1-cp311-cp311-win32.whl", hash = "sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741"}, + {file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"}, + {file = "PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28"}, + {file = "PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9"}, + {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0"}, + {file = "PyYAML-6.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4"}, + {file = "PyYAML-6.0.1-cp312-cp312-win32.whl", hash = "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54"}, + {file = "PyYAML-6.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df"}, + {file = "PyYAML-6.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47"}, + {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98"}, + {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c"}, + {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:afd7e57eddb1a54f0f1a974bc4391af8bcce0b444685d936840f125cf046d5bd"}, + {file = "PyYAML-6.0.1-cp36-cp36m-win32.whl", hash = "sha256:fca0e3a251908a499833aa292323f32437106001d436eca0e6e7833256674585"}, + {file = "PyYAML-6.0.1-cp36-cp36m-win_amd64.whl", hash = "sha256:f22ac1c3cac4dbc50079e965eba2c1058622631e526bd9afd45fedd49ba781fa"}, + {file = "PyYAML-6.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b1275ad35a5d18c62a7220633c913e1b42d44b46ee12554e5fd39c70a243d6a3"}, + {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:18aeb1bf9a78867dc38b259769503436b7c72f7a1f1f4c93ff9a17de54319b27"}, + {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:596106435fa6ad000c2991a98fa58eeb8656ef2325d7e158344fb33864ed87e3"}, + {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:baa90d3f661d43131ca170712d903e6295d1f7a0f595074f151c0aed377c9b9c"}, + {file = "PyYAML-6.0.1-cp37-cp37m-win32.whl", hash = "sha256:9046c58c4395dff28dd494285c82ba00b546adfc7ef001486fbf0324bc174fba"}, + {file = "PyYAML-6.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:4fb147e7a67ef577a588a0e2c17b6db51dda102c71de36f8549b6816a96e1867"}, + {file = "PyYAML-6.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1d4c7e777c441b20e32f52bd377e0c409713e8bb1386e1099c2415f26e479595"}, + {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5"}, + {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696"}, + {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735"}, + {file = "PyYAML-6.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:49a183be227561de579b4a36efbb21b3eab9651dd81b1858589f796549873dd6"}, + {file = "PyYAML-6.0.1-cp38-cp38-win32.whl", hash = "sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206"}, + {file = "PyYAML-6.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62"}, + {file = "PyYAML-6.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8"}, + {file = "PyYAML-6.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c8098ddcc2a85b61647b2590f825f3db38891662cfc2fc776415143f599bb859"}, + {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6"}, + {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0"}, + {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c"}, + {file = "PyYAML-6.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5"}, + {file = "PyYAML-6.0.1-cp39-cp39-win32.whl", hash = "sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c"}, + {file = "PyYAML-6.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486"}, + {file = "PyYAML-6.0.1.tar.gz", hash = "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43"}, +] + +[[package]] +name = "pyyaml-env-tag" +version = "0.1" +description = "A custom YAML tag for referencing environment variables in YAML files. " +optional = false +python-versions = ">=3.6" +files = [ + {file = "pyyaml_env_tag-0.1-py3-none-any.whl", hash = "sha256:af31106dec8a4d68c60207c1886031cbf839b68aa7abccdb19868200532c2069"}, + {file = "pyyaml_env_tag-0.1.tar.gz", hash = "sha256:70092675bda14fdec33b31ba77e7543de9ddc88f2e5b99160396572d11525bdb"}, +] + +[package.dependencies] +pyyaml = "*" + +[[package]] +name = "regex" +version = "2023.10.3" +description = "Alternative regular expression module, to replace re." +optional = false +python-versions = ">=3.7" +files = [ + {file = "regex-2023.10.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:4c34d4f73ea738223a094d8e0ffd6d2c1a1b4c175da34d6b0de3d8d69bee6bcc"}, + {file = "regex-2023.10.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a8f4e49fc3ce020f65411432183e6775f24e02dff617281094ba6ab079ef0915"}, + {file = "regex-2023.10.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4cd1bccf99d3ef1ab6ba835308ad85be040e6a11b0977ef7ea8c8005f01a3c29"}, + {file = "regex-2023.10.3-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:81dce2ddc9f6e8f543d94b05d56e70d03a0774d32f6cca53e978dc01e4fc75b8"}, + {file = "regex-2023.10.3-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9c6b4d23c04831e3ab61717a707a5d763b300213db49ca680edf8bf13ab5d91b"}, + {file = "regex-2023.10.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c15ad0aee158a15e17e0495e1e18741573d04eb6da06d8b84af726cfc1ed02ee"}, + {file = "regex-2023.10.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6239d4e2e0b52c8bd38c51b760cd870069f0bdf99700a62cd509d7a031749a55"}, + {file = "regex-2023.10.3-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:4a8bf76e3182797c6b1afa5b822d1d5802ff30284abe4599e1247be4fd6b03be"}, + {file = "regex-2023.10.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:d9c727bbcf0065cbb20f39d2b4f932f8fa1631c3e01fcedc979bd4f51fe051c5"}, + {file = "regex-2023.10.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:3ccf2716add72f80714b9a63899b67fa711b654be3fcdd34fa391d2d274ce767"}, + {file = "regex-2023.10.3-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:107ac60d1bfdc3edb53be75e2a52aff7481b92817cfdddd9b4519ccf0e54a6ff"}, + {file = "regex-2023.10.3-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:00ba3c9818e33f1fa974693fb55d24cdc8ebafcb2e4207680669d8f8d7cca79a"}, + {file = "regex-2023.10.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:f0a47efb1dbef13af9c9a54a94a0b814902e547b7f21acb29434504d18f36e3a"}, + {file = "regex-2023.10.3-cp310-cp310-win32.whl", hash = "sha256:36362386b813fa6c9146da6149a001b7bd063dabc4d49522a1f7aa65b725c7ec"}, + {file = "regex-2023.10.3-cp310-cp310-win_amd64.whl", hash = "sha256:c65a3b5330b54103e7d21cac3f6bf3900d46f6d50138d73343d9e5b2900b2353"}, + {file = "regex-2023.10.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:90a79bce019c442604662d17bf69df99090e24cdc6ad95b18b6725c2988a490e"}, + {file = "regex-2023.10.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c7964c2183c3e6cce3f497e3a9f49d182e969f2dc3aeeadfa18945ff7bdd7051"}, + {file = "regex-2023.10.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4ef80829117a8061f974b2fda8ec799717242353bff55f8a29411794d635d964"}, + {file = "regex-2023.10.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5addc9d0209a9afca5fc070f93b726bf7003bd63a427f65ef797a931782e7edc"}, + {file = "regex-2023.10.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c148bec483cc4b421562b4bcedb8e28a3b84fcc8f0aa4418e10898f3c2c0eb9b"}, + {file = "regex-2023.10.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8d1f21af4c1539051049796a0f50aa342f9a27cde57318f2fc41ed50b0dbc4ac"}, + {file = "regex-2023.10.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0b9ac09853b2a3e0d0082104036579809679e7715671cfbf89d83c1cb2a30f58"}, + {file = "regex-2023.10.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ebedc192abbc7fd13c5ee800e83a6df252bec691eb2c4bedc9f8b2e2903f5e2a"}, + {file = "regex-2023.10.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:d8a993c0a0ffd5f2d3bda23d0cd75e7086736f8f8268de8a82fbc4bd0ac6791e"}, + {file = "regex-2023.10.3-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:be6b7b8d42d3090b6c80793524fa66c57ad7ee3fe9722b258aec6d0672543fd0"}, + {file = "regex-2023.10.3-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:4023e2efc35a30e66e938de5aef42b520c20e7eda7bb5fb12c35e5d09a4c43f6"}, + {file = "regex-2023.10.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:0d47840dc05e0ba04fe2e26f15126de7c755496d5a8aae4a08bda4dd8d646c54"}, + {file = "regex-2023.10.3-cp311-cp311-win32.whl", hash = "sha256:9145f092b5d1977ec8c0ab46e7b3381b2fd069957b9862a43bd383e5c01d18c2"}, + {file = "regex-2023.10.3-cp311-cp311-win_amd64.whl", hash = "sha256:b6104f9a46bd8743e4f738afef69b153c4b8b592d35ae46db07fc28ae3d5fb7c"}, + {file = "regex-2023.10.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:bff507ae210371d4b1fe316d03433ac099f184d570a1a611e541923f78f05037"}, + {file = "regex-2023.10.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:be5e22bbb67924dea15039c3282fa4cc6cdfbe0cbbd1c0515f9223186fc2ec5f"}, + {file = "regex-2023.10.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4a992f702c9be9c72fa46f01ca6e18d131906a7180950958f766c2aa294d4b41"}, + {file = "regex-2023.10.3-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7434a61b158be563c1362d9071358f8ab91b8d928728cd2882af060481244c9e"}, + {file = "regex-2023.10.3-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c2169b2dcabf4e608416f7f9468737583ce5f0a6e8677c4efbf795ce81109d7c"}, + {file = "regex-2023.10.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a9e908ef5889cda4de038892b9accc36d33d72fb3e12c747e2799a0e806ec841"}, + {file = "regex-2023.10.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:12bd4bc2c632742c7ce20db48e0d99afdc05e03f0b4c1af90542e05b809a03d9"}, + {file = "regex-2023.10.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:bc72c231f5449d86d6c7d9cc7cd819b6eb30134bb770b8cfdc0765e48ef9c420"}, + {file = "regex-2023.10.3-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:bce8814b076f0ce5766dc87d5a056b0e9437b8e0cd351b9a6c4e1134a7dfbda9"}, + {file = "regex-2023.10.3-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:ba7cd6dc4d585ea544c1412019921570ebd8a597fabf475acc4528210d7c4a6f"}, + {file = "regex-2023.10.3-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:b0c7d2f698e83f15228ba41c135501cfe7d5740181d5903e250e47f617eb4292"}, + {file = "regex-2023.10.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:5a8f91c64f390ecee09ff793319f30a0f32492e99f5dc1c72bc361f23ccd0a9a"}, + {file = "regex-2023.10.3-cp312-cp312-win32.whl", hash = "sha256:ad08a69728ff3c79866d729b095872afe1e0557251da4abb2c5faff15a91d19a"}, + {file = "regex-2023.10.3-cp312-cp312-win_amd64.whl", hash = "sha256:39cdf8d141d6d44e8d5a12a8569d5a227f645c87df4f92179bd06e2e2705e76b"}, + {file = "regex-2023.10.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:4a3ee019a9befe84fa3e917a2dd378807e423d013377a884c1970a3c2792d293"}, + {file = "regex-2023.10.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:76066d7ff61ba6bf3cb5efe2428fc82aac91802844c022d849a1f0f53820502d"}, + {file = "regex-2023.10.3-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bfe50b61bab1b1ec260fa7cd91106fa9fece57e6beba05630afe27c71259c59b"}, + {file = "regex-2023.10.3-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9fd88f373cb71e6b59b7fa597e47e518282455c2734fd4306a05ca219a1991b0"}, + {file = "regex-2023.10.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b3ab05a182c7937fb374f7e946f04fb23a0c0699c0450e9fb02ef567412d2fa3"}, + {file = "regex-2023.10.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dac37cf08fcf2094159922edc7a2784cfcc5c70f8354469f79ed085f0328ebdf"}, + {file = "regex-2023.10.3-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:e54ddd0bb8fb626aa1f9ba7b36629564544954fff9669b15da3610c22b9a0991"}, + {file = "regex-2023.10.3-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:3367007ad1951fde612bf65b0dffc8fd681a4ab98ac86957d16491400d661302"}, + {file = "regex-2023.10.3-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:16f8740eb6dbacc7113e3097b0a36065a02e37b47c936b551805d40340fb9971"}, + {file = "regex-2023.10.3-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:f4f2ca6df64cbdd27f27b34f35adb640b5d2d77264228554e68deda54456eb11"}, + {file = "regex-2023.10.3-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:39807cbcbe406efca2a233884e169d056c35aa7e9f343d4e78665246a332f597"}, + {file = "regex-2023.10.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:7eece6fbd3eae4a92d7c748ae825cbc1ee41a89bb1c3db05b5578ed3cfcfd7cb"}, + {file = "regex-2023.10.3-cp37-cp37m-win32.whl", hash = "sha256:ce615c92d90df8373d9e13acddd154152645c0dc060871abf6bd43809673d20a"}, + {file = "regex-2023.10.3-cp37-cp37m-win_amd64.whl", hash = "sha256:0f649fa32fe734c4abdfd4edbb8381c74abf5f34bc0b3271ce687b23729299ed"}, + {file = "regex-2023.10.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:9b98b7681a9437262947f41c7fac567c7e1f6eddd94b0483596d320092004533"}, + {file = "regex-2023.10.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:91dc1d531f80c862441d7b66c4505cd6ea9d312f01fb2f4654f40c6fdf5cc37a"}, + {file = "regex-2023.10.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:82fcc1f1cc3ff1ab8a57ba619b149b907072e750815c5ba63e7aa2e1163384a4"}, + {file = "regex-2023.10.3-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7979b834ec7a33aafae34a90aad9f914c41fd6eaa8474e66953f3f6f7cbd4368"}, + {file = "regex-2023.10.3-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ef71561f82a89af6cfcbee47f0fabfdb6e63788a9258e913955d89fdd96902ab"}, + {file = "regex-2023.10.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd829712de97753367153ed84f2de752b86cd1f7a88b55a3a775eb52eafe8a94"}, + {file = "regex-2023.10.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:00e871d83a45eee2f8688d7e6849609c2ca2a04a6d48fba3dff4deef35d14f07"}, + {file = "regex-2023.10.3-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:706e7b739fdd17cb89e1fbf712d9dc21311fc2333f6d435eac2d4ee81985098c"}, + {file = "regex-2023.10.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:cc3f1c053b73f20c7ad88b0d1d23be7e7b3901229ce89f5000a8399746a6e039"}, + {file = "regex-2023.10.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:6f85739e80d13644b981a88f529d79c5bdf646b460ba190bffcaf6d57b2a9863"}, + {file = "regex-2023.10.3-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:741ba2f511cc9626b7561a440f87d658aabb3d6b744a86a3c025f866b4d19e7f"}, + {file = "regex-2023.10.3-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:e77c90ab5997e85901da85131fd36acd0ed2221368199b65f0d11bca44549711"}, + {file = "regex-2023.10.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:979c24cbefaf2420c4e377ecd1f165ea08cc3d1fbb44bdc51bccbbf7c66a2cb4"}, + {file = "regex-2023.10.3-cp38-cp38-win32.whl", hash = "sha256:58837f9d221744d4c92d2cf7201c6acd19623b50c643b56992cbd2b745485d3d"}, + {file = "regex-2023.10.3-cp38-cp38-win_amd64.whl", hash = "sha256:c55853684fe08d4897c37dfc5faeff70607a5f1806c8be148f1695be4a63414b"}, + {file = "regex-2023.10.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:2c54e23836650bdf2c18222c87f6f840d4943944146ca479858404fedeb9f9af"}, + {file = "regex-2023.10.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:69c0771ca5653c7d4b65203cbfc5e66db9375f1078689459fe196fe08b7b4930"}, + {file = "regex-2023.10.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6ac965a998e1388e6ff2e9781f499ad1eaa41e962a40d11c7823c9952c77123e"}, + {file = "regex-2023.10.3-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1c0e8fae5b27caa34177bdfa5a960c46ff2f78ee2d45c6db15ae3f64ecadde14"}, + {file = "regex-2023.10.3-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6c56c3d47da04f921b73ff9415fbaa939f684d47293f071aa9cbb13c94afc17d"}, + {file = "regex-2023.10.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7ef1e014eed78ab650bef9a6a9cbe50b052c0aebe553fb2881e0453717573f52"}, + {file = "regex-2023.10.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d29338556a59423d9ff7b6eb0cb89ead2b0875e08fe522f3e068b955c3e7b59b"}, + {file = "regex-2023.10.3-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:9c6d0ced3c06d0f183b73d3c5920727268d2201aa0fe6d55c60d68c792ff3588"}, + {file = "regex-2023.10.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:994645a46c6a740ee8ce8df7911d4aee458d9b1bc5639bc968226763d07f00fa"}, + {file = "regex-2023.10.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:66e2fe786ef28da2b28e222c89502b2af984858091675044d93cb50e6f46d7af"}, + {file = "regex-2023.10.3-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:11175910f62b2b8c055f2b089e0fedd694fe2be3941b3e2633653bc51064c528"}, + {file = "regex-2023.10.3-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:06e9abc0e4c9ab4779c74ad99c3fc10d3967d03114449acc2c2762ad4472b8ca"}, + {file = "regex-2023.10.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:fb02e4257376ae25c6dd95a5aec377f9b18c09be6ebdefa7ad209b9137b73d48"}, + {file = "regex-2023.10.3-cp39-cp39-win32.whl", hash = "sha256:3b2c3502603fab52d7619b882c25a6850b766ebd1b18de3df23b2f939360e1bd"}, + {file = "regex-2023.10.3-cp39-cp39-win_amd64.whl", hash = "sha256:adbccd17dcaff65704c856bd29951c58a1bd4b2b0f8ad6b826dbd543fe740988"}, + {file = "regex-2023.10.3.tar.gz", hash = "sha256:3fef4f844d2290ee0ba57addcec17eec9e3df73f10a2748485dfd6a3a188cc0f"}, +] + +[[package]] +name = "requests" +version = "2.31.0" +description = "Python HTTP for Humans." +optional = false +python-versions = ">=3.7" +files = [ + {file = "requests-2.31.0-py3-none-any.whl", hash = "sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f"}, + {file = "requests-2.31.0.tar.gz", hash = "sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1"}, +] + +[package.dependencies] +certifi = ">=2017.4.17" +charset-normalizer = ">=2,<4" +idna = ">=2.5,<4" +urllib3 = ">=1.21.1,<3" + +[package.extras] +socks = ["PySocks (>=1.5.6,!=1.5.7)"] +use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] + +[[package]] +name = "six" +version = "1.16.0" +description = "Python 2 and 3 compatibility utilities" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +files = [ + {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, + {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, +] + +[[package]] +name = "urllib3" +version = "2.0.7" +description = "HTTP library with thread-safe connection pooling, file post, and more." +optional = false +python-versions = ">=3.7" +files = [ + {file = "urllib3-2.0.7-py3-none-any.whl", hash = "sha256:fdb6d215c776278489906c2f8916e6e7d4f5a9b602ccbcfdf7f016fc8da0596e"}, + {file = "urllib3-2.0.7.tar.gz", hash = "sha256:c97dfde1f7bd43a71c8d2a58e369e9b2bf692d1334ea9f9cae55add7d0dd0f84"}, +] + +[package.extras] +brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"] +secure = ["certifi", "cryptography (>=1.9)", "idna (>=2.0.0)", "pyopenssl (>=17.1.0)", "urllib3-secure-extra"] +socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] +zstd = ["zstandard (>=0.18.0)"] + +[[package]] +name = "watchdog" +version = "3.0.0" +description = "Filesystem events monitoring" +optional = false +python-versions = ">=3.7" +files = [ + {file = "watchdog-3.0.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:336adfc6f5cc4e037d52db31194f7581ff744b67382eb6021c868322e32eef41"}, + {file = "watchdog-3.0.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a70a8dcde91be523c35b2bf96196edc5730edb347e374c7de7cd20c43ed95397"}, + {file = "watchdog-3.0.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:adfdeab2da79ea2f76f87eb42a3ab1966a5313e5a69a0213a3cc06ef692b0e96"}, + {file = "watchdog-3.0.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:2b57a1e730af3156d13b7fdddfc23dea6487fceca29fc75c5a868beed29177ae"}, + {file = "watchdog-3.0.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:7ade88d0d778b1b222adebcc0927428f883db07017618a5e684fd03b83342bd9"}, + {file = "watchdog-3.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:7e447d172af52ad204d19982739aa2346245cc5ba6f579d16dac4bfec226d2e7"}, + {file = "watchdog-3.0.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:9fac43a7466eb73e64a9940ac9ed6369baa39b3bf221ae23493a9ec4d0022674"}, + {file = "watchdog-3.0.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:8ae9cda41fa114e28faf86cb137d751a17ffd0316d1c34ccf2235e8a84365c7f"}, + {file = "watchdog-3.0.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:25f70b4aa53bd743729c7475d7ec41093a580528b100e9a8c5b5efe8899592fc"}, + {file = "watchdog-3.0.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:4f94069eb16657d2c6faada4624c39464f65c05606af50bb7902e036e3219be3"}, + {file = "watchdog-3.0.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:7c5f84b5194c24dd573fa6472685b2a27cc5a17fe5f7b6fd40345378ca6812e3"}, + {file = "watchdog-3.0.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3aa7f6a12e831ddfe78cdd4f8996af9cf334fd6346531b16cec61c3b3c0d8da0"}, + {file = "watchdog-3.0.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:233b5817932685d39a7896b1090353fc8efc1ef99c9c054e46c8002561252fb8"}, + {file = "watchdog-3.0.0-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:13bbbb462ee42ec3c5723e1205be8ced776f05b100e4737518c67c8325cf6100"}, + {file = "watchdog-3.0.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:8f3ceecd20d71067c7fd4c9e832d4e22584318983cabc013dbf3f70ea95de346"}, + {file = "watchdog-3.0.0-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:c9d8c8ec7efb887333cf71e328e39cffbf771d8f8f95d308ea4125bf5f90ba64"}, + {file = "watchdog-3.0.0-py3-none-manylinux2014_aarch64.whl", hash = "sha256:0e06ab8858a76e1219e68c7573dfeba9dd1c0219476c5a44d5333b01d7e1743a"}, + {file = "watchdog-3.0.0-py3-none-manylinux2014_armv7l.whl", hash = "sha256:d00e6be486affb5781468457b21a6cbe848c33ef43f9ea4a73b4882e5f188a44"}, + {file = "watchdog-3.0.0-py3-none-manylinux2014_i686.whl", hash = "sha256:c07253088265c363d1ddf4b3cdb808d59a0468ecd017770ed716991620b8f77a"}, + {file = "watchdog-3.0.0-py3-none-manylinux2014_ppc64.whl", hash = "sha256:5113334cf8cf0ac8cd45e1f8309a603291b614191c9add34d33075727a967709"}, + {file = "watchdog-3.0.0-py3-none-manylinux2014_ppc64le.whl", hash = "sha256:51f90f73b4697bac9c9a78394c3acbbd331ccd3655c11be1a15ae6fe289a8c83"}, + {file = "watchdog-3.0.0-py3-none-manylinux2014_s390x.whl", hash = "sha256:ba07e92756c97e3aca0912b5cbc4e5ad802f4557212788e72a72a47ff376950d"}, + {file = "watchdog-3.0.0-py3-none-manylinux2014_x86_64.whl", hash = "sha256:d429c2430c93b7903914e4db9a966c7f2b068dd2ebdd2fa9b9ce094c7d459f33"}, + {file = "watchdog-3.0.0-py3-none-win32.whl", hash = "sha256:3ed7c71a9dccfe838c2f0b6314ed0d9b22e77d268c67e015450a29036a81f60f"}, + {file = "watchdog-3.0.0-py3-none-win_amd64.whl", hash = "sha256:4c9956d27be0bb08fc5f30d9d0179a855436e655f046d288e2bcc11adfae893c"}, + {file = "watchdog-3.0.0-py3-none-win_ia64.whl", hash = "sha256:5d9f3a10e02d7371cd929b5d8f11e87d4bad890212ed3901f9b4d68767bee759"}, + {file = "watchdog-3.0.0.tar.gz", hash = "sha256:4d98a320595da7a7c5a18fc48cb633c2e73cda78f93cac2ef42d42bf609a33f9"}, +] + +[package.extras] +watchmedo = ["PyYAML (>=3.10)"] + +[metadata] +lock-version = "2.0" +python-versions = "^3.10" +content-hash = "d1fabfe987f612cf532ccc9e1410c5c1072a8a37f13c5cf19d19ac737c48068e" diff --git a/docs/pyproject.toml b/docs/pyproject.toml new file mode 100644 index 000000000..c497b237d --- /dev/null +++ b/docs/pyproject.toml @@ -0,0 +1,17 @@ +[tool.poetry] +name = "docs" +version = "0.1.0" +description = "" +authors = ["Your Name "] +readme = "README.md" + +[tool.poetry.dependencies] +python = "^3.10" + + +[tool.poetry.group.dev.dependencies] +mkdocs-material = "^9.4.6" + +[build-system] +requires = ["poetry-core"] +build-backend = "poetry.core.masonry.api" diff --git a/docs/src/appendix/earthly.md b/docs/src/appendix/earthly.md new file mode 100644 index 000000000..4c6fabde6 --- /dev/null +++ b/docs/src/appendix/earthly.md @@ -0,0 +1,232 @@ +# Earthly + +This appendix is designed to get you quickly up and running with [Earthly](https://earthly.dev). +Earthly serves a central role in the CI process and is the primary orchestrator along with Github Actions. + +## Getting Started with Earthly + + +!!! Warning + The process described in this section is purely for educational purposes. + While the CI process does use Earthly, it does so in a very specific and opinionated way. + Do *not* package your service using the methodology shown below. + Instead, refer to the onboarding documentation for a description and examples of the proper method. + + +This section will get you started with the basics of Earthly in as little time as possible. +To maximize learning, this section is written with a hands-on approach, and you are highly encouraged to follow along. + +### Video + +If you prefer to learn visually, a video tutorial has been provided which introduces Earthly using a similar hands-on process. + + +!!! +note + Before starting the video, check out the setup section below to get your local environment prepared to follow along. + + + +
+ +
+ + +### Pre-requisites + +The only pre-requisite knowledge that is required is experience working with Docker and `Dockerfile`s. +Since Earthly is built on top of Docker, it's assumed you're already familiar with Docker concepts. + +### Setup + +#### Installation + +See the [installation methods](https://earthly.dev/get-earthly) available on the Earthly website. + +#### Clone the example + + +!!! Note + Even though we're using Go, you don't need to be familiar with the language or its tooling. + The process we will walk through is generic enough that applying it to other languages should be trivial. + + +To demonstrate how to use Earthly, we'll be using a tiny Go program which simply prints "Hello, World!" to the screen. +You can get a local copy by performing the following: + +```bash +git clone https://github.com/input-output-hk/catalyst-ci.git && \ + cd examples/onboarding/appendix_earthly +``` + +### Building an Earthfile + +To begin, we are first going to introduce the most fundamental component of Earthly: the `Earthfile`. +The easiest way to think of an `Earthfile` is a mix between a `Dockerfile` and a GNU `makefile`. +Like a `Dockerfile`, only a single `Earthfile` can exist per directory and it *must* be named `Earthfile` in order to be detected. + +#### Sample Structure + +```Earthfile +VERSION 0.7 # This defines the "schema" that this Earthfile satisfies, much like the version of a Docker Compose file + +# A target, which is functionally equivalent to a `makefile` target. +deps: + # A target can be thought of as a group of container image layers (think of Docker multi-stage builds) + # For this target, we start by deriving from an image which contains the Go tooling we need + FROM golang:1.20-alpine3.18 + + # Earthly has a 1:1 relationship with most Dockerfile commands, but there are a few exceptions + WORKDIR /work +``` + +Go ahead and copy the contents from above to an `Earthfile` in the local directory you cloned in the previous section. +At a foundational level, an `Earthfile` is *very* similar to a `Dockerfile`. +The commands are in all uppercase letters and there's typically only one command per line. + +#### Schema + +An `Earthfile` always starts by specifying a schema version which informs Earthly how it should go about parsing the file. +This allows the syntax and format of an Earthfile to evolve while maintaining backwards compatibility. +In our case, we target version `0.7` which is the latest version at the time of this writing. + +#### Targets + +An `Earthfile` also always has at least one target. +A target can be thought of as a grouping of image layers, similar to the way multi-stage builds work with Docker. +Each target then specifies one or more commands that create the image layers associated with that target. + +```Earthfile +VERSION 0.7 + +deps: + FROM golang:1.20-alpine3.18 + WORKDIR /work + + # These commands work identical to their Dockerfile equivalent + COPY go.mod go.sum . + RUN go mod download + +src: + # This target "inherits" from the `deps` target + FROM +deps + + # The --dir flag is unique to Earthly and just ensures the entire directory + # is copied (not just the contents inside of it) + COPY --dir cmd . +``` + +Like multi-stage builds, targets can inherit from other targets. +In the above case, we now have two targets: the `deps` target downloads our external dependencies, and the `src` target copies the +source files into the image. +The `src` target inherits the `deps` target, meaning the `go.mod`, `go.sum`, and all externally downloaded dependencies will be +present. + +#### Artifacts + +```Earthfile +# Omitted for brevity + +src: + FROM +deps + + COPY --dir cmd . + +build: + FROM +src + + # This forces go to build a "static" binary with no dependencies + ENV CGO_ENABLED=0 + RUN go build -ldflags="-extldflags=-static" -o bin/hello cmd/main.go + + # This "exports" the built binary as an "output" of this target + SAVE ARTIFACT bin/hello hello +``` + +In the above example, we introduce yet another target which is responsible for building our Go binary. +The above invocation is typical for building static Go binaries. +What's new is the usage of `SAVE ARTIFACT`. +This command takes two parameters: the local path inside the container to save, and a name to save it as. +In this case, we are saving our binary (`bin/hello`) as `hello`. +With this in place, other targets may now pull in this binary *without* having to inherit from the image. + +Our targets don't produce anything useful yet, but this is a good point to stop and actually invoke earthly: + +```bash +earthly +build +``` + +Earthly provides a CLI which is used for invoking Earthly targets. +The format is similar to GNU Make where you add a `+` followed by the target name. +If everything is working correctly, the Earthly run should succeed. + +#### Images + +```Earthfile +# Omitted for brevity + +build: + FROM +src + + ENV CGO_ENABLED=0 + RUN go build -ldflags="-extldflags=-static" -o bin/hello cmd/main.go + + SAVE ARTIFACT bin/hello hello + +docker: + # Here we inherit from a "fresh" minimal alpine version + FROM alpine:3.18 + WORKDIR /app + + # By default, we'll output this image with the 'latest' tag, but this can be + # changed + ARG tag=latest + + # Since we saved the artifact in the previous target, we can now directly + # copy the + # binary to this "fresh" image with none of the dependency bloat. + COPY +build/hello . + + ENTRYPOINT ["/app/hello"] + + # This tells Earthly that this target produces a container image we want to + # use + SAVE IMAGE hello:${tag} +``` + +In the above example, we now add our fourth and final target which is responsible for building the final container image. +Instead of inheriting from `build`, and thereby inheriting all of its bloat, we instead inherit from a "fresh" Alpine image. +We then use `COPY` to pull in our binary that we saved from the `build` target. +This is a special Earthly syntax and is a powerful way to copy single outputs from a target without worrying about inheriting the +entire context. + +We also add an `ARG` which allows us to specify the tag of the image when its created by Earthly. +By default, we set it to `latest`, but it can be changed in a number of ways, one of which is via the CLI: + +```bash +earthly +docker --tag="foobar" +``` + +If you run the above command, you should see the image show up in your local Docker registry: + +```bash +> docker image ls +REPOSITORY TAG IMAGE ID CREATED SIZE +hello foobar 61c8a3947c93 About an hour ago 9.95MB +``` + +The reason Earthly produces an image is because of the `SAVE IMAGE` we included at the very end of the `Earthfile`. +This informs Earthly that this target produces an image we actually want to use by saving it locally. + +You'll notice the size of the image is very small (< 10MB). +This is because we started from a base alpine image and *only* copied the binary from our `build` target. +Additionally, the image was saved with the `foobar` tag because we provided an alterative value for the `tag` argument when we +called the Earthly CLI. + +#### Conclusion + +Congratulations, you've created your first container image using Earthly. +We have only scratched the surface of the features provided by Earthly, and it's highly encouraged that you review the +[official documentation](https://docs.earthly.dev) to learn more. +You should now have enough knowledge to continue on with the onboarding process and learn about how Catalyst CI works using Earthly. diff --git a/docs/src/index.md b/docs/src/index.md new file mode 100644 index 000000000..022f83379 --- /dev/null +++ b/docs/src/index.md @@ -0,0 +1,10 @@ +# Introduction + +Welcome to the Catalyst CI documentation! +The purpose of this documentation is to familiarize end-users with the various Project Catalyst CI processes. +Our team uses a specific subset of technologies to build and deliver our services. +It's critical to understand what those tools are and how they interact together in the CI process. + +The quickest way to get started learning is by going through the [onboarding process](./onboarding/index.md). +For more in-depth documentation, please review the [reference section](./reference/index.md). +Before contributing to an `Earthfile`, please review the [style guide](./style.md). diff --git a/docs/src/onboarding/index.md b/docs/src/onboarding/index.md new file mode 100644 index 000000000..b15e147e1 --- /dev/null +++ b/docs/src/onboarding/index.md @@ -0,0 +1,161 @@ +# Welcome + +Welcome to the onboarding section of the documentation. +This section will guide you through the fundamentals of the Catalyst CI process and introduce you to the various tools and processes +that we use. + +## Overview + + +!!! Note + This section will talk about concepts related to [Earthly](https://earthly.dev). + If you are not familiar with Earthly, please head over [to the appendix](../appendix/earthly.md) to learn more about it before + continuing. + + +The CI process works through a discovery mechanism that identifies `Earthfile`s in a repository and filters them by target. +During every run, the CI will automatically discover and execute a select number of reserved targets. +Each of these targets serves a single purpose and together they are responsible for executing the entire release process. + +The CI process is designed to be modular and reusable across a variety of different requirements. +By default, if a specific target the CI executes is not found in the discovery phase, it simply passes and moves on to the next one. +This allows slowly building out a repository and only implementing the targets that make sense at that time. + +The discovery and execution nature of the CI allows developers to contractually define the outputs of the particular subproject they +happen to be working within. +For example, a developer can introduce a new `Earthfile` into the `service-a` subdirectory of a mono-repo and begin using the +reserved target names to interact with the CI. +This promotes self-service and establishes a clear boundary of ownership whereby developers only need to be concerned about +maintaining a single file in their subproject. + +The CI process is well-documented and troubleshooting unexpected errors only requires knowledge of Earthly and GitHub Actions. +All of the code is contained in a single open-source repository and contributions are welcome. +The remainder of the overview section will focus on discussing some of these concepts in more detail. + +### Discovery + +The discovery process serves as a critical piece in the overall CI strategy. +It enables a declarative approach whereby developers can declare the deliverables of their particular subproject and rely on the CI +process to reconcile them. +This reduces the friction of onboarding while simultaneously establishing a separation of concerns in a complex mono-repo +environment. + +During a single run, the CI will go through multiple phases of discovery. +In each of these discovery phases, a custom CLI provided by the `catalyst-ci` repository is executed. +The CLI is responsible for recursively scanning the repository for `Earthfile`s and filtering them by target. +For example, during the `check` phase of the CI, the CLI will return a list of `Earthfile`s that contain the `check` target. + +The discovery phase will then return a list of `Earthfile`s matching the given criteria. +This list is fed into a [matrix job](https://docs.github.com/en/actions/using-jobs/using-a-matrix-for-your-jobs) that multiplexes +executing the targets from each of the discovered `Earthfile`s. +By running targets in parallel, we maximize network throughput and create an easier to digest view of the CI status. +For example, by doing this, every individual target gets its own dedicated job and logs that can be easily seen from the GitHub +Actions UI. + +### Execution + +After each discovery phase, a list of targets will be executed by the CI in parallel. +Execution is handled by Earthly and usually occurs on a remote Earthly runner that maximizes the benefits of caching. +The exact steps that get executed by the target is defined by the developer. +While most targets generally have a clearly defined scope, the overall goal is to enable adaptability by offloading the logic to the +developer who is more aware of their immediate context. + +Some targets have additional processing beyond simply executing the target and returning. +For example, the `publish` target is expected to produce a single container image that is then further processed by the CI system. +The image will go through static analysis and ultimately get published to multiple image registries depending on the context. +The exact targets that are available, as well as their scope and function, can be explored more in the reference documentation. + +### Pipeline + +```mermaid +flowchart LR + A[Check] --> B[Build] --> C[Package] --> D[Test] + D --> E[Release] + D --> F[Publish] +``` + +The full CI process consists of combining the discovery and execution mechanisms into a complete pipeline, as shown above. +Each of the boxes represent a distinct stage which consists of discovering and then executing a target. +As previously mentioned, some stages, like the `release` and `publish` stages, have additional logic that occurs after executing the +target. + +Each stage is self-contained and the only dependency occurs when validating that the previous stage was successful. +For example, the `build` stage will not execute until the `check` stage has passed. +Recall that stages consist of executing multiple targets in parallel. +This means that all subprojects within a repository must pass the `check` stage before any building will begin. +This fits into the overall goal of ensuring that the default branch is always in a healthy state and it also promotes cross-team +collaboration. + +The exact scope of each stage is documented in the reference section. +However, as a short introduction, here is a brief summary of each one: + +1. `check` - This stage is expected to run all necessary checks to validate the health of the project. + This includes formatting, linting, and other static analysis tools. + The goal of this stage is to provide a quick way to validate the overall health of the code and avoid wasting cycles on building + unhealthy code. +1. `build` - This stage is expected to build any artifacts provided by a given subproject. + The primary purpose of this target is to validate that things are building without error. + It also ensures that builds are cached prior to executing subsequent steps that typically depend on these builds. +1. `package` - This stage is expected to package multiple artifacts into a single package. + It is typically used outside of the scope of a single subproject and instead combines outputs from multiple subprojects into a + single deliverable. + As such, it typically doesn't appear within the scope of a single subproject and is instead found in `Earthfile`s at higher + points in the repository hierarchy. +1. `test` - This stage is expected to run tests that prove the subproject, or multiple subprojects, are working as expected. + The target can be used to run any sort of test, including unit tests, smoke tests, and integration tests. +1. `release` - This stage is expected to produce a single release artifact. + This could be a binary, a collection of resources, or even certain reports. + When a tag commit is pushed, the CI will build this target and include the produced artifact as part of a GitHub Release. +1. `publish` - This stage is expected to produce a single container image. + After the image is built by executing the target, the CI will perform other steps to transform the image. + For example, tagging it with the git commit hash and performing general static analysis. + The CI will automatically build and publish this image to configured registries during certain types of git events. + +Each of the above stages are purely optional and can be combined to perform different types of CI workflows. +For smaller projects, only a number of stages will be utilized initially. +However, as a project grows, it can begin incorporating more stages without having to fundamentally alter the CI system. + +## Usage + +Now that we've covered how the CI process works at a conceptual level, how can we use it practically? +As a developer, the main interface you need to be most concerned with is the `Earthfile`. +Each "stage" discussed in the previous section can be directly correlated to an Earthly target. +For example, the `check` stage will search for and execute a `check` target. +In your `Earthfile`, you'll be responsible for defining these targets and their associated logic within the context of your +subproject. + +If you're contributing a new subproject with deliverables, you'll need to include an initial `Earthfile` as part of the +contribution. +Likewise, if you add a new deliverable to an existing project, you'll need to make sure it's captured in the existing `Earthfile`. +Not all `Earthfile`s are constrained to a single subproject. +In many cases, an `Earthfile` exists at higher points in the repository hierarchy that performs packaging and testing across +multiple subprojects. +This is especially true for integration testing, and it something you need to take into account when providing new features. + +Not all targets need to be present in your `Earthfile`. +For a project that is still gaining maturity, it might make sense to only define the `check` and `build` targets until the project +is ready to be tested and shipped. + +## Getting Started + +Before creating and/or modifying an `Earthfile`, it's imperative to review the [style guide](../style.md). +Due to the relative flexibility of Earthly, it's possible to structure an `Earthfile` in dozens of valid ways. +To provide consistency across our projects, we have implemented a style guide which brings a level of standardization to +`Earthfile`s. + +The next step after reviewing the style guide is taking a look at the examples provided in the `catalyst-ci` repository. +The examples are broken up by language and serve as a starter template for getting off the ground quickly. +Reviewing the examples also helps with connecting the concepts discussed in this onboarding guide with actual code. + +Experimentation is also encouraged. +The CI process runs on every single commit, even commits to PRs. +You can utilize this fact to begin experimenting with an `Earthfile` and seeing how the CI reacts to different targets. +The only limitation is that not all targets execute fully in a PR setting (i.e. no artifacts are published/released). + +Finally, if you get stuck, or have a need to understand the the CI process more, there is reference documentation available which +covers not only individual targets, but also how the entire CI process operates under the hood. +You may also use the discussions section of the `catalyst-ci` repository to ask questions specific to the CI process. + +You are now equipped and ready to start using the Catalyst CI! +We are very open-source friendly and will review all feedback/PRs made against the repository. +So please be encouraged to contribute. diff --git a/docs/src/reference/actions.md b/docs/src/reference/actions.md new file mode 100644 index 000000000..48f183b95 --- /dev/null +++ b/docs/src/reference/actions.md @@ -0,0 +1,64 @@ +# GitHub Actions + +Catalyst CI is made up of several GitHub Actions that simplify the steps required to perform the CI process. +All of these GitHub Actions are compiled into reusable workflows which perform a majority of the CI logic. + +## Overview + +The following actions are provided by Catalyst CI: + +* [configure-runner](https://github.com/input-output-hk/catalyst-ci/tree/master/actions/configure-runner) +* [discover](https://github.com/input-output-hk/catalyst-ci/tree/master/actions/discover) +* [install](https://github.com/input-output-hk/catalyst-ci/tree/master/actions/install) +* [merge](https://github.com/input-output-hk/catalyst-ci/tree/master/actions/merge) +* [push](https://github.com/input-output-hk/catalyst-ci/tree/master/actions/push) +* [run](https://github.com/input-output-hk/catalyst-ci/tree/master/actions/run) +* [setup](https://github.com/input-output-hk/catalyst-ci/tree/master/actions/setup) + +This section will only highlight the actions which are commonly used in most workflows. +Additionally, we will not cover these actions in depth. +If you're interested in learning more about a specific action, please click the link above and review the `README`. + +## Actions + +### Setup + +The `setup` action is by far the most common action and shows up in a majority of workflows. +It performs the necessary steps to setup the local GitHub runner to perform CI tasks. +This includes: + +* Installing Earthly +* Installing the custom CI CLI +* Configuring access to AWS +* Authenticating with container registries +* Configuring the Earthly remote runner + +Most of these steps are configurable and can be individually disabled. +When creating custom workflows, it's highly recommended to use this action to perform common set up tasks. +This action uses the `configure-runner` and `install` actions underneath the hood. +Using these actions individually should be avoided unless absolutely necessary. + +### Discover + +The `discover` action is another common action that shows up in many workflows. +It performs the "discovery" mechanism of finding Earthfiles with specific targets. +For example, the `check` workflow uses this action to discover all Earthfiles that have a `check` target. +The custom CI CLI **must** be installed (see the above section) in order for this action to work. + +This action is useful when creating custom workflows which extend the existing Catalyst CI process. +It can be used to create similar logic for discovering and acting upon specific Earthly targets contained in a repository. + +### Run + +The `run` action is another common action that shows up in many workflows. +It is responsible for executing the `earthly` CLI underneath the hood. +A custom action was created to perform this task for the following reasons: + +1. It simplifies long and hard to read Earthly invocations into a simple contractual interface. +2. It allows capturing and parsing output for additional information (i.e., the names of produced container images) +3. It allows bolting on additional functionality (i.e., automatic retries) + +When creating custom workflows, it's highly recommended to use this action when calling Earthly for the above reasons. +If the action does not support the invocation you need, it's better to modify the action rather than manually execute the `earthly` +CLI. +The only exception to this rule is when the invocation is unlikely to be used in more than one place. diff --git a/docs/src/reference/index.md b/docs/src/reference/index.md new file mode 100644 index 000000000..8df84a13c --- /dev/null +++ b/docs/src/reference/index.md @@ -0,0 +1,11 @@ +# Reference + +This section contains in-depth documentation about the various components that make up the Catalyst CI process. +The CI process does provide a useful layer of abstraction for developers to use, however, it's not intended to be a black box. +The full system is built on two simple technologies: Earthly and GitHub Actions. +A combination of these two systems is what ultimately constructs the whole pipeline. + +If you need help with troubleshooting the CI process, or have a desire to modify the process to meet a particular need, this section +will prove helpful. +It is broken up into the foundational components of the CI process, with each component getting an in-depth breakdown of how it +works. diff --git a/docs/src/reference/targets.md b/docs/src/reference/targets.md new file mode 100644 index 000000000..3c0f8110d --- /dev/null +++ b/docs/src/reference/targets.md @@ -0,0 +1,183 @@ +# Targets + +As discussed in onboarding, the Catalyst CI automatically searches for and executes distinct Earthly targets. +By creating these targets in your `Earthfile`, you can hook into the Catalyst CI process with minimal effort. +This section is dedicated to explaining what these targets are, how they work, and how to use them. + + +!!! Tip + The targets discussed below are *not* required to be implemented in every single `Earthfile`. + Consider each target a building block that can be composed into a complete structure that CI runs. + The system is meant to be adaptable to different workflows. + + +## Check + +### Summary + +The `check` target is responsible for validating that a given subproject is healthy and up to the appropriate standards. +This target should be used by all subprojects to improve the upkeep of code. +No additional tasks are performed before or after running the target. + +### How it Works + +The `check` target is the **first target run** in the CI pipeline and **must pass** before any other targets are run. +The CI will call the `check` target and fail if it returns a non-zero exit code. + +### Usage + +It's important to avoid adding any steps that may have flaky results to the `check` target. +Reducing the runtime of the `check` phase by avoiding any lengthy processes is also advisable. +This includes things like complex integrations tests or E2E tests that should have their own dedicated workflows. +The goal of the `check` target is to "fail fast" and avoid running a lengthy CI pipeline if there are immediate problems with the +code. + +Some typical tasks that would be appropriate for the `check` target are as follows: + +1. Validating code format +2. Linting code +3. Running static analysis tools (i.e. vulnerability scanners) + +## Build + +### Summary + +The `build` target is responsible for building artifacts. +It serves two purposes: + +1. To validate that a given build works prior to performing any other steps +2. To cache the build so future steps can re-use it without a performance impact. + +No additional tasks are performed before or after running the target. +The target must pass before subsequent targets are called. + +### How it Works + +The `build` target is the **second target run** in the CI pipeline and **must pass** before any other targets are run. +The CI will call the `build` target and fail if it returns a non-zero exit code. + +### Usage + +The `build` artifact should only be used for running "build" processes. +What defines a build process is unique to each project. +For example, it could be anything from compiling a binary to transpiling a medium into its final form +(i.e., Typescript -> Javascript). + +Downstream targets should always depend on the `build` target for maximizing cache hits. +For example, the `test` and `release` targets should either inherit from the `build` target or copy artifacts from it. + +## Package + +### Summary + +The `package` target is responsible for taking multiple artifacts and packaging them together. +In mono-repos especially, deliverables sometime consist of more than one artifact being produced by different subprojects. +This target is intended to provide an additional step where this packaging can happen before the `test` phase where these packages +are usually utilized in E2E or integration testing. + +### How it Works + +The `package` target is the **third target run** in the CI pipeline and **must pass** before any other targets are run. +The CI will call the `package` target and fail if it returns a non-zero exit code. + +### Usage + +The `package` target is very similar to the `build` target in that it should be used for building artifacts. +However, the `build` target is geared specifically at building an artifact from the context of a single project +(i.e., a single binary). +The `package` target is instead focused on composing the outputs of multiple build artifacts into a single package. +What constitutes a package is intentionally left vague, as the definition can change from project to project. +In smaller repos, this target should be skipped. + +## Test + +### Summary + +The `test` target is responsible for running tests to validate things are working as expected. +The target is intended to be versatile, and can be used to run several different formats of testing. +For example: + +1. Unit tests +2. Smoke tests +3. Integration tests + +### How it Works + +The `test` target is the **fourth target run** in the CI pipeline and **must pass** before any other targets are run. +The CI will call the `test` target and fail if it returns a non-zero exit code. + +### Usage + +The `test` target is intended to be versatile. +In many cases, separate `Earthfile`s that are outside of the scope of a single subproject are created to hold a `test` target which +runs integration tests. +At the same time, individual subprojects may utilize this target to run their own unit tests. + +The only requirement is that the target should *only* be used to run tests. +This target is the final target that is run (and must pass) before artifacts are released and/or published. + +## Publish + +### Summary + +The `publish` target is responsible for building and publishing a container image to image registries. +This target should be used when a subproject needs to produce and publish a container image. +The CI will execute this target after the `check` target, assuming it passes. + +### How it Works + +After executing the target, the CI will automatically detect the name and tag of the resulting image and save it for future steps. +If the commit that triggered the CI is from a PR, the resulting image **will not** be published to an image registry. +Instead, after building the image, the CI will immediately stop. +This allows end-users to validate that an image is building correctly during the PR process without cluttering downstream image +registries with incomplete and/or broken images. + +If the commit that triggered the CI is a merge into the default branch (i.e. `main`), the resulting image is re-tagged with the +commit hash and published to the Project Catalyst internal registry. +If the resulting image is deployable, the CI will automatically deploy it to the `dev` cluster (i.e. `dev.projectcatalyst.io`). +This ensures that the `dev` cluster always reflects changes from the mainline branch. + +Finally, if the commit that triggered the CI contains a tag, the steps discussed in the previous section are also performed, but +with additional steps. +The resulting image is not only tagged with the commit hash, but also with the git tag contained in the commit. +The image is also published to the public GHCR registry associated with the GitHub repository. + +### Usage + +When creating the `target` image, the only requirement is that the target produce a **single** image at the end using `SAVE IMAGE`. +It's recommended that you use the `latest` tag, as by default the CI ignores the tag produced by the target. +The CI will automatically handle auxiliary tasks like image scanning and/or signing, so these steps should be omitted. + +## Release + +The `release` target is responsible for building and releasing artifacts to GitHub. +This target should be used when a subproject produces artifacts (i.e. a binary) that is appropriate to include in a GitHub release. +For example, a subproject may produce a binary that is intended to be used directly (i.e. a CLI) or it may produce a set of files +that end-users need access to during a release cycle. +The CI will execute this target after the `check` target, assuming it passes. + +### How it Works + +After executing the target, the CI will automatically detect any artifacts that were produced by the target and mark them to be +saved. +If the commit that triggered the CI does not contain a git tag, then the CI will immediately stop. +This allows end-users to validate that their release artifacts build as expected without relying on a release cycle. + +If instead the commit contains a git tag, then the resulting artifacts are compressed into a single tarball and uploaded as an +artifact of the GitHub Action job. +The compression happens regardless of whether a single or multiple artifacts were produced. +After the `release` target has been run for *every* subproject, the produced artifacts from all subprojects are then attached into a +single GitHub release for the given git tag (i.e., `1.0.0`). + +### Usage + +When creating the `release` image, you may use as many `SAVE ARTIFACT` statements as you would like, however, it's recommended to +only use one. +At a minimum, the target must produce at least a single artifact. +An artifact may be a single file, multiple files, or even a complex folder structure. + +Artifacts should have some relevance for a GitHub release. +For example, making the target save the local source code is redundant since GitHub automatically includes all source code when a +new release is created. +However, a consumer may want to be able to download precompiled versions of a binary (without relying on a container). +In this case, it makes sense to create a release target that produces the binary as an artifact. diff --git a/docs/src/reference/udc.md b/docs/src/reference/udc.md new file mode 100644 index 000000000..8dfc85249 --- /dev/null +++ b/docs/src/reference/udc.md @@ -0,0 +1,37 @@ +# UDCs + +## Overview + +The Catalyst CI repository provides a number of Earthly [User Defined Commands](https://docs.earthly.dev/docs/guides/udc) (UDCs). +You can think of a UDC as a reusable snippet of Earthly code that serves the same purpose as functions in a common programming +language. +UDCs are helpful for several reasons: + +1. They keep Earthfiles DRY +2. They can encapsulate complex logic into a simple contractual interface +3. They enforce standardization and prevent solving the same problem in multiple different ways + +The third reason is particularly useful for Catalyst as we have multiple repositories with dozens of Earthfiles often solving +similar problems. + +## Usage + +You are highly encouraged to review the currently available UDCs in the +[Catalyst CI repository](https://github.com/input-output-hk/catalyst-ci/tree/master/earthly). +The folder structure is broken out by language/technology and should be relatively easy to navigate. +You can incorporate these UDCs into your Earthfiles by using something like below: + +```Earthfile +DO github.com/input-output-hk/catalyst-ci/earthly/+ --arg1=value1 +``` + +Replacing `folder` and `UDC_NAME` respectively. +The passing of an argument is optional, as some UDCs do not require any input arguments. + +## Contributing + +Please feel encouraged to contribute UDCs to the repository. +If you're seeing the same logic being re-used across multiple Earthfiles in a repository, this is a good candidate for refactoring +into a UDC. +Additionally, for SMEs who are aware of language best practices, encoding those into a UDC will help increase the overall health of +the CI process. diff --git a/docs/src/reference/workflows.md b/docs/src/reference/workflows.md new file mode 100644 index 000000000..4011c2817 --- /dev/null +++ b/docs/src/reference/workflows.md @@ -0,0 +1,145 @@ +# Workflows + +The Catalyst CI process works by combining several high-level reusable workflows into a single workflow that is used across all of +our repositories. +The purpose for this is to standardize the CI process across all repositories as well as provide control for easily updating the CI +process without having to make changes across multiple repositories. +This section gives a brief overview of these reusable workflows, which can aid in troubleshooting purposes. + +## Overview + +Most reusable workflows have a one-to-one relationship with the Earthly targets discussed in the previous section: + +* `ci.yml` is responsible for running the entire CI pipeline +* `run.yml` is responsible for executing targets with no additional steps (i.e., `check`, `build`, and `package` targets) +* `publish.yml` is responsible for handling the `publish` target +* `release.yml` is responsible for handling the `release` target + +Each workflow is self-contained and independent of the other workflows. +However, in most cases, they are tied together with conditionals (i.e. `publish` only runs if `check` succeeds). +Each workflow typically uses one or more custom GitHub Actions that are also provided by the Catalyst CI system. +These individual actions will be discussed in the next section. +Since most of the workflow logic was discussed in the previous section, this section will refrain from duplicating that effort and +instead focus on how to use the workflows (including covering their inputs). + +## Common Inputs + +### AWS + +Most of the workflows accept an optional AWS role and region. +The workflow will attempt to automatically authenticate and assume the role prior to performing any other steps. +In most cases, this is necessary, because the Catalyst CI uses a remote Earthly runner to improve caching efforts. +The credentials for the remote runner are held in AWS and need to be retrieved by the workflow. +The only other case where AWS authentication is required is during the `publish` workflow where images are pushed to ECR. + +| Name | Type | Description | Required | Default | +| ------------ | ------ | ------------------------------------------------------------ | -------- | ------- | +| aws_role_arn | string | The ARN of the AWS role that will be assumed by the workflow | No | `""` | +| aws_region | string | The AWS region that will be used by the workflow | No | `""` | + +### Earthly Runner + +As noted above, Catalyst CI uses a remote Earthly runner in order to maximize cache hits. +As a result, all workflows that interact with Earthly will accept optional inputs describing the address of the runner as well as +the name of an AWS secret containing the authentication details. +The workflow will configure the local GitHub runner using the TLS credentials retrieved from AWS so that it can successfully connect +and interact with the remote Earthly runner. + +| Name | Type | Description | Required | Default | +| ---------------------- | ------ | ----------------------------------------------------------- | -------- | -------- | +| earthly_runner_address | string | The address of the Earthly runner that will be used | No | `""` | +| earthly_runner_secret | string | The ID of the AWS secret holding Earthly runner credentials | No | `""` | +| earthly_version | string | The version of Earthly to use. | No | `latest` | + +### CLI + +Most workflows utilize the custom CLI provided by the Catalyst CI repository. +It's possible to specify a specific version of the CI to be installed (as opposed to the default of installing the latest). + +| Name | Type | Description | Required | Default | +| -------------- | ------ | --------------------------------- | -------- | -------- | +| ci_cli_version | string | The version of the CI CLI to use. | No | `latest` | + +## CI + +The CI workflow is responsible for executing the entire CI pipeline. +This workflow is a composition of the other reusable workflows covered in this section. +It's purpose is to reduce the friction for introducing the CI process into a repository by consolidating it to a single workflow. + +### Inputs + +| Name | Type | Description | Required | Default | +| ---------------- | ------ | ---------------------------------------------------------------------------------- | -------- | ------- | +| aws_ecr_registry | string | The AWS ECR registry that will be used to publish images | No | `""` | +| force_artifact | bool | If true, the workflow will always produce an artifact | No | `false` | +| tags | string | A line separated list of additional tags that will be applied to published images. | No | `""` | + +## Run + +The run workflow is a general purpose workflow that discovers and executes a given Earthly target. +Many of the CI steps follow this same pattern and this workflow serves the purpose of reducing boilerplate. +For adding ad-hoc steps, specifically ones that just need to execute a target, this is the correct workflow to use. + +### Inputs + +| Name | Type | Description | Required | Default | +| ------ | ------ | ------------------------------ | -------- | ------- | +| target | string | The target to discover and run | Yes | N/A | + +## Publish + +The publish workflow is responsible for performing the logic related to the `publish` target. +It uses the custom `run` GitHub Action to execute the target and parse the name/tag of the resulting image. +It then uses the custom `push` GitHub Action to re-tag the image and push it to the appropriate image registries. + +### Inputs + +| Name | Type | Description | Required | Default | +| ---------------- | ------ | ---------------------------------------------------------------------------------- | -------- | --------- | +| target | string | The target used to mark check builds | No | `publish` | +| aws_ecr_registry | string | The AWS ECR registry that will be used to publish images | No | `""` | +| tags | string | A line separated list of additional tags that will be applied to published images. | No | `""` | + +## Release + +The release workflow is responsible for performing logic related to the `release` target. +It uses the custom `run` GitHub Action to execute the target and store the produced artifacts to a local directory on the runner. +These artifacts are then compressed and ultimately uploaded as artifacts for the job and/or a new GitHub release. + +### Inputs + +| Name | Type | Description | Required | Default | +| -------------- | ------ | ----------------------------------------------------- | -------- | --------- | +| target | string | The target used to mark check builds | No | `release` | +| force_artifact | bool | If true, the workflow will always produce an artifact | No | `false` | + +## Deploy + +The deploy workflow is responsible for deploying services to the Catalyst `dev` cluster when new container images are produced. +It checks out the code from the Catalyst gitops repository and uses the custom `merge` GitHub Action to merge the new image tags +into the deployment files. +The changes are then committed, causing the `dev` environment to deploy the newly produced images. + +### Inputs + +| Name | Type | Description | Required | Default | +| --------------- | ------ | -------------------------------------------------------- | -------- | -------------------------------- | +| deployment_repo | string | The URL of the repository containing deployment code | No | `input-output-hk/catalyst-world` | +| environment | string | The target environment to deploy to | No | `dev` | +| images | string | A newline separated list of image names to deploy | Yes | N/A | +| tag | string | The image tag to deploy | Yes | N/A | +| token | string | A Github token with access to the deployment repository. | Yes | N/A | + +## Pages + +The pages workflow is responsible for building documentation and deploying to GitHub Pages. +It can be configured to point to an `Earthfile` and target that produces static documentation. +The workflow will execute the target, and if the commit is a merge to the default branch, push the resulting files to the `gh_pages` +branch. + +### Inputs + +| Name | Type | Description | Required | Default | +| --------- | ------ | ------------------------------------------------------------------ | -------- | ------- | +| earthfile | string | The path to the folder containing the Earthfile that will be built | Yes | N/A | +| target | string | The target that will be used to build docs | Yes | N/A | diff --git a/docs/src/style.md b/docs/src/style.md new file mode 100644 index 000000000..910d716ef --- /dev/null +++ b/docs/src/style.md @@ -0,0 +1,132 @@ +# Style Guide + +## Introduction + +This style guide is intended for individuals who are contributing towards the various `Earthfile`s within Catalyst repositories. +It provides a set of standards that we use in creating these files. +In most circumstances, the standards provided by this style guide should *not* be violated. +If an exception must me made, the rationale should be included in the respective PR. +Any `Earthfile` which does not adhere to this style guide will be rejected if no further justification is made. + +## Organization + +### Adhere to a consistent structure + +The following structure should be used to provide a consistent structure to `Earthfile`s: + +```Earthfile +VERSION 0.7 # Should be the same across the repository + +deps: + FROM + # This target should download and install all external dependencies. This + # includes language dependencies as well as system dependencies. + +src: + FROM +deps + # This target should copy in all source code. + # By doing this, it makes it clear what's considered source code. + # It also consolidates this step to a single target and avoids trying to + # track the source files across multiple targets. + +check: + FROM +src + # This target is used by the CI and should perform linting/formatting/static + # analysis checks. + +build: + FROM +build + # This target is used by the CI and should be used to build the project. + +test: + FROM +build + # This target is used by the CI and should be used to running all tests that + # are related to the project. This includes unit tests and basic smoke tests. + +release: + FROM +build + SAVE ARTIFACT ./artifact + # This target is used by the CI and should use `SAVE ARTIFACT` to save the + # result of the build step in cases where the artifact should be included + # with the GitHub release (i.e., things that are self-contained like CLIs). + +publish: + FROM + COPY +build/artifact . + SAVE IMAGE image:latest + # This target is used by the CI and should use `SAVE IMAGE` to save a + # container image that should be published to a registry by the CI. It + # typically copies artifacts from the build target and then sets up the + # required container environment. +``` + +While the above structure is not perfect for every situation, it's flexible enough to meet most requirements. +When steering away from this structure, every effort should be made to keep as much of it as possible for the sake of consistency. + +### Avoid using the base target + +Every `Earthfile` has an invisible "base" target. +This target is made up of the commands that appear outside of an existing target. +For example: + +```Earthfile +VERSION 0.7 +FROM ubuntu:latest # Apart of the base target +WORKDIR /work # Apart of the base target +``` + +By default, any target which does not inherit from a base image will use the +`FROM` statement included in the base target. +This can become especially confusing when the target is far away from the base +target which is usually put at the beginning of the file. + +There's no technical advantage for using the base target, and at most it makes +code a bit more DRY. +However, this comes at the expense of clarity. +As such, the base target should be avoided, and individual targets should be +clear about their intentions: + +```Earthfile +VERSION 0.7 + +deps: + FROM ubuntu:latest + WORKDIR /work +``` + +## Syntax + +### Always tag remote Earthfile references + +When referencing an Earthfile from another repository, always append a git tag +to it. +For example: + +```Earthfile +DO github.com/input-output-hk/catalyst-ci/earthly/udc+NAME:tag +``` + +Where `tag` is the git tag. +This ensures that upstream changes do not incidentally break builds. + +### Avoid `--no-cache` + +The `RUN` command allows passing a `--no-cache` flag which will force Earthly +to skip caching this particular command. +The result is that the cache will *always* be broken at this step. +This is especially frustrating when downstream targets inherit a target using +this flag and all caching proceeds to immediately stop. + +To prevent this, the `--no-cache` should be avoided at all times. +The only acceptable time to use it is for debugging purposes. + +### Prefer UDCs + +The primary purpose of a UDC is to reduce boilerplate and promote reusing common workflows. +Many build patterns tend to be repetitive. +For example, copying a package lockfile and installing dependencies is very common. + +In these cases, a UDC should be preferred. +The `catalyst-ci` repository provides a number of UDCs in the `earthly` subdirectory. +These should be used prior to writing a new one. +If a common use case is not covered in this subdirectory, a PR should be opened to add it. diff --git a/earthly/docs/Earthfile b/earthly/docs/Earthfile index 85088b812..7c35f1b22 100644 --- a/earthly/docs/Earthfile +++ b/earthly/docs/Earthfile @@ -33,8 +33,6 @@ mkdocs-material: # So we can extract these files in other steps. SAVE ARTIFACT /services - SAVE IMAGE mkdocs-material - # Build the documentation statically MKDOCS_BUILD: COMMAND @@ -90,4 +88,3 @@ mkdocs-develop-test: FROM alpine:latest DO +DEVELOP --dest=./local - \ No newline at end of file diff --git a/examples/onboarding/appendix_earthly/cmd/main.go b/examples/onboarding/appendix_earthly/cmd/main.go new file mode 100644 index 000000000..8713fdc08 --- /dev/null +++ b/examples/onboarding/appendix_earthly/cmd/main.go @@ -0,0 +1,19 @@ +package main + +import ( + "fmt" + + cowsay "github.com/Code-Hex/Neo-cowsay/v2" +) + +func main() { + say, err := cowsay.Say( + "Hello, World!", + cowsay.Type("default"), + cowsay.BallonWidth(40), + ) + if err != nil { + panic(err) + } + fmt.Println(say) +} diff --git a/examples/onboarding/appendix_earthly/go.mod b/examples/onboarding/appendix_earthly/go.mod new file mode 100644 index 000000000..dae7d965d --- /dev/null +++ b/examples/onboarding/appendix_earthly/go.mod @@ -0,0 +1,11 @@ +module github.com/input-output-hk/catalyst-ci/examples/onboarding/appendix_earthly + +go 1.20 + +require github.com/Code-Hex/Neo-cowsay/v2 v2.0.4 + +require ( + github.com/Code-Hex/go-wordwrap v1.0.0 // indirect + github.com/mattn/go-runewidth v0.0.13 // indirect + github.com/rivo/uniseg v0.2.0 // indirect +) diff --git a/examples/onboarding/appendix_earthly/go.sum b/examples/onboarding/appendix_earthly/go.sum new file mode 100644 index 000000000..dc66ae8e2 --- /dev/null +++ b/examples/onboarding/appendix_earthly/go.sum @@ -0,0 +1,14 @@ +github.com/Code-Hex/Neo-cowsay/v2 v2.0.4 h1:y80Hd9hmB+rsEH/p4c5ti5PbO0PhBmxw4NgbpFZvoHg= +github.com/Code-Hex/Neo-cowsay/v2 v2.0.4/go.mod h1:6k40Pwrc2FazLf1BUbmAC36E9LvT+DErjZr30isbXhg= +github.com/Code-Hex/go-wordwrap v1.0.0 h1:yl5fLyZEz3+hPGbpTRlTQ8mQJ1HXWcTq1FCNR1ch6zM= +github.com/Code-Hex/go-wordwrap v1.0.0/go.mod h1:/SsbgkY2Q0aPQRyvXcyQwWYTQOIwSORKe6MPjRVGIWU= +github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ= +github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/mattn/go-runewidth v0.0.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= +github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU= +github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= +github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= +github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/flake.nix b/flake.nix index 1ff3c8a55..aef269ca3 100644 --- a/flake.nix +++ b/flake.nix @@ -43,12 +43,14 @@ # Misc markdownlint-cli2 + mkdocs # Node nodejs_20 nodePackages.typescript # Python + poetry python312 ]; enterShell = ''