Skip to content

Commit 497b61d

Browse files
authored
Merge pull request #3 from zapta/main
Updated the build workflow of the verible package
2 parents 6bf4dae + 04c713a commit 497b61d

5 files changed

Lines changed: 399 additions & 235 deletions

File tree

Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
# Daily build and release workflow.
2+
3+
name: build-and-release
4+
5+
on:
6+
# Run on each commit to this repo.
7+
push:
8+
9+
# Run daily at 10AM UTC
10+
schedule:
11+
- cron: "0 10 * * *"
12+
13+
# Allow manual activations.
14+
workflow_dispatch:
15+
16+
permissions:
17+
# Allow release creation
18+
contents: write
19+
20+
env:
21+
# -- Set the version of the upstream release.
22+
# -- See list at https://github.com/chipsalliance/verible/releases
23+
VERIBLE_RELEASE_TAG: "v0.0-3862-g936dfb1d"
24+
25+
jobs:
26+
# -- Build packages for all supported architectures and
27+
# -- export them in a release.
28+
build-and-release:
29+
runs-on: ubuntu-22.04
30+
31+
steps:
32+
# E.g. "2025-11-02"
33+
- name: Determine release tag
34+
run: |
35+
release_tag="$(date +'%Y-%m-%d')"
36+
echo $release_tag
37+
echo "RELEASE_TAG=$release_tag" >> $GITHUB_ENV
38+
39+
# E.g. "20251102"
40+
- name: Determine package tag
41+
run: |
42+
package_tag="${RELEASE_TAG//-/}"
43+
echo $package_tag
44+
echo "PACKAGE_TAG=$package_tag" >> $GITHUB_ENV
45+
46+
# Check out the this repo in the workflow work directory.
47+
- name: Checkout this repo
48+
uses: actions/checkout@v4
49+
50+
- name: Determine last commit
51+
run: |
52+
commit=$(git rev-parse HEAD)
53+
echo $commit
54+
echo "RELEASE_COMMIT=$commit" >> $GITHUB_ENV
55+
56+
- name: Create the build-info.json file
57+
run: |
58+
cat > build-info.json <<EOF
59+
{
60+
"package-name": "verible",
61+
"description" : "Verible tools for Apio",
62+
"release-tag": "$RELEASE_TAG",
63+
"verible-release-tag": "$VERIBLE_RELEASE_TAG",
64+
"build-repo": "${{github.repository}}",
65+
"build-workflow": "${{ github.workflow }}",
66+
"workflow-run-id": "${{github.run_id}}",
67+
"workflow-run-number": "${{github.run_number}}",
68+
"build-time": "$(date +'%Y-%m-%d %H:%M:%S %Z')",
69+
"commit": "$RELEASE_COMMIT"
70+
}
71+
EOF
72+
73+
cat -n build-info.json
74+
75+
# This tool is used also by build.py
76+
- name: Format build info
77+
run: |
78+
npm install -g json-align
79+
json-align --in-place --spaces 2 build-info.json
80+
cat -n build-info.json
81+
82+
- name: Make the build info file read only
83+
run: |
84+
chmod 444 build-info.json
85+
86+
- name: Build package [darwin-arm64]
87+
run: |
88+
python .github/workflows/build.py \
89+
--platform-id darwin-arm64 \
90+
--build-info-json build-info.json
91+
92+
- name: Build package [darwin-x86-64]
93+
run: |
94+
python .github/workflows/build.py \
95+
--platform-id darwin-x86-64 \
96+
--build-info-json build-info.json
97+
98+
- name: Build package [linux-x86-64]
99+
run: |
100+
python .github/workflows/build.py \
101+
--platform-id linux-x86-64 \
102+
--build-info-json build-info.json
103+
104+
- name: Build package [linux-aarch64]
105+
run: |
106+
python .github/workflows/build.py \
107+
--platform-id linux-aarch64 \
108+
--build-info-json build-info.json
109+
110+
- name: Build package [windows-amd64]
111+
run: |
112+
python .github/workflows/build.py \
113+
--platform-id windows-amd64 \
114+
--build-info-json build-info.json
115+
116+
- name: List packages
117+
run: |
118+
ls -al _packages/*
119+
120+
- name: Prepare release text
121+
run: |
122+
cat > RELEASE_BODY.txt <<EOF
123+
This is an automated build-and-release.
124+
125+
Build info:
126+
\`\`\`
127+
$(tr -d '",{}' < build-info.json)
128+
\`\`\`
129+
EOF
130+
131+
cat -n $out
132+
133+
# In case we overwrite and exiting release.
134+
- name: Force tag update
135+
run: |
136+
git tag -f ${{env.RELEASE_TAG}}
137+
git push origin -f ${{env.RELEASE_TAG}}
138+
139+
- name: Create the Release and upload files
140+
uses: softprops/action-gh-release@v2.2.2
141+
with:
142+
tag_name: ${{env.RELEASE_TAG}}
143+
name: ${{env.RELEASE_TAG}}
144+
body_path: RELEASE_BODY.txt
145+
preserve_order: true
146+
fail_on_unmatched_files: true
147+
files: |
148+
_packages/apio-verible-darwin-arm64-${{env.PACKAGE_TAG}}.tgz
149+
_packages/apio-verible-darwin-x86-64-${{env.PACKAGE_TAG}}.tgz
150+
_packages/apio-verible-linux-x86-64-${{env.PACKAGE_TAG}}.tgz
151+
_packages/apio-verible-linux-aarch64-${{env.PACKAGE_TAG}}.tgz
152+
_packages/apio-verible-windows-amd64-${{env.PACKAGE_TAG}}.tgz

.github/workflows/build.py

Lines changed: 242 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,242 @@
1+
"""A Python script to build the Verible package for a given platform"""
2+
3+
# This script is called from the github build workflow and runs
4+
# in the repo's top dir. It uses _upstream and _packages dirs
5+
# for input and output respectivly.
6+
7+
8+
import os
9+
import json
10+
import subprocess
11+
from dataclasses import dataclass
12+
from typing import List, Union
13+
import argparse
14+
import shutil
15+
from pathlib import Path
16+
17+
# -- Command line options.
18+
parser = argparse.ArgumentParser()
19+
20+
21+
# The platform id. E.g. "darwin-arm64"
22+
parser.add_argument("--platform-id", required=True, type=str, help="Platform to build")
23+
24+
25+
# Path to the properties file with the build info.
26+
parser.add_argument(
27+
"--build-info-json", required=True, type=str, help="JSON with build properties"
28+
)
29+
30+
args = parser.parse_args()
31+
32+
33+
def run(cmd_args: Union[List[str], str], shell: bool = False) -> None:
34+
"""Run a command and check that it succeeded. Select shell=true to enable
35+
shell features such as '*' glob."""
36+
print(f"\nRun: {cmd_args}", flush=True)
37+
print(f"{shell=}", flush=True)
38+
subprocess.run(cmd_args, check=True, shell=shell)
39+
print("Run done\n", flush=True)
40+
41+
42+
@dataclass(frozen=True)
43+
class PlatformInfo:
44+
"""Represents the properties of a platform."""
45+
46+
verible_base_filename: str
47+
verible_ext: str
48+
# The name of the wrapper dir when uncompressing Verible package.
49+
verible_wrapper_dir: str
50+
unarchive_cmd: str
51+
52+
53+
def get_platform_info(platform_id: str, verible_release_tag: str) -> PlatformInfo:
54+
"""Extract (platform_id, platform_info)"""
55+
platforms = {
56+
"darwin-arm64": PlatformInfo(
57+
f"verible-{verible_release_tag}-macOS",
58+
"tar.gz",
59+
f"verible-{verible_release_tag}-macOS",
60+
["tar", "zxf"],
61+
),
62+
"darwin-x86-64": PlatformInfo(
63+
f"verible-{verible_release_tag}-macOS",
64+
"tar.gz",
65+
f"verible-{verible_release_tag}-macOS",
66+
["tar", "zxf"],
67+
),
68+
"linux-x86-64": PlatformInfo(
69+
f"verible-{verible_release_tag}-linux-static-x86_64",
70+
"tar.gz",
71+
f"verible-{verible_release_tag}",
72+
["tar", "zxf"],
73+
),
74+
"linux-aarch64": PlatformInfo(
75+
f"verible-{verible_release_tag}-linux-static-arm64",
76+
"tar.gz",
77+
f"verible-{verible_release_tag}",
78+
["tar", "zxf"],
79+
),
80+
"windows-amd64": PlatformInfo(
81+
f"verible-{verible_release_tag}-win64",
82+
"zip",
83+
f"verible-{verible_release_tag}-win64",
84+
["unzip"],
85+
),
86+
}
87+
88+
return platforms[platform_id]
89+
90+
91+
def main():
92+
"""Builds the Apio oss-cad-suite package for one platform."""
93+
94+
# -- Save the start dir. It is assume to be at top of this repo.
95+
work_dir: Path = Path.cwd()
96+
print(f"\n{work_dir=}")
97+
98+
# -- Get platform id.
99+
platform_id = args.platform_id
100+
print(f"{platform_id=}")
101+
102+
# -- Get the build info
103+
with Path(args.build_info_json).open("r", encoding="utf-8") as f:
104+
build_info = json.load(f)
105+
106+
print("\nOriginal build info:")
107+
print(json.dumps(build_info, indent=2))
108+
109+
# -- Determine if processing the windows package.
110+
is_windows = "windows" in platform_id
111+
print(f"\n{is_windows=}")
112+
113+
# -- Extract build info params
114+
release_tag = build_info["release-tag"]
115+
package_tag = release_tag.replace("-", "")
116+
verible_release_tag = build_info["verible-release-tag"]
117+
# verible_package_tag = verible_release_tag.replace("-", "")
118+
platform_info = get_platform_info(platform_id, verible_release_tag)
119+
120+
print()
121+
print(f"* {platform_id=}")
122+
print(f"* {release_tag=}")
123+
print(f"* {package_tag=}")
124+
print(f"* {platform_info=}")
125+
print(f"* {verible_release_tag=}")
126+
127+
# -- Create folder for storing the upstream packages
128+
upstream_dir: Path = work_dir / "_upstream" / platform_id
129+
print(f"\n{upstream_dir=}")
130+
upstream_dir.mkdir(parents=True, exist_ok=True)
131+
132+
# -- Create folder for storing the generated package file.
133+
package_dir: Path = work_dir / "_packages" / platform_id
134+
print(f"\n{package_dir=}")
135+
package_dir.mkdir(parents=True, exist_ok=True)
136+
137+
# -- Construct target package file name
138+
parts = [
139+
"apio-verible",
140+
"-",
141+
platform_id,
142+
"-",
143+
package_tag,
144+
".tgz",
145+
]
146+
package_filename = "".join(parts)
147+
print(f"\n{package_filename=}")
148+
build_info["target-platform"] = platform_id
149+
build_info["file-name"] = package_filename
150+
151+
# Construct verible file name
152+
verible_fname = (
153+
platform_info.verible_base_filename + "." + platform_info.verible_ext
154+
)
155+
print(f"\n{verible_fname=}")
156+
157+
# -- Construct Verible URL
158+
parts = [
159+
"https://github.com/chipsalliance/verible/releases/download",
160+
"/",
161+
verible_release_tag,
162+
"/",
163+
verible_fname,
164+
]
165+
verible_url = "".join(parts)
166+
print(f"\n{verible_url=}")
167+
168+
# -- Download the Verible file.
169+
print(f"\nChanging to UPSTREAM_DIR: {str(upstream_dir)}")
170+
os.chdir(upstream_dir)
171+
print(f"\nDownloading {verible_url}")
172+
run(["wget", "-nv", verible_url])
173+
run(["ls", "-al"])
174+
175+
# -- Uncompress the Verible archive
176+
print("Uncompressing the Verible file")
177+
run(platform_info.unarchive_cmd + [verible_fname])
178+
run(["ls", "-al"])
179+
180+
# -- Delete the Verible archive, we don't need it anymore
181+
print("Deleting the Verible archive file")
182+
Path(verible_fname).unlink()
183+
run(["ls", "-al"])
184+
185+
# -- Determine the root dir of the Verible files, below the
186+
# -- wrapper dir.
187+
print(f"\n{Path.cwd()=}")
188+
verible_root = Path(platform_info.verible_wrapper_dir)
189+
print(f"{verible_root=}")
190+
print(f"{verible_root.absolute()=}")
191+
if is_windows:
192+
# -- Windows package has no 'bin' dir.
193+
assert (verible_root / "verible-verilog-format.exe").is_file()
194+
else:
195+
assert (verible_root / "bin").is_dir()
196+
197+
# -- Copy the package files to the output directory.
198+
# -- We use rsync to copy all, including sim links, if any.
199+
# -- The does "/" matters.
200+
print("\nCopying package files.")
201+
# -- For windows, inset the missing 'bin' dir.
202+
dst = package_dir / "bin" if is_windows else package_dir
203+
run(["rsync", "-aq", f"{verible_root}/", f"{dst}/"])
204+
205+
# -- Delete the upstream dir
206+
print(f"\nDeleting upstream dir {verible_root}")
207+
shutil.rmtree(verible_root)
208+
209+
# Write updated build info to the package
210+
print("Writing package build info.")
211+
output_json_file = package_dir / "BUILD-INFO.json"
212+
with output_json_file.open("w", encoding="utf-8") as f:
213+
json.dump(build_info, f, indent=2)
214+
f.write("\n") # Ensure the file ends with a newline
215+
run(["cat", "-n", output_json_file])
216+
217+
# Format the json file in the package dir
218+
print("Formatting package build info.")
219+
run(["json-align", "--in-place", "--spaces", "2", output_json_file])
220+
run(["cat", "-n", output_json_file])
221+
222+
# -- Compress the package. We run in a shell for the '*' glob to expand.
223+
print("Compressing the package.")
224+
os.chdir(package_dir)
225+
run(f"tar zcf ../{package_filename} ./*", shell=True)
226+
227+
# -- Delete the package dir
228+
print(f"\nDeleting package dir {package_dir}")
229+
shutil.rmtree(package_dir)
230+
231+
# -- Final check
232+
os.chdir(work_dir)
233+
print(f"{Path.cwd()=}")
234+
run(["ls", "-al"])
235+
run(["ls", "-al", "_packages"])
236+
assert (Path("_packages") / package_filename).is_file()
237+
238+
# -- All done
239+
240+
241+
if __name__ == "__main__":
242+
main()

0 commit comments

Comments
 (0)