Skip to content

Commit

Permalink
ci: add automated release pipeline
Browse files Browse the repository at this point in the history
Problem: we need to release in synx with flux-sched upstream
Solution: have a release workflow that tests the current master,
and tests and updates the version file and releases, coinciding
with flux-sched. This will likely need further testing and tweaking
as we decide on further customization, but should be a good start.

Signed-off-by: vsoch <[email protected]>
  • Loading branch information
vsoch committed Feb 17, 2024
1 parent aae4119 commit ab5aa9c
Show file tree
Hide file tree
Showing 3 changed files with 234 additions and 0 deletions.
146 changes: 146 additions & 0 deletions .github/scripts/check-upstream-release.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
#!/usr/bin/env python3

# Check for upstream releases of flux-sched, and compare
# to current version here. If a new version is found, we

import argparse
import requests
import sys
import os

# python .github/scripts/check-upstream-release.py flux-framework/flux-sched

token = os.environ.get("GITHUB_TOKEN")
headers = {}
if token:
headers["Authorization"] = "token %s" % token


def write_file(data, filename):
"""
Write content to file
"""
with open(filename, "w") as fd:
fd.writelines(data)


def read_file(filename):
"""
Read content from file
"""
with open(filename, "r") as fd:
content = fd.read()
return content


def set_env_and_output(name, value):
"""
helper function to echo a key/value pair to output and env.
Parameters:
name (str) : the name of the environment variable
value (str) : the value to write to file
"""
for env_var in ("GITHUB_ENV", "GITHUB_OUTPUT"):
environment_file_path = os.environ.get(env_var)
print("Writing %s=%s to %s" % (name, value, env_var))

with open(environment_file_path, "a") as environment_file:
environment_file.write("%s=%s\n" % (name, value))


class UpstreamUpdater:
def __init__(self, version_file, repo, dry_run=False):
self.version_file = os.path.abspath(version_file)
self.repo = repo
self.dry_run = dry_run
self._latest_version = None
self._current_version = self.get_current_version()

@property
def current_version(self):
return self._current_version

def get_current_version(self):
"""
Derive current version from file (or VERSION)
"""
if not os.path.exists(self.version_file):
sys.exit(f"{self.version_file} does not exist.")
self._current_version = read_file(self.version_file).strip("\n")

def check(self):
"""
Given a repository name, check for new releases.
"""
latest = self.get_latest_release()
version = self.current_version
tag = latest["tag_name"]

# Some versions are prefixed with v
if tag == version or tag == f"v{version}":
print("No new version found.")
return
print(f"New version {tag} detected!")
naked_version = tag.replace("v", "")
self.update_version_file(naked_version)
set_env_and_output("version", tag)

def get_latest_release(self):
"""
Get the lateset release of a repository (under flux-framework)
"""
url = f"https://api.github.com/repos/{self.repo}/releases"
response = requests.get(url, headers=headers, params={"per_page": 100})
response.raise_for_status()

# latest release should be first
return response.json()[0]

def update_version_file(self, version):
"""
Update the package file with a new version and digest.
"""
write_file(version, self.version_file)


def get_parser():
parser = argparse.ArgumentParser(
description="Upstream Release Updater",
formatter_class=argparse.RawTextHelpFormatter,
)
parser.add_argument(
"--version-file",
help="version file to parse",
default="VERSION",
dest="version_file",
)
parser.add_argument(
"--repo", help="GitHub repository name", default="flux-framework/flux-sched"
)
parser.add_argument(
"--dry-run",
action="store_true",
default=False,
help="Don't write changes to file",
)
return parser


def main():
parser = get_parser()

# If an error occurs while parsing the arguments, the interpreter will exit with value 2
args, extra = parser.parse_known_args()

# Show args to the user
print("version file: %s" % args.version_file)
print(" repo: %s" % args.repo)
print(" dry-run: %s" % args.dry_run)

updater = UpstreamUpdater(args.version_file, args.repo, args.dry_run)
updater.check()


if __name__ == "__main__":
main()
88 changes: 88 additions & 0 deletions .github/workflows/release.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
name: release fluxion-go
on:
# Ensure we can trigger on demand
workflow_dispatch:
pull_request: []

# schedule runs on default branch
schedule:
- cron: '0 4 * * *'

jobs:

# We always test before release
test:
name: Test fluxion-go
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
test: [["fluxrm/flux-sched:jammy", "/usr/lib"],
["fluxrm/flux-sched:fedora38", "/usr/lib64"],
["fluxrm/flux-sched:bookworm-amd64", "/usr/lib"],
["fluxrm/flux-sched:el8", "/usr/lib64"]]

container:
image: ${{ matrix.test[0] }}
options: --user root
steps:
- uses: actions/checkout@v4
- name: Setup Go
uses: actions/setup-go@v3
with:
go-version: ^1.19

- name: flux-sched build
run: git clone https://github.com/flux-framework/flux-sched /opt/flux-sched
- name: Build
run: LIB_PREFIX=${{ matrix.test[1] }} make build
- name: Test
run: LIB_PREFIX=${{ matrix.test[1] }} make test

release:
runs-on: ubuntu-latest
needs: [test]
permissions:
contents: write
steps:
- uses: actions/checkout@v4
- name: Check for New Releases
id: check
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
python -m pip install requests
python .github/scripts/check-upstream-release.py --repo flux-framework/flux-sched
- name: Commit latest release version
if: (steps.check.outputs.version != '' && github.event_name != 'pull_request')
env:
version: ${{ steps.check.outputs.version }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
echo "Found new version ${version}"
export BRANCH_FROM="release/${package}-${version}"
git remote set-url origin "https://x-access-token:${GITHUB_TOKEN}@github.com/${GITHUB_REPOSITORY}.git"
git branch
git config --global user.name "github-actions"
git config --global user.email "[email protected]"
git config --global pull.rebase true
git add VERSION
if git diff-index --quiet HEAD --; then
printf "No changes\n"
else
printf "Changes\n"
today=$(date '+%Y-%m-%d')
git commit -a -m "Update for release ${today}" -m "Signed-off-by: github-actions <[email protected]>"
git push origin main
fi
- name: Release
if: (steps.check.outputs.version != '' && github.event_name != 'pull_request')
uses: softprops/action-gh-release@v1
with:
name: goshare ${{ steps.check.outputs.version }}
tag_name: ${{ steps.check.outputs.version }}
body: "fluxion-go ${{ steps.check.outputs.version }}"
env:
GITHUB_REPOSITORY: flux-framework/fluxion-go
Empty file added VERSION
Empty file.

0 comments on commit ab5aa9c

Please sign in to comment.