Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

basic execution #32

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions .github/workflows/run_script.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
name: shbin run

on:
workflow_dispatch:
inputs:
command:
description: 'Command to use'
required: true
type: string

file_path:
description: 'Relative path of the script to run'
required: true
type: string

jobs:
run-script:
env:
SHBIN_GITHUB_TOKEN: ${{ secrets.github_token }}
SHBIN_REPO: ${{ github.repository }}
SHBIN_FORCE_USER: ${{ github.actor }}
runs-on: ubuntu-latest
steps:
- name: Install shbin
run: pip install https://github.com/Shiphero/shbin/archive/refs/heads/gha.zip
- name: Download script
run: shbin dl ${{ inputs.file_path }}
- name: Run script
run: ${{ inputs.command}} $(basename "${{ inputs.file_path }}") > output.txt
- name: Upload results
run: |
rm $(basename "${{ inputs.file_path }}")
shbin ./* -d ${{ inputs.file_path }}_run_${{ github.run_id }}
81 changes: 76 additions & 5 deletions shbin.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,21 @@
import re
import secrets
import sys
import time
from mimetypes import guess_extension


import pyclip
from docopt import DocoptExit, docopt
from github import Github, GithubException
from rich import print
import requests

usage = """

Usage:
shbin dl <url_or_path>
shbin run [--logs] [--command=<command>] <url_or_path>
shbin (<path>... | -x | -) [-f <file-name>] [-n] [-m <message>] [-d <target-dir>]
[--namespace=<namespace>] [--url-link-to-pages]
shbin (-h | --help)
Expand All @@ -32,10 +36,11 @@
-d <target-dir>, --target-dir=<target-dir> Optional (sub)directory to upload file/s.
--namespace=<namespace> Base namespace to upload. Default to
SHBIN_NAMESPACE envvar or "{user}/".
--command=<command> How to run the given file. Default "auto".
-p, --url-link-to-pages Reformat the url to link to Github pages.
"""

__version__ = "0.3.0"
__version__ = "0.4.0a1"


class FakePath:
Expand All @@ -57,7 +62,13 @@ def __getattr__(self, attr):

def get_repo_and_user():
gh = Github(os.environ["SHBIN_GITHUB_TOKEN"])
return gh.get_repo(os.environ["SHBIN_REPO"]), gh.get_user().login
try:
user = gh.get_user().login
except GithubException:
user = os.environ.get("SHBIN_FORCE_USER")
if not user:
raise
return gh.get_repo(os.environ["SHBIN_REPO"]), user


def expand_paths(path_or_patterns):
Expand Down Expand Up @@ -89,6 +100,62 @@ def get_extension(content):
return guess_extension(magic.from_buffer(content, mime=True))


def normalize_path(url_or_path, repo):
return re.sub(rf"^https://github\.com/{repo.full_name}/(blob|tree)/{repo.default_branch}/", "", url_or_path).rstrip(
"/"
)


def run(url_or_path, repo, user, show_logs=True, command="auto"):
path = normalize_path(url_or_path, repo)
try:
wf = repo.get_workflow("run_script.yml")
except GithubException:
print("[bold].github/workflows/run_script.yml[/bold] doesn't exist in your repo.")
print("Setup as 🔗 https://github.com/Shiphero/shbin/.github/workflows/run_script.yml")
return

if command == "auto":
executables = {"py": "python", "sh": "bash", "js": "node", "rb": "ruby", "php": "php", "go": "go run"}
extension = path.rpartition(".")[-1]
try:
command = executables[extension]
except KeyError:
raise DocoptExit(f"Unknown command for .{extension} files")

wf.create_dispatch(repo.default_branch, {"file_path": path, "command": command})
while True:
run = wf.get_runs(user, repo.default_branch, event="workflow_dispatch")[0]
if run.status == "in_progress":
job = run.jobs()[0]
break
time.sleep(1)
continue

print(f"⚙️ {job.html_url}")

if show_logs:
url = job.logs_url()
sentinel = "Cleaning up orphan processes" # determines the logs is finished
seen = 0
while True:
response = requests.get(url)
lines = response.text.splitlines()
new_lines = lines[seen:] # only print new lines
seen = len(lines)
for line in new_lines:
print(line)
if sentinel in line:
break
while job.status != "completed":
job.update()
time.sleep(1)

output = repo.get_contents(f"{user}/{path}_run_{run.id}/output.txt").decoded_content.decode("utf-8")
print(f"[green]Result:[/green]\n\n{output}")
print(f"[green]More at:[/green]\n\n shbin dl {path}_run_{run.id}")


def download(url_or_path, repo, user):
"""
# download a file
Expand All @@ -99,8 +166,7 @@ def download(url_or_path, repo, user):
$ shbin dl https://github.com/Shiphero/pastebin/blob/main/bibo/AWS_API_fullfilment_methods/
$ shbin dl bibo/AWS_API_fullfilment_methods/
"""
path = re.sub(rf"^https://github\.com/{repo.full_name}/(blob|tree)/{repo.default_branch}/", "", url_or_path)
path = path.rstrip("/")
path = normalize_path(url_or_path, repo)
try:
content = repo.get_contents(path)
if isinstance(content, list):
Expand All @@ -113,6 +179,10 @@ def download(url_or_path, repo, user):
else:
content = content.decoded_content
except GithubException:
if not path.startswith(f"{user}/"):
new_path = f"{user}/{path}"
print(f"[yellow]trying {new_path}")
return download(new_path, repo, user)
print("[red]x[/red] content not found")
else:
target = pathlib.Path(path).name
Expand All @@ -139,7 +209,8 @@ def main(argv=None) -> None:

if args["dl"]:
return download(args["<url_or_path>"], repo, user)

elif args["run"]:
return run(args["<url_or_path>"], repo, user, args["--logs"], args["--command"])
elif args["--from-clipboard"] or args["<path>"] == ["-"]:
if args["--from-clipboard"]:
try:
Expand Down
Loading