Skip to content

Commit

Permalink
Merge pull request #11 from LuxorLabs/pr/beta-builder
Browse files Browse the repository at this point in the history
Publish pip wheel into pypi on master merge
  • Loading branch information
cav71 authored Apr 8, 2024
2 parents d34ed51 + b764a8d commit 8a7dcf7
Show file tree
Hide file tree
Showing 6 changed files with 133 additions and 74 deletions.
17 changes: 14 additions & 3 deletions .github/workflows/push-main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ concurrency: ${{ github.workflow }}-${{ github.ref }}

env:
PACKAGE: luxos
GITHUB_DUMP: ${{ toJson(github) }}

jobs:
build:
Expand Down Expand Up @@ -68,14 +69,24 @@ jobs:
--junitxml=$OUTDIR/junit/junit.xml --html=$OUTDIR/junit/junit.html --self-contained-html \
tests
- name: Dump env
shell: bash
run: |
echo "github env:"
echo "$GITHUB_DUMP"
- name: Build wheel packages
if: ${{ ! contains(matrix.os, 'windows') }}
env:
GITHUB_DUMP: ${{ toJson(github) }}
run: |
python -m build
python make.pyz beta-release -v
touch .keepme
- name: "Publish beta package to pypi"
uses: pypa/gh-action-pypi-publish@release/v1
if: ${{ matrix.python-version == env.XTARGET }}
with:
password: ${{ secrets.PYPI_API_TOKEN }}

- name: Archive artifacts
uses: actions/upload-artifact@v4
with:
Expand Down
11 changes: 9 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,18 @@
# LUXOS CHANGELOG
# LUXOS TOOLING CHANGELOG

- [LUXOS TOOLING CHANGELOG](#luxos-tooling-changelog)
- [\[Unreleased\]](#unreleased)

All notable changes to this project will be documented in this file.
<!--
All notable changes to this project will be documented in this file.
Please, use the format:
## [Unreleased]
- <module>: short description
-->

## [Unreleased]

- beta-builder: automatically publish beta packages into pypi from main branch
Binary file modified health-checker.pyz
Binary file not shown.
Binary file modified luxos.pyz
Binary file not shown.
177 changes: 108 additions & 69 deletions make.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,64 +2,42 @@
"""A make-like script"""
import argparse
import contextlib
import hashlib
import json
import os
import shutil
import sys
import logging
import functools
import subprocess
import zipfile
from pathlib import Path

# curl -LO https://github.com/cav71/hatch-ci/raw/beta/0.1.4/make.pyz
from make import fileos, misc, task, text # type: ignore

log = logging.getLogger(__name__)

def task(name=None):
"""task decorator
This decorator will run the decorated function so:
1. change the current directory to this script
directory
2. call the decorated task
3. return to the (eventual) starting dir
The wrapped function can have few `magic` arguments:
- args : this is the sys.argv[2:] list
- parser : this will be a argparse.ArgumentParser ready
- workdir : in case you dont want to auto cd into workdir
"""
def _task1(fn):
@functools.wraps(fn)
def _task(workdir, args):
from inspect import signature
cwd = Path.cwd()
try:
kwargs = {}
if "args" in signature(fn).parameters:
kwargs["args"] = args
if "parser" in signature(fn).parameters:
class F(argparse.ArgumentDefaultsHelpFormatter):
pass
kwargs["parser"] = argparse.ArgumentParser(
formatter_class=F, description=_task.description)
if "workdir" in signature(fn).parameters:
kwargs["workdir"] = workdir
else:
os.chdir(workdir)
return fn(**kwargs)
finally:
os.chdir(cwd)

_task.task = name or fn.__name__
_task.description = (
fn.__doc__.strip().partition("\n")[0] if fn.__doc__ else "no help available"
)
return _task

return _task1
@task()
def hello(argv):
"""this is the hello world"""
print( # noqa: T201
f"""
Hi!
python: {sys.executable}
version: {sys.version_info.major}.{sys.version_info.minor}.{sys.version_info.micro}
cwd: {Path.cwd()}
argv: {argv}
"""
)


@task(name=None)
def onepack(parser, args, workdir):
def onepack(parser, argv):
"""create a one .pyz single file package"""
from zipapp import create_archive
from configparser import ConfigParser, ParsingError
workdir = Path.cwd()

config = ConfigParser(strict=False)
with contextlib.suppress(ParsingError):
Expand All @@ -73,22 +51,55 @@ def onepack(parser, args, workdir):

parser.add_argument("-o", "--output-dir",
default=workdir, type=Path)
o = parser.parse_args(args)
o = parser.parse_args(argv)

def extract(path: Path) -> dict[str, list[str | None, str | None]]:
result = {}
if not path.exists():
return result
zfp = zipfile.ZipFile(path)
for item in zfp.infolist():
with zfp.open(item) as fp:
data = fp.read()
result[item.filename] = [hashlib.sha256(data).hexdigest(), None]
return result

for target, entrypoint in targets:
dst = o.output_dir / target
create_archive(
workdir / "src",
dst,
main=entrypoint,
compressed=True
)

# cleanup cache dirs
for xx in (workdir / "src").rglob("__pycache__"):
shutil.rmtree(xx, ignore_errors=True)

# get the relatove path (nicer for display)
relpath = (
dst.relative_to(Path.cwd())
if dst.is_relative_to(Path.cwd())
else dst
)
print(f"Written: {relpath}", file=sys.stderr)

generate = True
if dst.exists():
dst1 = dst.parent / f"{dst.name}.bak"
create_archive(
workdir / "src",
dst1,
main=entrypoint,
compressed=True
)
generate = (extract(dst) != extract(dst1))
dst1.unlink()
if generate:
create_archive(
workdir / "src",
dst,
main=entrypoint,
compressed=True
)

print(f"Written: {relpath}", file=sys.stderr)
else:
print(f"Skipping generation: {relpath}", file=sys.stderr)


@task()
Expand All @@ -99,29 +110,57 @@ def checks():

@task()
def tests():
"""runs all tests (excluding the manual ones)"""
workdir = Path.cwd()
subprocess.check_call(
["pytest", "-vvs", str(workdir / "tests") ]
)


if __name__ == "__main__":
logging.basicConfig(level=logging.DEBUG)
tasks = [ item for item in list(locals().values()) if getattr(item, "task", None)]
@task(name="beta-build")
def beta_build(parser, argv):
"""create beta packages for luxos (only works in github)"""

if len(sys.argv) < 2 or sys.argv[1] not in [t.task for t in tasks]:
txt = "\n".join(f" {task.task} - {task.description}" for task in tasks)
print( # noqa: T201
f"""\
make.py <command> {{arguments}}
parser.add_argument("-n", "--dry-run", dest="dryrun", action="store_true")
options = parser.parse_args(argv)

Commands:
{txt}
""",
file=sys.stderr,
)
sys.exit()
github_dump = os.getenv("GITHUB_DUMP")
if not github_dump:
raise RuntimeError("missing GITHUB_DUMP variable")
gdata = (
json.loads(Path(github_dump[1:]).read_text())
if github_dump.startswith("@")
else json.loads(github_dump)
)
misc.validate_gdata(
gdata, ["run_number", "sha", "ref_name", "ref_type", "workflow_ref"]
)

workdir = Path(__file__).parent
function = [t for t in tasks if sys.argv[1] == t.task][0]
function(workdir, args=sys.argv[2:])
with contextlib.ExitStack() as stack:
save = stack.enter_context(fileos.backups())

# pyproject.toml
pyproject = save("pyproject.toml")
lineno, current, quote = misc.get_variable_def(pyproject, "version")
log.debug("found at LN:%i: version = '%s'", lineno, current)
version = f"{current}b{gdata['run_number']}"

log.info("creating for version %s [%s]", version, gdata["sha"])
misc.set_variable_def(pyproject, "version", lineno, version, quote)

# __init__.py
initfile = save("src/luxos/__init__.py")
lineno, old, quote = misc.get_variable_def(initfile, "__version__")
log.debug("found at LN:%i: __version__ = '%s'", lineno, old)
if old != "" and old != current:
raise RuntimeError(f"found in {initfile} __version__ {old} != {current}")
misc.set_variable_def(pyproject, "__version__", lineno, version, quote)

lineno, old, quote = misc.get_variable_def(initfile, "__hash__")
log.debug("found at LN:%i: __hash__ = '%s'", lineno, old)
if old != "" and old != gdata["sha"]:
raise RuntimeError(f"found in {initfile} __hash__ {old} != {gdata['sha']}")
misc.set_variable_def(pyproject, "__hash__", lineno, gdata["sha"], quote)

if not options.dryrun:
subprocess.check_call([sys.executable, "-m", "build"]) # noqa: S603
2 changes: 2 additions & 0 deletions src/luxos/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
__version__ = ""
__hash__ = ""

0 comments on commit 8a7dcf7

Please sign in to comment.