Skip to content

Commit

Permalink
Merge pull request #2 from DiamondLightSource/add-image-ci
Browse files Browse the repository at this point in the history
Add CI to build and release images
  • Loading branch information
MJGaughran authored Sep 23, 2024
2 parents 00ee93b + d6edc21 commit 86e9939
Show file tree
Hide file tree
Showing 12 changed files with 117 additions and 13 deletions.
6 changes: 4 additions & 2 deletions .copier-answers.yml
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
# Changes here will be overwritten by Copier
_commit: 2.2.0
_commit: 2.3.0
_src_path: gh:DiamondLightSource/python-copier-template
author_email: [email protected]
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
docker: true
docs_type: README
git_platform: github.com
github_org: DiamondLightSource
Expand Down
2 changes: 1 addition & 1 deletion .github/CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -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).
14 changes: 8 additions & 6 deletions .github/pages/make_switcher.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
"""Make switcher.json to allow docs to switch between different versions."""

import json
import logging
from argparse import ArgumentParser
Expand All @@ -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
Expand Down Expand Up @@ -52,21 +55,20 @@ 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}")
path.write_text(text, encoding="utf-8")


def main(args=None):
"""Parse args and write switcher."""
parser = ArgumentParser(
description="Make a versions.json file from gh-pages directories"
)
Expand Down
60 changes: 60 additions & 0 deletions .github/workflows/_container.yml
Original file line number Diff line number Diff line change
@@ -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 }}
8 changes: 8 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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 == ''
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ cov.xml

# Sphinx documentation
docs/_build/
docs/_api

# PyBuilder
target/
Expand Down
15 changes: 15 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -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

Check warning on line 19 in Dockerfile

View workflow job for this annotation

GitHub Actions / container / build

The 'as' keyword should match the case of the 'from' keyword

FromAsCasing: 'as' and 'FROM' keywords' casing do not match More info: https://docs.docker.com/go/dockerfile/rule/from-as-casing/

Check warning on line 19 in Dockerfile

View workflow job for this annotation

GitHub Actions / container / build

The 'as' keyword should match the case of the 'from' keyword

FromAsCasing: 'as' and 'FROM' keywords' casing do not match More info: https://docs.docker.com/go/dockerfile/rule/from-as-casing/

Check warning on line 19 in Dockerfile

View workflow job for this annotation

GitHub Actions / container / build

The 'as' keyword should match the case of the 'from' keyword

FromAsCasing: 'as' and 'FROM' keywords' casing do not match More info: https://docs.docker.com/go/dockerfile/rule/from-as-casing/
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

Check warning on line 25 in Dockerfile

View workflow job for this annotation

GitHub Actions / container / build

The 'as' keyword should match the case of the 'from' keyword

FromAsCasing: 'as' and 'FROM' keywords' casing do not match More info: https://docs.docker.com/go/dockerfile/rule/from-as-casing/

Check warning on line 25 in Dockerfile

View workflow job for this annotation

GitHub Actions / container / build

The 'as' keyword should match the case of the 'from' keyword

FromAsCasing: 'as' and 'FROM' keywords' casing do not match More info: https://docs.docker.com/go/dockerfile/rule/from-as-casing/

Check warning on line 25 in Dockerfile

View workflow job for this annotation

GitHub Actions / container / build

The 'as' keyword should match the case of the 'from' keyword

FromAsCasing: 'as' and 'FROM' keywords' casing do not match More info: https://docs.docker.com/go/dockerfile/rule/from-as-casing/
# 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"]
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ access to a shared filesystem.
Source | <https://github.com/DiamondLightSource/deploy-tools>
:---: | :---:
PyPI | `pip install dls-deploy-tools`
Docker | `docker run ghcr.io/diamondlightsource/deploy-tools:latest`
Releases | <https://github.com/DiamondLightSource/deploy-tools/releases>

The demo_configuration folder can be passed as the config_folder to the deploy-tools
Expand Down
2 changes: 1 addition & 1 deletion catalog-info.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
8 changes: 8 additions & 0 deletions src/deploy_tools/__init__.py
Original file line number Diff line number Diff line change
@@ -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__"]
12 changes: 9 additions & 3 deletions tests/conftest.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import os
from typing import Any

import pytest

Expand All @@ -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

0 comments on commit 86e9939

Please sign in to comment.