Skip to content

Commit

Permalink
Add task to generate release body (#233)
Browse files Browse the repository at this point in the history
* bumping code version for release

* ci: add step to generate changelog

* ci: generate release body with changelog

* ci: add task to generate release body without dependencies

* docs: update docs with latest releasing info

* cli: support running both as a submodule and as a standalone project

* ci: change format of release template so that it only includes the pr title

* ci: automate release creation/publishing from tasks
  • Loading branch information
csegarragonz committed Feb 23, 2022
1 parent 88ef806 commit b11e8ab
Show file tree
Hide file tree
Showing 10 changed files with 228 additions and 16 deletions.
4 changes: 2 additions & 2 deletions .env
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FAABRIC_VERSION=0.3.0
FAABRIC_CLI_IMAGE=faasm/faabric:0.3.0
FAABRIC_VERSION=0.3.1
FAABRIC_CLI_IMAGE=faasm/faabric:0.3.1
COMPOSE_PROJECT_NAME=faabric-dev
CONAN_CACHE_MOUNT_SOURCE=./conan-cache/
10 changes: 5 additions & 5 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:
if: github.event.pull_request.draft == false
runs-on: ubuntu-latest
container:
image: faasm/faabric:0.3.0
image: faasm/faabric:0.3.1
defaults:
run:
working-directory: /code/faabric
Expand All @@ -31,7 +31,7 @@ jobs:
if: github.event.pull_request.draft == false
runs-on: ubuntu-latest
container:
image: faasm/faabric:0.3.0
image: faasm/faabric:0.3.1
defaults:
run:
working-directory: /code/faabric
Expand All @@ -47,7 +47,7 @@ jobs:
if: github.event.pull_request.draft == false
runs-on: ubuntu-latest
container:
image: faasm/faabric:0.3.0
image: faasm/faabric:0.3.1
defaults:
run:
working-directory: /code/faabric
Expand Down Expand Up @@ -81,7 +81,7 @@ jobs:
TSAN_OPTIONS: "verbosity=1:halt_on_error=1:suppressions=/code/faabric/thread-sanitizer-ignorelist.txt:history_size=7"
UBSAN_OPTIONS: "print_stacktrace=1:halt_on_error=1"
container:
image: faasm/faabric:0.3.0
image: faasm/faabric:0.3.1
defaults:
run:
working-directory: /code/faabric
Expand Down Expand Up @@ -130,7 +130,7 @@ jobs:
REDIS_QUEUE_HOST: redis
REDIS_STATE_HOST: redis
container:
image: faasm/faabric:0.3.0
image: faasm/faabric:0.3.1
defaults:
run:
working-directory: /code/faabric
Expand Down
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ conan-cache/
.clangd
compile_commands.json

# Faabric config file
faabric.ini

# Ansible
*.retry

Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.3.0
0.3.1
57 changes: 57 additions & 0 deletions cliff.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# configuration file for git-cliff (0.1.0)

[changelog]
# changelog header
header = """
Here is what has changed since last release:
"""
# template for the changelog body
# https://tera.netlify.app/docs/#introduction
body = """
{% if version %}\
## [{{ version | trim_start_matches(pat="v") }}] - {{ timestamp | date(format="%Y-%m-%d") }}
{% else %}\
## [unreleased]
{% endif %}\
{% for commit in commits %} * {{ commit.message | upper_first | split(pat="\n") | first }}
{% endfor %}
"""
# remove the leading and trailing whitespace from the template
trim = true
# changelog footer
footer = """
<!-- generated by git-cliff -->
"""

[git]
# parse the commits based on https://www.conventionalcommits.org
conventional_commits = false
# filter out the commits that are not conventional
filter_unconventional = false
# regex for parsing and grouping commits
commit_parsers = [
{ message = "^feat", group = "Features"},
{ message = "^fix", group = "Bug Fixes"},
{ message = "^doc", group = "Documentation"},
{ message = "^perf", group = "Performance"},
{ message = "^refactor", group = "Refactor"},
{ message = "^style", group = "Styling"},
{ message = "^test", group = "Testing"},
{ message = "^chore\\(release\\): prepare for", skip = true},
{ message = "^chore", group = "Miscellaneous Tasks"},
{ body = ".*security", group = "Security"},
]
# filter out the commits that are not matched by commit parsers
filter_commits = false
# glob pattern for matching git tags
tag_pattern = "v[0-9]*"
# regex for skipping tags
skip_tags = "v0.1.0-beta.1"
# regex for ignoring tags
ignore_tags = ""
# sort the tags chronologically
date_order = true
# sort the commits inside sections by oldest/newest order
sort_commits = "newest"
45 changes: 42 additions & 3 deletions docs/source/development.md
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ docker-compose stop
./dist-test/run.sh
```

## Releasing
## Creating a new tag

Create a new branch, then find and replace the current version with the relevant
bumped version. It should appear in:
Expand All @@ -154,10 +154,17 @@ If you want to overwrite a tag, you can run:
inv git.tag --force
```

After the new tag has been merged in, and in order to keep a clean commit
history, you may re-tag the code again:

```bash
inv git.tag --force
```

### Building images manually

Containers are built with Github Actions, so you should only need to build them
yourself when diagnosing issues.
Containers are built with Github Actions, when a new tag is pushed, so you
should only need to build them yourself when diagnosing issues.

To build the main container, run:

Expand All @@ -174,3 +181,35 @@ inv container.push
inv container.build --push
```

## Publishing a release

To publish a release in Github, make sure you are in the main branch, and have
just tagged the code (see previous section).

Then, you can create a release on [Github](https://github.com/faasm/faabric/releases)
and publish it from the command line. If it is the first time you are creating
a release you will have to configure a Github access token (see below).

First, generate a draft release:

```bash
inv git.release_create
```

Then, after verifying that the release looks fine, you may publish it:

```bash
inv git.release_publish
```

### Configuring a Github access token

Follow the instructions on [how to create a personal access token](
https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token).
Then, create a config file for faabric in the main directory named
`faabric.ini` with the following contents:

```toml
[Github]
access_token = <paste your personal access token>
```
2 changes: 1 addition & 1 deletion mpi-native/mpi-native.env
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FAABRIC_VERSION=0.3.0
FAABRIC_VERSION=0.3.1
FAABRIC_MPI_NATIVE_IMAGE=faasm/faabric-mpi-native:0.0.18
COMPOSE_PROJECT_NAME=faabric-mpi

Expand Down
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,6 @@ flake8==4.0.1
invoke==1.6.0
myst-parser==0.16.1
numpy==1.21.5
PyGithub==1.55
redis==4.1.0
sphinx-rtd-theme==1.0.0
102 changes: 99 additions & 3 deletions tasks/git.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,19 @@
from github import Github
from invoke import task
from tasks.util.env import get_faabric_config, get_version, PROJ_ROOT
from subprocess import run, PIPE, STDOUT

from tasks.util.env import get_version, PROJ_ROOT

from subprocess import run
def get_tag_name(version):
return "v{}".format(version)


@task
def tag(ctx, force=False):
"""
Creates git tag from the current tree
"""
git_tag = "v{}".format(get_version())
git_tag = get_tag_name(get_version())
run(
"git tag {} {}".format("--force" if force else "", git_tag),
shell=True,
Expand All @@ -24,3 +27,96 @@ def tag(ctx, force=False):
check=True,
cwd=PROJ_ROOT,
)


def is_git_submodule():
git_cmd = "git rev-parse --show-superproject-working-tree"
result = run(git_cmd, shell=True, stdout=PIPE, stderr=STDOUT)
return result.stdout.decode("utf-8") != ""


def get_github_instance():
conf = get_faabric_config()

if not conf.has_section("Github") or not conf.has_option(
"Github", "access_token"
):
print("Must set up Github config with access token")

token = conf["Github"]["access_token"]
g = Github(token)
return g


def get_repo():
g = get_github_instance()
return g.get_repo("faasm/faabric")


def get_release():
r = get_repo()
rels = r.get_releases()

return rels[0]


def get_release_body():
"""
Generate body for release with detailed changelog
"""
if is_git_submodule():
docker_cmd = [
"docker run -t -v",
"{}/..:/app/".format(PROJ_ROOT),
"orhunp/git-cliff:latest",
"--config ./faabric/cliff.toml",
"--repository ./faabric",
"{}..v{}".format(get_release().tag_name, get_version()),
]
else:
docker_cmd = [
"docker run -t -v",
"{}:/app/".format(PROJ_ROOT),
"orhunp/git-cliff:latest",
"--config cliff.toml",
"--repository .",
"{}..v{}".format(get_release().tag_name, get_version()),
]

cmd = " ".join(docker_cmd)
print("Generating release body...")
print(cmd)
result = run(cmd, shell=True, stdout=PIPE, stderr=PIPE)

return result.stdout.decode("utf-8")


@task
def release_create(ctx):
"""
Create a draft release on Github
"""
# Work out the tag
faabric_ver = get_version()
tag_name = get_tag_name(faabric_ver)

# Create a release in github from this tag
r = get_repo()
r.create_git_release(
tag_name,
"Faabric {}".format(faabric_ver),
get_release_body(),
draft=True,
)

print("You may now review the draft release in:")
print("https://github.com/faasm/faabric/releases")


@task
def release_publish(ctx):
"""
Publish the draft release
"""
rel = get_release()
rel.update_release(rel.title, rel.raw_data["body"], draft=False)
18 changes: 17 additions & 1 deletion tasks/util/env.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from os import environ
from os.path import dirname, realpath, join, expanduser
from os.path import dirname, exists, realpath, join, expanduser
import configparser

HOME_DIR = expanduser("~")
PROJ_ROOT = dirname(dirname(dirname(realpath(__file__))))
Expand All @@ -11,6 +12,8 @@

FAABRIC_INSTALL_PREFIX = join(_FAABRIC_BUILD_DIR, "install")

FAABRIC_CONFIG_FILE = join(PROJ_ROOT, "faabric.ini")


def get_version():
ver_file = join(PROJ_ROOT, "VERSION")
Expand All @@ -20,3 +23,16 @@ def get_version():

version = version.strip()
return version


def get_faabric_config():
config = configparser.ConfigParser()
if not exists(FAABRIC_CONFIG_FILE):
print("Creating config file at {}".format(FAABRIC_CONFIG_FILE))

with open(FAABRIC_CONFIG_FILE, "w") as fh:
config.write(fh)
else:
config.read(FAABRIC_CONFIG_FILE)

return config

0 comments on commit b11e8ab

Please sign in to comment.