fix: make weekly release notify idempotent
Closes #238
Juan Manuel Servera committed
Jun 5, 2026 at 19:21 UTC
268f5e7dcdd05d177b51a575c24a3cff1364bac3
3 files changed
+18
-1
.github/workflows/crawl-and-publish.yml
+8
-1
@@ -771,8 +771,15 @@ jobs:
771
SUMMARY_FILE: ${{ needs.analyze.outputs.summary_file }}
772
run: |
773
WEEK=$(basename "$SUMMARY_FILE" | sed 's/-summary.md//')
774
+ TAG="week-${WEEK}"
775
+ TITLE="Week ${WEEK} — Tech Trends Summary"
776
775
- gh release create "week-${WEEK}" --title "Week ${WEEK} — Tech Trends Summary" --notes-file "$SUMMARY_FILE" --latest
777
+ if gh release view "$TAG" >/dev/null 2>&1; then
778
+ echo "::notice::Release $TAG already exists; updating it instead of failing."
779
+ gh release edit "$TAG" --title "$TITLE" --notes-file "$SUMMARY_FILE" --latest
780
+ else
781
+ gh release create "$TAG" --title "$TITLE" --notes-file "$SUMMARY_FILE" --latest
782
+ fi
783
784
- name: Post to Discussions
785
env:
.squad/agents/fry/history.md
+6
@@ -87,3 +87,9 @@
87
- Tests to add: merge helper validation (schema, dedupe, sorting, error handling), per-source failure handling, fallback paths, reproducibility gates, citation preservation.
88
- Metrics: per-source (name, host, duration, article counts, errors) and aggregate (source_count, failed_source_count, total articles, artifact size).
89
- Decision recorded in .squad/decisions.md.
90
+
91
+## Issue #238 notify triage (2026-06-05)
92
+
93
+- Run 27026348186 completed crawl, analyze, generate, and deploy successfully; only `notify` failed.
94
+- Root cause: `gh release create week-2026-W23` is not idempotent when the weekly release tag already exists, so rerunning/publishing the same week produced HTTP 422 `Release.tag_name already exists`.
95
+- QA fix: make notify update an existing weekly release with `gh release edit` instead of failing, while preserving release creation for new weeks.
tests/test_pipeline.py
+4
@@ -288,6 +288,10 @@ class WorkflowConfigTests(unittest.TestCase):
288
release_step = next((s for s in notify_job["steps"] if s.get("name") == "Create GitHub Release"), None)
289
self.assertIsNotNone(release_step)
290
self.assertEqual(release_step["env"]["SUMMARY_FILE"], "${{ needs.analyze.outputs.summary_file }}")
291
+ release_run = release_step["run"]
292
+ self.assertIn('gh release view "$TAG"', release_run)
293
+ self.assertIn('gh release edit "$TAG"', release_run)
294
+ self.assertIn('gh release create "$TAG"', release_run)
295
296
webhook_run = webhook_step["run"]
297
self.assertIn("curl -s -X POST \"$WEBHOOK_URL\"", webhook_run)