From 759cec56c814f0e269440cf217bf985f010a87b6 Mon Sep 17 00:00:00 2001 From: Martin Gaughran Date: Mon, 23 Sep 2024 10:34:22 +0000 Subject: [PATCH 1/2] Update copier template version --- .copier-answers.yml | 4 +++- .github/CONTRIBUTING.md | 2 +- .github/pages/make_switcher.py | 14 ++++++++------ .gitignore | 1 + catalog-info.yaml | 2 +- pyproject.toml | 1 + src/deploy_tools/__init__.py | 8 ++++++++ tests/conftest.py | 12 +++++++++--- 8 files changed, 32 insertions(+), 12 deletions(-) diff --git a/.copier-answers.yml b/.copier-answers.yml index 2501e12..17e75f3 100644 --- a/.copier-answers.yml +++ b/.copier-answers.yml @@ -1,9 +1,11 @@ # Changes here will be overwritten by Copier -_commit: 2.2.0 +_commit: 2.3.0 _src_path: gh:DiamondLightSource/python-copier-template author_email: martin.gaughran@diamond.ac.uk author_name: Martin Gaughran +component_lifecycle: experimental component_owner: group:default/sscc +component_type: library description: A set of tools used for deploying applications to a shared filesystem. distribution_name: dls-deploy-tools docker: false diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index dc0c204..1706a87 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -24,4 +24,4 @@ It is recommended that developers use a [vscode devcontainer](https://code.visua This project was created using the [Diamond Light Source Copier Template](https://github.com/DiamondLightSource/python-copier-template) for Python projects. -For more information on common tasks like setting up a developer environment, running the tests, and setting a pre-commit hook, see the template's [How-to guides](https://diamondlightsource.github.io/python-copier-template/2.2.0/how-to.html). +For more information on common tasks like setting up a developer environment, running the tests, and setting a pre-commit hook, see the template's [How-to guides](https://diamondlightsource.github.io/python-copier-template/2.3.0/how-to.html). diff --git a/.github/pages/make_switcher.py b/.github/pages/make_switcher.py index 29f646c..c06813a 100755 --- a/.github/pages/make_switcher.py +++ b/.github/pages/make_switcher.py @@ -1,3 +1,5 @@ +"""Make switcher.json to allow docs to switch between different versions.""" + import json import logging from argparse import ArgumentParser @@ -6,6 +8,7 @@ def report_output(stdout: bytes, label: str) -> list[str]: + """Print and return something received frm stdout.""" ret = stdout.decode().strip().split("\n") print(f"{label}: {ret}") return ret @@ -52,14 +55,12 @@ def get_versions(ref: str, add: str | None) -> list[str]: return versions -def write_json(path: Path, repository: str, versions: str): +def write_json(path: Path, repository: str, versions: list[str]): + """Write the JSON switcher to path.""" org, repo_name = repository.split("/") - pages_url = f"https://{org}.github.io" - if repo_name != f"{org}.github.io": - # Only add the repo name if it isn't the source for the org pages site - pages_url += f"/{repo_name}" struct = [ - {"version": version, "url": f"{pages_url}/{version}/"} for version in versions + {"version": version, "url": f"https://{org}.github.io/{repo_name}/{version}/"} + for version in versions ] text = json.dumps(struct, indent=2) print(f"JSON switcher:\n{text}") @@ -67,6 +68,7 @@ def write_json(path: Path, repository: str, versions: str): def main(args=None): + """Parse args and write switcher.""" parser = ArgumentParser( description="Make a versions.json file from gh-pages directories" ) diff --git a/.gitignore b/.gitignore index b69b75b..5eda15c 100644 --- a/.gitignore +++ b/.gitignore @@ -55,6 +55,7 @@ cov.xml # Sphinx documentation docs/_build/ +docs/_api # PyBuilder target/ diff --git a/catalog-info.yaml b/catalog-info.yaml index 5194d55..19eebb1 100644 --- a/catalog-info.yaml +++ b/catalog-info.yaml @@ -5,6 +5,6 @@ metadata: title: deploy-tools description: A set of tools used for deploying applications to a shared filesystem. spec: - type: documentation + type: library lifecycle: experimental owner: group:default/sscc diff --git a/pyproject.toml b/pyproject.toml index bbf1c4e..50dced3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -57,6 +57,7 @@ reportMissingImports = false # Ignore missing stubs in imported mo strict = ["src"] exclude = ["src/deploy_tools/_version.py"] deprecateTypingAliases = true +typeCheckingMode = "standard" [tool.pytest.ini_options] # Run pytest with all our checkers, and don't spam us with massive tracebacks on error diff --git a/src/deploy_tools/__init__.py b/src/deploy_tools/__init__.py index 26d23ba..a2ffbf3 100644 --- a/src/deploy_tools/__init__.py +++ b/src/deploy_tools/__init__.py @@ -1,3 +1,11 @@ +"""Top level API. + +.. data:: __version__ + :type: str + + Version number as calculated by https://github.com/pypa/setuptools_scm +""" + from ._version import __version__ __all__ = ["__version__"] diff --git a/tests/conftest.py b/tests/conftest.py index d5cdd5f..ebe9c10 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,4 +1,5 @@ import os +from typing import Any import pytest @@ -7,9 +8,14 @@ if os.getenv("PYTEST_RAISE", "0") == "1": @pytest.hookimpl(tryfirst=True) - def pytest_exception_interact(call): - raise call.excinfo.value + def pytest_exception_interact(call: pytest.CallInfo[Any]): + if call.excinfo is not None: + raise call.excinfo.value + else: + raise RuntimeError( + f"{call} has no exception data, an unknown error has occurred" + ) @pytest.hookimpl(tryfirst=True) - def pytest_internalerror(excinfo): + def pytest_internalerror(excinfo: pytest.ExceptionInfo[Any]): raise excinfo.value From d6edc211ec5bf2f4020f23fc5e97cb07f40621df Mon Sep 17 00:00:00 2001 From: Martin Gaughran Date: Mon, 23 Sep 2024 12:23:20 +0000 Subject: [PATCH 2/2] Update copier config to build container image --- .copier-answers.yml | 2 +- .github/workflows/_container.yml | 60 ++++++++++++++++++++++++++++++++ .github/workflows/ci.yml | 8 +++++ Dockerfile | 15 ++++++++ README.md | 1 + 5 files changed, 85 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/_container.yml diff --git a/.copier-answers.yml b/.copier-answers.yml index 17e75f3..ed54a71 100644 --- a/.copier-answers.yml +++ b/.copier-answers.yml @@ -8,7 +8,7 @@ component_owner: group:default/sscc component_type: library description: A set of tools used for deploying applications to a shared filesystem. distribution_name: dls-deploy-tools -docker: false +docker: true docs_type: README git_platform: github.com github_org: DiamondLightSource diff --git a/.github/workflows/_container.yml b/.github/workflows/_container.yml new file mode 100644 index 0000000..da5e493 --- /dev/null +++ b/.github/workflows/_container.yml @@ -0,0 +1,60 @@ +on: + workflow_call: + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + # Need this to get version number from last tag + fetch-depth: 0 + + - name: Set up Docker Buildx + id: buildx + uses: docker/setup-buildx-action@v3 + + - name: Log in to GitHub Docker Registry + if: github.event_name != 'pull_request' + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Build and export to Docker local cache + uses: docker/build-push-action@v6 + env: + DOCKER_BUILD_RECORD_UPLOAD: false + with: + context: . + # Need load and tags so we can test it below + load: true + tags: tag_for_testing + + - name: Test cli works in cached runtime image + run: docker run --rm tag_for_testing --version + + - name: Create tags for publishing image + id: meta + uses: docker/metadata-action@v5 + with: + images: ghcr.io/${{ github.repository }} + tags: | + type=ref,event=tag + type=raw,value=latest + + - name: Push cached image to container registry + if: github.ref_type == 'tag' + uses: docker/build-push-action@v6 + env: + DOCKER_BUILD_RECORD_UPLOAD: false + # This does not build the image again, it will find the image in the + # Docker cache and publish it + with: + context: . + push: true + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7cb8d90..0662518 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -34,6 +34,14 @@ jobs: secrets: CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} + container: + needs: check + if: needs.check.outputs.branch-pr == '' + uses: ./.github/workflows/_container.yml + permissions: + contents: read + packages: write + dist: needs: check if: needs.check.outputs.branch-pr == '' diff --git a/Dockerfile b/Dockerfile index 7c3b1fb..fcffeee 100644 --- a/Dockerfile +++ b/Dockerfile @@ -14,3 +14,18 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ # Set up a virtual environment and put it in PATH RUN python -m venv /venv ENV PATH=/venv/bin:$PATH + +# The build stage installs the context into the venv +FROM developer as build +COPY . /context +WORKDIR /context +RUN touch dev-requirements.txt && pip install -c dev-requirements.txt . + +# The runtime stage copies the built venv into a slim runtime container +FROM python:${PYTHON_VERSION}-slim as runtime +# Add apt-get system dependecies for runtime here if needed +COPY --from=build /venv/ /venv/ +ENV PATH=/venv/bin:$PATH + +ENTRYPOINT ["deploy-tools"] +CMD ["--version"] diff --git a/README.md b/README.md index 27a9da5..0b91185 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,7 @@ access to a shared filesystem. Source | :---: | :---: PyPI | `pip install dls-deploy-tools` +Docker | `docker run ghcr.io/diamondlightsource/deploy-tools:latest` Releases | The demo_configuration folder can be passed as the config_folder to the deploy-tools