-
Notifications
You must be signed in to change notification settings - Fork 80
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This workflow is scheduled weekly and fetches the latest GHC release for each of the current stable versions. It adds the version to the gen_ghc_bindist.py file and runs this script to update the ghc_bindist_generated.bzl file.
- Loading branch information
Showing
2 changed files
with
137 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
#!/usr/bin/env python | ||
|
||
import os, sys, re | ||
import importlib | ||
import importlib.util | ||
import importlib.machinery | ||
import http.client | ||
import json | ||
from pathlib import PurePosixPath, Path | ||
from pprint import pprint | ||
from urllib.parse import quote | ||
from subprocess import Popen, PIPE, STDOUT, DEVNULL, check_output, run | ||
|
||
def import_path(path): | ||
module_name = os.path.basename(path).replace('-', '_') | ||
spec = importlib.util.spec_from_loader( | ||
module_name, | ||
importlib.machinery.SourceFileLoader(module_name, path) | ||
) | ||
module = importlib.util.module_from_spec(spec) | ||
spec.loader.exec_module(module) | ||
sys.modules[module_name] = module | ||
return module | ||
|
||
|
||
GHC_GITLAB_SERVER="gitlab.haskell.org" | ||
|
||
def get_gitlab_tags_with_prefix(project_id, prefix): | ||
connection = http.client.HTTPSConnection(GHC_GITLAB_SERVER) | ||
encoded_project_id = encoded_project_id = quote(project_id, safe='') | ||
endpoint = f"/api/v4/projects/{encoded_project_id}/repository/tags?search=^{prefix}&order-by=version" | ||
|
||
connection.request("GET", endpoint) | ||
response = connection.getresponse() | ||
|
||
if response.status == 200: | ||
tags_data = response.read().decode("utf-8") | ||
tags = json.loads(tags_data) | ||
return tags | ||
else: | ||
print(f"Error: {response.status} - {response.reason}") | ||
return None | ||
|
||
project_id = "ghc/ghc" | ||
|
||
# matches GHC release versions | ||
version_re = re.compile("ghc-(?P<version>.*)-release") | ||
|
||
def parse_version(s): | ||
return tuple(map(int, s.split("."))) | ||
|
||
def main(): | ||
SCRIPT_PATH = Path(__file__) | ||
|
||
if len(sys.argv) != 2: | ||
sys.exit(f"usage: {SCRIPT_PATH.name} GHC_MAJOR_MINOR") | ||
|
||
bindist = import_path(str(SCRIPT_PATH.parent.parent.joinpath('haskell/private/ghc_bindist_generated.bzl'))) | ||
|
||
GHC_MAJOR_MINOR = sys.argv[1] | ||
|
||
versions = [ version for version in bindist.GHC_BINDIST if version.startswith(GHC_MAJOR_MINOR) ] | ||
|
||
prefix = f"ghc-{GHC_MAJOR_MINOR}." | ||
|
||
tags = get_gitlab_tags_with_prefix(project_id, prefix) | ||
|
||
if tags: | ||
releases = [ m.group("version") for tag in tags if (m := version_re.match(tag["name"])) ] | ||
|
||
latest_release = releases[0] | ||
|
||
if latest_release in versions: | ||
print(f"GHC {GHC_MAJOR_MINOR} is up-to-date", file=sys.stderr) | ||
else: | ||
print("found update:", latest_release, file=sys.stderr) | ||
|
||
replace = re.compile(r'^(?P<indent>\s+)\{\s*"version"\s*:\s*"' + re.escape(GHC_MAJOR_MINOR + '.'), re.MULTILINE) | ||
|
||
gen_script_path = SCRIPT_PATH.parent.parent.joinpath('haskell/gen_ghc_bindist.py') | ||
with open(gen_script_path, 'r+') as gen: | ||
gen_script = gen.read() | ||
|
||
print(" 1. modify haskell/gen_ghc_bindist.py", file=sys.stderr) | ||
|
||
added_version = replace.sub(fr'''\g<indent>{{ "version": { repr(latest_release) }, | ||
\g<indent> "ignore_suffixes": [".bz2", ".lz", ".zip"] }}, | ||
\g<0>''', gen_script, count=1) | ||
|
||
if added_version is gen_script: | ||
sys.exit(f"could not add new version {latest_release} using regex {replace}") | ||
else: | ||
gen.truncate(0) | ||
gen.seek(0) | ||
gen.write(added_version) | ||
|
||
print(" 2. call haskell/gen_ghc_bindist.py", file=sys.stderr) | ||
|
||
bzl = check_output([sys.executable, 'haskell/gen_ghc_bindist.py']) | ||
|
||
print(" 3. format bzl code, write to haskell/private/ghc_bindist_generated.bzl", file=sys.stderr) | ||
with open('haskell/private/ghc_bindist_generated.bzl', 'r+') as generated: | ||
run(['buildifier'], check=True, input=bzl, stdout=generated) | ||
generated.truncate() | ||
else: | ||
print("no tags found for prefix", prefix, file=sys.stderr) | ||
|
||
|
||
if __name__ == '__main__': | ||
main() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
name: Update GHC | ||
on: | ||
schedule: | ||
# run weekly on Thursday | ||
- cron: '0 15 * * THU' | ||
workflow_dispatch: # allows manual triggering | ||
|
||
jobs: | ||
update_ghc: | ||
name: GHC ${{ matrix.ghc }} Update | ||
runs-on: ubuntu-latest | ||
strategy: | ||
fail-fast: false | ||
matrix: | ||
ghc: | ||
- '9.2' | ||
- '9.4' | ||
- '9.6' | ||
steps: | ||
- uses: actions/checkout@v3 | ||
- uses: cachix/install-nix-action@v22 | ||
with: | ||
nix_path: nixpkgs=nixpkgs/default.nix | ||
- name: Fetch updates | ||
run: nix shell 'nixpkgs#bazel-buildtools' 'nixpkgs#python3' --command python .github/update-ghc.py ${{ matrix.ghc }} | ||
- run: git diff | ||
|