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 #!/usr/bin/env python3
# Generate a BOM from a PrjPcb file.
# For more information, read the README file in this directory.
import argparse import argparse
import csv
import os import os
import yaml
import sys import sys
from contextlib import ExitStack import json
from allspice import AllSpice 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__": if __name__ == "__main__":
parser = argparse.ArgumentParser( 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( parser.add_argument(
"repository", help="The repo containing the project in the form 'owner/repo'" "repository", help="The repo containing the project in the form 'owner/repo'"
) )
parser.add_argument( parser.add_argument(
"source_file", "source_file",
help=( help="The path to the source file used for the task. Example: 'Archimajor.PrjPcb', 'Schematics/Beagleplay.dsn'."
"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'."
),
) )
parser.add_argument( parser.add_argument(
"--columns", "--task_type",
help=( help="The type of hardware task to perform. Options include 'Schematic-Review', 'PCB-Review', 'ECO-Review', 'Release'.",
"A path to a YAML file mapping columns to the attributes they are from. See the README " default="Schematic-Review",
"for more details. Defaults to 'columns.yml'."
),
default="columns.yml",
) )
parser.add_argument( parser.add_argument(
"--source_ref", "--source_ref",
help=( help="The git reference the task should be performed for (eg. branch name, tag name, commit SHA).",
"The git reference the BOM should be generated for (eg. branch name, tag name, commit "
"SHA). Defaults to the main branch."
),
default="main", 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( parser.add_argument(
"--allspice_hub_url", "--allspice_hub_url",
help="The URL of your AllSpice Hub instance. Defaults to https://hub.allspice.io.", help="The URL of your AllSpice Hub instance. Defaults to https://hub.allspice.io.",
default="https://hub.allspice.io",
) )
parser.add_argument( parser.add_argument(
"--output_file", "--allspice_token",
help="The path to the output file. If absent, the CSV will be output to the command line.", help="Your AllSpice application token. Generate a token: https://hub.allspice.io/user/settings/applications",
)
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."
),
) )
args = parser.parse_args() args = parser.parse_args()
columns_file = args.columns auth_token = os.environ.get("GITHUB_TOKEN") or args.allspice_token
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")
if auth_token is None: 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) exit(1)
if args.allspice_hub_url is None: # Test connection to AllSpice API
allspice = AllSpice(token_text=auth_token) test_allspice_connection(args.allspice_hub_url, auth_token)
else:
allspice = AllSpice(token_text=auth_token, allspice_hub_url=args.allspice_hub_url)
repo_owner, repo_name = args.repository.split("/") # Perform the Hello World task
repository = allspice.get_repository(repo_owner, repo_name) hello_world(
group_by = args.group_by.split(",") if args.group_by else None task_type=args.task_type,
source_file=args.source_file,
print("Generating BOM...", file=sys.stderr) output_file=args.output_file,
additional_params=args.additional_params,
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,
) )
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)