Skip to content
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
75 changes: 75 additions & 0 deletions .github/workflows/_codecov.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
name: Gather coverage report and upload to codecov

on:
workflow_call:
inputs:
project:
description: 'Name of the project to test'
default: 'PROJECT_NAME'
required: false
type: string
c_extension:
description: 'Whether the project has a C extension'
default: false
required: false
type: boolean
headless:
description: 'Whether to run headless tests'
default: false
required: false
type: boolean

jobs:
coverage:
defaults:
run:
shell: bash -l {0}

runs-on: ubuntu-latest
steps:
- name: Check out ${{ inputs.project }}
uses: actions/checkout@v4

- name: Initialize miniconda
uses: conda-incubator/setup-miniconda@v3
with:
activate-environment: test
auto-update-conda: true
environment-file: environment.yml
auto-activate-base: false

- name: Conda config
run: >-
conda config --set always_yes yes
--set changeps1 no

- name: Install ${{ inputs.project }} and requirements
run: |
conda install --file requirements/run.txt
conda install --file requirements/test.txt
if ${{ inputs.c_extension }}; then
conda install --file requirements/build.txt
fi
python -m pip install -r requirements/pip.txt
python -m pip install . --no-deps

- name: Start Xvfb
if: ${{ inputs.headless }}
run: |
sudo apt-get install -y xvfb
export DISPLAY=:99
Xvfb :99 -screen 0 1024x768x16 &

- name: Validate ${{ inputs.project }}
run: |
if ${{ inputs.headless }}; then
xport DISPLAY=:99
fi
coverage run -m pytest -vv -s
coverage report -m
codecov

- name: Upload coverage to Codecov
uses: codecov/codecov-action@v4
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
58 changes: 58 additions & 0 deletions .github/workflows/_docs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
name: Build and Deploy Documentation

on:
workflow_call:
inputs:
project:
description: 'Name of the project to test'
default: 'PROJECT_NAME'
required: false
type: string
c_extension:
description: 'Whether the project has a C extension'
default: false
required: false
type: boolean

jobs:
docs:
defaults:
run:
shell: bash -l {0}

runs-on: ubuntu-latest
steps:
- name: Check out ${{ inputs.project }}
uses: actions/checkout@v4

- name: Initialize miniconda
uses: conda-incubator/setup-miniconda@v3
with:
activate-environment: build
auto-update-conda: true
environment-file: environment.yml
auto-activate-base: false

- name: Conda config
run: >-
conda config --set always_yes yes
--set changeps1 no

- name: IInstall ${{ inputs.project }} and docs requirements
run: |
conda install --file requirements/run.txt
conda install --file requirements/docs.txt
if ${{ inputs.c_extension }}; then
conda install --file requirements/build.txt
fi
python -m pip install -r requirements/pip.txt
python -m pip install . --no-deps

- name: build documents
run: make -C doc html

- name: Deploy
uses: peaceiris/actions-gh-pages@v4
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./doc/build/html
68 changes: 68 additions & 0 deletions .github/workflows/_main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
name: Test

on:
workflow_call:
inputs:
project:
description: 'Name of the project to test'
default: 'PROJECT_NAME'
required: false
type: string
c_extension:
description: 'Whether the project has a C extension'
default: false
required: false
type: boolean
headless:
description: 'Whether to run headless tests'
default: false
required: false
type: boolean

jobs:
validate:
defaults:
run:
shell: bash -l {0}

runs-on: ubuntu-latest
steps:
- name: Check out ${{ inputs.project }}
uses: actions/checkout@v4

- name: Initialize miniconda
uses: conda-incubator/setup-miniconda@v3
with:
activate-environment: test
auto-update-conda: true
environment-file: environment.yml
auto-activate-base: false

- name: Conda config
run: >-
conda config --set always_yes yes
--set changeps1 no

- name: Install ${{ inputs.project }} and requirements
run: |
conda install --file requirements/run.txt
conda install --file requirements/test.txt
if ${{ inputs.c_extension }}; then
conda install --file requirements/build.txt
fi
python -m pip install -r requirements/pip.txt
python -m pip install . --no-deps

- name: Start Xvfb
if: ${{ inputs.headless }}
run: |
sudo apt-get install -y xvfb
export DISPLAY=:99
Xvfb :99 -screen 0 1024x768x16 &

- name: Validate ${{ inputs.project }}
run: |
if ${{ inputs.headless }}; then
xport DISPLAY=:99
fi
python -m pytest
19 changes: 19 additions & 0 deletions .github/workflows/templates/codecov.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
name: Gather coverage report and upload to codecov

on:
push:
branches:
- main
release:
types:
- prereleased
- published
workflow_dispatch: null

jobs:
coverage:
uses: Billingegroup/release-scripts/.github/workflows/_codecov.yml@main
with:
project: PROJECT_NAME
c_extension: false
headless: false
14 changes: 14 additions & 0 deletions .github/workflows/templates/docs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
name: Build and Deploy Documentation

on:
release:
types:
- published
workflow_dispatch:

jobs:
docs:
uses: Billingegroup/release-scripts/.github/workflows/_docs.yml@main
with:
project: PROJECT_NAME
c_extension: false
16 changes: 16 additions & 0 deletions .github/workflows/templates/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
name: Test

on:
push:
branches:
- main
pull_request:
workflow_dispatch:

jobs:
validate:
uses: Billingegroup/release-scripts/.github/workflows/_main.yml@main
with:
project: PROJECT_NAME
c_extension: false
headless: false
78 changes: 78 additions & 0 deletions update_workflow.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
#!/usr/bin/env python

from pathlib import Path
import requests
import yaml

proj = input(f"Enter project name (default: {'PROJECT_NAME'}): ").strip() or 'PROJECT_NAME'

CENTRAL_REPO_ORG = "Billingegroup"
CENTRAL_REPO_NAME = "release-scripts"
CENTRAL_WORKFLOW_DIR = ".github/workflows/templates"
LOCAL_WORKFLOW_DIR = Path("../"+proj+"/.github/workflows")

user_input_cache = {'project': proj}

def get_central_workflows():
base_url = f"https://api.github.com/repos/{CENTRAL_REPO_ORG}/{CENTRAL_REPO_NAME}/contents/{CENTRAL_WORKFLOW_DIR}"
response = requests.get(base_url, timeout=5)
if response.status_code != 200:
raise Exception(f"Failed to fetch central workflows: {response.status_code}")

workflows = {}
for file in response.json():
if file['type'] == 'file' and file['name'].endswith('.yml'):
content_response = requests.get(file['download_url'], timeout=5)
if content_response.status_code == 200:
workflows[file['name']] = content_response.text
return workflows

def get_user_input(prompt, default, param_name):
if param_name in user_input_cache:
return user_input_cache[param_name]

user_value = input(f"{prompt} (default: {default}): ").strip()
if user_value:
value = user_value
else:
value = default

user_input_cache[param_name] = value
return value

def update_workflow_params(workflow):
if 'jobs' in workflow:
for _, job_content in workflow['jobs'].items():
if isinstance(job_content, dict) and 'with' in job_content:
for key, default_value in job_content['with'].items():
user_value = get_user_input(f"Enter value for '{key}'", default_value, key)
job_content['with'][key] = user_value
return workflow

def update_local_workflows(central_workflows):
local_workflows = set(f.name for f in LOCAL_WORKFLOW_DIR.glob("*.yml"))
central_workflow_names = set(central_workflows.keys())

for name, content in central_workflows.items():
local_file = LOCAL_WORKFLOW_DIR / name
central_yaml = yaml.safe_load(content)

central_yaml = update_workflow_params(central_yaml)
with open(local_file, 'w', encoding='utf-8') as file:
yaml.dump(central_yaml, file, sort_keys=False)

for name in local_workflows - central_workflow_names:
(LOCAL_WORKFLOW_DIR / name).unlink()
print(f"Removed workflow {name}")

def main():
try:
LOCAL_WORKFLOW_DIR.mkdir(parents=True, exist_ok=True)
central_workflows = get_central_workflows()
update_local_workflows(central_workflows)
print("Workflow synchronization completed successfully")
except Exception as e:
print(f"Error: {str(e)}")

if __name__ == "__main__":
main()