You've already forked ReleaseNotifiableRepo
133 lines
8.5 KiB
Markdown
133 lines
8.5 KiB
Markdown
# 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](https://allspiceio.github.io/py-allspice/allspice.html) Python wrapper, and one using direct HTTP calls to the [AllSpice Hub REST API](https://hub.allspice.io/api/swagger).
|
|
|
|
## 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](#example-notify-repstxt-with-multiple-targets).
|
|
|
|
**`.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](https://allspiceio.github.io/py-allspice/allspice.html) 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](https://allspiceio.github.io/py-allspice/allspice.html) 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](https://hub.allspice.io/api/swagger) 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
|
|
|
|
- [py-allspice API reference](https://allspiceio.github.io/py-allspice/allspice.html)
|
|
- [AllSpice Hub REST API (Swagger)](https://hub.allspice.io/api/swagger)
|