initial commit

This commit is contained in:
eine
2020-05-14 16:58:15 +02:00
commit c9d3643b20
5 changed files with 189 additions and 0 deletions

29
.github/workflows/push.yml vendored Normal file
View File

@@ -0,0 +1,29 @@
name: 'tip'
on:
push:
tags:
- '*'
- '!tip'
branches:
- '*'
pull_request:
env:
CI: true
jobs:
tip:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Build
run: |
echo "Build some tool and generate some artifacts" > artifact.txt
- uses: ./
with:
token: ${{ secrets.GITHUB_TOKEN }}
files: |
artifact.txt
README.md

4
Dockerfile Normal file
View File

@@ -0,0 +1,4 @@
FROM python:alpine
COPY tip.py /tip.py
RUN pip install PyGithub --progress-bar off
ENTRYPOINT ["/tip.py"]

38
README.md Normal file
View File

@@ -0,0 +1,38 @@
**tip** is a Docker GitHub Action written in Python. **tip** allows to keep a pre-release and its artifacts up to date with a latest builds. Combined with a workflow that is executed periodically, **tip** allows to provide a fixed release name for users willing to use daily/nightly artifacts of a project.
The following block shows a minimal YAML workflow file:
```yml
name: 'workflow'
on:
schedule:
- cron: '0 0 * * 5'
jobs:
mwe:
runs-on: ubuntu-latest
steps:
# Clone repository
- uses: actions/checkout@v2
# Build your application, tool, artifacts, etc.
- name: Build
run: |
echo "Build some tool and generate some artifacts" > artifact.txt
# Update tag and pre-release
# - Update (force-push) tag to the commit that is used in the workflow.
# - Upload artifacts defined by the user.
- uses: eine/tip@master
with:
token: ${{ secrets.GITHUB_TOKEN }}
files: |
artifact.txt
README.md
```
Note that the tag and the pre-release need to be created manually the first time. The workflow above will fail if the release does not exist.
The default tag name is `tip`, but it can be optionally overriden through option `tag` or setting envvar `INPUT_TAG`.

16
action.yml Normal file
View File

@@ -0,0 +1,16 @@
name: 'tip'
description: "keep a pre-release always up-to-date"
inputs:
token:
description: 'Token to make authenticated API calls; can be passed in using {{ secrets.GITHUB_TOKEN }}'
required: true
files:
description: 'Multi-line list of glob patterns describing the artifacts to be uploaded'
required: true
tag:
description: 'Name of the tag that corresponds to the tip/nightly pre-release'
required: false
default: tip
runs:
using: 'docker'
image: 'Dockerfile'

102
tip.py Executable file
View File

@@ -0,0 +1,102 @@
#!/usr/bin/env python3
from os import environ, getenv
from sys import argv, stdout
from github import Github
from subprocess import check_call
from glob import glob
print("· Get list of artifacts to be uploaded")
args = []
files = []
if 'INPUT_FILES' in environ:
args = environ['INPUT_FILES'].split()
if len(argv) > 1:
args = args + argv[1:]
if len(args) == 0:
stdout.flush()
raise(Exception("Glob patterns need to be provided as positional arguments or through envvar 'INPUT_FILES'!"))
for item in args:
items = glob(item)
print("glob(%s)" % item, "->", items)
files = files + items
if len(files) < 1:
stdout.flush()
raise(Exception('Empty list of files to upload/update!'))
print("· Get GitHub API handler (authenticate)")
if 'GITHUB_TOKEN' in environ:
gh = Github(environ["GITHUB_TOKEN"])
elif 'INPUT_TOKEN' in environ:
gh = Github(environ["INPUT_TOKEN"])
else:
if 'GITHUB_USER' not in environ or 'GITHUB_PASS' not in environ:
stdout.flush()
raise(Exception("Need credentials to authenticate! Please, provide 'GITHUB_TOKEN', 'INPUT_TOKEN', or 'GITHUB_USER' and 'GITHUB_PASS'"))
gh = Github(environ["GITHUB_USER"], environ["GITHUB_PASS"])
print("· Get Repository handler")
if 'GITHUB_REPOSITORY' not in environ:
stdout.flush()
raise(Exception("Repository name not defined! Please set 'GITHUB_REPOSITORY"))
gh_repo = gh.get_repo(environ['GITHUB_REPOSITORY'])
print("· Get Release handler")
tag = getenv('INPUT_TAG', 'tip')
try:
gh_tag = gh_repo.get_git_ref('tags/%s' % tag)
except Exception as e:
stdout.flush()
# TODO: create the tag/release, instead of raising an exception
raise(Exception("Tag '%s' does not exist!" % tag))
gh_release = gh_repo.get_release(tag)
print("· Upload artifacts")
artifacts = files
for asset in gh_release.get_assets():
print(">", asset)
print(" ", asset.name)
for fname in artifacts:
if asset.name == fname:
print(" removing '%s'..." % asset.name)
asset.delete_asset()
print(" uploading '%s'..." % fname)
gh_release.upload_asset(fname)
artifacts.remove(fname)
break
for fname in artifacts:
print(" uploading '%s'..." % fname)
gh_release.upload_asset(fname)
stdout.flush()
print("· Update Release reference (force-push tag)")
if ('GITHUB_SHA' in environ) and ('GITHUB_REF' in environ) and environ['GITHUB_REF'] != 'refs/tags/%s' % tag:
sha = environ['GITHUB_SHA']
print("force-push '%s' to %s" % (tag, sha))
gh_repo.get_git_ref('tags/%s' % tag).edit(sha)
# TODO: alternatively, update the title/body of the release (while keeping the tag or not)
# gh_release.update_release(
# gh_release.title,
# gh_release.body,
# draft=False,
# prerelease=True,
# tag_name=gh_release.tag_name,
# target_commitish=gh_release.target_commitish
# )