Creating Issues from AllSpice Actions

This repository demonstrates a general-purpose pattern: using an AllSpice Action to automatically create issues in one or more repositories in response to an event. A release trigger is used here as a concrete example, but the same code works with any event AllSpice Actions supports — a push, a pull request merge, a tag, a scheduled run, or a custom webhook.

It shows two implementation approaches side by side: one using the py-allspice Python wrapper, and one using direct HTTP calls to the AllSpice Hub REST API.

Why create issues from an Action?

Actions can open a tracked issue in any repository the moment something happens — no manual notification, no missed handoff. The issue is a natural place to assign an owner, attach context, and track the response. Because the issue can be opened in a different repo than the one that triggered the event, this pattern creates lightweight orchestration across teams without coupling repositories at the code level.

Ways an EE team might use this pattern

The trigger does not have to be a release. Any of these could fire the same script:

  • Release published — notify firmware, purchasing, manufacturing, and test repos that a new hardware revision is available for their review
  • Schematic review approved — open a layout kickoff issue in the PCB repo automatically when a design review closes
  • BOM exported — open a procurement issue in a purchasing repo when a BOM file is committed or updated
  • Gerber package committed — trigger a DFM review issue in a manufacturing repo when fabrication outputs land on a branch
  • Pull request merged to main — open a regression test issue in a test fixture repo whenever the schematic or layout changes
  • Component flagged as obsolete — open a redesign issue in every affected board repo when a part is marked end-of-life
  • Scheduled audit — run nightly or weekly to open issues for any repos that have gone a set period without a release or review
  • Milestone reached — open a cross-functional integration issue when a project milestone is closed
  • Tag applied — use a naming convention like bom-freeze-v2 to trigger purchasing and supply chain notifications automatically

File tree

.
├── README.md
└── .allspice/
    ├── notify-repos.txt                              # List of repos to open issues in
    ├── workflows/
    │   └── notify-repos-on-release.yml               # Action triggered on release events
    └── utils/
        ├── requirements.txt                          # Python dependencies
        ├── py-allspice-BIST.py                       # Connection smoke test
        ├── create-release-review-issues-api.py       # Method 1: raw HTTP via http.client
        └── create-release-review-issues-py-allspice.py  # Method 2: py-allspice wrapper

File descriptions

.allspice/notify-repos.txt A plain text list of AllSpice Hub repository URLs. One URL per line. When a release is published, issues are opened in every repository listed here. Lines beginning with # are ignored. See the example below.

.allspice/workflows/notify-repos-on-release.yml The Action definition. It triggers on release events (published, edited, deleted), checks out the repo, installs dependencies, runs the BIST, then runs both issue-creation scripts in sequence.

.allspice/utils/requirements.txt Pins py-allspice and typing-extensions. Both scripts depend on this.

.allspice/utils/py-allspice-BIST.py Built-In Self Test. Verifies that the PAT secret can reach the AllSpice Hub instance and authenticate before the main scripts run. If this step fails, the workflow stops early with a clear error rather than a confusing mid-script failure.

.allspice/utils/create-release-review-issues-api.py Creates issues using Python's standard http.client — no third-party HTTP library required. Handles authentication, redirects, label resolution by ID, and archive inspection directly. Produces verbose [release-review-api] prefixed log output for each HTTP exchange. Supports --issue_label to attach labels by name if they exist in the target repo.

.allspice/utils/create-release-review-issues-py-allspice.py Creates issues using the py-allspice Python wrapper. Uses Issue.create_issue() and Repository objects from the library rather than constructing endpoints manually. Label assignment is not available through the py-allspice high-level API and is omitted. Produces verbose [release-review-pyallspice] prefixed log output.


User story: Alice (py-allspice)

Alice is a systems engineer who is comfortable with Python and wants to automate release notifications across her team's repositories. She has heard of py-allspice and wants to use its high-level API rather than writing raw HTTP code.

Where she is now

Alice copies this repository's .allspice folder into her hardware design repo. She edits notify-repos.txt to list her downstream repos (firmware, purchasing, test). She sets a PAT secret in her repository settings with a token that has write access to those repos. On her next release, the Action runs create-release-review-issues-py-allspice.py, which:

  1. Calls allspice.get_repository() to load each target repository as a Repository object
  2. Calls Issue.create_issue(allspice_client, repository, title, body) to open the issue
  3. Logs each step with a [release-review-pyallspice] prefix so she can trace the run in the Actions tab

The issue body includes the release tag, title, body text, and a file manifest from the release zip.

Next steps for Alice

  • Review the py-allspice API reference to add label assignment once that is supported, or extend the script with allspice.requests_post for label calls in the meantime
  • Add milestone assignment or assignees to the Issue.create_issue call
  • Extend the issue body template in format_issue_body() to include BOM summary or component counts from the release assets

User story: Bob (direct API)

Bob is a firmware engineer who prefers to keep dependencies minimal and wants full visibility into every HTTP exchange. He does not want a wrapper library between his script and the API.

Where he is now

Bob uses create-release-review-issues-api.py, which uses only Python's standard library (http.client, json, zipfile). It:

  1. Resolves each target repository from notify-repos.txt
  2. Fetches the release metadata from the AllSpice API to get the attached asset list
  3. Downloads each .zip asset and lists its contents for the issue body
  4. Resolves label names to IDs with a paginated labels GET before creating the issue
  5. POSTs the issue to each target repo and logs the full HTTP response code, content type, and byte count

Every request is logged with a sequential HTTP request ID so Bob can match log lines to API calls in the Swagger UI when debugging.

Next steps for Bob

  • Replace the --issue_label "priority/5- critical" argument in the workflow with a label that exists in his target repositories, or remove it if labels are not needed
  • Extend format_issue_body() to parse zip contents and call out specific file types (e.g. Gerber, BOM, netlist) with custom messaging per type
  • Add a deleted release handler that closes the previously created issue rather than opening a new one

Example notify-repos.txt with multiple targets

# Firmware team — needs the Gerber and BOM for each hardware release
https://hub.allspice.io/acme-corp/firmware-main.git

# Purchasing — tracks BOM changes across releases
https://hub.allspice.io/acme-corp/purchasing-tracker.git

# Test engineering — monitors release assets for test fixture updates
https://hub.allspice.io/acme-corp/test-fixtures.git

# Manufacturing — needs final Gerber packages
https://hub.allspice.io/acme-corp/manufacturing-handoff.git

The scripts accept any AllSpice Hub URL format: full HTTPS URL, SSH git@ URL, or bare owner/repo path. Lines beginning with # are treated as comments.


References

Description
No description provided
Readme 48 KiB
2026-06-04 22:41:48 +00:00