Skip to content

Commit a68e945

Browse files
committed
add release script
1 parent 8663997 commit a68e945

11 files changed

Lines changed: 250 additions & 0 deletions

File tree

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
name: Release Prepare
2+
3+
on:
4+
workflow_dispatch:
5+
inputs:
6+
tag:
7+
type: string
8+
required: true
9+
description: "Tag for the next release. Ex.: v1.0.0"
10+
11+
env:
12+
NEXT_RELEASE_TAG: ${{ github.event.inputs.tag }}
13+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
14+
15+
jobs:
16+
prepare-release-and-pull-request:
17+
permissions:
18+
contents: write
19+
pull-requests: write
20+
runs-on: ubuntu-latest
21+
22+
steps:
23+
- uses: actions/checkout@v4
24+
25+
- name: Prepare Python
26+
uses: actions/setup-python@v5
27+
with:
28+
cache: 'pip'
29+
30+
- name: Install dependencies
31+
run: pip install -r ./tools/release/requirements.txt
32+
33+
- name: Update source code versions
34+
run: ./tools/release/update_versions.py
35+
36+
- name: Setup Ninja
37+
run: sudo apt-get install ninja-build
38+
39+
- name: Build
40+
run: cmake -B build -G Ninja && cmake --build build
41+
42+
- name: Test
43+
run: ctest --output-on-failure --test-dir build
44+
45+
- name: Create PR with code updates for new release
46+
uses: peter-evans/create-pull-request@v7
47+
with:
48+
commit-message: "chore: release ${{ env.NEXT_RELEASE_TAG }}"
49+
branch: "release/${{ env.NEXT_RELEASE_TAG }}"
50+
title: "chore: release ${{ env.NEXT_RELEASE_TAG }}"
51+
body: |
52+
This pull PR updates the source code version to ${{ env.NEXT_RELEASE_TAG }}
53+
delete-branch: true
54+
sign-commits: true

.github/workflows/release.yml

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
name: Release Create
2+
3+
on:
4+
pull_request:
5+
types: [closed]
6+
7+
env:
8+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
9+
10+
jobs:
11+
check-release-conditions:
12+
runs-on: ubuntu-latest
13+
if: |
14+
github.event.pull_request.merged == true &&
15+
github.event.pull_request.base.ref == 'main' &&
16+
startsWith(github.event.pull_request.head.ref, 'release/v') &&
17+
startsWith(github.event.pull_request.user.login, 'github-actions')
18+
19+
steps:
20+
- name: Check release conditions
21+
run: |
22+
echo "All conditions have been met!"
23+
24+
create-release:
25+
permissions:
26+
contents: write
27+
needs: check-release-conditions
28+
runs-on: ubuntu-latest
29+
30+
env:
31+
NEXT_RELEASE_TAG: ${{ github.event.pull_request.head.ref }}
32+
steps:
33+
- name: Checkout
34+
uses: actions/checkout@v4
35+
36+
- name: Prepare Python
37+
uses: actions/setup-python@v5
38+
with:
39+
cache: 'pip'
40+
41+
- name: Install dependencies
42+
run: pip install -r ./tools/release/requirements.txt
43+
44+
- name: Extract Tag from branch name
45+
run: |
46+
NEXT_RELEASE_TAG=$(echo $NEXT_RELEASE_TAG | sed 's/^release\///')
47+
echo "NEXT_RELEASE_TAG=${NEXT_RELEASE_TAG}" >> $GITHUB_ENV
48+
49+
- name: Target release Tag
50+
run: echo "New tag $NEXT_RELEASE_TAG"
51+
52+
- name: Setup Ninja
53+
run: sudo apt-get install ninja-build
54+
55+
- name: Build singleheader
56+
run: |
57+
cmake -DLEXER_TESTING=OFF -G Ninja -B build
58+
cmake --build build --target lexer-singleheader-lib
59+
60+
- name: Create singleheader.zip
61+
run: |
62+
cd build/singleheader
63+
zip singleheader.zip lexer.h lexer.cpp
64+
mv singleheader.zip ../../singleheader/
65+
cp lexer.h lexer.cpp ../../singleheader/
66+
67+
- name: Create release
68+
run: ./tools/release/create_release.py

include/lexer/parser.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
#ifndef LEXER_PARSER_H
22
#define LEXER_PARSER_H
33

4+
#include "lexer/version.h"
5+
46
#include <optional>
57
#include <string>
68
#include <string_view>

include/lexer/version.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
/**
2+
* @file version.h
3+
* @brief Definitions for commonjs-lexer's version number.
4+
*/
5+
#ifndef LEXER_VERSION_H
6+
#define LEXER_VERSION_H
7+
8+
#define LEXER_VERSION "1.0.0"
9+
10+
namespace lexer {
11+
12+
enum {
13+
LEXER_VERSION_MAJOR = 1,
14+
LEXER_VERSION_MINOR = 0,
15+
LEXER_VERSION_REVISION = 0,
16+
};
17+
18+
} // namespace lexer
19+
20+
#endif // LEXER_VERSION_H

tools/release/__init__.py

Whitespace-only changes.

tools/release/create_release.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
#!/usr/bin/env python3
2+
3+
from os import environ, path
4+
from github import Github
5+
from lib.release import create_release
6+
7+
WORK_DIR = path.dirname(path.abspath(__file__)).replace("/tools/release", "")
8+
9+
NEXT_TAG = environ.get("NEXT_RELEASE_TAG", None)
10+
REPO_NAME = environ.get("GITHUB_REPOSITORY", None)
11+
TOKEN = environ.get("GITHUB_TOKEN", None)
12+
if not NEXT_TAG or not REPO_NAME or not TOKEN:
13+
raise Exception("Bad environment variables. Invalid GITHUB_REPOSITORY, GITHUB_TOKEN or NEXT_RELEASE_TAG")
14+
15+
g = Github(TOKEN)
16+
repository = g.get_repo(REPO_NAME)
17+
18+
release = create_release(repository, NEXT_TAG)
19+
release.upload_asset("singleheader/lexer.cpp")
20+
release.upload_asset("singleheader/lexer.h")
21+
release.upload_asset("singleheader/singleheader.zip")
22+
release.update_release(name=release.name, message=release.body, draft=False, make_latest="true")

tools/release/lib/__init__.py

Whitespace-only changes.

tools/release/lib/release.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#!/usr/bin/env python3
2+
3+
import re
4+
from github.Repository import Repository
5+
from github.GitRelease import GitRelease
6+
7+
8+
def is_valid_tag(tag: str) -> bool:
9+
tag_regex = r"^v\d+\.\d+\.\d+$"
10+
return bool(re.match(tag_regex, tag))
11+
12+
13+
def create_release(repository: Repository, tag: str) -> GitRelease:
14+
if not is_valid_tag(tag):
15+
raise Exception(f"Invalid tag: {tag}")
16+
17+
try:
18+
return repository.create_git_release(tag=tag, name=tag, draft=True, prerelease=False, generate_release_notes=True)
19+
except Exception as exp:
20+
raise Exception(f"create_release: Error creating release/tag {tag}: {exp!s}") from exp

tools/release/lib/versions.py

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
#!/usr/bin/env python3
2+
3+
import fileinput
4+
import re
5+
6+
7+
def update_cmakelists_version(new_version: str, file_path: str) -> None:
8+
inside_project = False
9+
with fileinput.FileInput(file_path, inplace=True) as cmakelists:
10+
for line in cmakelists:
11+
if "set(LEXER_LIB_VERSION" in line:
12+
line = re.sub(r"[0-9]+\.[0-9]+\.[0-9]+", new_version, line)
13+
elif "set(LEXER_LIB_SOVERSION" in line:
14+
line = re.sub(r"[0-9]+", new_version.split(".")[0], line)
15+
16+
elif "project(" in line:
17+
inside_project = True
18+
elif inside_project:
19+
if "VERSION" in line:
20+
line = re.sub(r"[0-9]+\.[0-9]+\.[0-9]+", new_version, line)
21+
inside_project = False
22+
print(line, end="")
23+
24+
25+
def update_lexer_version_h(new_version: str, file_path: str) -> None:
26+
new_version_list = new_version.split(".")
27+
with fileinput.FileInput(file_path, inplace=True) as version_h:
28+
inside_enum = False
29+
for line in version_h:
30+
if "#define LEXER_VERSION" in line:
31+
line = f'#define LEXER_VERSION "{new_version}"\n'
32+
33+
elif "enum {" in line:
34+
inside_enum = True
35+
elif inside_enum:
36+
if line.strip().startswith("LEXER_VERSION_MAJOR"):
37+
line = re.sub(r"\d+", new_version_list[0], line)
38+
elif line.strip().startswith("LEXER_VERSION_MINOR"):
39+
line = re.sub(r"\d+", new_version_list[1], line)
40+
elif line.strip().startswith("LEXER_VERSION_REVISION"):
41+
line = re.sub(r"\d+", new_version_list[2], line)
42+
43+
print(line, end="")

tools/release/requirements.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
PyGithub==2.8.1
2+
pytest==9.0.2

0 commit comments

Comments
 (0)