diff --git a/.github/workflows/pytest.yml b/.github/workflows/pytest.yml new file mode 100644 index 00000000..c56da0f7 --- /dev/null +++ b/.github/workflows/pytest.yml @@ -0,0 +1,46 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# +name: pytest + +on: + pull_request: + branches: [main] + +permissions: + contents: read + +jobs: + test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + persist-credentials: false + + - name: Set up Python environment + uses: actions/setup-python@v5 + + - name: Install dependencies + run: | + pip install pytest ruyaml + + - name: Run tests + run: | + pytest + env: + GH_TOKEN: ${{ github.token }} diff --git a/gateway/gateway.py b/gateway/gateway.py index 862ea1f2..2a0fa296 100644 --- a/gateway/gateway.py +++ b/gateway/gateway.py @@ -3,8 +3,7 @@ from pathlib import Path from typing import Dict, NotRequired, TypedDict -import yaml - +import ruyaml class RefDetails(TypedDict): """ @@ -50,19 +49,11 @@ def load_yaml(path: Path) -> dict: dict: Parsed YAML content """ with open(path, "r") as file: - actions = yaml.safe_load(file) + yaml = ruyaml.YAML() + actions = yaml.load(file) return actions -class IndentDumper(yaml.Dumper): - """ - Custom YAML dumper that maintains indentation for improved readability. - """ - - def increase_indent(self, flow=False, indentless=False): - return super(IndentDumper, self).increase_indent(flow, False) - - def write_yaml(path: Path, yaml_dict: dict | list): """ Write data as YAML to a file using custom indentation. @@ -72,7 +63,8 @@ def write_yaml(path: Path, yaml_dict: dict | list): yaml_dict: Data to write as YAML """ with open(path, "w") as file: - yaml.dump(yaml_dict, file, Dumper=IndentDumper, sort_keys=False) + yaml = ruyaml.YAML() + yaml.dump(yaml_dict, file) def write_str(path: Path, content: str): diff --git a/gateway/test_dummy.yml b/gateway/test_dummy.yml new file mode 100644 index 00000000..fa162b1c --- /dev/null +++ b/gateway/test_dummy.yml @@ -0,0 +1,132 @@ +name: Dummy Workflow + +on: + workflow_dispatch: + +jobs: + dummy: + if: false + runs-on: ubuntu-latest + steps: + - uses: 1Password/load-secrets-action@581a835fb51b8e7ec56b71cf2ffddd7e68bb25e0 + - uses: ana06/get-changed-files@v2.3.0 + - uses: DavidAnson/markdownlint-cli2-action@b4c9feab76d8025d1e83c653fa3990936df0e6c8 # v16 + - uses: JamesIves/github-pages-deploy-action@881db5376404c5c8d621010bcbec0310b58d5e29 # v4.6.8 + - uses: JustinBeckwith/linkinator-action@3d5ba091319fa7b0ac14703761eebb7d100e6f6d + - uses: JustinBeckwith/linkinator-action@v1.11.0 + - uses: Kesin11/actions-timeline@427ee2cf860166e404d0d69b4f2b24012bb7af4f + - uses: Madrapps/jacoco-report@fd4800e8a81e21bdf373438e5918b975df041d15 + - uses: VirtusLab/scala-cli-setup@ca54569bf13a29cd648721038a89c47c7921c060 + - uses: VirtusLab/scala-cli-setup@6fc878be89f1990f6599f4f6a2e52a252e54d9f9 + - uses: actions/setup-go@0aaccfd150d50ccaeb58ebd88d36e91967a5f35b + - uses: actions/setup-go@v5 + - uses: addnab/docker-run-action@4f65fabd2431ebc8d299f8e5a018d79a769ae185 + - uses: addnab/docker-run-action@v3 + - uses: amondnet/vercel-action@225d234cfe5340ca1f9a6cd158338126b5b6845f + - uses: amondnet/vercel-action@v25.1.1 + - uses: aws-actions/configure-aws-credentials@ececac1a45f3b08a01d2dd070d28d111c5fe6722 + - uses: aws-actions/configure-aws-credentials@v4.1.0 + - uses: azure/setup-helm@5119fcb9089d432beecbf79bb2c7915207344b78 + - uses: azure/setup-helm@v3 + - uses: betahuhn/repo-file-sync-action@8b92be3375cf1d1b0cd579af488a9255572e4619 + - uses: betahuhn/repo-file-sync-action@v1 + - uses: bnjbvr/cargo-machete@5eaad10acf89fb0c6a31d9b197a2d48ba762d28e + - uses: bnjbvr/cargo-machete@v0.7.0 + - uses: browser-actions/setup-firefox@5b19b18df8c293aae9e77f0a936e9fdc358f543a + - uses: browser-actions/setup-firefox@v1 + - uses: browser-actions/setup-geckodriver@5ef1526ed36211ab6cb531ec1cfb11f924ca2dee + - uses: burnett01/rsync-deployments@0dc935cdecc5f5e571865e60d2a6cdc673704823 + - uses: burnett01/rsync-deployments@5.2 + - uses: carloscastrojumo/github-cherry-pick-action@a145da1b8142e752d3cbc11aaaa46a535690f0c5 + - uses: carloscastrojumo/github-cherry-pick-action@v1.0.9 + - uses: carloscastrojumo/github-cherry-pick-action@503773289f4a459069c832dc628826685b75b4b3 + - uses: carloscastrojumo/github-cherry-pick-action@v1.0.10 + - uses: commit-check/commit-check-action@8d507e12899a9feb405c3ed546252ff9508724e0 + - uses: coursier/cache-action@4e2615869d13561d626ed48655e1a39e5b192b3c + - uses: coursier/setup-action@039f736548afa5411c1382f40a5bd9c2d30e0383 + - uses: cpp-linter/cpp-linter-action@e3fcb174b19d50de4eae1b46896698a1dd48b094 + - uses: cpp-linter/cpp-linter-action@v2.13.3 + - uses: crazy-max/ghaction-import-gpg@111c56156bcc6918c056dbef52164cfa583dc549 + - uses: crazy-max/ghaction-setup-docker@b60f85385d03ac8acfca6d9996982511d8620a19 + - uses: crazy-max/ghaction-setup-docker@v4 + - uses: damccorm/tag-ur-it@6fa72bbf1a2ea157b533d7e7abeafdb5855dbea5 + - uses: dawidd6/action-send-mail@4226df7daafa6fc901a43789c49bf7ab309066e7 + - uses: dawidd6/action-send-mail@v3 + - uses: docker://jekyll/jekyll@sha256:400b8d1569f118bca8a3a09a25f32803b00a55d1ea241feaf5f904d66ca9c625 + - uses: docker://jekyll/jekyll@* + - uses: dominikh/staticcheck-action@4ec9a0dff54be2642bc76581598ba433fd8d4967 + - uses: dominikh/staticcheck-action@v1.1.0 + - uses: dorny/paths-filter@v3.0.2 + - uses: google-github-actions/setup-gcloud@77e7a554d41e2ee56fc945c52dfd3f33d12def9a + - uses: graalvm/setup-graalvm@01ed653ac833fe80569f1ef9f25585ba2811baab + - uses: graalvm/setup-graalvm@v1 + - uses: gradle/wrapper-validation-action@v3.5.0 + - uses: hadolint/hadolint-action@f988afea3da57ee48710a9795b6bb677cc901183 + - uses: hadolint/hadolint-action@v2.1.0 + - uses: hashicorp/setup-terraform@b9cd54a3c349d3f38e8881555d616ced269862dd + - uses: hashicorp/setup-terraform@v3 + - uses: helm/chart-releaser-action@fc23f249f75decd5edf254c6b4401532cef093c3 + - uses: helm/chart-releaser-action@v1.4.0 + - uses: helm/chart-testing-action@e6669bcd63d7cb57cb4380c33043eebe5d111992 + - uses: helm/chart-testing-action@v2.6.1 + - uses: helm/chart-testing-action@0d28d3144d3a25ea2cc349d6e59901c4ff469b3b + - uses: helm/chart-testing-action@v2.7.0 + - uses: helm/kind-action@0025e74a8c7512023d06dc019c617aa3cf561fde + - uses: helm/kind-action@v1.10.0 + - uses: ilammy/setup-nasm@e77cc62a22a374a4d0668286007cc3e3b4c17760 + - uses: ilammy/setup-nasm@v1 + - uses: jasonetco/create-an-issue@1b14a70e4d8dc185e5cc76d3bec9eab20257b2c5 + - uses: jasonetco/create-an-issue@v2 + - uses: jrouly/scalafmt-native-action@14620cde093e5ff6bfbbecd4f638370024287b9d + - uses: jwgmeligmeyling/pmd-github-action@322e346bd76a0757c4d54ff9209e245965aa066d + - uses: korandoru/setup-zig@92b649f4723a14798d8b3cf3b6168edb65d5b04e + - uses: korandoru/setup-zig@v1 + - uses: leafo/gh-actions-luarocks@e65774a6386cb4f24e293dca7fc4ff89165b64c5 + - uses: ludeeus/action-shellcheck@1.1.0 + - uses: ludeeus/action-shellcheck@94e0aab03ca135d11a35e5bfc14e6746dc56e7e9 + - uses: manusa/actions-setup-minikube@b589f2d61bf96695c546929c72b38563e856059d + - uses: mozilla-actions/sccache-action@2e7f9ec7921547d4b46598398ca573513895d0bd + - uses: mozilla-actions/sccache-action@v0.0.4 + - uses: mozilla-actions/sccache-action@7d986dd989559c6ecdb630a3fd2557667be217ad + - uses: mozilla-actions/sccache-action@v0.0.9 + - uses: mukunku/tag-exists-action@bdad1eaa119ce71b150b952c97351c75025c06a9 + - uses: mukunku/tag-exists-action@v1.6.0 + - uses: ncipollo/release-action@1e3e9c6637e5566e185b7ab66f187539c5a76da7 + - uses: neofinancial/ticket-check-action@609d901d5130a4bbd7d9f62931082ed67f855891 + - uses: neofinancial/ticket-check-action@v2.0.0 + - uses: nwtgck/actions-netlify@ac1cb16858bada08a9c71a81240a85cfc3f72913 + - uses: nwtgck/actions-netlify@v1.2 + - uses: opentofu/setup-opentofu@592200bd4b9bbf4772ace78f887668b1aee8f716 + - uses: opentofu/setup-opentofu@v1 + - uses: orhun/git-cliff-action@4a4a951bc43fafe41cd2348d181853f52356bee7 + - uses: orhun/git-cliff-action@v4 + - uses: packetcoders/action-setup-cache-python-poetry@a3f2e6ed12462e038bc14270d139e373bf5ac564 + - uses: packetcoders/action-setup-cache-python-poetry@v1.1.0 + - uses: pdm-project/setup-pdm@483717a073bdef51804a58dac17d043a4183c384 + - uses: pdm-project/setup-pdm@v4 + - uses: peter-evans/close-issue@1373cadf1f0c96c1420bc000cfba2273ea307fd1 + - uses: peter-evans/close-issue@v2 + - uses: peter-evans/create-or-update-comment@c9fcb64660bc90ec1cc535646af190c992007c32 + - uses: phoenix-actions/test-reporting@f957cd93fc2d848d556fa0d03c57bc79127b6b5e + - uses: phoenix-actions/test-reporting@v15 + - uses: pmd/pmd-github-action@967a81f8b657c87f7c3e96b62301cb1a48efef29 + - uses: pre-commit/action@2c7b3805fd2a0fd8c1884dcaebf91fc102a13ecd + - uses: pre-commit/action@v3.0.1 + - uses: pypa/cibuildwheel@0f04e96e2f58e63b8b03886c1db16a507f2199bf + - uses: pypa/cibuildwheel@v2.12.0 + - uses: sbt/setup-sbt@26ab4b0fa1c47fa62fc1f6e51823a658fb6c760c + - uses: scacap/action-surefire-report@1a128e49c0585bc0b8e38e541ac3b6e35a5bc727 + - uses: scala-steward-org/scala-steward-action@5021652c555c5724af574758b78ea5be49640007 + - uses: scalacenter/sbt-dependency-submission@64084844d2b0a9b6c3765f33acde2fbe3f5ae7d3 + - uses: seanmiddleditch/gha-setup-ninja@8b297075da4cd2a5f1fd21fe011b499edf06e9d2 + - uses: seanmiddleditch/gha-setup-ninja@v4 + - uses: snok/install-poetry@76e04a911780d5b312d89783f7b1cd627778900a + - uses: snok/install-poetry@v1 + - uses: untitaker/hyperlink@0.1.21 + - uses: untitaker/hyperlink@d277930ba480c61cd3dd1a0caf0d18acfed294a6 + - uses: uraimo/run-on-arch-action@ac33288c3728ca72563c97b8b88dda5a65a84448 + - uses: uraimo/run-on-arch-action@v2 + - uses: vimtor/action-zip@5f1c4aa587ea41db1110df6a99981dbe19cee310 + - uses: vimtor/action-zip@v1 + - uses: slackapi/slack-github-action@485a9d42d3a73031f12ec201c457e2162c45d02d + - uses: slackapi/slack-github-action@v2.0.0 diff --git a/gateway/test_gateway.py b/gateway/test_gateway.py index 74badb76..4184a351 100644 --- a/gateway/test_gateway.py +++ b/gateway/test_gateway.py @@ -1,8 +1,24 @@ import datetime +import filecmp from gateway import * +def test_load_yaml(): + this_dir = os.path.dirname(os.path.realpath(__file__)) + parsed = load_yaml(this_dir + "/test_dummy.yml") + comment = parsed['jobs']['dummy']['steps'][3].ca.items['uses'][2].value + assert comment == "# v4.6.8\n" + +def test_roundtrip_yaml(): + this_dir = os.path.dirname(os.path.realpath(__file__)) + infile = this_dir + "/test_dummy.yml" + parsed = load_yaml(infile) + outfile = this_dir + "/test_out_dummy.yml" + write_yaml(outfile, parsed) + assert filecmp.cmp(infile, outfile, shallow=False) + + def test_update_refs(): steps = [ {"uses": "actions/setup-go@v5"}, @@ -38,7 +54,7 @@ def test_update_refs(): }, "dorny/paths-filter": { "0bc4621a3135347011ad047f9ecf449bf72ce2bd": { - "expires_at": calculate_expiry() + "expires_at": calculate_expiry(12) }, "de90cc6fb38fc0963ad72b210f1f284cd68cea36": { "expires_at": datetime.date(2100, 1, 1), diff --git a/stash/restore/test_get_stash.py b/stash/restore/test_get_stash.py index d638b0ba..c8e1a575 100644 --- a/stash/restore/test_get_stash.py +++ b/stash/restore/test_get_stash.py @@ -14,6 +14,7 @@ import unittest import json +import os from get_stash import ensure_json, gh_api, jq @@ -23,7 +24,8 @@ def test_jq(self): self.assertEqual(jq('{"a": 1}', ".a", ["-j"]).stdout, "1") def test_jq_file(self): - self.assertEqual(jq("test.json", ".a").stdout, "1\n") + this_dir = os.path.dirname(os.path.realpath(__file__)) + self.assertEqual(jq(this_dir + "/test.json", ".a").stdout, "1\n") def test_jq_error(self): with self.assertRaises(ValueError):