Create boilerplate template from example #1

Merged
AllSpiceAlice merged 11 commits from dd/dev into main 2024-07-22 01:14:25 +00:00
5 changed files with 79 additions and 88 deletions
Showing only changes of commit 9ddef54109 - Show all commits

View File

@ -0,0 +1 @@
# Mock config yaml file

View File

@ -0,0 +1 @@
Mock input file

View File

@ -0,0 +1,22 @@
name: Hardware DevOps Workflow
on: [push, pull_request]
jobs:
hardware-devops:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Run Hardware DevOps Action
uses: ./
with:
source_path: "path/to/source_file"
output_file_name: "output.txt"
config_file: "path/to/config_file"
task_type: "Schematic-Review"
additional_params: '{"SCH_VER":"3"}'
env:
ALLSPICE_TOKEN: ${{ secrets.ALLSPICE_TOKEN }}

View File

@ -1,123 +1,90 @@
#!/usr/bin/env python3
# Generate a BOM from a PrjPcb file.
# For more information, read the README file in this directory.
import argparse
import csv
import os
import yaml
import sys
from contextlib import ExitStack
import json
from allspice import AllSpice
from allspice.utils.bom_generation import generate_bom
def hello_world(task_type, source_file, output_file, additional_params):
print(f"Hello, World! Performing task: {task_type}")
print(f"Source file: {source_file}")
print(f"Output file: {output_file}")
print(f"Additional parameters: {additional_params}")
# Parse additional_params
params = json.loads(additional_params)
sch_ver = params.get("SCH_VER", "3")
print(f"Schematic version: {sch_ver}")
def test_allspice_connection(allspice_hub_url, auth_token):
try:
allspice = AllSpice(token_text=auth_token, allspice_hub_url=allspice_hub_url)
print("AllSpice Version: " + allspice.get_version())
print("API-Token belongs to user: " + allspice.get_user().username)
except Exception as e:
print(f"Error connecting to AllSpice API: {e}")
sys.exit(1)
if __name__ == "__main__":
parser = argparse.ArgumentParser(
prog="generate_bom", description="Generate a BOM from a project repository."
prog="hardware_devops_action",
description="Perform hardware development tasks such as Schematic-Review, PCB-Review, ECO-Review, and Release."
)
parser.add_argument(
"repository", help="The repo containing the project in the form 'owner/repo'"
)
parser.add_argument(
"source_file",
help=(
"The path to the source file used to generate the BOM. If this is an Altium project, "
"this should be the .PrjPcb file. For an OrCAD project, this should be the .dsn file. "
"Example: 'Archimajor.PrjPcb', 'Schematics/Beagleplay.dsn'."
),
help="The path to the source file used for the task. Example: 'Archimajor.PrjPcb', 'Schematics/Beagleplay.dsn'."
)
parser.add_argument(
"--columns",
help=(
"A path to a YAML file mapping columns to the attributes they are from. See the README "
"for more details. Defaults to 'columns.yml'."
),
default="columns.yml",
"--task_type",
help="The type of hardware task to perform. Options include 'Schematic-Review', 'PCB-Review', 'ECO-Review', 'Release'.",
default="Schematic-Review",
)
parser.add_argument(
"--source_ref",
help=(
"The git reference the BOM should be generated for (eg. branch name, tag name, commit "
"SHA). Defaults to the main branch."
),
help="The git reference the task should be performed for (eg. branch name, tag name, commit SHA).",
default="main",
)
parser.add_argument(
"--server_url",
help="The URL of your GitHub server instance.",
)
parser.add_argument(
"--output_file",
help="The path to the output file. If absent, the output will be printed to the command line.",
)
parser.add_argument(
"--additional_params",
help="Any additional parameters required for the task, provided as a JSON string.",
default="{}",
)
parser.add_argument(
"--allspice_hub_url",
help="The URL of your AllSpice Hub instance. Defaults to https://hub.allspice.io.",
default="https://hub.allspice.io",
)
parser.add_argument(
"--output_file",
help="The path to the output file. If absent, the CSV will be output to the command line.",
)
parser.add_argument(
"--group_by",
help=(
"A comma-separated list of columns to group the BOM by. If not present, the BOM will "
"be flat."
),
)
parser.add_argument(
"--variant",
help=(
"The variant of the project to generate the BOM for. If not present, the BOM will be "
"generated for the default variant. This is not used for OrCAD projects."
),
"--allspice_token",
help="Your AllSpice application token. Generate a token: https://hub.allspice.io/user/settings/applications",
)
args = parser.parse_args()
columns_file = args.columns
columns = {}
try:
with open(columns_file, "r") as f:
columns_data = yaml.safe_load(f.read())
for column_value in columns_data["columns"]:
columns[column_value["name"]] = column_value["part_attributes"]
except KeyError as e:
print(f"Error: columns file {columns_file} does not seem to be in the right format.")
print("Please refer to the README for more information.")
print(f"Caused by: {e}")
sys.exit(1)
auth_token = os.environ.get("ALLSPICE_AUTH_TOKEN")
auth_token = os.environ.get("GITHUB_TOKEN") or args.allspice_token
if auth_token is None:
print("Please set the environment variable ALLSPICE_AUTH_TOKEN")
print("Please set the environment variable GITHUB_TOKEN or supply a token with --allspice_token <your_token>. Generate a token: https://hub.allspice.io/user/settings/applications")
exit(1)
if args.allspice_hub_url is None:
allspice = AllSpice(token_text=auth_token)
else:
allspice = AllSpice(token_text=auth_token, allspice_hub_url=args.allspice_hub_url)
# Test connection to AllSpice API
test_allspice_connection(args.allspice_hub_url, auth_token)
repo_owner, repo_name = args.repository.split("/")
repository = allspice.get_repository(repo_owner, repo_name)
group_by = args.group_by.split(",") if args.group_by else None
print("Generating BOM...", file=sys.stderr)
bom_rows = generate_bom(
allspice,
repository,
args.source_file,
columns,
group_by=group_by,
ref=args.source_ref if args.source_ref else "main",
variant=args.variant if args.variant else None,
# Perform the Hello World task
hello_world(
task_type=args.task_type,
source_file=args.source_file,
output_file=args.output_file,
additional_params=args.additional_params,
)
with ExitStack() as stack:
keys = bom_rows[0].keys()
if args.output_file is not None:
f = stack.enter_context(open(args.output_file, "w"))
writer = csv.DictWriter(f, fieldnames=keys)
else:
writer = csv.DictWriter(sys.stdout, fieldnames=keys)
writer.writeheader()
writer.writerows(bom_rows)
print("Generated bom.", file=sys.stderr)