Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Some cleanup on the fpga releaser #300

Merged
merged 1 commit into from
Mar 5, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion tools/fpga_releaser/archive_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,14 @@
# the nextpnr log at that same directory called nextpnr.log
# all the stuff in the _maps_ directory at that same level

def get_relevant_files_from_buck_zip(zip):
def get_relevant_files_from_buck_zip(fpga_name, zip):
zip_names = []
for item in zip.infolist():
# folders use _ instead of -
if fpga_name not in item.filename and fpga_name.replace('-', '_') not in item.filename:
# filter out stuff without the fpga name in it
# (might be other projects if local build etc)
continue
if item.filename.endswith(".bz2"):
zip_names.append(item.filename)
if "/maps/" in item.filename and (item.filename.endswith(".json") or item.filename.endswith(".html")):
Expand Down
24 changes: 24 additions & 0 deletions tools/fpga_releaser/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
parser.add_argument("--branch", default="main", help="Quartz branch to use for the artifact")
parser.add_argument("--fpga", help="Name of FPGA project to release")
parser.add_argument("--hubris", default=None, help="Path to hubris git checkout as target for copying files. Will skip if None")
parser.add_argument("--local", default=False, action="store_true", help="Path to local build directory. Will skip if None")
parser.add_argument("--skip-gh", default=False, action="store_true", help="Skip doing GH release. Note that doing this still generates release metadata that just will be wrong")
parser.add_argument("--zip", default=None, help="Path to zip file to use instead of downloading from GitHub")

Expand Down Expand Up @@ -49,6 +50,15 @@ def main():
print(f"Processing {args.fpga} with builder {project_info.builder}")

# Get build archive
if args.local:
print("Using local build directory")
# make a zip file from the local build directory
zip_file = make_buck2_zip()
args.zip = str(zip_file)

if args.zip:
project_info.local = True

zip_file = process_gh_build(args, api, project_info.job_name)
project_info.add_archive(zip_file)

Expand Down Expand Up @@ -99,11 +109,25 @@ def get_latest_artifact_info(api, fpga_name: str, branch: str = "main") -> dict:
artifacts = sorted(artifacts, key=lambda x: arrow.get(x["created_at"]), reverse=True)
return artifacts[0]


def download_artifact(api: GhApi, artifact_inf: dict):
print(f"Downloading artifact {artifact_inf['name']} from GH: {artifact_inf['workflow_run']['head_branch']}")
r = requests.get(artifact_inf["archive_download_url"], auth=("oxidecomputer", os.getenv("GITHUB_TOKEN", None)))
return zipfile.ZipFile(io.BytesIO(r.content))


def make_buck2_zip():
"""
Create a zip file from the buck2 build directory.
"""
import shutil
# Create object of ZipFile
zipfile_path = Path.cwd() / Path("buck_out.zip")
folder = Path.cwd() / "buck-out" / "v2" / "gen" / "root"
shutil.make_archive(zipfile_path.with_suffix(''), 'zip', folder)
return zipfile_path


if __name__ == '__main__':
main()

Expand Down
2 changes: 1 addition & 1 deletion tools/fpga_releaser/config.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[cosmo-hp]
job_name = "cosmo-hp-image"
hubris_path = "drv/ice40-loader/cosmo-hp"
hubris_path = "drv/cosmo-seq-server/cosmo-hp"
builder = "buck2"
toolchain = "yosys"

Expand Down
17 changes: 10 additions & 7 deletions tools/fpga_releaser/project.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ def __init__(self, name, job_name, hubris_path, toolchain, builder):
self.gh_release_name = ""
self.gh_release_url = ""
self.gh_build_sha = ""
self.local = False

@classmethod
def from_dict(cls, fpga_name, data: dict):
Expand Down Expand Up @@ -77,7 +78,7 @@ def add_archive(self, archive: zipfile.ZipFile):
"""
self.archive = archive
if self.builder == "buck2":
self.filenames = get_relevant_files_from_buck_zip(self.archive)
self.filenames = get_relevant_files_from_buck_zip(self.name, self.archive)

def add_build_sha(self, sha):
self.gh_build_sha = sha
Expand Down Expand Up @@ -141,9 +142,13 @@ def _get_fit_report(self):
raise NotImplementedError

def make_readme_contents(self):
txt = ("FPGA images and collateral are generated from:\n"
f"[this sha](https://github.com/oxidecomputer/quartz/commit/{self.gh_build_sha})\n"
f"[release]({self.gh_release_url})")
if not self.local:
txt = ("FPGA images and collateral are generated from:\n"
f"[this sha](https://github.com/oxidecomputer/quartz/commit/{self.gh_build_sha})\n"
f"[release]({self.gh_release_url})")
else:
# This is some local build
txt = ("FPGA images and collateral are generated from some hw guy's local build\n")
return txt


Expand All @@ -154,11 +159,9 @@ def get_config(fpga_name):
with open(config_toml, "rb") as f:
config = tomli.load(f)

print(config.keys())

known_fpga = config.get(fpga_name, None)
if known_fpga is None:
raise ValueError(f"FPGA {fpga_name} not found in config.")

return FPGAImage.from_dict(fpga_name, config)