Skip to content

Commit 73ee849

Browse files
committed
Initial import
0 parents  commit 73ee849

File tree

3 files changed

+239
-0
lines changed

3 files changed

+239
-0
lines changed

Dockerfile

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
FROM ubuntu:bionic
2+
3+
LABEL maintainer="jrandiny <[email protected]>"
4+
5+
ENV DEBIAN_FRONTEND=noninteractive
6+
7+
RUN apt update
8+
RUN apt install -y reprepro gpg python3 python3-git python3-gnupg expect
9+
10+
COPY entrypoint.py /entrypoint.py
11+
12+
ENTRYPOINT ["python3","/entrypoint.py"]

action.yml

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
name: "Github page APT repo"
2+
description: "Setup and manage APT repo"
3+
inputs:
4+
github_token:
5+
description: "Github token"
6+
required: true
7+
arch:
8+
description: "Newline-delimited list of supported architecture"
9+
required: true
10+
version:
11+
description: "Newline-delimited list of supported version"
12+
required: true
13+
file:
14+
description: "Newline-delimited list of .deb files"
15+
required: true
16+
file_target_version:
17+
description: "Newline-delimited list of version target of supplied .deb file"
18+
required: true
19+
public_key:
20+
description: "GPG public key for apt repo"
21+
required: false
22+
private_key:
23+
description: "GPG private key for signing apt repo"
24+
required: true
25+
key_secret:
26+
description: "Secret of GPG key"
27+
required: false
28+
page_branch:
29+
description: "Branch of Github page"
30+
required: false
31+
default: "gh-pages"
32+
repo_folder:
33+
description: "Location of APT repo folder relative to root of Github page"
34+
required: false
35+
default: "repo"
36+
debug:
37+
description: "Print debug log"
38+
required: false
39+
default: false
40+
runs:
41+
using: "docker"
42+
image: "Dockerfile"

entrypoint.py

Lines changed: 185 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,185 @@
1+
import os
2+
import sys
3+
import logging
4+
import gnupg
5+
import git
6+
import shutil
7+
8+
debug = os.environ.get('INPUT_DEBUG')
9+
10+
if debug:
11+
logging.basicConfig(format='%(levelname)s: %(message)s', level=logging.DEBUG)
12+
else:
13+
logging.basicConfig(format='%(levelname)s: %(message)s', level=logging.INFO)
14+
15+
if __name__ == '__main__':
16+
logging.info('-- Parsing input --')
17+
18+
github_token = os.environ.get('INPUT_GITHUB_TOKEN')
19+
arch = os.environ.get('INPUT_ARCH')
20+
version = os.environ.get('INPUT_VERSION')
21+
deb_file = os.environ.get('INPUT_FILE')
22+
deb_file_version = os.environ.get('INPUT_FILE_TARGET_VERSION')
23+
github_repo = os.environ.get('GITHUB_REPOSITORY')
24+
25+
gh_branch = os.environ.get('INPUT_PAGE_BRANCH', 'gh-pages')
26+
apt_folder = os.environ.get('INPUT_REPO_FOLDER', 'repo')
27+
28+
if None in (github_token, arch, version, deb_file):
29+
logging.error('Required key is missing')
30+
sys.exit(1)
31+
32+
arch_list = arch.strip().split('\n')
33+
version_list = version.strip().split('\n')
34+
deb_file_list = deb_file.strip().split('\n')
35+
deb_file_version_list = deb_file_version.strip().split('\n')
36+
37+
logging.debug(arch_list)
38+
logging.debug(version_list)
39+
logging.debug(deb_file_list)
40+
logging.debug(deb_file_version_list)
41+
42+
if any((target_version not in version_list) for target_version in deb_file_version_list):
43+
logging.error('File version target is not listed in repo supported version list')
44+
sys.exit(1)
45+
46+
pub_key = os.environ.get('INPUT_PUBLIC_KEY')
47+
sign_key = os.environ.get('INPUT_PRIVATE_KEY')
48+
secret = os.environ.get('INPUT_KEY_SECRET')
49+
50+
logging.debug(github_token)
51+
logging.debug(arch_list)
52+
logging.debug(version_list)
53+
54+
logging.info('-- Done parsing input --')
55+
56+
logging.info('-- Cloning current repo --')
57+
58+
github_user = github_repo.split('/')[0]
59+
github_slug = github_repo.split('/')[1]
60+
61+
if os.path.exists(github_slug):
62+
shutil.rmtree(github_slug)
63+
64+
git_repo = git.Repo.clone_from(
65+
'https://{}@github.com/{}.git'.format(github_token, github_repo),
66+
github_slug,
67+
branch=gh_branch,
68+
)
69+
70+
if git_repo.head.commit.message[:12] == '[apt-action]':
71+
logging.info('Loop detected, exiting')
72+
sys.exit(0)
73+
74+
logging.info('-- Done cloning current Github page --')
75+
76+
logging.info('-- Importing key --')
77+
78+
logging.info('Detecting public key')
79+
80+
logging.debug('Detecting existing public key')
81+
82+
key_dir = os.path.join(github_slug, 'public.key')
83+
key_exists = os.path.isfile(key_dir)
84+
85+
logging.debug('Existing public key file exists? {}'.format(key_exists))
86+
87+
gpg = gnupg.GPG()
88+
89+
if not key_exists:
90+
logging.info('Directory doesn\'t contain public.key trying to import')
91+
if pub_key is None:
92+
logging.error('Please specify public key for setup')
93+
sys.exit(1)
94+
95+
logging.debug('Trying to import key')
96+
97+
public_import_result = gpg.import_keys(pub_key)
98+
public_import_result.ok_reason
99+
100+
logging.debug(public_import_result)
101+
102+
if public_import_result.count != 1:
103+
logging.error('Invalid public key provided, please provide 1 valid key')
104+
sys.exit(1)
105+
106+
with open(key_dir, 'w') as key_file:
107+
key_file.write(pub_key)
108+
109+
logging.info('Public key valid')
110+
111+
logging.info('Importing private key')
112+
113+
private_import_result = gpg.import_keys(sign_key)
114+
115+
if private_import_result.count != 1:
116+
logging.error('Invalid private key provided, please provide 1 valid key')
117+
sys.exit(1)
118+
119+
logging.debug(private_import_result)
120+
121+
if not any(data['ok'] >= '16' for data in private_import_result.results):
122+
logging.error('Key provided is not a secret key')
123+
sys.exit(1)
124+
125+
private_key_id = private_import_result.results[0]['fingerprint']
126+
127+
logging.info('Private key valid')
128+
129+
logging.debug('Key id: {}'.format(private_key_id))
130+
131+
logging.info('-- Done importing key --')
132+
133+
logging.info('-- Preparing repo directory --')
134+
135+
apt_dir = os.path.join(github_slug, apt_folder)
136+
137+
apt_conf_dir = os.path.join(apt_dir, 'conf')
138+
139+
if not os.path.isdir(apt_folder):
140+
logging.debug('Existing repo not detected, creating new repo')
141+
os.mkdir(apt_dir)
142+
os.mkdir(apt_conf_dir)
143+
144+
logging.debug('Creating repo config')
145+
146+
with open(os.path.join(apt_conf_dir, 'distributions'), "w") as distributions_file:
147+
for codename in version_list:
148+
distributions_file.write('Description: {}\n'.format(github_repo))
149+
distributions_file.write('Codename: {}\n'.format(codename))
150+
distributions_file.write('Architectures: {}\n'.format(' '.join(arch_list)))
151+
distributions_file.write('Components: main\n')
152+
distributions_file.write('SignWith: {}\n'.format(private_key_id))
153+
distributions_file.write('\n\n')
154+
155+
logging.info('-- Done preparing repo directory --')
156+
157+
logging.info('-- Adding package to repo --')
158+
159+
for deb, target in zip(deb_file_list, deb_file_version_list):
160+
os.system(
161+
'reprepro -b {} --export=silent-never includedeb {} {}'.format(
162+
apt_dir,
163+
target,
164+
deb,
165+
)
166+
)
167+
168+
gpg.sign('test', keyid=private_key_id, passphrase=secret)
169+
170+
os.system('reprepro -b {} export'.format(apt_dir))
171+
172+
logging.info('-- Done adding package to repo --')
173+
174+
logging.info('-- Saving changes --')
175+
176+
git_repo.config_writer().set_value(
177+
'user', 'email', '{}@users.noreply.github.com'.format(github_user)
178+
)
179+
180+
git_repo.git.add('*')
181+
git_repo.index.commit('[apt-action] Update apt repo')
182+
origin = git_repo.remote()
183+
origin.push()
184+
185+
logging.info('-- Done saving changes --')

0 commit comments

Comments
 (0)