-
Notifications
You must be signed in to change notification settings - Fork 6
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
Wy/wakeup actions lambda #6
base: main
Are you sure you want to change the base?
Changes from all commits
151f540
811aee5
8f06c18
a9b4d0d
44eb5e8
a5f9f6e
18625ca
ca89cfb
5b964ed
3385d50
e560017
5661a16
46d0aa8
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,14 @@ | ||
# KeepActionsAlive | ||
Prevent scheduled GitHub Actions from becoming disabled after 60 days | ||
|
||
## How to use | ||
|
||
This requires installing the github api package, which can be done with `python -m pip install github` | ||
|
||
Afterwards this can be started by setting the following environment variables: | ||
* `GH_LOGIN_OR_TOKEN` | ||
* Used both for API calls to get repo/organization info, and to send the request to re-enable workflows | ||
* A Github [Personal Access Token (PAT)](https://docs.github.com/en/rest/overview/other-authentication-methods#via-oauth-and-personal-access-tokens) | ||
* `GH_ORGANIZATION` | ||
* The name of the organization you would like to work with | ||
* Used to fetch the list of all owned repositories, and then all workflows |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
#!/bin/sh | ||
# For best results run this in a manylinux docker container or AL2 container | ||
# Some packages ignore the `plat-name` build option | ||
|
||
# target build platform options: https://github.com/pypa/manylinux | ||
PLATFORM=manylinux1_x86_64 | ||
TARGET_DIR=./lambda_package/lambda_wheel/ | ||
|
||
. ./venv/bin/activate | ||
pip install -e ".[deploy]" | ||
python -m pip wheel \ | ||
--wheel-dir="$TARGET_DIR" \ | ||
--build-option "--plat-name=$PLATFORM" \ | ||
--no-binary ":all:" \ | ||
-e . | ||
|
||
cp ./lambda_package_files/* ./lambda_package/. | ||
mkdir ./lambda_package/src | ||
cp src/keep_actions_alive.py ./lambda_package/src/. | ||
cp src/lambda.py ./lambda_package/src/. | ||
cp ./setup.cfg ./lambda_package/. | ||
cp ./setup.py ./lambda_package/. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
-e . |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
-e . |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
from setuptools import find_packages, setup # type: ignore | ||
|
||
REQUIREMENTS = [ | ||
"pygithub", | ||
] | ||
|
||
DEPLOY_DEPS = [ | ||
# Used to zip up the code | ||
"wheel", | ||
] | ||
|
||
EXTRAS = { | ||
"deploy": DEPLOY_DEPS | ||
} | ||
|
||
setup( | ||
name="KeepActionsAlive", | ||
version="0.0.1", | ||
description="Re-enables Github Workflows disabled due to inactivity", | ||
author="Invenia Technical Computing", | ||
url="https://github.com/invenia/KeepActionsAlive", | ||
packages=find_packages(), | ||
install_requires=REQUIREMENTS, | ||
include_package_data=True, | ||
extras_require=EXTRAS, | ||
) |
Original file line number | Diff line number | Diff line change | ||||||
---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,56 @@ | ||||||||
#!/usr/bin/env python | ||||||||
|
||||||||
from github import Github | ||||||||
import os | ||||||||
import pprint | ||||||||
import requests | ||||||||
|
||||||||
IS_LAMBDA = bool(os.getenv("AWS_EXECUTION_ENV")) | ||||||||
|
||||||||
|
||||||||
def get_parameters(): | ||||||||
# Add more options for adding arguments here, | ||||||||
# such as CLI args, AWS Secrets Manager, config file, etc. | ||||||||
|
||||||||
# Get keyword arguments from environment variables | ||||||||
return { | ||||||||
"login_or_token": os.getenv("GH_LOGIN_OR_TOKEN"), | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This should not be an environment variable. It needs to be stored in SecretsManager and using boto to retrieve it. |
||||||||
"organization": os.getenv("GH_ORGANIZATION"), | ||||||||
} | ||||||||
|
||||||||
|
||||||||
def keep_actions_alive(parameters): | ||||||||
pp = pprint.PrettyPrinter(indent=4) | ||||||||
|
||||||||
login_or_token = parameters["login_or_token"] | ||||||||
organization = parameters["organization"] | ||||||||
|
||||||||
g = Github(login_or_token=login_or_token) | ||||||||
|
||||||||
# Get all repos that are not forks and are not archived | ||||||||
# Only supports repos owned by an organization for now, | ||||||||
# but could be changed to users | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||
repos = g.get_organization(organization).get_repos() | ||||||||
owned_repos = [r for r in repos if not r.fork and not r.archived] | ||||||||
|
||||||||
for repo in owned_repos: | ||||||||
# Get all workflows disabled from inactivity | ||||||||
disabled_workflows = [ | ||||||||
w for w in repo.get_workflows() if w.state == "disabled_inactivity" | ||||||||
] | ||||||||
|
||||||||
if login_or_token: # Use token authentication | ||||||||
for workflow in disabled_workflows: | ||||||||
# There's no documented pygithub API call for enabling the | ||||||||
# workflow, so the rest API should work here | ||||||||
enable_url = f"{workflow.url}/enable" | ||||||||
token_header = {"Authorization": f"Bearer {login_or_token}"} | ||||||||
requests.put(enable_url, headers=token_header) | ||||||||
else: | ||||||||
# No authentication, so just output the disabled workflows | ||||||||
pp.pprint(disabled_workflows) | ||||||||
|
||||||||
|
||||||||
if __name__ == "__main__": | ||||||||
parameters = get_parameters() | ||||||||
keep_actions_alive(parameters) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
#!/usr/bin/env python | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't understand the point of this file, why not just have everything in one script? |
||
|
||
import boto3 | ||
import json | ||
import os | ||
|
||
import keep_actions_alive | ||
|
||
|
||
# Specifically gets parameters for running in a Lambda | ||
def get_parameters(): | ||
sm_client = boto3.client("secretsmanager") | ||
secret_key = os.getenv("GH_LOGIN_OR_TOKEN_KEY") | ||
login_or_token = json.loads( | ||
sm_client.get_secret_value(SecretId=secret_key)["SecretString"] | ||
)["Personal Access Token"] | ||
return { | ||
"login_or_token": login_or_token, | ||
"organization": os.getenv("GH_ORGANIZATION"), | ||
} | ||
|
||
|
||
# Lambda entry point. Does not use `event` and `context` | ||
def lambda_handler(*kwargs): | ||
keep_actions_alive.keep_actions_alive(get_parameters()) | ||
|
||
|
||
# mainly for testing | ||
if __name__ == "__main__": | ||
lambda_handler() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.