Skip to content

Commit 235dc41

Browse files
committed
refactor: convert post-release-status to pure function design
- All parameters now passed explicitly from GitHub Action - No environment variable dependencies in script - is-production flag determines release type (not tag pattern) - package-name parameter for flexibility - Improved testability with pure function approach - Updated tests to match new design - Decision logic moved to GitHub Action
1 parent ba7592d commit 235dc41

File tree

4 files changed

+165
-317
lines changed

4 files changed

+165
-317
lines changed

.github/actions/create-release/action.yml

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -127,14 +127,21 @@ runs:
127127

128128
- name: Post release status
129129
shell: bash
130-
env:
131-
GITHUB_TOKEN: ${{ github.token }}
132130
run: |
131+
# Determine if this is a production release
132+
IS_PRODUCTION="true"
133+
if [[ "${{ inputs.package-version }}" == *"-dev-"* ]] || [[ "${{ inputs.package-version }}" == *"-dev" ]]; then
134+
IS_PRODUCTION="false"
135+
fi
136+
133137
uv run python scripts/post_release_status.py \
134138
--version "${{ inputs.package-version }}" \
135139
--release-url "${{ steps.create-release.outputs.url }}" \
136140
--pypi-url "${{ steps.package-urls.outputs.pypi-url }}" \
137141
--docker-image "${{ steps.docker-info.outputs.image-uri }}" \
138142
--release-id "${{ steps.create-release.outputs.id }}" \
139143
--sha "${{ github.sha }}" \
140-
--repo "${{ github.repository }}"
144+
--repo "${{ github.repository }}" \
145+
--github-token "${{ github.token }}" \
146+
--is-production "${IS_PRODUCTION}" \
147+
--package-name "quilt-mcp-server"

scripts/post_release_status.py

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,11 @@ def generate_release_comment(
2222
release_url: str,
2323
pypi_url: str,
2424
docker_image: Optional[str] = None,
25+
is_production: bool = True,
26+
package_name: str = "quilt-mcp-server",
2527
) -> str:
2628
"""Generate the release status comment body."""
27-
is_prod = "-dev-" not in version
29+
# Use the is_production flag passed explicitly
2830

2931
body = f"## 🚀 Release Status for v{version}\n\n"
3032
body += "### 📦 Package Locations\n\n"
@@ -39,19 +41,19 @@ def generate_release_comment(
3941
body += "```\n"
4042

4143
body += "\n### 📥 Installation\n"
42-
if is_prod:
44+
if is_production:
4345
body += "```bash\n"
4446
body += "# Install from PyPI\n"
45-
body += f"pip install quilt-mcp-server=={version}\n"
47+
body += f"pip install {package_name}=={version}\n"
4648
body += "# or\n"
47-
body += f"uv add quilt-mcp-server=={version}\n"
49+
body += f"uv add {package_name}=={version}\n"
4850
body += "```\n"
4951
else:
5052
body += "```bash\n"
5153
body += "# Install from TestPyPI\n"
52-
body += f"pip install -i https://test.pypi.org/simple/ quilt-mcp-server=={version}\n"
54+
body += f"pip install -i https://test.pypi.org/simple/ {package_name}=={version}\n"
5355
body += "# or\n"
54-
body += f"uv add --index https://test.pypi.org/simple/ quilt-mcp-server=={version}\n"
56+
body += f"uv add --index https://test.pypi.org/simple/ {package_name}=={version}\n"
5557
body += "```\n"
5658

5759
return body
@@ -258,6 +260,8 @@ def main():
258260
release_url=args.release_url,
259261
pypi_url=args.pypi_url,
260262
docker_image=args.docker_image,
263+
is_production=args.is_production,
264+
package_name=args.package_name,
261265
)
262266

263267
if args.dry_run:
@@ -267,13 +271,7 @@ def main():
267271

268272
# PRIMARY GOAL: Update release notes if release-id is provided
269273
if args.release_id:
270-
if not args.github_token:
271-
print("Error: GitHub token required to update release notes", file=sys.stderr)
272-
return 1
273-
274-
if not args.repo:
275-
print("Error: Repository required to update release notes", file=sys.stderr)
276-
return 1
274+
# All required parameters are already validated by argparse
277275

278276
# Format content for release notes (add separator)
279277
release_notes_content = f"\n---\n\n{status_content}"
@@ -294,15 +292,15 @@ def main():
294292
# SECONDARY GOAL: Post PR comment if possible (failure = graceful continue)
295293
pr_number = args.pr_number
296294

297-
if not pr_number and args.sha and args.github_token:
295+
if not pr_number and args.sha:
298296
# Try to find PR from SHA
299297
pr_number = find_pr_for_sha(
300298
github_token=args.github_token,
301299
repo=args.repo,
302300
sha=args.sha,
303301
)
304302

305-
if pr_number and args.github_token and args.repo:
303+
if pr_number:
306304
# Attempt to post PR comment
307305
pr_success = post_comment_to_pr(
308306
github_token=args.github_token,

spec/feature-docker-container/14-post-release-status.md

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,22 @@ When a development tag (`v*-dev-*`) is pushed:
4343
3. **Update the release notes** with formatted status information
4444
4. Attempt to find associated PR and post comment
4545

46+
## Design Philosophy
47+
48+
### Pure Function Approach
49+
50+
The post-release status script follows a pure function design:
51+
- All parameters are passed explicitly from the GitHub Action
52+
- No environment variable dependencies (except GITHUB_TOKEN for API calls)
53+
- No implicit behavior based on tag patterns or environment
54+
- All decision logic happens in the GitHub Action, not the script
55+
- Script focuses solely on formatting and posting status
56+
57+
This design ensures:
58+
- Testability: All behavior can be tested with explicit inputs
59+
- Predictability: No hidden dependencies or side effects
60+
- Maintainability: Clear separation between orchestration (action) and execution (script)
61+
4662
## Implementation Requirements
4763

4864
### Release Notes Update (Primary)
@@ -128,16 +144,18 @@ The `create-release` action should output:
128144

129145
### Script Parameters
130146

131-
The `post_release_status.py` script should accept:
147+
The `post_release_status.py` script should accept ALL parameters explicitly (pure function design):
132148

133149
- `--release-id`: GitHub release ID for updating notes
134150
- `--version`: Package version
135151
- `--release-url`: GitHub release URL
136152
- `--pypi-url`: PyPI package URL
137153
- `--docker-image`: Docker image URI (optional)
138154
- `--sha`: Git SHA for PR detection (optional)
139-
- `--repo`: Repository identifier
155+
- `--repo`: Repository identifier (owner/repo format)
140156
- `--github-token`: API token
157+
- `--is-production`: Boolean flag for production vs development release
158+
- `--package-name`: Package name for display (e.g., "quilt-mcp-server")
141159

142160
### Workflow Steps
143161

@@ -159,7 +177,10 @@ The `post_release_status.py` script should accept:
159177
--pypi-url "${{ steps.package-urls.outputs.pypi-url }}" \
160178
--docker-image "${{ steps.docker-info.outputs.image-uri }}" \
161179
--sha "${{ github.sha }}" \
162-
--repo "${{ github.repository }}"
180+
--repo "${{ github.repository }}" \
181+
--github-token "${{ github.token }}" \
182+
--is-production "${{ inputs.is-production }}" \
183+
--package-name "quilt-mcp-server"
163184
```
164185
165186
## Content Format

0 commit comments

Comments
 (0)