Initial CI stuff

This commit is contained in:
Mike A. Trethewey
2020-02-26 02:44:11 -08:00
parent 47f60b5612
commit 30e8fd132c
7 changed files with 312 additions and 0 deletions

70
.github/workflows/ci.yml vendored Normal file
View File

@@ -0,0 +1,70 @@
# workflow name
name: Build
# fire on
on: [ push, pull_request ]
# stuff to do
jobs:
# Install & Build
# Set up environment
# Build
# Run build-gui.py
# Run build-dr.py
install-build:
name: Install/Build
# cycle through os list
runs-on: ${{ matrix.os-name }}
# VM settings
# os & python versions
strategy:
matrix:
os-name: [ ubuntu-latest, ubuntu-16.04, macOS-latest, windows-latest ]
python-version: [ 3.7 ]
# needs: [ install-test ]
steps:
# checkout commit
- name: Checkout commit
uses: actions/checkout@v1
# install python
- name: Install python
uses: actions/setup-python@v1
with:
python-version: ${{ matrix.python-version }}
architecture: "x64"
- run: |
python --version
# install dependencies via pip
- name: Install dependencies via pip
env:
OS_NAME: ${{ matrix.os-name }}
run: |
python ./resources/ci/common/install.py
# try to get UPX
- name: Get UPX
env:
OS_NAME: ${{ matrix.os-name }}
run: |
python ./resources/ci/common/get_upx.py
# run build-gui.py
- name: Build GUI
run: |
pip install pyinstaller
python ./build-gui.py
# run build-dr.py
- name: Build DungeonRandomizer
run: |
python ./build-dr.py
# prepare binary artifacts for later step
- name: Prepare Binary Artifacts
env:
OS_NAME: ${{ matrix.os-name }}
run: |
python ./resources/ci/common/prepare_binary.py
# upload binary artifacts for later step
- name: Upload Binary Artifacts
uses: actions/upload-artifact@v1
with:
name: binaries-${{ matrix.os-name }}
path: ../artifact

View File

@@ -0,0 +1 @@
pyinstaller

1
resources/ci/__init__.py Normal file
View File

@@ -0,0 +1 @@
#do nothing, just exist to make "common" package

131
resources/ci/common.py Normal file
View File

@@ -0,0 +1,131 @@
import os # for env vars
import stat # file statistics
# take number of bytes and convert to string with units measure
def convert_bytes(num):
for x in ["bytes","KB","MB","GB","TB","PB"]:
if num < 1024.0:
return "%3.1f %s" % (num,x)
num /= 1024.0
# get filesize of file at path
def file_size(file_path):
if os.path.isfile(file_path):
file_info = os.stat(file_path)
return convert_bytes(file_info.st_size)
# prepare environment variables
def prepare_env():
DEFAULT_EVENT = "event"
DEFAULT_REPO_SLUG = "miketrethewey/ALttPDoorRandomizer"
env = {}
# get app version
APP_VERSION = ""
APP_VERSION_FILE = "./resources/app/meta/manifests/app_version.txt"
if os.path.isfile(APP_VERSION_FILE):
with open(APP_VERSION_FILE,"r") as f:
APP_VERSION = f.readlines()[0].strip()
# ci data
env["CI_SYSTEM"] = os.getenv("CI_SYSTEM","")
# git data
env["BRANCH"] = os.getenv("TRAVIS_BRANCH","")
env["GITHUB_ACTOR"] = os.getenv("GITHUB_ACTOR","MegaMan.EXE")
env["GITHUB_SHA"] = os.getenv("GITHUB_SHA","")
env["GITHUB_SHA_SHORT"] = env["GITHUB_SHA"]
# commit data
env["COMMIT_ID"] = os.getenv("TRAVIS_COMMIT",os.getenv("GITHUB_SHA",""))
env["COMMIT_COMPARE"] = os.getenv("TRAVIS_COMMIT_RANGE","")
# event data
env["EVENT_MESSAGE"] = os.getenv("TRAVIS_COMMIT_MESSAGE","")
env["EVENT_LOG"] = os.getenv("GITHUB_EVENT_PATH","")
env["EVENT_TYPE"] = os.getenv("TRAVIS_EVENT_TYPE",os.getenv("GITHUB_EVENT_NAME",DEFAULT_EVENT))
# repo data
env["REPO_SLUG"] = os.getenv("TRAVIS_REPO_SLUG",os.getenv("GITHUB_REPOSITORY",DEFAULT_REPO_SLUG))
env["REPO_USERNAME"] = ""
env["REPO_NAME"] = ""
# repo slug
if '/' in env["REPO_SLUG"]:
tmp = env["REPO_SLUG"].split('/')
env["REPO_USERNAME"] = tmp[0]
env["REPO_NAME"] = tmp[1]
if not env["GITHUB_SHA"] == "":
env["GITHUB_SHA_SHORT"] = env["GITHUB_SHA"][:7]
# ci data
env["BUILD_NUMBER"] = os.getenv("TRAVIS_BUILD_NUMBER",env["GITHUB_SHA_SHORT"])
GITHUB_TAG = os.getenv("TRAVIS_TAG",os.getenv("GITHUB_TAG",""))
OS_NAME = os.getenv("TRAVIS_OS_NAME",os.getenv("OS_NAME","")).replace("macOS","osx")
OS_DIST = os.getenv("TRAVIS_DIST","notset")
OS_VERSION = ""
if '-' in OS_NAME:
OS_VERSION = OS_NAME[OS_NAME.find('-')+1:]
OS_NAME = OS_NAME[:OS_NAME.find('-')]
if OS_NAME == "linux" or OS_NAME == "ubuntu":
if OS_VERSION == "latest":
OS_VERSION = "bionic"
elif OS_VERSION == "16.04":
OS_VERSION = "xenial"
OS_DIST = OS_VERSION
if OS_VERSION == "" and not OS_DIST == "" and not OS_DIST == "notset":
OS_VERSION = OS_DIST
# if no tag
if GITHUB_TAG == "":
# if we haven't appended the build number, do it
if env["BUILD_NUMBER"] not in GITHUB_TAG:
GITHUB_TAG = APP_VERSION
# if the app version didn't have the build number, add it
# set to <app_version>.<build_number>
if env["BUILD_NUMBER"] not in GITHUB_TAG:
GITHUB_TAG += '.' + env["BUILD_NUMBER"]
env["GITHUB_TAG"] = GITHUB_TAG
env["OS_NAME"] = OS_NAME
env["OS_DIST"] = OS_DIST
env["OS_VERSION"] = OS_VERSION
return env
# build filename based on metadata
def prepare_filename(BUILD_FILENAME):
env = prepare_env()
DEST_FILENAME = ""
# build the filename
if not BUILD_FILENAME == "":
os.chmod(BUILD_FILENAME,0o755)
fileparts = os.path.splitext(BUILD_FILENAME)
DEST_SLUG = fileparts[0]
DEST_EXTENSION = fileparts[1]
DEST_SLUG = DEST_SLUG + '-' + env["GITHUB_TAG"] + '-' + env["OS_NAME"]
if not env["OS_DIST"] == "" and not env["OS_DIST"] == "notset":
DEST_SLUG += '-' + env["OS_DIST"]
DEST_FILENAME = DEST_SLUG + DEST_EXTENSION
return DEST_FILENAME
# find a binary file if it's executable
# failing that, assume it's over 10MB
def find_binary(listdir):
BUILD_FILENAMES = []
executable = stat.S_IEXEC | stat.S_IXGRP | stat.S_IXOTH
for filename in os.listdir(listdir):
if os.path.isfile(filename):
st = os.stat(filename)
mode = st.st_mode
big = st.st_size > (10 * 1024 * 1024) # 10MB
if (mode & executable) or big:
if "GUI" in filename or "DungeonRandomizer" in filename:
BUILD_FILENAMES.append(filename)
return BUILD_FILENAMES
if __name__ == "__main__":
env = prepare_env()
print(env)

42
resources/ci/get_upx.py Normal file
View File

@@ -0,0 +1,42 @@
import common
import os # for env vars
import sys # for path
import urllib.request # for downloads
from shutil import unpack_archive
# only do stuff if we don't have a UPX folder
if not os.path.isdir("./upx"):
# get env vars
env = common.prepare_env()
# set up download url
UPX_VERSION = os.getenv("UPX_VERSION") or "3.96"
UPX_SLUG = ""
UPX_FILE = ""
if "windows" in env["OS_NAME"]:
UPX_SLUG = "upx-" + UPX_VERSION + "-win64"
UPX_FILE = UPX_SLUG + ".zip"
else:
UPX_SLUG = "upx-" + UPX_VERSION + "-amd64_linux"
UPX_FILE = UPX_SLUG + ".tar.xz"
UPX_URL = "https://github.com/upx/upx/releases/download/v" + UPX_VERSION + '/' + UPX_FILE
if "osx" not in env["OS_NAME"]:
print("Getting UPX: " + UPX_FILE)
with open("./" + UPX_FILE,"wb") as upx:
UPX_REQ = urllib.request.Request(
UPX_URL,
data=None
)
UPX_REQ = urllib.request.urlopen(UPX_REQ)
UPX_DATA = UPX_REQ.read()
upx.write(UPX_DATA)
unpack_archive(UPX_FILE,"./")
os.rename("./" + UPX_SLUG,"./upx")
os.remove("./" + UPX_FILE)
print("UPX should " + ("not " if not os.path.isdir("./upx") else "") + "be available.")

27
resources/ci/install.py Normal file
View File

@@ -0,0 +1,27 @@
import common
import os # for env vars
import subprocess # do stuff at the shell level
env = common.prepare_env()
# get executables
# python
# linux/windows: python
# macosx: python3
# pip
# linux/macosx: pip3
# windows: pip
PYTHON_EXECUTABLE = "python3" if "osx" in env["OS_NAME"] else "python"
PIP_EXECUTABLE = "pip" if "windows" in env["OS_NAME"] else "pip3"
PIP_EXECUTABLE = "pip" if "osx" in env["OS_NAME"] and "actions" in env["CI_SYSTEM"] else PIP_EXECUTABLE
# upgrade pip
subprocess.check_call([PYTHON_EXECUTABLE,"-m","pip","install","--upgrade","pip"])
# pip version
subprocess.check_call([PIP_EXECUTABLE,"--version"])
# if pip3, install wheel
if PIP_EXECUTABLE == "pip3":
subprocess.check_call([PIP_EXECUTABLE,"install","-U","wheel"])
# install listed dependencies
subprocess.check_call([PIP_EXECUTABLE,"install","-r","./resources/app/meta/manifests/pip_requirements.txt"])

View File

@@ -0,0 +1,40 @@
import distutils.dir_util # for copying trees
import os # for env vars
import stat # for file stats
import subprocess # do stuff at the shell level
import common
from shutil import copy, make_archive, move, rmtree # file manipulation
env = common.prepare_env()
# make dir to put the binary in
if not os.path.isdir(os.path.join("..","artifact")):
os.mkdir(os.path.join("..","artifact"))
BUILD_FILENAME = ""
# list executables
BUILD_FILENAME = common.find_binary('.')
if BUILD_FILENAME == "":
BUILD_FILENAME = common.find_binary(os.path.join("..","artifact"))
if isinstance(BUILD_FILENAME,str):
BUILD_FILENAME = list(BUILD_FILENAME)
BUILD_FILENAMES = BUILD_FILENAME
for BUILD_FILENAME in BUILD_FILENAMES:
DEST_FILENAME = common.prepare_filename(BUILD_FILENAME)
print("OS Name: " + env["OS_NAME"])
print("OS Version: " + env["OS_VERSION"])
print("Build Filename: " + BUILD_FILENAME)
print("Dest Filename: " + DEST_FILENAME)
if not BUILD_FILENAME == "":
print("Build Filesize: " + common.file_size(BUILD_FILENAME))
if not BUILD_FILENAME == "":
move(
os.path.join(".",BUILD_FILENAME),
os.path.join("..","artifact",BUILD_FILENAME)
)