test
This commit is contained in:
@@ -0,0 +1,40 @@
|
||||
name: Autodeploy Setup
|
||||
description: Copy the `autodeploy` scripts into the caller repository, install prerequisites and run `setup.sh`.
|
||||
inputs:
|
||||
branch:
|
||||
description: "Branch or ref to check out in the caller repository"
|
||||
required: false
|
||||
default: "main"
|
||||
# install_prereqs:
|
||||
# description: "Whether to install prerequisites on the runner"
|
||||
# required: false
|
||||
# default: "true"
|
||||
|
||||
runs:
|
||||
using: "composite"
|
||||
steps:
|
||||
- name: Checkout caller repository
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
persist-credentials: true
|
||||
ref: ${{ inputs.branch }}
|
||||
|
||||
- name: Copy autodeploy into workspace
|
||||
run: |
|
||||
cp -R "$GITHUB_ACTION_PATH/autodeploy" "$GITHUB_WORKSPACE/"
|
||||
shell: bash
|
||||
|
||||
# - name: Install prerequisites
|
||||
# if: ${{ inputs.install_prereqs == 'true' }}
|
||||
# run: |
|
||||
# sudo apt-get update
|
||||
# sudo apt-get install -y curl tar
|
||||
# shell: bash
|
||||
|
||||
- name: Run autodeploy setup script
|
||||
working-directory: ${{ github.workspace }}/autodeploy
|
||||
run: |
|
||||
chmod +x setup.sh
|
||||
./setup.sh
|
||||
shell: bash
|
||||
@@ -0,0 +1,28 @@
|
||||
Usage
|
||||
-----
|
||||
|
||||
Call this composite action from any repository to run the `autodeploy/setup.sh` script included in this repo.
|
||||
|
||||
Example workflow snippet (in the caller repo):
|
||||
|
||||
```yaml
|
||||
name: call-autodeploy
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
run-autodeploy:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Run autodeploy action from repo
|
||||
uses: your-username/snek/.github/actions/autodeploy@main
|
||||
with:
|
||||
branch: main
|
||||
install_prereqs: 'true'
|
||||
```
|
||||
|
||||
Notes:
|
||||
- The action will `checkout` the caller repository (so it can `git add`/`git commit` and `git push`).
|
||||
- If you rely on `GITHUB_TOKEN` permissions for pushing, ensure `permissions.contents` in the caller workflow allows `write`.
|
||||
- The action copies the `autodeploy` directory from this repo into the caller workspace before running the script.
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
# 🐍 snek
|
||||
|
||||
## Usage
|
||||
|
||||
```bash
|
||||
$ ./snek -h
|
||||
```
|
||||
```
|
||||
usage: snek [-h] [--root ROOT] [--exe EXE] {envs,root,exe,info,fork,bless} ...
|
||||
|
||||
🐍
|
||||
|
||||
optional arguments:
|
||||
-h, --help show this help message and exit
|
||||
--root ROOT conda root folder / prefix (read from the current env, if not given)
|
||||
--exe EXE conda or mamba executable (read from the current env, if not given)
|
||||
|
||||
commands:
|
||||
{envs,root,exe,info,fork,bless}
|
||||
envs print existing envs
|
||||
root print root
|
||||
exe print exe
|
||||
info print info
|
||||
fork fork a conda env
|
||||
bless bless a conda env
|
||||
```
|
||||
|
||||
@@ -1,192 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import shutil
|
||||
import subprocess
|
||||
from collections import defaultdict
|
||||
from datetime import datetime
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
TS_FMT = "%Y%m%d-%H%M%S"
|
||||
|
||||
|
||||
class Conda:
|
||||
|
||||
def __init__(self, root=None, exe=None):
|
||||
self.exe = exe or shutil.which("mamba") or shutil.which("conda")
|
||||
if not self.exe:
|
||||
raise SystemExit("neither conda nor mamba found")
|
||||
|
||||
root = root or self.get_root()
|
||||
self.root = Path(root)
|
||||
|
||||
|
||||
def fork(self, name):
|
||||
envs = self.get_envs()
|
||||
if name not in envs:
|
||||
envs = ", ".join(envs)
|
||||
msg = f'"{name}" is not a known environment.\nChoose from: {envs}'
|
||||
raise SystemExit(msg)
|
||||
|
||||
basename = name
|
||||
if "@" in name:
|
||||
basename, original_timestamp = name.rsplit("@", 1)
|
||||
original_timestamp = datetime.strptime(original_timestamp, TS_FMT)
|
||||
print(f'extracted basename "{basename}" from {name} (original timestamp: {original_timestamp})')
|
||||
|
||||
timestamp = datetime.now().strftime(TS_FMT)
|
||||
new = f"{basename}@{timestamp}"
|
||||
self.clone(name, new)
|
||||
|
||||
|
||||
def bless(self, name):
|
||||
if "@" not in name:
|
||||
msg = f'"{name}" is not a forked environment'
|
||||
raise SystemExit(msg)
|
||||
|
||||
basename, timestamp = name.rsplit("@", 1)
|
||||
|
||||
try:
|
||||
timestamp = datetime.strptime(timestamp, TS_FMT)
|
||||
except ValueError as e:
|
||||
raise SystemExit(e)
|
||||
|
||||
self.clone(name, basename)
|
||||
|
||||
|
||||
def print_envs(self):
|
||||
envs = self.get_envs()
|
||||
for i in envs:
|
||||
print("-", i)
|
||||
|
||||
|
||||
def get_envs(self):
|
||||
cmd = [self.exe, "env", "list", "--json"]
|
||||
info = run_and_parse(cmd)
|
||||
envs = info["envs"]
|
||||
envs = sorted(envs)
|
||||
|
||||
if self.root:
|
||||
envs_root = self.root / "envs"
|
||||
envs = [Path(i) for i in envs]
|
||||
envs = [i.relative_to(envs_root) for i in envs if i.is_relative_to(envs_root)]
|
||||
envs = [str(i) for i in envs]
|
||||
|
||||
return envs
|
||||
|
||||
|
||||
def print_root(self):
|
||||
print(self.root)
|
||||
|
||||
|
||||
def get_root(self):
|
||||
info = self.get_info()
|
||||
return info["conda_prefix"]
|
||||
|
||||
|
||||
def print_exe(self):
|
||||
print(self.exe)
|
||||
|
||||
|
||||
def print_info(self):
|
||||
info = self.get_info()
|
||||
length = maxstrlen(info.keys())
|
||||
for k, v in sorted(info.items()):
|
||||
k = str(k) + ":"
|
||||
v = str(v)
|
||||
if len(v) >= 100:
|
||||
v = "\n" + v + "\n"
|
||||
print(k.ljust(length), v)
|
||||
|
||||
|
||||
def get_info(self):
|
||||
cmd = [self.exe, "info", "--json"]
|
||||
info = run_and_parse(cmd)
|
||||
return info
|
||||
|
||||
|
||||
def clone(self, original, new):
|
||||
# conda create --name theclone --clone theoriginal # uses hardlinks
|
||||
# conda create --name thecopy --copy theoriginal # copies files
|
||||
print("clone:", original, "=>", new)
|
||||
cmd = [self.exe, "create", "--name", new, "--clone", original]
|
||||
subprocess.run(cmd)
|
||||
|
||||
|
||||
def get_list(self, env):
|
||||
cmd = [self.exe, "list", "--json", "--name", env]
|
||||
pkgs = run_and_parse(cmd)
|
||||
res = defaultdict(list)
|
||||
for p in pkgs:
|
||||
for k in ("name", "version", "build_string", "build_number", "channel"):
|
||||
res[k].append(p[k])
|
||||
return dict(res)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
def run_and_parse(cmd):
|
||||
completed = subprocess.run(cmd, capture_output=True)
|
||||
|
||||
stderr = completed.stderr
|
||||
if stderr:
|
||||
msg = stderr.decode().strip()
|
||||
raise SystemExit(msg)
|
||||
|
||||
stdout = completed.stdout
|
||||
if stdout:
|
||||
return json.loads(stdout)
|
||||
|
||||
|
||||
def maxstrlen(seq):
|
||||
return max(len(str(i)) for i in seq)
|
||||
|
||||
|
||||
|
||||
def handle_clargs():
|
||||
parser = argparse.ArgumentParser(description="🐍")
|
||||
|
||||
parser.add_argument("--root", help="conda root folder / prefix (read from the current env, if not given)")
|
||||
parser.add_argument("--exe", help="conda or mamba executable (read from the current env, if not given)")
|
||||
|
||||
subparsers = parser.add_subparsers(title="commands", dest="command", required=True)
|
||||
|
||||
parser_envs = subparsers.add_parser("envs", help="print existing envs")
|
||||
parser_root = subparsers.add_parser("root", help="print root")
|
||||
parser_exe = subparsers.add_parser("exe", help="print exe")
|
||||
parser_info = subparsers.add_parser("info", help="print info")
|
||||
|
||||
parser_fork = subparsers.add_parser("fork", help="fork a conda env")
|
||||
parser_bless = subparsers.add_parser("bless", help="bless a conda env")
|
||||
|
||||
msg = "name of the conda env"
|
||||
parser_fork.add_argument("name", help=msg)
|
||||
parser_bless.add_argument("name", help=msg)
|
||||
|
||||
clargs = parser.parse_args()
|
||||
return clargs
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
clargs = handle_clargs()
|
||||
conda = Conda(root=clargs.root, exe=clargs.exe)
|
||||
|
||||
dispatch = {
|
||||
"envs": conda.print_envs,
|
||||
"root": conda.print_root,
|
||||
"exe": conda.print_exe,
|
||||
"info": conda.print_info,
|
||||
"fork": lambda: conda.fork(clargs.name),
|
||||
"bless": lambda: conda.bless(clargs.name)
|
||||
}
|
||||
|
||||
dispatch[clargs.command]()
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user