Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Release/0.8.0rc1 #18

Merged
merged 7 commits into from
Oct 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.6.0
rev: v5.0.0
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
Expand All @@ -24,7 +24,7 @@ repos:
- id: forbid-crlf
- id: forbid-tabs
- repo: https://github.com/streetsidesoftware/cspell-cli
rev: v8.13.1
rev: v8.15.2
hooks:
- id: cspell
exclude: \.gitignore|.*\.properties
Expand All @@ -46,7 +46,7 @@ repos:
- id: pyroma
args: ["-d", "--min=10", ".", "--skip-tests", "ValidREST"]
- repo: https://github.com/pre-commit/mirrors-mypy
rev: v1.11.1
rev: v1.13.0
hooks:
- id: mypy
additional_dependencies: ["types-docutils", "types-python-dateutil", "types-requests"]
Expand Down
70 changes: 63 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<img alt="ConcourseTools logo" src="https://raw.githubusercontent.com/gchq/ConcourseTools/main/docs/source/_static/logo.png">
</picture>

![version](https://img.shields.io/badge/version-0.7.1-informational)
![version](https://img.shields.io/badge/version-0.8.0rc1-informational)
![pre-release](https://img.shields.io/badge/pre--release-beta-red)
![python](https://img.shields.io/badge/python-%3E%3D3.9-informational)
![coverage](https://img.shields.io/badge/coverage-96%25-brightgreen)
Expand Down Expand Up @@ -32,14 +32,70 @@ $ pip install concoursetools

## Usage

Creating a Concourse resource type with Concourse Tools couldn't be simpler:
Start by familiarising yourself with the Concourse resource "rules" in the [documentation](https://concourse-ci.org/implementing-resource-types.html). To recreate that example, start by creating a new `concourse.py` file in your repository. The first step is to create a `Version` subclass:

1. Create subclasses of `concoursetools.version.Version` and `concoursetools.resource.ConcourseResource`, taking care to
implement any required functions.
2. Create a Dockerfile containing your requirements and calling your resource.
3. Upload the Docker image to a registry, and use it in your pipelines!
```python
from dataclasses import dataclass
from concoursetools import TypedVersion

For more information, see the [documentation](https://concoursetools.readthedocs.io/en/stable/).

@dataclass()
class GitVersion(TypedVersion):
ref: str
```

Next, create a subclass of `ConcourseResource`:

```python
from concoursetools import ConcourseResource


class GitResource(ConcourseResource[GitVersion]):

def __init__(self, uri: str, branch: str, private_key: str) -> None:
super().__init__(GitVersion)
self.uri = uri
self.branch = branch
self.private_key = private_key
```

Here, the parameters in the `__init__` method will be taken from the `source` configuration for the resource.
Now, implement the three methods required to define the behaviour of the resource:


```python
from pathlib import Path
from typing import Any
from concoursetools import BuildMetadata


class GitResource(ConcourseResource[GitVersion]):
...

def fetch_new_versions(self, previous_version: GitVersion | None) -> list[GitVersion]:
...

def download_version(self, version: GitVersion, destination_dir: pathlib.Path,
build_metadata: BuildMetadata, **kwargs: Any) -> tuple[GitVersion, dict[str, str]]:
...

def publish_new_version(self, sources_dir: pathlib.Path, build_metadata: BuildMetadata,
**kwargs: Any) -> tuple[GitVersion, dict[str, str]]:
...
```

The keyword arguments in `download_version` and `publish_new_version` correspond to `params` in the `get` step,
and `get_params` in the `put` step respectively.

Once you are happy with the resource, generate the `Dockerfile` using the Concourse Tools CLI:

```shell
$ python3 -m concoursetools dockerfile .
```

Finally, upload the Docker image to a registry, and use it in your pipelines!

For more information - and for more in-depth examples - see the [documentation](https://concoursetools.readthedocs.io/en/stable/).


## Bugs and Contributions
Expand Down
2 changes: 1 addition & 1 deletion concoursetools/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@

__all__ = ("BuildMetadata", "ConcourseResource", "Version", "TypedVersion")
__author__ = "GCHQ"
__version__ = "0.7.1"
__version__ = "0.8.0rc1"
2 changes: 2 additions & 0 deletions concoursetools/metadata.py
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,8 @@ def format_string(self, string: str, additional_values: dict[str, str] | None =
By passing additional values you are allowing an arbitrary user to view these with the correct choice
of variable. You should take **great care** not to pass any sensitive values.

.. versionadded:: 0.8.0

:param string: The string to be interpolated.
:param additional_values: Additional values which can be used for interpolation.
The keys of the mapping should not include the ``$`` character.
Expand Down
6 changes: 6 additions & 0 deletions concoursetools/testing.py
Original file line number Diff line number Diff line change
Expand Up @@ -660,6 +660,8 @@ class DockerTestResourceWrapper(TestResourceWrapper[Version]):
This is best to use if you want to be sure that your Docker image has been built properly,
or to test resource types which have **not** been built with Concourse Tools.

.. versionadded:: 0.8.0

:param inner_resource_config: The JSON configuration for the resource.
:param image: The Docker image to use, which must exist in the local cache. Passed verbatim to ``docker run``.
:param directory_dict: The initial state of the resource directory. See :class:`~concoursetools.mocking.TemporaryDirectoryState`
Expand Down Expand Up @@ -773,6 +775,8 @@ class DockerConversionTestResourceWrapper(DockerTestResourceWrapper, Generic[Ver
.. tip::
This is best to use if you want easier testing, but are concerned about the Dockerfile.

.. versionadded:: 0.8.0

:param inner_resource_type: The :class:`~concoursetools.resource.ConcourseResource` subclass corresponding to the resource.
:param inner_resource_config: The JSON configuration for the resource.
:param image: The Docker image to use, which must exist in the local cache. Passed verbatim to ``docker run``.
Expand Down Expand Up @@ -858,6 +862,8 @@ def run_docker_container(image: str, command: str, additional_args: list[str] |
Parameters of this function are meant to refer to the command within the Docker container,
and **not** the external command used to run the image.

.. versionadded:: 0.8.0

:param image: The Docker image to use for the container, which must exist in the local cache.
Passed verbatim to ``docker run``.
:param command: The command to be passed to ``docker run``. Can also be a path to a script within the container.
Expand Down
3 changes: 3 additions & 0 deletions cspell.config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ words:
- elif
- furo
- GCHQ
- gchqdev
- genindex
- HEALTHCHECK
- INPROGRESS
Expand All @@ -46,6 +47,7 @@ words:
- maxsplit
- modindex
- mypy
- ncsc
- ONBUILD
- outdir
- pathlib
Expand All @@ -71,6 +73,7 @@ words:
- urllib
- vars
- versionadded
- versionchanged
- viewcode
- WORKDIR
- xkcd
Expand Down
10 changes: 1 addition & 9 deletions docs/source/deployment.rst
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ If these were two separate commands then Docker would cache the first one and ``
Including Certs in your Docker Build
____________________________________

.. versionadded:: 0.8
.. versionchanged:: 0.8
In previous versions the advice was to use multi-stage builds for this. Although that practice is equally
secure, it makes sense to use `Docker secrets <https://docs.docker.com/build/building/secrets/>`_ instead.

Expand Down Expand Up @@ -205,14 +205,6 @@ The secrets must then be passed at build time:
The files are then mounted securely using the `correct permissions
<https://superuser.com/questions/215504/permissions-on-private-key-in-ssh-folder>`_.

.. tip::

You can easily generate this skeleton with the :ref:`cli.dockerfile` CLI command:

.. code:: shell

$ python3 -m concoursetools docker . --include-rsa


Creating Asset Files
____________________
Expand Down
1 change: 1 addition & 0 deletions docs/source/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ Contents
testing
deployment
internals
whats_new

.. toctree::
:caption: Examples
Expand Down
83 changes: 78 additions & 5 deletions docs/source/quickstart.rst
Original file line number Diff line number Diff line change
@@ -1,12 +1,85 @@
Quickstart
==========

Creating a Concourse resource type with Concourse Tools couldn't be simpler:
Creating a Concourse resource type with Concourse Tools couldn't be simpler.
To begin, install **Concourse Tools** from source or from PyPI (see the footer for links).

.. code:: shell

$ pip install concoursetools

Start by familiarising yourself with the Concourse resource "rules" in the
:concourse:`documentation <implementing-resource-types>`. To recreate that example, start by creating a new
``concourse.py`` file in your repository. The first step is to create a :class:`~concoursetools.version.Version` subclass:


.. code:: python

from dataclasses import dataclass
from concoursetools import TypedVersion


@dataclass()
class GitVersion(TypedVersion):
ref: str


Next, create a subclass of :class:`~concoursetools.resource.ConcourseResource`:

.. code:: python

from concoursetools import ConcourseResource


class GitResource(ConcourseResource[GitVersion]):

def __init__(self, uri: str, branch: str, private_key: str) -> None:
super().__init__(GitVersion)
self.uri = uri
self.branch = branch
self.private_key = private_key


Here, the parameters in the ``__init__`` method will be taken from the ``source`` configuration for the resource.
Now, implement the three methods required to define the behaviour of the resource:


.. code:: python

from pathlib import Path
from typing import Any
from concoursetools import BuildMetadata


class GitResource(ConcourseResource[GitVersion]):
...

def fetch_new_versions(self, previous_version: GitVersion | None) -> list[GitVersion]:
...

def download_version(self, version: GitVersion, destination_dir: pathlib.Path,
build_metadata: BuildMetadata, **kwargs: Any) -> tuple[GitVersion, dict[str, str]]:
...

def publish_new_version(self, sources_dir: pathlib.Path, build_metadata: BuildMetadata,
**kwargs: Any) -> tuple[GitVersion, dict[str, str]]:
...


The keyword arguments in :meth:`~concoursetools.resource.ConcourseResource.download_version`
and :meth:`~concoursetools.resource.ConcourseResource.publish_new_version` correspond to ``params`` in the ``get`` step,
and ``get_params`` in the ``put`` step respectively.

Once you are happy with the resource, freeze your requirements into a ``requirements.txt`` file,
then generate the ``Dockerfile`` using the Concourse Tools CLI:

.. code:: shell

$ python3 -m concoursetools dockerfile .


Finally, upload the Docker image to a registry, and use it in your pipelines!

1. Install **Concourse Tools** from source or from PyPI (see the footer for links).
2. Create subclasses of :class:`~concoursetools.version.Version` and :class:`~concoursetools.resource.ConcourseResource`, taking care to implement any required functions.
3. Create a :ref:`Dockerfile <Dockerfile Structure>` containing your requirements and calling your resource.
4. Upload the Docker image to a registry, and use it in your pipelines!

.. tip::
Check out the :ref:`Examples` section for different ways to leverage Concourse Tools for your use case.
7 changes: 7 additions & 0 deletions docs/source/whats_new.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
What's New
==========

.. toctree::
:glob:

whats_new/*
Loading
Loading