Skip to content

Commit 815b669

Browse files
committed
CI: Merge artifacts
1 parent 6d77ee2 commit 815b669

File tree

3 files changed

+123
-2
lines changed

3 files changed

+123
-2
lines changed

.github/workflows/main.yml

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ on:
1515
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
1616
jobs:
1717
build:
18+
name: "Build"
19+
1820
strategy:
1921
matrix:
2022
os:
@@ -25,7 +27,7 @@ jobs:
2527
vcpkg-triplet: x86-linux
2628
preset: ci-linux
2729
target: [client, server]
28-
30+
2931
# The type of runner that the job will run on
3032
runs-on: ${{ matrix.os.runs-on }}
3133

@@ -94,3 +96,38 @@ jobs:
9496
with:
9597
name: ${{ steps.prepare_artifact.outputs.artifact_name }}
9698
path: ${{github.workspace}}/_build/ci-artifact
99+
100+
merge-artifacts:
101+
name: "Merge Artifacts"
102+
needs: build
103+
104+
strategy:
105+
matrix:
106+
target: [client, server]
107+
runs-on: ubuntu-latest
108+
109+
steps:
110+
# Download artifacts
111+
- uses: actions/download-artifact@v4
112+
with:
113+
path: ${{github.workspace}}/_build/ci-artifacts
114+
pattern: "*-${{ matrix.target }}-ci-*"
115+
merge-multiple: true
116+
117+
# Merge them
118+
- name: Merge artifacts
119+
id: merge_artifacts
120+
run: >
121+
python scripts/merge_artifacts.py
122+
--artifact-dir ${{github.workspace}}/_build/ci-artifacts
123+
--out-dir ${{github.workspace}}/_build/ci-out-artifact
124+
--target ${{ matrix.target }}
125+
ci-linux
126+
ci-windows
127+
128+
# Upload merged artifact
129+
- name: Upload merged artifact
130+
uses: actions/upload-artifact@v4
131+
with:
132+
name: ${{ steps.merge_artifacts.outputs.artifact_name }}
133+
path: ${{github.workspace}}/_build/ci-out-artifact

scripts/create_metadata.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
import os
1414
from pathlib import Path
1515

16+
METADATA_FILE_NAME = 'bugfixedhl_install_metadata.dat'
17+
1618
# List of files that don't need to be updated
1719
USER_MODIFIABLE_FILES = [
1820
'ui/resource/ChatScheme.res',
@@ -57,7 +59,7 @@ def create_metadata(version: str, startpath: Path):
5759

5860
meta['files'][path] = file_data
5961

60-
with open(startpath / 'bugfixedhl_install_metadata.dat', "w", encoding='utf-8') as f:
62+
with open(startpath / METADATA_FILE_NAME, "w", encoding='utf-8') as f:
6163
f.write(json.dumps(meta, indent=2))
6264

6365

scripts/merge_artifacts.py

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
import argparse
2+
import json
3+
import os
4+
import re
5+
import shutil
6+
from pathlib import Path
7+
from create_metadata import METADATA_FILE_NAME, create_metadata
8+
9+
10+
def _read_metadata_version(meta_path: Path) -> str:
11+
with open(meta_path, 'r', encoding='utf-8') as f:
12+
j = json.load(f)
13+
return j['version']
14+
15+
16+
def main():
17+
parser = argparse.ArgumentParser(description='Merges multiple artifacts into one')
18+
parser.add_argument('--artifact-dir', required=True, help='Where artifacts are located')
19+
parser.add_argument('--out-dir', required=True, help='Where to put the merged artifact')
20+
parser.add_argument('--target', required=True, help='Target name')
21+
parser.add_argument('suffixes', nargs='+', help='Artifact suffixes to combine. Priority is first to last.')
22+
23+
args = parser.parse_args()
24+
artifact_dir = Path(args.artifact_dir)
25+
out_dir = Path(args.out_dir)
26+
27+
# Build file list
28+
files: dict[str, tuple[Path, Path]] = {} # lower_case_path -> rel path, root path
29+
30+
for suffix in args.suffixes:
31+
# Find the artifact for this suffix
32+
name_suffix = f'-{args.target}-{suffix}'
33+
artifacts_with_suffix = list(artifact_dir.glob(f'*{name_suffix}', case_sensitive=True))
34+
35+
if len(artifacts_with_suffix) == 0:
36+
raise Exception(f'No artifacts found for suffix = {suffix}')
37+
38+
if len(artifacts_with_suffix) > 1:
39+
print('Found too many artifacts:')
40+
for i in artifacts_with_suffix:
41+
print(f'- {i}')
42+
raise Exception(f'Too many artifacts found for suffix = {suffix}')
43+
44+
artifact_with_suffix = artifacts_with_suffix[0]
45+
46+
# Build the file list
47+
for dirpath, _, filenames in os.walk(artifact_with_suffix):
48+
for filename in filenames:
49+
full_path = Path(dirpath) / filename
50+
rel_path = full_path.relative_to(artifact_with_suffix)
51+
key = rel_path.as_posix().lower()
52+
53+
if key not in files:
54+
files[key] = (rel_path, artifact_with_suffix)
55+
print(f'{rel_path} -> {artifact_with_suffix.name}')
56+
57+
# Read version from old metadata
58+
meta_rel_path, meta_root_dir = files[f'valve_addon/{METADATA_FILE_NAME}'.lower()]
59+
version = _read_metadata_version(meta_root_dir / meta_rel_path)
60+
out_artifact_name = f'BugfixedHL-{version}-{args.target}'
61+
62+
# Pass artifact name to GitHub Actions
63+
if 'GITHUB_OUTPUT' in os.environ:
64+
print(f'Passing artifact name to GitHub Actions as artifact_name')
65+
with open(os.environ['GITHUB_OUTPUT'], 'a', encoding='utf-8') as f:
66+
f.write(f'artifact_name={out_artifact_name}\n')
67+
else:
68+
print(f'Not running on GitHub Actions')
69+
70+
# Copy the files
71+
artifact_inner_dir = out_dir / out_artifact_name
72+
artifact_inner_dir.mkdir(parents=True, exist_ok=True)
73+
74+
for rel_path, root_path in files.values():
75+
abs_path = artifact_inner_dir / rel_path
76+
abs_path.parent.mkdir(parents=True, exist_ok=True)
77+
shutil.copy2(root_path / rel_path, abs_path)
78+
79+
# Create new metadata
80+
create_metadata(version, artifact_inner_dir / 'valve_addon')
81+
82+
main()

0 commit comments

Comments
 (0)