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

Add a docker/dagger-based testing workflow, adopt PEP 517/621 #300

Open
wants to merge 39 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
4ab74a3
add some more linting checks
Zeitsperre Jul 13, 2023
1d618c9
try a docker-based testing approach using dagger-io
Zeitsperre Jul 13, 2023
025218c
update sphinx-rtd-theme package name
Zeitsperre Jul 13, 2023
3ba5ea2
Change LICENSE to BSD-3-Clause, move license to top-level, rename rel…
Zeitsperre Jul 13, 2023
05578ed
adopt PEP517 and PEP 621, add more metadata, add pre-commit hooks for…
Zeitsperre Jul 13, 2023
57dae29
try a different approach using a Dockerfile and build arguments
Zeitsperre Jul 17, 2023
65ceb12
Tryo to build docker image in GitHub
Zeitsperre Jul 17, 2023
60cd527
use python3.8
Zeitsperre Jul 17, 2023
949e9c1
make dagger config local and CI compatible
Zeitsperre Jul 17, 2023
f47cd20
add run-cancelling action
Zeitsperre Jul 17, 2023
cdd8d45
install dagger in running kernel
Zeitsperre Jul 17, 2023
73e6e34
fix python versions and metadata
Zeitsperre Jul 17, 2023
bbeaad0
fix version number
Zeitsperre Jul 17, 2023
251b1c0
fix triggering
Zeitsperre Jul 17, 2023
6566b9c
fix dagger package name
Zeitsperre Jul 17, 2023
ca1a85b
try a different approach, typo fix
Zeitsperre Jul 17, 2023
c1049c0
fix approach
Zeitsperre Jul 17, 2023
646587c
cleanup
Zeitsperre Jul 17, 2023
343cc53
better information
Zeitsperre Jul 17, 2023
0b0e945
implement workflow_dispatch with inputs, do not modify base image
Zeitsperre Jul 18, 2023
1485340
debugging
Zeitsperre Jul 18, 2023
f39f2a9
fix double env-var setting
Zeitsperre Jul 18, 2023
0b88ef1
re-enable notebook tests
Zeitsperre Jul 18, 2023
2fd7a0a
better organization
Zeitsperre Jul 18, 2023
5313a10
typo fix
Zeitsperre Jul 18, 2023
2ea3cac
cleaner
Zeitsperre Jul 18, 2023
44448e5
more typos
Zeitsperre Jul 18, 2023
fd9dc13
remove Dockerfile
Zeitsperre Jul 18, 2023
2a12d9d
give jenkins rights to the folder
Zeitsperre Jul 18, 2023
2176210
place kwargs in proper context
Zeitsperre Jul 18, 2023
b9c964b
fix arguments
Zeitsperre Jul 18, 2023
de8b004
fix PAVICS_HOST env var
Zeitsperre Jul 19, 2023
a08eb64
add a conftest.py, use pytest_collectstart to ignore widget and javas…
Zeitsperre Jul 25, 2023
f1f580c
try a different approach
Zeitsperre Jul 26, 2023
09774b9
re-add testing dirs to cli calls
Zeitsperre Jul 26, 2023
929530b
BASE_IMAGE_TAG must always be supplied to dagger-pipeline.py
Zeitsperre Aug 15, 2023
e0cc4d4
deal with changing API
Zeitsperre Aug 15, 2023
a83e283
Merge branch 'master' into docker-testing
Zeitsperre Sep 5, 2023
30d6a52
Merge branch 'master' into docker-testing
Zeitsperre Oct 20, 2023
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
74 changes: 74 additions & 0 deletions .github/workflows/dagger-docker.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
name: Dagger/Docker Testing Suite

on:
# FIXME: Remove Pull Request trigger before merging
pull_request:
schedule:
# Every night at 4:00 AM UTC
- cron: '0 4 * * *'
workflow_dispatch:
inputs:
BASE_IMAGE_TAG:
description: 'Image tag to use for the Docker image'
required: true
PAVICS_HOST:
description: 'Pavics URL to test against'
required: true
default: 'https://pavics.ouranos.ca/'
SANITIZE_FILE_URL:
description: 'URL for the sanitizer configuration'
required: true
default: 'https://github.com/Ouranosinc/PAVICS-e2e-workflow-tests/raw/master/notebooks/output-sanitize.cfg'

env:
BASE_IMAGE_TAG: 230601

jobs:
lint:
name: Linting
runs-on: ubuntu-latest
steps:
- name: Cancel previous runs
uses: styfle/cancel-workflow-action@0.11.0
with:
access_token: ${{ github.token }}
- name: Checkout
uses: actions/checkout@v3
- name: Setup Python
uses: actions/setup-python@v4
with:
python-version: "3.9"
- name: Run pre-commit
uses: pre-commit/action@v3.0.0

integration:
name: Integration Tests (Python${{ matrix.python-version }})
needs: lint
runs-on: ubuntu-latest
defaults:
run:
shell: bash -l {0}
strategy:
matrix:
python-version: ["3.10"]
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Setup Python
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version }}
- name: Set Environment Variables
if: ${{ github.event_name != 'workflow_dispatch' }}
run: |
echo "BASE_IMAGE_TAG=${{ env.BASE_IMAGE_TAG }}" >> $GITHUB_ENV
- name: Set Environment Variables (Workflow Dispatch)
if: ${{ github.event_name == 'workflow_dispatch' }}
run: |
echo "BASE_IMAGE_TAG=${{ github.event.inputs.image_tag }}" >> $GITHUB_ENV
echo "PAVICS_HOST=${{ github.event.inputs.PAVICS_HOST }}" >> $GITHUB_ENV
echo "SANITIZE_FILE_URL=${{ github.event.inputs.SANITIZE_FILE_URL }}" >> $GITHUB_ENV
- name: Dagger testing
run: |
pip install .[dagger]
python ./ci/dagger-pipeline.py
23 changes: 20 additions & 3 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ repos:
rev: v3.14.0
hooks:
- id: pyupgrade
args: [ '--py37-plus' ]
args: [ '--py38-plus' ]
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.4.0
hooks:
Expand All @@ -15,6 +15,19 @@ repos:
- id: end-of-file-fixer
exclude: .ipynb|.po|.xml
- id: debug-statements
exclude: .ipynb
- id: check-toml
- id: check-yaml
args: [ '--allow-multiple-documents' ]
- repo: https://github.com/pappasam/toml-sort
rev: v0.23.1
hooks:
- id: toml-sort-fix
- repo: https://github.com/adrienverge/yamllint.git
rev: v1.32.0
hooks:
- id: yamllint
args: [ '--config-file=.yamllint.yaml' ]
- repo: https://github.com/psf/black
rev: 23.9.1
hooks:
Expand All @@ -28,10 +41,9 @@ repos:
rev: 1.7.0
hooks:
- id: nbqa-black
args: [ '--target-version=py37' ]
additional_dependencies: [ 'black==23.9.1' ]
- id: nbqa-pyupgrade
args: [ '--py37-plus' ]
args: [ '--py38-plus' ]
additional_dependencies: [ 'pyupgrade==v3.14.0' ]
- id: nbqa-isort
args: [ '--profile=black' ]
Expand All @@ -42,6 +54,11 @@ repos:
- id: nbstripout
files: ".ipynb"
args: [ '--keep-output', '--keep-count' ]
- repo: https://github.com/keewis/blackdoc
rev: v0.3.8
hooks:
- id: blackdoc
additional_dependencies: ['black==23.3.0']
- repo: meta
hooks:
- id: check-hooks-apply
Expand Down
8 changes: 8 additions & 0 deletions .yamllint.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---

rules:
document-start: disable
line-length:
max: 120
level: warning
truthy: disable
28 changes: 28 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
BSD 3-Clause License
Zeitsperre marked this conversation as resolved.
Show resolved Hide resolved

Copyright (c) 2017, Ouranos, CRIM

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.

2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.

3. Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
123 changes: 123 additions & 0 deletions ci/dagger-pipeline.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
"""Run notebook tests within a docker pipeline to test integration."""

import logging
import os
import sys
from pathlib import Path

try:
import anyio
import dagger
from dagger import BuildArg
except ImportError:
raise ImportError(
"Dagger is not installed. Please install it with `pip install dagger-io` first."
)

try:
from dagger._engine._version import CLI_VERSION as __dagger_version__ # noqa
except ModuleNotFoundError:
__dagger_version__ = "unknown"


BASE_IMAGE_TAG = os.getenv("BASE_IMAGE_TAG")
PAVICS_HOST = os.getenv("PAVICS_HOST", "https://pavics.ouranos.ca")
SANITIZE_FILE_URL = os.getenv(
"SANITIZE_FILE_URL",
"https://github.com/Ouranosinc/PAVICS-e2e-workflow-tests/raw/master/notebooks/output-sanitize.cfg",
)


async def main():
async with dagger.Connection(
dagger.Config(
log_output=sys.stderr, workdir=Path(__file__).parent.parent.as_posix()
)
) as client:
if not BASE_IMAGE_TAG:
raise ValueError("BASE_IMAGE_TAG environment variable is not set.")

sources = await (
# pull container
client.container().from_(f"pavics/workflow-tests:{BASE_IMAGE_TAG}")
# copy files to container
.with_directory(
"/code",
client.host().directory("."),
exclude=[".git", "ci"],
owner="jenkins",
)
)

# run notebooks
notebooks = (
sources.with_exec(
notebook_sanitizer(SANITIZE_FILE_URL, "/code/docs/source/notebooks")
)
.with_env_variable("PAVICS_HOST", PAVICS_HOST)
.with_exec(
test_notebooks(
notebook_path="/code/docs/source/notebooks",
conftest_dir="/code",
)
)
)

# execute
whoami = await sources.with_exec(["whoami"]).stdout()
version = await sources.with_exec(["python", "-V"]).stdout()
whereami = await sources.with_exec(["pwd"]).stdout()
whatshere = await sources.with_exec(["ls", "-alh"]).stdout()
notebook_tests = await notebooks.stdout()

print("\n")
print(
f"Hello from Dagger {__dagger_version__}"
" and "
f"{'.'.join([str(v) for v in sys.version_info[0:3]])}"
" in "
f"{whereami.strip()}\n"
f"{whatshere.strip()}\n"
)
print(f"Running commands as `{whoami.strip()}` user in {version.strip()}.\n")
print(notebook_tests)


def notebook_sanitizer(file_url: str, notebook_path: str) -> list[str]:
logging.debug("Copying notebook output sanitizer ...")

cmd = [
"curl",
"-L",
file_url,
"-o",
f"{notebook_path}/output-sanitize.cfg",
"--silent",
]
return cmd


def test_notebooks(
notebook_path: str,
conftest_dir: str | None,
) -> list[str]:
logging.debug("Running notebook-based tests ...")

cmd = [
"pytest",
f"--confcutdir={conftest_dir}" if conftest_dir else None,
f"--rootdir={conftest_dir}" if conftest_dir else None,
"--nbval",
"--verbose",
notebook_path,
f"--sanitize-with={notebook_path}/output-sanitize.cfg",
f"--ignore={notebook_path}/.ipynb_checkpoints",
]

while None in cmd:
cmd.remove(None)

return cmd


anyio.run(main)
5 changes: 1 addition & 4 deletions docs/source/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,10 @@ Contents
arch/index
provenance/index
support
releasenotes
release_notes
license
todo




Indices and tables
==================

Expand Down
16 changes: 1 addition & 15 deletions docs/source/license.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,4 @@
License
=======


Copyright (c) 2017, Ouranos, CRIM
All rights reserved.

Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.

THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.. include:: ../../LICENSE
File renamed without changes.
3 changes: 2 additions & 1 deletion environment-dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@ channels:
- defaults
dependencies:
- python >=3.8,<3.12
- flit # solely needed for installing pavics-sdi
- jinja2 <=3.0.3
- jupyter
- myst-nb
- nbval
- pytest
- sphinx
- sphinx-intl
- sphinx_rtd_theme >=1.0
- sphinx-rtd-theme >=1.0
4 changes: 4 additions & 0 deletions pavics_sdi/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
"""PAVICS SDI package."""


__version__ = "1.3.0"
Loading
Loading