Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
webknjaz committed Feb 10, 2020
1 parent 023152d commit f87d273
Showing 1 changed file with 64 additions and 72 deletions.
136 changes: 64 additions & 72 deletions octomachinery/cli/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
"""Octomachinery CLI entrypoint."""

import asyncio
import contextlib
import importlib
import json
import os
Expand All @@ -10,7 +11,6 @@

import click

from ..app.action.runner import run as process_action
from ..github.utils.event_utils import (
augment_http_headers, make_http_headers_from_event,
parse_event_stub_from_fd, validate_http_headers,
Expand All @@ -24,15 +24,24 @@ def cli(ctx):
pass


def run_async(orig_async_func):
from functools import wraps
@wraps(orig_async_func)
def func_wrapper(*args, **kwargs):
return asyncio.run(orig_async_func(*args, **kwargs))
return func_wrapper


@cli.command()
@click.option('--event', '-e', prompt=True, type=str)
@click.option('--event', '-e', prompt=False, type=str)
@click.option('--payload-path', '-p', prompt=True, type=click.File(mode='r'))
@click.option('--token', '-t', prompt=True, type=str)
@click.option('--app', '-a', prompt=True, type=int)
@click.option('--app', '-a', prompt=False, type=int)
@click.option('--private-key', '-P', prompt=True, type=click.File(mode='r'))
@click.option('--entrypoint-module', '-m', prompt=True, type=str)
@click.pass_context
def receive(
@run_async
async def receive(
ctx,
event, payload_path,
token,
Expand All @@ -54,7 +63,7 @@ def receive(
'Please choose between a token or an app id with a private key',
)

http_headers, event_data = parse_event_stub_from_fd(payload_path)
http_headers, _event_data = parse_event_stub_from_fd(payload_path)

if event and http_headers:
ctx.fail('Supply only one of an event name or an event fixture file')
Expand All @@ -67,91 +76,74 @@ def receive(
validate_http_headers(http_headers)

if app is None:
_process_event_as_action(
event, event_data,
from ..github.models.events import GitHubEvent as make_event
else:
from ..github.models.events import GitHubWebhookEvent as make_event
gh_event = make_event.from_fixture_fd(payload_path, event=event)
if app is None:
cm = _process_event_as_action(
gh_event,
token,
entrypoint_module,
)
else:
asyncio.run(_process_event_as_app(
http_headers, event_data,
cm = _process_event_as_app(
app, private_key,
entrypoint_module,
))
)
from aiohttp.client import ClientSession
from ..github.api.app_client import GitHubApp
from ..app.config import BotAppConfig
from ..github.entities.action import GitHubAction
from ..app.routing.webhooks_dispatcher import route_github_event
with cm as env:
os.environ.update(env)
importlib.import_module(entrypoint_module)
config = BotAppConfig.from_dotenv()
async with ClientSession() as http_client_session:
if app is None:
github_app = GitHubAction(metadata=config.action, config=config.github, http_session=http_client_session) # FIXME: select routers?
else:
github_app = GitHubApp(config.github, http_session=http_client_session) # FIXME: select routers?
await route_github_event(github_event=gh_event, github_app=github_app)


@contextlib.contextmanager
def _process_event_as_action(
event, event_data,
gh_event,
token,
entrypoint_module,
):
os.environ['OCTOMACHINERY_APP_MODE'] = 'action'

os.environ['GITHUB_ACTION'] = 'Fake CLI Action'
os.environ['GITHUB_ACTOR'] = event_data['sender']['login']
os.environ['GITHUB_EVENT_NAME'] = event
os.environ['GITHUB_WORKSPACE'] = str(pathlib.Path('.').resolve())
os.environ['GITHUB_SHA'] = event_data['head_commit']['id']
os.environ['GITHUB_REF'] = event_data['ref']
os.environ['GITHUB_REPOSITORY'] = event_data['repository']['full_name']
os.environ['GITHUB_TOKEN'] = token
os.environ['GITHUB_WORKFLOW'] = 'Fake CLI Workflow'
env = {}
env['OCTOMACHINERY_APP_MODE'] = 'action'

env['GITHUB_ACTION'] = 'Fake CLI Action'
env['GITHUB_ACTOR'] = gh_event.payload.get('sender', {}).get('login', '')
env['GITHUB_EVENT_NAME'] = gh_event.name
env['GITHUB_WORKSPACE'] = str(pathlib.Path('.').resolve())
env['GITHUB_SHA'] = gh_event.payload.get('head_commit', {}).get('id', '')
env['GITHUB_REF'] = gh_event.payload.get('ref', '')
env['GITHUB_REPOSITORY'] = gh_event.payload.get('repository', {}).get('full_name', '')
env['GITHUB_TOKEN'] = token
env['GITHUB_WORKFLOW'] = 'Fake CLI Workflow'

with tempfile.NamedTemporaryFile(
suffix='.json', prefix='github-workflow-event-',
) as tmp_event_file:
json.dump(tmp_event_file, event_data)
os.environ['GITHUB_EVENT_PATH'] = tmp_event_file.name
importlib.import_module(entrypoint_module)
process_action()
tmp_workflow_path = tmp_event_file.name
with open(tmp_workflow_path, 'w') as fd:
json.dump(gh_event.payload, fd)
env['GITHUB_EVENT_PATH'] = tmp_workflow_path
yield env


async def _process_event_as_app(
http_headers, event_data,
@contextlib.contextmanager
def _process_event_as_app(
app, private_key,
entrypoint_module,
):
os.environ['OCTOMACHINERY_APP_MODE'] = 'app'
env = {}
env['OCTOMACHINERY_APP_MODE'] = 'app'

os.environ['GITHUB_APP_IDENTIFIER'] = str(app)
os.environ['GITHUB_PRIVATE_KEY'] = private_key.read()

importlib.import_module(entrypoint_module)
from ..app.routing.webhooks_dispatcher import route_github_webhook_event
from ..app.runtime.context import RUNTIME_CONTEXT
from ..app.config import BotAppConfig
from ..github.api.app_client import GitHubApp
from aiohttp.client import ClientSession
from aiohttp.web_request import Request
config = BotAppConfig.from_dotenv()
from aiohttp.http_parser import RawRequestMessage
import yarl

class protocol_stub:
class transp:
get_extra_info = lambda *a, **k: None
transport = transp()
message = RawRequestMessage(
'POST', '/', 'HTTP/1.1',
http_headers,
None, None, None, None, None,
yarl.URL('/'),
)
http_request = Request(
message=message,
payload=None, # dummy
protocol=protocol_stub(),
payload_writer=None, # dummy
task=None, # dummy
loop=asyncio.get_running_loop(),
)

async def read_coro():
return json.dumps(event_data).encode()
http_request.read = read_coro
async with ClientSession() as http_client_session:
github_app = GitHubApp(config.github, http_session=http_client_session)
await route_github_webhook_event(http_request, github_app=github_app)
env['GITHUB_APP_IDENTIFIER'] = str(app)
env['GITHUB_PRIVATE_KEY'] = private_key.read()
yield env


def main():
Expand Down

0 comments on commit f87d273

Please sign in to comment.