Skip to content

Commit 7d1d8bc

Browse files
authored
Merge pull request #1613 from larsewi/treasure
Multiple improvements to automated dependency updates
2 parents 6cae290 + 17eea4f commit 7d1d8bc

File tree

2 files changed

+77
-52
lines changed

2 files changed

+77
-52
lines changed

.github/workflows/update-deps.py

Lines changed: 68 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,33 @@
88
import urllib.request
99
import logging as log
1010
from itertools import batched
11+
import subprocess
1112

1213
DEPS_PACKAGING = "deps-packaging"
1314

1415

16+
def run_command(cmd: list):
17+
try:
18+
log.debug(f"Running command '{" ".join(cmd)}'")
19+
subprocess.run(cmd, check=True)
20+
except subprocess.CalledProcessError:
21+
log.error(f"Command '{" ".join(cmd)}' failed")
22+
return False
23+
return True
24+
25+
26+
def git_commit(root, msg):
27+
return run_command(["git", "-C", root, "add", "-u"]) and run_command(
28+
[
29+
"git",
30+
"-C",
31+
root,
32+
"commit",
33+
f"--message={msg}",
34+
],
35+
)
36+
37+
1538
def parse_args():
1639
parser = argparse.ArgumentParser(description="CFEngine dependency updater")
1740
parser.add_argument(
@@ -20,25 +43,28 @@ def parse_args():
2043
help="enable debug log messages",
2144
)
2245
parser.add_argument(
23-
"--update",
46+
"--bump",
2447
default="minor",
2548
choices=["major", "minor", "patch"],
26-
help="whether to do major, minor or patch updates",
49+
help="whether to bump version major, minor or patch",
2750
)
2851
parser.add_argument(
2952
"--skip",
3053
nargs=2,
3154
action="extend",
3255
default=[],
3356
metavar=("PACKAGE", "VERSION"),
34-
help="skip updates for specific version of a package (e.g., --skip librsync 2.3.4)"
57+
help="skip updates for specific version of a package (e.g., --skip librsync 2.3.4)",
58+
)
59+
parser.add_argument(
60+
"--root", default=".", help="specify build scripts root directory"
3561
)
3662

3763
return parser.parse_args()
3864

3965

40-
def determine_old_version(pkg_name):
41-
distfile = os.path.join(DEPS_PACKAGING, pkg_name, "distfiles")
66+
def determine_old_version(root, pkg_name):
67+
distfile = os.path.join(root, DEPS_PACKAGING, pkg_name, "distfiles")
4268
with open(distfile, "r") as f:
4369
data = f.read().strip().split()
4470
filename = data[-1]
@@ -92,12 +118,12 @@ def get_available_versions(proj_id):
92118

93119
def select_new_version(
94120
package_name,
95-
update_type,
121+
bump_version,
96122
skip_versions,
97123
old_version,
98124
available_versions,
99125
):
100-
assert len(skip_versions) % 2 == 0 # Is guaranteed by the argument parser
126+
assert len(skip_versions) % 2 == 0 # Is guaranteed by the argument parser
101127

102128
old_split = old_version.replace("-", ".").replace("_", ".").split(".")
103129
for new_version in available_versions:
@@ -112,11 +138,11 @@ def select_new_version(
112138
log.info(f"Skipping version {new_version} for package {package_name}")
113139
continue
114140

115-
if update_type == "major":
141+
if bump_version == "major":
116142
return new_version
117-
if update_type == "minor" and old_split[:1] == new_split[:1]:
143+
if bump_version == "minor" and old_split[:1] == new_split[:1]:
118144
return new_version
119-
if update_type == "patch" and old_split[:2] == new_split[:2]:
145+
if bump_version == "patch" and old_split[:2] == new_split[:2]:
120146
return new_version
121147
return None # Didn't find a suitable version
122148

@@ -141,22 +167,22 @@ def replace_string_in_file(filename, old, new):
141167
f.write(contents.replace(old, new))
142168

143169

144-
def update_version_numbers(pkg_name, old_version, new_version):
170+
def update_version_numbers(root, pkg_name, old_version, new_version):
145171
filenames = [
146-
os.path.join(DEPS_PACKAGING, pkg_name, f"cfbuild-{pkg_name}.spec"),
147-
os.path.join(DEPS_PACKAGING, pkg_name, f"cfbuild-{pkg_name}-aix.spec"),
148-
os.path.join(DEPS_PACKAGING, pkg_name, "distfiles"),
149-
os.path.join(DEPS_PACKAGING, pkg_name, "source"),
172+
os.path.join(root, DEPS_PACKAGING, pkg_name, f"cfbuild-{pkg_name}.spec"),
173+
os.path.join(root, DEPS_PACKAGING, pkg_name, f"cfbuild-{pkg_name}-aix.spec"),
174+
os.path.join(root, DEPS_PACKAGING, pkg_name, "distfiles"),
175+
os.path.join(root, DEPS_PACKAGING, pkg_name, "source"),
150176
]
151177
for filename in filenames:
152178
replace_string_in_file(filename, old_version, new_version)
153179

154180

155-
def update_distfiles_digest(pkg_name):
156-
with open(os.path.join(DEPS_PACKAGING, pkg_name, "source"), "r") as f:
181+
def update_distfiles_digest(root, pkg_name):
182+
with open(os.path.join(root, DEPS_PACKAGING, pkg_name, "source"), "r") as f:
157183
source = f.read().strip()
158184

159-
filename = os.path.join(DEPS_PACKAGING, pkg_name, "distfiles")
185+
filename = os.path.join(root, DEPS_PACKAGING, pkg_name, "distfiles")
160186
with open(filename, "r") as f:
161187
content = f.read().strip().split()
162188
old_digest = content[0]
@@ -174,25 +200,20 @@ def update_distfiles_digest(pkg_name):
174200
replace_string_in_file(filename, old_digest, new_digest)
175201

176202

177-
def main():
178-
args = parse_args()
179-
loglevel = "DEBUG" if args.debug else "INFO"
180-
log.basicConfig(
181-
format="[%(filename)s:%(lineno)d][%(levelname)s]: %(message)s", level=loglevel
182-
)
183-
184-
with open(os.path.join(DEPS_PACKAGING, "release-monitoring.json"), "r") as f:
203+
def update_deps(root, bump, skip):
204+
with open(os.path.join(root, DEPS_PACKAGING, "release-monitoring.json"), "r") as f:
185205
release_monitoring = json.load(f)
186206

187-
commit_message = ["Updated dependencies\n\n"]
188207
for pkg_name, proj_id in release_monitoring.items():
189-
old_version = determine_old_version(pkg_name)
208+
old_version = determine_old_version(root, pkg_name)
190209
if not old_version:
191210
log.error(f"Failed to determine old version of package {pkg_name}")
192211
exit(1)
193212

194213
available_versions = get_available_versions(proj_id)
195-
new_version = select_new_version(pkg_name, args.update, args.skip, old_version, available_versions)
214+
new_version = select_new_version(
215+
pkg_name, bump, skip, old_version, available_versions
216+
)
196217
if not new_version:
197218
log.error(f"Could not find a suitable new version for package {pkg_name}")
198219
exit(1)
@@ -210,13 +231,26 @@ def main():
210231
continue
211232
log.info(f"Updating {pkg_name} from version {old_version} to {new_version}...")
212233

213-
update_version_numbers(pkg_name, old_version, new_version)
214-
update_distfiles_digest(pkg_name)
234+
update_version_numbers(root, pkg_name, old_version, new_version)
235+
update_distfiles_digest(root, pkg_name)
236+
237+
if not git_commit(
238+
root,
239+
f"Updated dependency '{pkg_name}' from version {old_version} to {new_version}",
240+
):
241+
log.error(f"Failed to commit changes after updating package '{pkg_name}'")
242+
exit(1)
243+
244+
245+
def main():
246+
args = parse_args()
247+
loglevel = "DEBUG" if args.debug else "INFO"
248+
log.basicConfig(
249+
format="[%(filename)s:%(lineno)d][%(levelname)s]: %(message)s", level=loglevel
250+
)
215251

216-
commit_message.append(f"- Updated dependency '{pkg_name}' from version {old_version} to {new_version}\n")
252+
update_deps(args.root, args.bump, args.skip)
217253

218-
with open("/tmp/commit-message.txt", "w") as f:
219-
f.writelines(commit_message)
220254

221255
if __name__ == "__main__":
222256
main()

.github/workflows/update-deps.yml

Lines changed: 9 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -26,32 +26,23 @@ jobs:
2626
run: |
2727
python -m pip install --upgrade pip
2828
python -m pip install requests
29-
- name: Run update script
30-
run: python3 .github/workflows/update-deps.py --debug --update=major
31-
- name: Check if there are changes
32-
run: |
33-
git diff --exit-code || touch git_diff_exists
34-
if [ -f git_diff_exists ]; then echo "Changes need to be committed"; else echo "No changes to commit"; fi
35-
- name: Commit changes
36-
if: hashFiles('git_diff_exists') != ''
29+
- name: Set Git user
3730
run: |
3831
git config user.name 'GitHub'
3932
git config user.email '<noreply@github.com>'
40-
git add -u
41-
git commit -F /tmp/commit-message.txt
42-
- id: commit-message-from-file
43-
name: Parse commit message from file into variable
44-
if: hashFiles('git_diff_exists') != ''
33+
- name: Run update script
34+
run: python3 .github/workflows/update-deps.py --debug --bump=major
35+
- name: Check if commits were made
4536
run: |
46-
body=$(cat /tmp/commit-message.txt)
47-
body="${body//$'\n'/'%0A'}"
48-
echo ::set-output name=body::$body
37+
if [[ $(git log --oneline -1 --author="GitHub") ]]; then
38+
echo "COMMIT_MADE=true" >> $GITHUB_ENV
39+
fi
4940
- name: Create Pull Request
50-
if: hashFiles('git_diff_exists') != ''
41+
if: env.COMMIT_MADE == 'true'
5142
uses: cfengine/create-pull-request@v6
5243
with:
5344
title: Updated dependencies
54-
body: ${{ steps.commit-message-from-file.outputs.body }}
45+
body: Automated dependency updates
5546
reviewers: |
5647
olehermanse
5748
larsewi

0 commit comments

Comments
 (0)