Skip to content

Commit

Permalink
Generate YEAR.json automatically and publish to artifactory (wpilibsu…
Browse files Browse the repository at this point in the history
  • Loading branch information
rzblue authored Dec 16, 2024
1 parent 25235df commit 1751582
Show file tree
Hide file tree
Showing 5 changed files with 270 additions and 1 deletion.
36 changes: 36 additions & 0 deletions .github/workflows/generate_bundles.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
name: Generate + Publish Bundles

on:
push:
pull_request:

jobs:
generate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: '3.12'
- run: python generate_year_bundles.py -o bundles 2024 2025
- uses: actions/upload-artifact@v4
with:
name: bundles
path: bundles
retention-days: 1

publish:
if: github.repository == 'wpilibsuite/vendor-json-repo' && github.ref == 'refs/heads/main'
needs: [generate]
runs-on: ubuntu-latest
steps:
- uses: jfrog/setup-jfrog-cli@v4
with:
disable-auto-build-publish: true
env:
JF_ENV_1: ${{ secrets.ARTIFACTORY_CLI_SECRET }}
- uses: actions/download-artifact@v4
with:
name: bundles
path: bundles
- run: jf rt upload "bundles/(*)" "vendordeps/vendordep-marketplace/{1}" --sync-deletes "vendordeps/vendordep-marketplace/" --quiet
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
*.sw?

bazel-*
user.bazelrc
user.bazelrc

bundles
62 changes: 62 additions & 0 deletions 2024_metadata.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
[
{
"uuid": "e995de00-2c64-4df5-8831-c1441420ff19",
"name": "CTRE-Phoenix (v6)",
"description": "CTR-Electronics Phoenix 6 framework",
"website": "https://v6.docs.ctr-electronics.com/en/latest/index.html"
},
{
"uuid": "ab676553-b602-441f-a38d-f1296eff6537",
"name": "CTRE-Phoenix (v5)",
"description": "CTR-Electronics Phoenix 5 framework",
"website": "https://v5.docs.ctr-electronics.com/en/latest/index.html"
},
{
"uuid": "3f48eb8c-50fe-43a6-9cb7-44c86353c4cb",
"name": "REVLib",
"description": "REV Robotics REVLib C++/Java",
"website": "https://docs.revrobotics.com/brushless/spark-max/revlib"
},
{
"uuid": "287cff6e-1b60-4412-8059-f6834fb30e30",
"name": "ChoreoLib",
"description": "A graphical tool for planning time-optimized trajectories for autonomous mobile robots in the FIRST Robotics Competition.",
"website": "https://github.com/SleipnirGroup/Choreo"
},
{
"uuid": "cb311d09-36e9-4143-a032-55bb2b94443b",
"name": "NavX",
"description": "navX2-MXP includes software which makes navX2-MXP easier to understand, integrate and use with FIRST FRC and FTC robots",
"website": "https://pdocs.kauailabs.com/navx-mxp/software/roborio-libraries/"
},
{
"uuid": "1b42324f-17c6-4875-8e77-1c312bc8c786",
"name": "PathplannerLib",
"description": "PathPlanner is a motion profile generator for FRC robots created by team 3015.",
"website": "https://pathplanner.dev/home.html"
},
{
"uuid": "515fe07e-bfc6-11fa-b3de-0242ac130004",
"name": "PhotonLib",
"description": "PhotonVision is the free, fast, and easy-to-use vision processing solution for the FIRST Robotics Competition.",
"website": "https://docs.photonvision.org/en/latest/docs/programming/photonlib/adding-vendordep.html"
},
{
"uuid": "14b8ad04-24df-11ea-978f-2e728ce88125",
"name": "playingwithfusion",
"description": "This library supports the Venom motor/controller as well as the CAN enabled Time of Flight sensor.",
"website": "https://www.playingwithfusion.com/docview.php?docid=1205"
},
{
"uuid": "151ecca8-670b-4026-8160-cdd2679ef2bd",
"name": "ReduxLib",
"description": "To make performant and open products at affordable costs to teams.",
"website": "https://docs.reduxrobotics.com/reduxlib"
},
{
"uuid": "1ccce5a4-acd2-4d18-bca3-4b8047188400",
"name": "yagsl",
"description": "YAGSL is a Swerve Library Developed by current and former BroncBotz mentors for all FRC Teams.",
"website": "https://yagsl.gitbook.io/yagsl"
}
]
68 changes: 68 additions & 0 deletions 2025_metadata.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
[
{
"uuid": "cb311d09-36e9-4143-a032-55bb2b94443b",
"name": "Studica",
"description": "Libraries for NavX-MXP and NavX-Micro",
"website": "https://pdocs.kauailabs.com/navx-mxp/software/roborio-libraries/"
},
{
"uuid": "e995de00-2c64-4df5-8831-c1441420ff19",
"name": "CTRE-Phoenix (v6)",
"description": "Libraries for Phoenix 6 devices",
"website": "https://docs.ctr-electronics.com/"
},
{
"uuid": "e7900d8d-826f-4dca-a1ff-182f658e98af",
"name": "CTRE-Phoenix Replay (v6)",
"description": "Libraries for Phoenix 6 devices with Hoot Replay",
"website": "https://docs.ctr-electronics.com/"
},
{
"uuid": "ab676553-b602-441f-a38d-f1296eff6537",
"name": "CTRE-Phoenix (v5)",
"description": "Libraries for Phoenix 5 devices",
"website": "https://docs.ctr-electronics.com/"
},
{
"uuid": "1b42324f-17c6-4875-8e77-1c312bc8c786",
"name": "PathplannerLib",
"description": "PathPlanner's powerful robot-side vendor library",
"website": "https://pathplanner.dev/pathplannerlib.html"
},
{
"uuid": "65592ce1-2251-4a31-8e4b-2df20dacebe4",
"name": "DogLog",
"description": "Simpler logging for FRC",
"website": "https://doglog.dev/"
},
{
"uuid": "3f48eb8c-50fe-43a6-9cb7-44c86353c4cb",
"name": "REVLib",
"description": "Library for all REV devices including SPARK Flex, SPARK MAX, and Color Sensor V3",
"website": "https://docs.revrobotics.com/brushless/revlib/revlib-overview"
},
{
"uuid": "84246d17-a797-4d1e-bd9f-c59cd8d2477c",
"name": "URCL",
"description": "Unofficial REV-Compatible Logger for AdvantageScope",
"website": "https://docs.advantagescope.org/more-features/urcl"
},
{
"uuid": "151ecca8-670b-4026-8160-cdd2679ef2bd",
"name": "ReduxLib",
"description": "Redux Robotics 2025 Beta",
"website": "https://docs.reduxrobotics.com/reduxlib"
},
{
"uuid": "c39481e8-4a63-4a4c-9df6-48d91e4da37b",
"name": "maplesim",
"description": "FRC Java Robot Simulation using a physics engine",
"website": "https://github.com/Shenzhen-Robotics-Alliance/maple-sim"
},
{
"uuid": "1ccce5a4-acd2-4d18-bca3-4b8047188400",
"name": "Yet Another Generic Swerve Library (YAGSL)",
"description": "YAGSL (Yet Another Generic Swerve Library) is an open-source robotics library designed to simplify and optimize the control, simulation, and configuration of swerve drive systems of all types.",
"website": "https://yagsl.gitbook.io/yagsl"
}
]
101 changes: 101 additions & 0 deletions generate_year_bundles.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
import argparse
import json
import shutil
from pathlib import Path


def check_metadata_schema(metadata: list[dict]):
required_keys = {"uuid", "name", "website", "description"}
for entry in metadata:
# no nested types, so just check root keys
if not required_keys.issubset(entry.keys()):
raise KeyError(
f"Missing one or more required keys: {required_keys - entry.keys()}, metadata listing: {entry}"
)


def load_metadata(file: Path) -> dict[str, dict]:
json_metadata = json.loads(file.read_text())
check_metadata_schema(json_metadata)
out = {}
for entry in json_metadata:
out[entry["uuid"]] = entry
return out


def generate_entry(
file: Path, path_prefix: str, metadata_database: dict[str, dict]
) -> dict[str, str]:
vendordep_data = json.loads(file.read_text())
if path_prefix and not path_prefix.endswith("/"):
path_prefix += "/"
uuid = vendordep_data["uuid"]
if uuid not in metadata_database.keys():
raise KeyError(f"UUID for {file} not found in metadata.")
metadata = metadata_database[uuid]
# Metadata schemas have already been checked for required keys, so we can just add all the values to the output
# This allows optional keys to be added as necessary without changing generation
return metadata | {
"path": path_prefix + file.name,
"version": vendordep_data["version"],
}


def generate_manifest_file(
json_files: list[Path], metadata_file: Path, path_prefix: str, outfile: Path
):
"""Generates a manifest for all vendordep json files in json_files."""
metadata_database = load_metadata(metadata_file)
entries = []
for file in json_files:
entries.append(generate_entry(file, path_prefix, metadata_database))
outfile.write_text(json.dumps(entries, indent=2), newline="\n")


def generate_bundle(year: str, root: Path, outdir: Path):
"""Generates a 'bundle' consisting of a YEAR.json manifest and a directory named YEAR containing all of the vendordep files
Requires a metadata file YEAR_metadata.json, and a directory named YEAR containing the input vendordeps.
"""
json_dir = root / year
metadata = root / f"{year}_metadata.json"
path_prefix = year
outdir.mkdir(parents=True, exist_ok=True)

manifest_file = Path(outdir) / f"{year}.json"
vendordeps = [file for file in json_dir.glob("*.json")]

generate_manifest_file(vendordeps, metadata, path_prefix, manifest_file)

# Copy all vendordeps to outdir/YEAR
depsdir = outdir / year
depsdir.mkdir(exist_ok=True)
for file in vendordeps:
shutil.copy(file, depsdir)


def main():
parser = argparse.ArgumentParser(
"Generates one or more vendordep repository bundles for publication"
)
parser.add_argument(
"--output", "-o", type=Path, help="Directory to place the output bundles in"
)
parser.add_argument(
"--root",
"-r",
type=Path,
default=Path(),
help="Root directory to find metadata files and year folders. Defaults to '.'",
)
parser.add_argument(
"year", nargs="+", type=str, help="Years to generate bundles for"
)
args = parser.parse_args()

for year in args.year:
generate_bundle(year, args.root, args.output)


if __name__ == "__main__":
main()

0 comments on commit 1751582

Please sign in to comment.