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

chore: add semantic release configs #79

Merged
merged 1 commit into from
Dec 12, 2023
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
180 changes: 180 additions & 0 deletions .github/workflows/pr-review.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
name: Review Pull Request

on:
pull_request_target:
types: [ opened, synchronize, edited, labeled, unlabeled ]
branches:
- main
- develop

permissions:
pull-requests: write
contents: read

# Use concurrency to ensure that only one instance of this workflow is running at a time
concurrency:
group: pr-lint-checker-${{ github.sha }}
cancel-in-progress: true

jobs:
load-config:
uses: AibelDevs/action-toolbox/.github/workflows/tool-load-config.yaml@main

pr-review:
uses: AibelDevs/action-toolbox/.github/workflows/tool-review-pr.yaml@main
needs: load-config
secrets:
SOURCE_KEY: ${{ secrets.SOURCE_KEY }}

python-review:
uses: AibelDevs/action-toolbox/.github/workflows/tool-review-python.yaml@main
with:
use_pylint: false
needs: load-config
if : ${{ needs.load-config.outputs.python_enabled == 'true' }}
secrets:
CONDA_API_TOKEN: ${{ secrets.CONDA_API_TOKEN }}
PYPI_API_TOKEN: ${{ secrets.PYPI_API_TOKEN }}
CUSTOM_PYPI_USERNAME: ${{ secrets.CUSTOM_PYPI_USERNAME }}
CUSTOM_PYPI_PASSWORD: ${{ secrets.CUSTOM_PYPI_PASSWORD }}
CUSTOM_PYPI_URL: ${{ secrets.CUSTOM_PYPI_URL }}
QUETZ_API_KEY: ${{ secrets.QUETZ_API_KEY }}
QUETZ_URL: ${{ secrets.QUETZ_URL }}

docker-review:
uses: AibelDevs/action-toolbox/.github/workflows/tool-review-docker.yaml@main
needs: load-config
if : ${{ needs.load-config.outputs.docker_enabled == 'true' }}
secrets:
CONTAINER_REGISTRY_URL: ${{ secrets.CONTAINER_REGISTRY_URL }}
CONTAINER_REGISTRY_USERNAME: ${{ secrets.CONTAINER_REGISTRY_USERNAME }}
CONTAINER_REGISTRY_PASSWORD: ${{ secrets.CONTAINER_REGISTRY_PASSWORD }}

gitops-review:
uses: AibelDevs/action-toolbox/.github/workflows/tool-review-gitops.yaml@main
needs: load-config
if : ${{ needs.load-config.outputs.gitops_enabled == 'true' }}
secrets:
CONTAINER_REGISTRY_URL: ${{ secrets.CONTAINER_REGISTRY_URL }}
SOURCE_KEY: ${{ secrets.SOURCE_KEY }}
GITOPS_KEY: ${{ secrets.GITOPS_KEY }}

pr-review-summary:
name: Python Check Pull Request
needs: [ load-config, pr-review, python-review, docker-review, gitops-review ]
if: always()
runs-on: ubuntu-latest
steps:
- name: Set up Python
uses: actions/setup-python@v3
with:
python-version: 3.11

- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install toml==0.10.2

- name: Checkout PR
uses: actions/checkout@v3
with:
fetch-depth: 0
ref: ${{ github.event.pull_request.head.sha }}

- name: Review all results and write a summary
id: comment_body
shell: python
run: |
import os
import base64

def set_output(name, value, encode_it=False):
if encode_it:
value = base64.b64encode(value.encode('utf-8')).decode('utf-8')
with open(os.environ['GITHUB_OUTPUT'], 'a') as fh:
print(f'{name}={value}', file=fh)

def deserialize_str(s):
return base64.b64decode(s).decode('utf-8')

all_checks = []
review_str = ''

# PR
review_str += deserialize_str('${{ needs.pr-review.outputs.pr_review_str }}')
all_checks.append('${{ needs.pr-review.outputs.pr_review_ok }}' == 'true')

# Python
if ${{ needs.load-config.outputs.python_enabled }}:
review_str += deserialize_str('${{ needs.python-review.outputs.python_review_str }}')
all_checks.append('${{ needs.python-review.outputs.python_review_ok }}' == 'true')

# Docker
if ${{ needs.load-config.outputs.docker_enabled }}:
review_str += deserialize_str('${{ needs.docker-review.outputs.docker_review_str }}')
all_checks.append('${{ needs.docker-review.outputs.docker_review_ok }}' == 'true')

# GitOps
if ${{ needs.load-config.outputs.gitops_enabled }}:
review_str += deserialize_str('${{ needs.gitops-review.outputs.gitops_review_str }}')
all_checks.append('${{ needs.gitops-review.outputs.gitops_review_ok }}' == 'true')

# check if all_checks are true
if all(all_checks):
header = "👋 Hi there! I have checked your PR and found no issues. Thanks for your contribution!\n"
set_output('REVIEW_OK', 'true')
else:
header = "👋 Hi there! I have checked your PR and found the following:\n\n"
set_output('REVIEW_OK', 'false')

body = header + review_str

# Set the output
set_output('body', body, True)

print(body)

- name: Delete previous bot comment
uses: actions/github-script@v7
with:
script: |
const issue_number = context.issue.number
const owner = context.repo.owner
const repo = context.repo.repo

// List all comments on the PR
const comments = await github.rest.issues.listComments({
issue_number,
owner,
repo
});

// Find the last comment made by the bot
const botComment = comments.data.reverse().find(comment => comment.user.login === 'github-actions[bot]');

// If a previous comment by the bot exists, delete it
if (botComment) {
await github.rest.issues.deleteComment({
owner,
repo,
comment_id: botComment.id
});
}

- name: Comment on PR
uses: actions/github-script@v7
with:
script: |
const bodyBase64 = '${{ steps.comment_body.outputs.body }}'
const body = Buffer.from(bodyBase64, 'base64').toString('utf-8')

github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: body
})

- name: Fail if linting failed
if: steps.comment_body.outputs.REVIEW_OK == 'false'
run: exit 1
127 changes: 127 additions & 0 deletions .github/workflows/pre-release-dispatch.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
name: Issue pre-release

on:
workflow_dispatch:
inputs:
release_pypi:
description: 'Issue Pre-Release to PyPI'
required: false
type: boolean
default: false
release_conda:
description: 'Issue Pre-Release to conda'
required: false
type: boolean
default: false
release_docker:
description: 'Issue Pre-Release to docker'
required: false
type: boolean
default: true
release_gitops:
description: 'Issue Pre-Release to gitops'
required: false
type: boolean
default: true


permissions:
id-token: write
contents: write
pull-requests: read

concurrency:
group: release-${{ github.sha }}
cancel-in-progress: true

jobs:
load-config:
uses: AibelDevs/action-toolbox/.github/workflows/tool-load-config.yaml@main

# Add a step to create a patch version "next.run_id"
bump_version:
runs-on: ubuntu-latest
outputs:
current_version: ${{ steps.get_current_version.outputs.current_version }}
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0 # Fetches all history for all branches and tags

- name: Create "next" version
id: get_current_version
shell: python
run: |
import os

def set_output(name, value):
with open(os.environ['GITHUB_OUTPUT'], 'a') as fh:
print(f'{name}={value}', file=fh)

# get the latest tagged release
tag_release = os.popen('git describe --tags --abbrev=0').read().strip()
print(f"{tag_release=}")

# strip v from the tag
if tag_release.startswith('v'):
tag_release = tag_release[1:]

# add a pre-release "version-next.build_id" to the latest tagged release
build_id = os.getenv('GITHUB_RUN_NUMBER')
print(f"{build_id=}")

# concatenate the version and build_id
current_version = f"{tag_release}-next.{build_id}"

print(current_version)
set_output('current_version', current_version)

release_pypi:
if: ${{ github.event.inputs.release_pypi == 'true' }}
needs: [ load-config, bump_version ]
uses: AibelDevs/action-toolbox/.github/workflows/tool-release-pip.yaml@main
with:
use_custom_pypi: ${{ needs.load-config.outputs.custom_pypi_server }}
version_override: ${{ needs.bump_version.outputs.current_version }}
secrets:
PYPI_API_TOKEN: ${{ secrets.PYPI_API_TOKEN }}
CUSTOM_PYPI_USERNAME: ${{ secrets.CUSTOM_PYPI_USERNAME }}
CUSTOM_PYPI_PASSWORD: ${{ secrets.CUSTOM_PYPI_PASSWORD }}
CUSTOM_PYPI_URL: ${{ secrets.CUSTOM_PYPI_URL }}

release_conda:
if: ${{ github.event.inputs.release_conda == 'true' }}
needs: [ load-config, bump_version ]
uses: AibelDevs/action-toolbox/.github/workflows/tool-release-conda.yaml@main
with:
use_quetz_server: ${{ needs.load-config.outputs.custom_quetz_server }}
push_conda: "true"
version_override: ${{ needs.bump_version.outputs.current_version }}
secrets:
CONDA_API_TOKEN: ${{ secrets.CONDA_API_TOKEN }}
QUETZ_API_KEY: ${{ secrets.QUETZ_API_KEY }}
QUETZ_URL: ${{ secrets.QUETZ_URL }}

release_docker:
if: ${{ github.event.inputs.release_docker == 'true' }}
needs: bump_version
uses: AibelDevs/action-toolbox/.github/workflows/tool-release-docker.yaml@main
with:
docker_tag_override: ${{ needs.bump_version.outputs.current_version }}
push_docker: "true"
secrets:
CONTAINER_REGISTRY_URL: ${{ secrets.CONTAINER_REGISTRY_URL }}
CONTAINER_REGISTRY_USERNAME: ${{ secrets.CONTAINER_REGISTRY_USERNAME }}
CONTAINER_REGISTRY_PASSWORD: ${{ secrets.CONTAINER_REGISTRY_PASSWORD }}

release_gitops:
if: ${{ github.event.inputs.release_gitops == 'true' }}
needs: [bump_version, release_docker]
uses: AibelDevs/action-toolbox/.github/workflows/tool-release-gitops-update.yaml@main
with:
push_commit: "true"
release_tag_override: ${{ needs.bump_version.outputs.current_version }}
secrets:
CONTAINER_REGISTRY_URL: ${{ secrets.CONTAINER_REGISTRY_URL }}
GITOPS_KEY: ${{ secrets.GITOPS_KEY }}
86 changes: 86 additions & 0 deletions .github/workflows/release-on-new-tag.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
name: Make Release on push of new tag

# triggered on a tagged release
on:
push:
tags:
- 'v*.*.*'

permissions:
id-token: write
contents: write

jobs:
interpret_tag:
runs-on: ubuntu-latest
outputs:
version: ${{ steps.interpret_tag.outputs.tagged_release }}
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Read and output tag (remove 'v' prefix)
id: interpret_tag
shell: python
run: |
import os

def set_output(name, value):
with open(os.environ['GITHUB_OUTPUT'], 'a') as fh:
print(f'{name}={value}', file=fh)

tag = os.getenv('GITHUB_REF').split('/')[-1]
if tag.startswith('v'):
tag = tag[1:]

print(f"{tag=}")
set_output('tagged_release', tag)

load-config:
uses: AibelDevs/action-toolbox/.github/workflows/tool-load-config.yaml@main

release_pypi:
needs: [ load-config, interpret_tag ]
if: ${{ needs.load-config.outputs.pip_enabled == 'true' }}
uses: AibelDevs/action-toolbox/.github/workflows/tool-release-pip.yaml@main
with:
use_custom_pypi: ${{ needs.load-config.outputs.custom_pypi_server }}
secrets:
PYPI_API_TOKEN: ${{ secrets.PYPI_API_TOKEN }}
CUSTOM_PYPI_USERNAME: ${{ secrets.CUSTOM_PYPI_USERNAME }}
CUSTOM_PYPI_PASSWORD: ${{ secrets.CUSTOM_PYPI_PASSWORD }}
CUSTOM_PYPI_URL: ${{ secrets.CUSTOM_PYPI_URL }}

release_conda:
needs: [ load-config, interpret_tag ]
if: ${{ needs.load-config.outputs.conda_enabled == 'true' }}
uses: AibelDevs/action-toolbox/.github/workflows/tool-release-conda.yaml@main
with:
use_quetz_server: ${{ needs.load-config.outputs.custom_quetz_server }}
push_conda: 'true'
secrets:
CONDA_API_TOKEN: ${{ secrets.CONDA_API_TOKEN }}
QUETZ_API_KEY: ${{ secrets.QUETZ_API_KEY }}
QUETZ_URL: ${{ secrets.QUETZ_URL }}

release_docker:
needs: [ load-config, interpret_tag ]
if: ${{ needs.load-config.outputs.docker_enabled == 'true' }}
uses: AibelDevs/action-toolbox/.github/workflows/tool-release-docker.yaml@main
with:
push_docker: 'true'
docker_tag_override: ${{ needs.interpret_tag.outputs.version }}
secrets:
CONTAINER_REGISTRY_URL: ${{ secrets.CONTAINER_REGISTRY_URL }}
CONTAINER_REGISTRY_USERNAME: ${{ secrets.CONTAINER_REGISTRY_USERNAME }}
CONTAINER_REGISTRY_PASSWORD: ${{ secrets.CONTAINER_REGISTRY_PASSWORD }}

release_gitops:
needs: [ load-config, interpret_tag, release_docker ]
if: ${{ needs.load-config.outputs.gitops_enabled == 'true' }}
uses: AibelDevs/action-toolbox/.github/workflows/tool-release-gitops-update.yaml@main
with:
push_commit: 'true'
release_tag_override: ${{ needs.interpret_tag.outputs.version }}
secrets:
CONTAINER_REGISTRY_URL: ${{ secrets.CONTAINER_REGISTRY_URL }}
GITOPS_KEY: ${{ secrets.GITOPS_KEY }}
Loading
Loading