Skip to content

Commit 95c1570

Browse files
authored
Merge pull request #105 from opsmill/pmc-20251220-release
docs: add release publishing documentation to README
2 parents b39462e + 7aebf75 commit 95c1570

File tree

1 file changed

+181
-0
lines changed

1 file changed

+181
-0
lines changed

README.md

Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,184 @@
1515
Infrahub Sync is a versatile Python package that synchronizes data between a source and a destination system. It builds on the robust capabilities of `diffsync` to offer flexible and efficient data synchronization across different platforms, including Netbox, Nautobot, and Infrahub. This package features a Typer-based CLI for ease of use, supporting operations such as listing available sync projects, generating diffs, and executing sync processes.
1616

1717
For comprehensive documentation on using Infrahub Sync, visit the [official Infrahub Sync documentation](https://docs.infrahub.app/sync/)
18+
19+
## Publishing a Release
20+
21+
This section documents how to publish new releases of `infrahub-sync` to PyPI.
22+
23+
### Overview
24+
25+
The project uses an automated release system powered by GitHub Actions. There are three ways to publish a release:
26+
27+
1. **Automated Release** (recommended for regular releases)
28+
2. **Manual GitHub Release** (for controlled releases)
29+
3. **Manual Workflow Dispatch** (for emergency or custom releases)
30+
31+
### Prerequisites
32+
33+
Before publishing, ensure:
34+
35+
- You have write access to the repository
36+
- The `PYPI_TOKEN` secret is configured in repository settings
37+
- The `GH_INFRAHUB_BOT_TOKEN` secret is configured (for automated releases)
38+
39+
### Method 1: Automated Release (Recommended)
40+
41+
This is the standard release flow. Releases are triggered automatically when PRs are merged to `main` or `stable` branches.
42+
43+
#### Step 1: Label Your Pull Requests
44+
45+
Apply appropriate labels to PRs before merging. Labels determine the version bump:
46+
47+
| Label | Version Bump | Use When |
48+
| ---------------------------------------------------------------------- | ---------------------- | ---------------------------- |
49+
| `changes/major`, `type/breaking-change` | Major (1.0.0 → 2.0.0) | Breaking API changes |
50+
| `changes/minor`, `type/feature`, `type/refactoring` | Minor (1.0.0 → 1.1.0) | New features, refactoring |
51+
| `changes/patch`, `type/bug`, `type/housekeeping`, `type/documentation` | Patch (1.0.0 → 1.0.1) | Bug fixes, docs, maintenance |
52+
53+
Auto-labeling rules are configured in `.github/release-drafter.yml` but require a separate
54+
workflow trigger to activate. For now, apply labels manually:
55+
56+
| PR Title Pattern | Recommended Label |
57+
| ---------------------------------------- | ------------------- |
58+
| Contains `fix` | `type/bug` |
59+
| Contains `enhance`, `improve`, `feature` | `type/feature` |
60+
| Contains `chore` | `ci/skip-changelog` |
61+
| Contains `deprecat` | `type/deprecated` |
62+
63+
#### Step 2: Merge to Main
64+
65+
Merge your labeled PR to the `main` branch. The automation will:
66+
67+
1. Calculate the next version based on PR labels
68+
2. Update `pyproject.toml` with the new version (and regenerate `poetry.lock`)
69+
3. Commit changes as `chore(release): v{VERSION} [skip ci]`
70+
4. Create/update a draft GitHub Release with auto-generated release notes
71+
72+
#### Step 3: Publish the GitHub Release
73+
74+
1. Navigate to the repository's **Releases** page
75+
2. Find the draft release created by Release Drafter
76+
3. Review the auto-generated release notes
77+
4. Edit if needed (add context, highlights, migration notes)
78+
5. Click **Publish release**
79+
80+
Publishing the release triggers the PyPI upload automatically.
81+
82+
### Method 2: Manual GitHub Release
83+
84+
Use this method when you want full control over the release timing and notes.
85+
86+
#### Step 1: Update the Version
87+
88+
Update the version in `pyproject.toml`:
89+
90+
```bash
91+
poetry version <major|minor|patch|X.Y.Z>
92+
poetry lock
93+
```
94+
95+
Commit and push the changes:
96+
97+
```bash
98+
git add pyproject.toml poetry.lock
99+
git commit -m "chore(release): v$(poetry version -s)"
100+
git push origin main
101+
```
102+
103+
#### Step 2: Create a GitHub Release
104+
105+
1. Go to **Releases****Draft a new release**
106+
2. Click **Choose a tag** and create a new tag matching your version (e.g., `1.6.0`)
107+
3. Set the target to `main` branch
108+
4. Add a release title (e.g., `1.6.0`)
109+
5. Write release notes describing the changes
110+
6. Click **Publish release**
111+
112+
This triggers the `trigger-release.yml` workflow, which publishes to PyPI.
113+
114+
### Method 3: Manual Workflow Dispatch
115+
116+
Use this for emergency releases or when you need to bypass the standard flow.
117+
118+
#### Via GitHub UI
119+
120+
1. Go to **Actions****Publish Infrahub Sync Package**
121+
2. Click **Run workflow**
122+
3. Configure the inputs:
123+
- `version`: The version string (e.g., `1.6.0`) - optional, for labeling
124+
- `publish`: Set to `true` to publish to PyPI (default: `false`)
125+
- `runs-on`: OS for the runner (default: `ubuntu-22.04`)
126+
4. Click **Run workflow**
127+
128+
#### Via GitHub CLI
129+
130+
```bash
131+
gh workflow run workflow-publish.yml \
132+
--field version="1.6.0" \
133+
--field publish=true
134+
```
135+
136+
**Important:** When using workflow dispatch, ensure `pyproject.toml` already has the correct version, as this method builds from the current code state.
137+
138+
### Release Notes
139+
140+
Release notes are auto-generated based on merged PRs and their labels:
141+
142+
| Category | Labels |
143+
| -------------------- | --------------------------------------------------- |
144+
| Breaking Changes | `changes/major` |
145+
| Minor Changes | `changes/minor`, `type/feature`, `type/refactoring` |
146+
| Patch & Bug Fixes | `type/bug`, `changes/patch` |
147+
| Documentation Change | `type/documentation` |
148+
149+
PRs with these labels are excluded from release notes:
150+
151+
- `ci/skip-changelog`
152+
- `type/duplicate`
153+
154+
### Verifying a Release
155+
156+
After publishing:
157+
158+
1. **Check PyPI**: Visit [pypi.org/project/infrahub-sync](https://pypi.org/project/infrahub-sync/) to confirm the new version is available
159+
2. **Check GitHub Actions**: Ensure the publish workflow completed successfully
160+
3. **Test Installation**:
161+
162+
```bash
163+
pip install infrahub-sync==<new-version>
164+
infrahub-sync --version
165+
```
166+
167+
### Troubleshooting
168+
169+
#### Release workflow skipped
170+
171+
The automated release is skipped when:
172+
173+
- The commit author is `opsmill-bot` with a `chore` prefix (prevents recursive releases)
174+
- No version bump is detected (no labeled PRs since last release)
175+
- Changes are only in the `docs/` directory
176+
177+
#### PyPI upload failed
178+
179+
Common causes:
180+
181+
- `PYPI_TOKEN` secret is missing or invalid
182+
- Version already exists on PyPI (versions cannot be overwritten)
183+
- Network issues during upload
184+
185+
To retry, use the manual workflow dispatch method.
186+
187+
#### Version not bumped correctly
188+
189+
Ensure PRs have appropriate labels before merging. If labels are missing, the version drafter may not calculate a new version.
190+
191+
### Workflow Files Reference
192+
193+
| Workflow | Type | Purpose |
194+
| ------------------------------ | ------------------------------ | ------------------------------------------------------------------------ |
195+
| `trigger-push-stable.yml` | Push to `main`/`stable` | Calculates version, bumps `pyproject.toml`, triggers release draft |
196+
| `workflow-release-drafter.yml` | Reusable (`workflow_call`) | Creates/updates GitHub Release draft; invoked by `trigger-release.yml` |
197+
| `trigger-release.yml` | GitHub Release published | Orchestrates release: invokes release drafter and publish workflows |
198+
| `workflow-publish.yml` | Reusable (`workflow_dispatch`) | Builds and publishes package to PyPI; invoked by `trigger-release.yml` |

0 commit comments

Comments
 (0)