Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
133 changes: 133 additions & 0 deletions .github/workflows/test-polish-dispatch.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
name: Test Polish Dispatch

# Temporary workflow to test repository_dispatch before modifying release pipeline.
# Delete this file after validation.

on:
repository_dispatch:
types: [test-polish-notes]
workflow_dispatch:
inputs:
tag_name:
description: 'Release tag to test (e.g., v0.23.0)'
required: true
type: string

env:
# repository_dispatch passes tag via client_payload, workflow_dispatch via inputs
TAG_NAME: ${{ github.event.client_payload.tag_name || inputs.tag_name }}
Comment on lines +16 to +18
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Add a guard when TAG_NAME is missing.
If neither payload nor input is set, gh release view fails with a confusing error. A fast, explicit check will make runs clearer.

🔧 Suggested guard step
+      - name: Validate tag input
+        run: |
+          if [ -z "${{ env.TAG_NAME }}" ]; then
+            echo "TAG_NAME is required via workflow_dispatch input or repository_dispatch payload"
+            exit 1
+          fi
🤖 Prompt for AI Agents
In @.github/workflows/test-polish-dispatch.yml around lines 16 - 18, The
workflow currently sets TAG_NAME from client_payload or inputs but lacks a guard
when it's empty, causing `gh release view` to fail with a confusing error; add
an explicit guard step that checks the TAG_NAME environment variable (TAG_NAME)
before any `gh release view` or release-related steps and fails fast with a
clear message if TAG_NAME is undefined or empty so CI prints a helpful error and
stops early.


permissions:
contents: write
Comment on lines +20 to +21
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Reduce token scope to least privilege.
This dry-run only reads release data and writes local files; contents: read should be sufficient unless the Claude action actually needs write.

🔒 Suggested permission tightening
 permissions:
-  contents: write
+  contents: read
🤖 Prompt for AI Agents
In @.github/workflows/test-polish-dispatch.yml around lines 20 - 21, The
workflow currently sets GitHub Actions permissions to "contents: write"; change
this to "contents: read" to follow least-privilege principles since the job only
reads release data and writes local files, and verify any action that might
require write (e.g., the Claude-related action) actually doesn't need push-level
content permission; update the permissions block to use "contents: read" and if
you discover an action truly requires write, scope that permission as narrowly
as possible or add it only to the specific job that needs it.


jobs:
test-polish:
if: github.repository == 'Fission-AI/OpenSpec'
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4

- name: Debug context
run: |
echo "Event name: ${{ github.event_name }}"
echo "Tag name: ${{ env.TAG_NAME }}"

- name: Get current release body
id: get-release
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
gh release view "${{ env.TAG_NAME }}" --json body -q '.body' > current-notes.md
echo "Fetched release notes for ${{ env.TAG_NAME }}"
echo "--- Content preview ---"
head -20 current-notes.md

- name: Transform release notes with Claude
uses: anthropics/claude-code-action@v1
id: claude
with:
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
github_token: ${{ secrets.GITHUB_TOKEN }}
claude_args: "--allowedTools Write,Read"
Comment on lines +46 to +52
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🌐 Web query:

anthropics/claude-code-action GitHub action

💡 Result:

anthropics/claude-code-action is Anthropic’s official GitHub Action for running Claude Code inside GitHub workflows. It can answer code questions, review and modify PRs, create PRs from prompts, and integrate with Anthropic API or cloud providers (Bedrock, Vertex AI, Foundry). Key points and quick setup:

  • Repo & license: anthropics/claude-code-action (MIT). [1]
  • Features: automatic mode detection, PR/issue integration, code implementation/review, structured JSON outputs, runs on your runner. [1]
  • Docs & quickstart: Anthropic docs explain installing the Claude GitHub app, adding ANTHROPIC_API_KEY secret, or using the CLI /install-github-app. Manual setup: install https://github.com/apps/claude, add secret, copy examples/claude.yml to .github/workflows. [2]
  • Marketplace listing and example usage (workflow snippet, outputs, and the dangerous skip-permissions flag info). [3]

If you want, I can:

  • show an example workflow configured for Anthropic API or for AWS Bedrock/Google Vertex,
  • or walk through installing the GitHub app and adding secrets step-by-step. Which do you want?

🌐 Web query:

GitHub Actions security best practices pinning commit SHA vs version tag

💡 Result:

Short answer

  • Pin to a full commit SHA for maximum security (immutable, prevents tag/branch tampering). [1][2]
  • Tags (version tags) are more convenient but mutable unless the project offers immutable releases — only use tags for actions you fully trust or when the author provides immutable/attested releases. [1][2]
  • Automate safe updates (Dependabot/Renovate or tooling that updates SHAs and opens PRs) and enforce SHA pinning/org policy where practical. [1][2][3]

Why (brief)

  • Commit SHA = exact Git object; cannot be changed without changing the SHA → strong protection against covert updates. [1]
  • Tags/branches (v3, v3.1, main) can be moved or re-pointed if a repo is compromised, so workflows using them can pick up malicious changes. [1][2]
  • Organizations can enforce SHA pinning via allowed-actions policies and block specific actions/versions. [2]

Practical recommendations

  • Use commit SHAs in workflows: uses: owner/repo/path@, and add a comment with the human-friendly tag/version. [1][8]
  • Run automation to keep SHAs up to date (Dependabot for Actions, Renovate, or pinning tools) so updates are reviewed before merging. [1][3]
  • Avoid floating refs: no @main, @latest, or bare major tags unless you accept the risk. [1][5]
  • Restrict/allowlist verified creators or specific repos; use the allowed-actions policy to block unapproved actions. [1][2]
  • Audit action source code and limit workflow permissions & secrets to reduce blast radius even if an action is compromised. [1]

References

  • GitHub Security hardening for Actions (pin to full-length commit SHA; tag guidance). [1]
  • GitHub Changelog: allowed actions policy, blocklist and SHA pin enforcement features. [2]
  • Example tooling & automation to enforce/update pins (Dependabot/third-party pinning actions). [3]

🏁 Script executed:

# Check if there are other actions used in the repository and their pinning practices
cd .github/workflows
find . -name "*.yml" -o -name "*.yaml" | head -10

Repository: Fission-AI/OpenSpec

Length of output: 147


🏁 Script executed:

# Check action pinning patterns in other workflow files
cd .github/workflows
for file in *.yml; do
  echo "=== $file ==="
  grep -E "uses:" "$file" | head -5
done

Repository: Fission-AI/OpenSpec

Length of output: 697


Pin the third‑party action to a commit SHA.

This step uses a sensitive OAuth token; pinning to a commit SHA prevents tag tampering and supply-chain surprises. GitHub security guidance recommends committing full commit SHAs rather than version tags for third-party actions, particularly when handling credentials.

🔒 Suggested pinning
-      - name: Transform release notes with Claude
-        uses: anthropics/claude-code-action@v1
+      - name: Transform release notes with Claude
+        uses: anthropics/claude-code-action@<pinned-commit-sha>
🤖 Prompt for AI Agents
In @.github/workflows/test-polish-dispatch.yml around lines 46 - 52, The GitHub
Actions step "Transform release notes with Claude" currently uses the tag
anthropics/claude-code-action@v1 while passing a sensitive
claude_code_oauth_token; replace the tag with the full commit SHA for
anthropics/claude-code-action (e.g.,
anthropics/claude-code-action@<full-commit-sha>) to pin the third‑party action,
keeping the step id "claude" and the same inputs (claude_code_oauth_token,
github_token, claude_args) unchanged.

prompt: |
Transform the changelog in `current-notes.md` into release notes for OpenSpec ${{ env.TAG_NAME }}.

## Voice

OpenSpec is a developer tool. Write like you're talking to a peer:
- Direct and practical, not marketing copy
- Focus on what changed and why it matters
- Skip the hype, keep it real

## Output

Create two files:

### 1. `release-title.txt`

A short title in this format:
```
${{ env.TAG_NAME }} - [1-4 words describing the release]
```

Examples:
- `v0.18.0 - OPSX Experimental Workflow`
- `v0.16.0 - Antigravity, iFlow Support`
- `v0.15.0 - Gemini CLI, RooCode`

Rules for title:
- Lead with the most notable addition
- 1-4 words after the dash, no fluff
- If multiple features, comma-separate the top 2
- For bugfix-only releases, use something like `v0.17.2 - Pre-commit Hook Fix`

### 2. `polished-notes.md`

```markdown
## What's New in ${{ env.TAG_NAME }}

[One sentence: what's the theme of this release?]

### New

- **Feature name** - What it does and why you'd use it

### Improved

- **Area** - What got better

### Fixed

- What was broken, now works
```

Omit empty sections.

## Rules

1. Write for developers using OpenSpec with AI coding assistants
2. Remove commit hashes (like `eb152eb:`), PR numbers, and changesets wrappers (`### Minor Changes`)
3. Lead with what users can do, not implementation details
4. One to two sentences per item, max
5. Use **bold** for feature/area names
6. Skip internal changes (CI, refactors, tests) unless they affect users
7. If the input is already well-formatted, just clean up structure and remove noise

Write both files. No other output.

- name: Show results (dry run - no actual update)
run: |
echo "=== DRY RUN - Would update release ${{ env.TAG_NAME }} ==="
echo ""
if [ -f "release-title.txt" ]; then
echo "--- Title ---"
cat release-title.txt
echo ""
fi
if [ -f "polished-notes.md" ]; then
echo "--- Notes ---"
cat polished-notes.md
fi
echo ""
echo "=== Test complete. If this looks good, the real workflow will work. ==="
Loading