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
75 changes: 63 additions & 12 deletions .github/workflows/feature-ideation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -107,23 +107,70 @@ jobs:
# A workflow_dispatch fired with GITHUB_TOKEN is accepted but never starts
# a run (loop prevention), so a PAT is required (same as initiative-planner).
env:
GH_TOKEN: ${{ secrets.GH_PAT_WORKFLOWS }}
GH_TOKEN: ${{ secrets.GH_PAT_DON_PETRY || secrets.GH_PAT_WORKFLOWS }}
run: |
if [ -z "${GH_TOKEN}" ]; then
echo "::error::GH_PAT_WORKFLOWS is required — a workflow_dispatch fired with GITHUB_TOKEN will not start a run."
echo "::error::GH_PAT_DON_PETRY or GH_PAT_WORKFLOWS is required — a workflow_dispatch fired with GITHUB_TOKEN will not start a run."
exit 1
fi
- name: Re-dispatch under workflow_dispatch
env:
GH_TOKEN: ${{ secrets.GH_PAT_WORKFLOWS }}
GH_TOKEN: ${{ secrets.GH_PAT_DON_PETRY || secrets.GH_PAT_WORKFLOWS }}
REPO: ${{ github.repository }}
DISCUSSION_NUMBER: ${{ github.event.discussion.number }}
run: |
gh workflow run feature-ideation.yml --repo "${REPO}" \
-f target_discussion="${DISCUSSION_NUMBER}"

# ── #571 input resolution — keep `inputs` out of the reusable `with:` ────────
# A reusable-workflow call graph (its `uses:` + `with:`) is validated at
# WORKFLOW SETUP, before — and regardless of — the calling job's `if:`. The
# `inputs` context is only populated for workflow_dispatch/workflow_call, so a
# `with:` that references `${{ inputs.* }}` trips a zero-job startup failure on
# the `discussion` event even though `ideate` is gated off it. We therefore
# resolve the dispatch inputs in this ordinary job (whose step expressions are
# evaluated at RUN time and are skipped on `discussion`) and hand them to
# `ideate` via `needs.prep.outputs.*` — an always-valid context that defers the
# `with:` evaluation to run time. Do not reference `inputs` in `ideate.with`.
prep:
if: github.event_name != 'discussion'
runs-on: ubuntu-latest
timeout-minutes: 5
permissions: {}
outputs:
target_discussion: ${{ steps.resolve.outputs.target_discussion }}
focus_area: ${{ steps.resolve.outputs.focus_area }}
research_depth: ${{ steps.resolve.outputs.research_depth }}
dry_run: ${{ steps.resolve.outputs.dry_run }}
enhance_backlog: ${{ steps.resolve.outputs.enhance_backlog }}
steps:
- name: Resolve dispatch inputs
id: resolve
# `github.event.inputs.*` (not the `inputs` context) so this reads
# cleanly on schedule too, where it is simply null → the defaults below.
env:
TARGET_DISCUSSION: ${{ github.event.inputs.target_discussion }}
FOCUS_AREA: ${{ github.event.inputs.focus_area }}
RESEARCH_DEPTH: ${{ github.event.inputs.research_depth }}
DRY_RUN: ${{ github.event.inputs.dry_run }}
ENHANCE_BACKLOG: ${{ github.event.inputs.enhance_backlog }}
run: |
{
echo "target_discussion=${TARGET_DISCUSSION:-}"
echo "research_depth=${RESEARCH_DEPTH:-standard}"
echo "dry_run=${DRY_RUN:-false}"
echo "enhance_backlog=${ENHANCE_BACKLOG:-false}"
} >> "$GITHUB_OUTPUT"
Comment thread
coderabbitai[bot] marked this conversation as resolved.
_delim="$(openssl rand -hex 8)"
{
echo "focus_area<<${_delim}"
printf '%s\n' "${FOCUS_AREA:-}"
echo "${_delim}"
} >> "$GITHUB_OUTPUT"

ideate:
# Runs on workflow_dispatch (including the redispatch bridge above) and schedule.
needs: [prep]
if: github.event_name != 'discussion'
# Permissions cascade from the calling job to the reusable workflow.
# The reusable workflow's two jobs (gather-signals + analyze) need:
Expand All @@ -142,10 +189,12 @@ jobs:
actions: read
uses: petry-projects/.github/.github/workflows/feature-ideation-reusable.yml@feature-ideation/v1-ring1 # NOSONAR(githubactions:S7637) first-party channel ref
with:
# Populated by the `redispatch` bridge above (which forwards the new
# Discussion number on `discussion: created`); empty on schedule/dispatch →
# normal scan. Do not edit this line.
target_discussion: ${{ inputs.target_discussion || '' }}
# All values below come from `needs.prep.outputs.*` (resolved in the `prep`
# job) — NOT the `inputs` context — so this reusable `with:` compiles on the
# `discussion` event without a zero-job startup failure (#571).
# `target_discussion` is forwarded by the `redispatch` bridge above on
# `discussion: created`; empty on schedule/dispatch → normal scan.
target_discussion: ${{ needs.prep.outputs.target_discussion }}
# === CUSTOMISE THIS PER REPO — the only required edit ===
# Replace this paragraph with a 3-5 sentence description of your project,
# its target users, and the competitive landscape. The more specific you
Expand All @@ -166,10 +215,12 @@ jobs:
# workflow defaults to that path, so you only need to uncomment and change
# sources_file below if you store the list somewhere else.
# sources_file: 'docs/feature-ideation-sources.md'
focus_area: ${{ inputs.focus_area || '' }}
research_depth: ${{ inputs.research_depth || 'standard' }}
dry_run: ${{ inputs.dry_run || false }}
focus_area: ${{ needs.prep.outputs.focus_area }}
research_depth: ${{ needs.prep.outputs.research_depth }}
# prep emits the string 'true'/'false'; fromJSON casts it to the boolean
# the reusable's typed inputs require.
dry_run: ${{ fromJSON(needs.prep.outputs.dry_run) }}
# Backlog enhancement sweep of existing un-enhanced Ideas (workflow_dispatch).
enhance_backlog: ${{ inputs.enhance_backlog == true }}
enhance_backlog: ${{ fromJSON(needs.prep.outputs.enhance_backlog) }}
secrets:
CLAUDE_CODE_OAUTH_TOKEN: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
CLAUDE_CODE_OAUTH_TOKEN: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
Loading