Repository: btschwertfeger/python-cmethods (language: python)

Issue:
Create a release workflow for dev and production releases
**Is your feature request related to a problem? Please describe.**
There should be a workflow (or more) that get triggered, when a new push via PR goes into the master that triggers the upload of the package to test.pypi.org. Also a workflow that gets triggered on a new release that uploads the package to the production PyPI should be added to improve the development processes. 


Discussion / hints:

Fix patch:
diff --git a/.github/codecov.yml b/.github/codecov.yml
new file mode 100644
index 0000000..7b54980
--- /dev/null
+++ b/.github/codecov.yml
@@ -0,0 +1,23 @@
+coverage:
+  ##    Status checks in PR
+  ##
+  status:
+    project:
+      default:
+        informational: true
+        ##    Target coverage is the last one
+        ##
+        target: auto
+        ##    this allows a 2% drop from the previous base commit coverage
+        ##
+        threshold: 2%
+    patch:
+      default:
+        informational: true
+
+comment:
+  layout: "reach, diff, flags, files"
+  behavior: default
+  require_changes: true # if false: post the comment even if coverage dont change
+  require_base: no # [yes :: must have a base report to post]
+  require_head: yes # [yes :: must have a head report to post]
diff --git a/.github/workflows/_build.yml b/.github/workflows/_build.yml
new file mode 100644
index 0000000..03a6895
--- /dev/null
+++ b/.github/workflows/_build.yml
@@ -0,0 +1,41 @@
+# -*- coding: utf-8 -*-
+# Copyright (C) 2023 Benjamin Thomas Schwertfeger
+# Github: https://github.com/btschwertfeger
+#
+# Template workflow to build the project for a specific os
+# and Python version.
+#
+
+name: Build
+
+on:
+  workflow_call:
+    inputs:
+      os:
+        type: string
+        required: true
+      python-version:
+        type: string
+        required: true
+
+jobs:
+  Build:
+    runs-on: ${{ inputs.os }}
+    steps:
+      - name: Checkout repository
+        uses: actions/checkout@v3
+
+      - name: Set up Python ${{ inputs.python-version }}
+        uses: actions/setup-python@v4
+        with:
+          python-version: ${{ inputs.python-version }}
+
+      - name: Install dependencies
+        run: |
+          python -m pip install --upgrade pip
+
+      - name: Build the package
+        run: python -m pip wheel -w dist --no-deps .
+
+      - name: Install the package
+        run: python3 -m pip install dist/python_cmethods*.whl
diff --git a/.github/workflows/codecov.yml b/.github/workflows/_codecov.yml
similarity index 61%
rename from .github/workflows/codecov.yml
rename to .github/workflows/_codecov.yml
index b6119ac..203cc95 100644
--- a/.github/workflows/codecov.yml
+++ b/.github/workflows/_codecov.yml
@@ -1,12 +1,22 @@
-name: Codecov
+# -*- coding: utf-8 -*-
+# Copyright (C) 2023 Benjamin Thomas Schwertfeger
+# Github: https://github.com/btschwertfeger
+#
+# Template workflow to build the project for a specific os
+# and Python version, run the tests and upload the results to codecov.
+#
+
+name: CodeCov
 
 on:
-  push:
-    branches:
-      - "**"
-  pull_request:
-    branches:
-      - "**"
+  workflow_call:
+    inputs:
+      os:
+        type: string
+        required: true
+      python-version:
+        type: string
+        required: true
 
 concurrency:
   group: codecov-${{ github.ref }}
@@ -15,17 +25,10 @@ concurrency:
 jobs:
   codecov:
     name: Coverage
-    runs-on: ${{ matrix.os }}
-    strategy:
-      fail-fast: false
-      max-parallel: 1
-      matrix:
-        os: [ubuntu-latest]
-        python-version: ["3.11"]
-
+    runs-on: ${{ inputs.os }}
     env:
-      OS: ${{ matrix.os }}
-      PYTHON: ${{ matrix.python-version }}
+      OS: ${{ inputs.os }}
+      PYTHON: ${{ inputs.python-version }}
 
     steps:
       - name: Checkout repository
@@ -34,7 +37,7 @@ jobs:
       - name: Set up Python ${{ matrix.python-version }}
         uses: actions/setup-python@v4
         with:
-          python-version: ${{ matrix.python-version }}
+          python-version: ${{ inputs.python-version }}
 
       - name: Install dependencies
         run: |
diff --git a/.github/workflows/_pre_commit.yml b/.github/workflows/_pre_commit.yml
new file mode 100644
index 0000000..0fca6f7
--- /dev/null
+++ b/.github/workflows/_pre_commit.yml
@@ -0,0 +1,19 @@
+# -*- coding: utf-8 -*-
+# Copyright (C) 2023 Benjamin Thomas Schwertfeger
+# Github: https://github.com/btschwertfeger
+#
+# Template workflow to run pre-commit.
+#
+
+name: Pre-Commit
+
+on:
+  workflow_call:
+
+jobs:
+  Pre-Commit:
+    runs-on: ubuntu-latest
+    steps:
+      - name: Checkout
+        uses: actions/checkout@v3
+      - uses: pre-commit/action@v3.0.0
diff --git a/.github/workflows/_pypi_publish.yml b/.github/workflows/_pypi_publish.yml
new file mode 100644
index 0000000..748e254
--- /dev/null
+++ b/.github/workflows/_pypi_publish.yml
@@ -0,0 +1,51 @@
+# -*- coding: utf-8 -*-
+# Copyright (C) 2023 Benjamin Thomas Schwertfeger
+# Github: https://github.com/btschwertfeger
+#
+# Template workflow to build the project and publish
+# the package to PyPI. It can be used to publish on the
+# test index and the "live" PyPI index.
+#
+
+name: PyPI Publish
+
+on:
+  workflow_call:
+    inputs:
+      REPOSITORY_URL:
+        type: string
+        required: true
+    secrets:
+      API_TOKEN:
+        required: true
+
+jobs:
+  PyPI-Publish:
+    name: Upload to ${{ inputs.REPOSITORY_URL }}
+    runs-on: ubuntu-latest
+    permissions:
+      id-token: write # IMPORTANT: this permission is mandatory for OIDC publishing
+
+    steps:
+      - name: Checkout repository
+        uses: actions/checkout@v3
+        with:
+          fetch-depth: 0 # IMPORTANT: otherwise the current tag does not get fetched and the build version gets worse
+
+      - name: Set up Python 3.11
+        uses: actions/setup-python@v4
+        with:
+          python-version: 3.11
+
+      - name: Install dependencies
+        run: |
+          python -m pip install --upgrade pip
+
+      - name: Build the package
+        run: python -m pip wheel -w dist --no-deps .
+
+      - name: Publish package distributions to PyPI (optional - testpypi)
+        uses: pypa/gh-action-pypi-publish@release/v1
+        with:
+          password: ${{ secrets.API_TOKEN }}
+          repository-url: ${{ inputs.REPOSITORY_URL }}
diff --git a/.github/workflows/cicd.yml b/.github/workflows/cicd.yml
new file mode 100644
index 0000000..cb809a3
--- /dev/null
+++ b/.github/workflows/cicd.yml
@@ -0,0 +1,74 @@
+# -*- coding: utf-8 -*-
+# Copyright (C) 2023 Benjamin Thomas Schwertfeger
+# Github: https://github.com/btschwertfeger
+#
+# Workflow to apply pre-commit, build, test and upload the package
+# to the test index of PyPI.
+
+name: CI/CD
+
+on:
+  push:
+    branches:
+      - "**"
+
+concurrency:
+  group: CICD-${{ github.ref }}
+  cancel-in-progress: true
+
+jobs:
+  ##    Checks the code logic, style and more
+  ##
+  Pre-Commit:
+    uses: ./.github/workflows/_pre_commit.yml
+
+  ##    Builds the package on multiple OS for multiple
+  ##    Python versions
+  ##
+  Build:
+    needs: [Pre-Commit]
+    uses: ./.github/workflows/_build.yml
+    strategy:
+      fail-fast: false
+      matrix:
+        os: [ubuntu-latest, macos-latest] # todo: windows-latest
+        python-version: ["3.8", "3.9", "3.10", "3.11"]
+    with:
+      os: ${{ matrix.os }}
+      python-version: ${{ matrix.python-version }}
+
+  ##    Run the unit tests for Python 3.8 until 3.11
+  ##
+  Test:
+    needs: [Build]
+    uses: ./.github/workflows/_test.yml
+    strategy:
+      matrix:
+        os: [ubuntu-latest]
+        python-version: ["3.8", "3.9", "3.10", "3.11"]
+    with:
+      os: ${{ matrix.os }}
+      python-version: ${{ matrix.python-version }}
+
+  ##    Uploads the package to test.pypi.org on master if triggered by
+  ##    a regular commit/push.
+  ##
+  UploadTestPyPI:
+    if: success() && github.ref == 'refs/heads/master'
+    needs: [Test]
+    name: Upload current development version to Test PyPI
+    uses: ./.github/workflows/_pypi_publish.yml
+    with:
+      REPOSITORY_URL: https://test.pypi.org/legacy/
+    secrets:
+      API_TOKEN: ${{ secrets.TEST_PYPI_API_TOKEN }}
+
+  ##    Generates and uploads the coverage statistics to codecov
+  ##
+  CodeCov:
+    needs: [Test]
+    uses: ./.github/workflows/_codecov.yml
+    with:
+      os: "ubuntu-latest"
+      python-version: "3.11"
+    secrets: inherit
diff --git a/.github/workflows/pre-commit.yml b/.github/workflows/pre-commit.yml
deleted file mode 100644
index 879585d..0000000
--- a/.github/workflows/pre-commit.yml
+++ /dev/null
@@ -1,20 +0,0 @@
-name: Pre-Commit
-
-on:
-  push:
-    branches: ["*", "!master"]
-  pull_request:
-    branches: ["*"]
-
-concurrency:
-  group: pre-commit-${{ github.ref }}
-  cancel-in-progress: true
-
-jobs:
-  pre-commit:
-    name: Pre-Commit
-    runs-on: ubuntu-latest
-    steps:
-      - name: Checkout
-        uses: actions/checkout@v3
-      - uses: pre-commit/action@v3.0.0
diff --git a/.github/workflows/python-package.yml b/.github/workflows/python-package.yml
deleted file mode 100644
index c5923f7..0000000
--- a/.github/workflows/python-package.yml
+++ /dev/null
@@ -1,50 +0,0 @@
-# This workflow will install Python dependencies, run tests and lint with a variety of Python versions
-# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-python
-
-name: Python-Package
-
-on:
-  push:
-    branches: ["master"]
-  pull_request:
-    branches: ["master"]
-
-concurrency:
-  group: pypackage-${{ github.ref }}
-  cancel-in-progress: true
-
-jobs:
-  pre-commit:
-    name: Pre-Commit
-    runs-on: ubuntu-latest
-    steps:
-      - name: Checkout
-        uses: actions/checkout@v3
-      - uses: pre-commit/action@v3.0.0
-
-  build:
-    needs: [pre-commit]
-    name: Build
-    runs-on: ubuntu-latest
-    strategy:
-      fail-fast: false
-      matrix:
-        python-version: ["3.8", "3.9", "3.10", "3.11"]
-    steps:
-      - uses: actions/checkout@v3
-      - name: Set up Python ${{ matrix.python-version }}
-        uses: actions/setup-python@v3
-        with:
-          python-version: ${{ matrix.python-version }}
-      - name: Install dependencies
-        run: |
-          python -m pip install --upgrade pip
-          # python -m pip install flake8 pytest scikit-learn scipy
-          # if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
-
-      - name: Install the package
-        run: python -m pip install ".[dev]"
-
-      - name: Test with pytest
-        run: |
-          pytest tests/*
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
new file mode 100644
index 0000000..63c24be
--- /dev/null
+++ b/.github/workflows/release.yml
@@ -0,0 +1,79 @@
+# -*- coding: utf-8 -*-
+# Copyright (C) 2023 Benjamin Thomas Schwertfeger
+# Github: https://github.com/btschwertfeger
+#
+# Workflow that gets triggered, when a release was created in the
+# Github UI. This enables the upload of the python-cmethods package
+# for the latest tag to PyPI.
+#
+
+name: PyPI Production Release
+
+on:
+  release:
+    types: [created]
+
+jobs:
+  ##    Run pre-commit - just to make shure that the code is still
+  ##    in the proper format
+  ##
+  Pre-Commit:
+    uses: ./.github/workflows/_pre_commit.yml
+
+  ##    Build the package - for all Python versions
+  ##
+  Build:
+    uses: ./.github/workflows/_build.yml
+    needs: [Pre-Commit]
+    strategy:
+      fail-fast: false
+      matrix:
+        os: ["macos-latest", "ubuntu-latest"]
+        python-version: ["3.8", "3.9", "3.10", "3.11"]
+    with:
+      os: ${{ matrix.os }}
+      python-version: ${{ matrix.python-version }}
+
+  ##    Build the documentation
+  ##
+  Build-Doc:
+    needs: [Pre-Commit]
+    uses: ./.github/workflows/_build_doc.yml
+    with:
+      os: "ubuntu-latest"
+      python-version: "3.11"
+
+  ##    Run the unit tests for Python 3.8 until 3.11
+  ##
+  Test:
+    needs: [Build]
+    uses: ./.github/workflows/_test_spot.yml
+    strategy:
+      matrix:
+        os: [ubuntu-latest]
+        python-version: ["3.8", "3.9", "3.10", "3.11"]
+    with:
+      os: ${{ matrix.os }}
+      python-version: ${{ matrix.python-version }}
+
+  ##    Upload the python-cmethods to Test PyPI
+  ##
+  UploadTestPyPI:
+    needs: [Test]
+    name: Upload the current release to Test PyPI
+    uses: ./.github/workflows/_pypi_publish.yml
+    with:
+      REPOSITORY_URL: https://test.pypi.org/legacy/
+    secrets:
+      API_TOKEN: ${{ secrets.TEST_PYPI_API_TOKEN }}
+
+  ##    Upload the python-cmethods to PyPI
+  ##
+  UploadPyPI:
+    needs: [Test]
+    name: Upload the current release to PyPI
+    uses: ./.github/workflows/_pypi_publish.yml
+    with:
+      REPOSITORY_URL: https://pypi.org/simple
+    secrets:
+      API_TOKEN: ${{ secrets.PYPI_API_TOKEN }}
diff --git a/README.md b/README.md
index 5fb8737..10dc130 100644
--- a/README.md
+++ b/README.md
@@ -7,10 +7,12 @@
 [![License: GPL v3](https://img.shields.io/badge/License-GPLv3-orange.svg)](https://www.gnu.org/licenses/gpl-3.0)
 [![Downloads](https://pepy.tech/badge/python-cmethods)](https://pepy.tech/project/python-cmethods)
 
-![ql-workflow](https://github.com/btschwertfeger/Bias-Adjustment-Python/actions/workflows/codeql.yml/badge.svg)
-![python-package](https://github.com/btschwertfeger/Bias-Adjustment-Python/actions/workflows/python-package.yml/badge.svg)
+![CodeQL](https://github.com/btschwertfeger/Bias-Adjustment-Python/actions/workflows/codeql.yml/badge.svg)
+[![CI/CD](https://github.com/btschwertfeger/python-cmethods/actions/workflows/cicd.yml/badge.svg?branch=master)](https://github.com/btschwertfeger/python-cmethods/actions/workflows/cicd.yml)
 [![codecov](https://codecov.io/github/btschwertfeger/python-cmethods/branch/master/graph/badge.svg?token=OSO4PAABPD)](https://codecov.io/github/btschwertfeger/python-cmethods)
 
+![release](https://shields.io/github/release-date/btschwertfeger/python-cmethods)
+![release](https://shields.io/github/v/release/btschwertfeger/python-cmethods?display_name=tag)
 [![DOI](https://zenodo.org/badge/496160109.svg)](https://zenodo.org/badge/latestdoi/496160109)
 
 </div>
@@ -46,7 +48,7 @@ These programs and data structures are designed to help minimize discrepancies b
   <figcaption>Figure 1: Schematic representation of a bias adjustment procedure</figcaption>
 </figure>
 
-In this way, for example, modeled data, which on average represent values that are too cold, can be adjusted by applying an adjustment procedure. The following figure shows the observed, the modeled, and the adjusted values. It is directly visible that the delta adjusted time series ($T^{*DM}_{sim,p}$) are much more similar to the observed data ($T_{obs,p}$) than the raw modeled data ($T_{sim,p}$).
+In this way, for example, modeled data, which on average represent values that are too cold, can be adjusted by applying an adjustment procedure. The following figure shows the observed, the modeled, and the adjusted values. It is directly visible that the delta adjusted time series ($T^{\*DM}_{sim,p}$) are much more similar to the observed data ($T_{obs,p}$) than the raw modeled data ($T_{sim,p}$).
 
 <figure>
   <img


Test patch:
diff --git a/.github/workflows/_test.yml b/.github/workflows/_test.yml
new file mode 100644
index 0000000..1cd0c3f
--- /dev/null
+++ b/.github/workflows/_test.yml
@@ -0,0 +1,41 @@
+# -*- coding: utf-8 -*-
+# Copyright (C) 2023 Benjamin Thomas Schwertfeger
+# Github: https://github.com/btschwertfeger
+#
+# Template workflow to run the unit tests of the package
+#
+
+name: Test Spot
+
+on:
+  workflow_call:
+    inputs:
+      os:
+        type: string
+        required: true
+      python-version:
+        type: string
+        required: true
+
+jobs:
+  Test-Spot:
+    name: Test ${{ inputs.os }} ${{ inputs.python-version }}
+    runs-on: ${{ inputs.os }}
+    steps:
+      - name: Checkout repository
+        uses: actions/checkout@v3
+
+      - name: Set up Python ${{ inputs.python-version }}
+        uses: actions/setup-python@v4
+        with:
+          python-version: ${{ inputs.python-version }}
+
+      - name: Install dependencies
+        run: |
+          python -m pip install --upgrade pip
+
+      - name: Install package
+        run: python -m pip install ".[dev]"
+
+      - name: Testing Spot REST endpoints
+        run: pytest tests/