From acc8704dc1b7c210d2162411cc62c47c08ef4fc7 Mon Sep 17 00:00:00 2001 From: ruben-cytonic Date: Thu, 12 Feb 2026 14:16:13 +0000 Subject: [PATCH] chore: simplify release flow and issue templates - Remove beta npm tag from release workflow (stable-only releases) - Simplify release-on-tag to always publish with latest tag - Simplify prepare-release to stable-only version calculation - Strip beta consolidation from stable-release workflow - Remove release:beta script from package.json - Reduce issue template fields (bug, config, feature) to essentials - Enable blank issues in config.yml Co-Authored-By: Claude Opus 4.6 --- .github/ISSUE_TEMPLATE/bug_report.yml | 71 ++------- .github/ISSUE_TEMPLATE/config.yml | 2 +- .github/ISSUE_TEMPLATE/config_issue.yml | 67 +-------- .github/ISSUE_TEMPLATE/feature_request.yml | 67 +-------- .github/workflows/prepare-release.yml | 115 ++++----------- .github/workflows/release-on-tag.yml | 51 +------ .github/workflows/release.yml | 7 +- .github/workflows/stable-release.yml | 162 +++------------------ package.json | 1 - 9 files changed, 74 insertions(+), 469 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index eba96fa..72ced53 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -1,31 +1,20 @@ name: Bug Report description: Report a bug or unexpected behavior title: "[Bug]: " -labels: ["bug", "triage"] +labels: ["bug"] body: - - type: markdown - attributes: - value: | - Thanks for taking the time to report a bug! Please fill out the form below. - - type: textarea id: description attributes: label: Bug Description - description: A clear and concise description of the bug - placeholder: Describe what happened... - validations: - required: true - - - type: textarea - id: reproduction - attributes: - label: Steps to Reproduce - description: Steps to reproduce the behavior + description: What happened? Include steps to reproduce if possible. placeholder: | + What happened: + ... + + Steps to reproduce: 1. Run `ralph ...` - 2. Select '...' - 3. See error + 2. ... validations: required: true @@ -34,57 +23,23 @@ body: attributes: label: Expected Behavior description: What did you expect to happen? - validations: - required: true - type: textarea - id: actual + id: logs attributes: - label: Actual Behavior - description: What actually happened? - validations: - required: true + label: Relevant Logs + description: Paste any error messages or output + render: shell - type: input id: version attributes: label: ralph-starter Version description: Run `ralph --version` to get this - placeholder: "0.1.1" - validations: - required: true - - - type: dropdown - id: os - attributes: - label: Operating System - options: - - macOS - - Linux - - Windows (WSL) - - Windows - - Other - validations: - required: true - - - type: input - id: node-version - attributes: - label: Node.js Version - description: Run `node --version` to get this - placeholder: "v20.10.0" - validations: - required: true - - - type: textarea - id: logs - attributes: - label: Relevant Logs - description: Please paste any relevant error logs or output - render: shell + placeholder: "0.2.1" - type: textarea id: additional attributes: label: Additional Context - description: Any other context about the problem (screenshots, config, etc.) + description: OS, Node.js version, or any other relevant info diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index e7c64c2..5ad43b1 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -1,4 +1,4 @@ -blank_issues_enabled: false +blank_issues_enabled: true contact_links: - name: Documentation url: https://ralph-starter.dev/docs diff --git a/.github/ISSUE_TEMPLATE/config_issue.yml b/.github/ISSUE_TEMPLATE/config_issue.yml index 6513825..f37980d 100644 --- a/.github/ISSUE_TEMPLATE/config_issue.yml +++ b/.github/ISSUE_TEMPLATE/config_issue.yml @@ -1,31 +1,8 @@ name: Configuration Issue description: Report issues with configuration or setup title: "[Config]: " -labels: ["configuration", "help wanted"] +labels: ["configuration"] body: - - type: markdown - attributes: - value: | - Having trouble with configuration? Let us help! - - - type: dropdown - id: integration - attributes: - label: Which integration? - description: Which service or integration is this related to? - options: - - General Setup - - Anthropic (Claude) - - OpenAI - - OpenRouter - - Linear - - Notion - - GitHub - - Todoist - - Other - validations: - required: true - - type: textarea id: description attributes: @@ -35,18 +12,6 @@ body: validations: required: true - - type: textarea - id: steps - attributes: - label: Steps Taken - description: What have you tried so far? - placeholder: | - 1. Ran `ralph config` - 2. Entered API key - 3. Got error... - validations: - required: true - - type: textarea id: error attributes: @@ -54,36 +19,8 @@ body: description: Any error messages you're seeing render: shell - - type: textarea - id: config - attributes: - label: Configuration (sanitized) - description: "Relevant config (REMOVE any API keys or secrets!)" - render: json - - - type: input - id: version - attributes: - label: ralph-starter Version - placeholder: "0.1.1" - validations: - required: true - - - type: dropdown - id: os - attributes: - label: Operating System - options: - - macOS - - Linux - - Windows (WSL) - - Windows - - Other - validations: - required: true - - type: textarea id: additional attributes: label: Additional Context - description: Any other relevant information + description: Version, OS, relevant config (remove any API keys!) diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml index a834fcf..adcb4a7 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.yml +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -3,72 +3,21 @@ description: Suggest a new feature or enhancement title: "[Feature]: " labels: ["enhancement"] body: - - type: markdown - attributes: - value: | - Thanks for suggesting a feature! Please describe your idea below. - - type: textarea - id: problem + id: description attributes: - label: Problem Statement - description: What problem does this feature solve? Is it related to a frustration? - placeholder: I'm always frustrated when... - validations: - required: true + label: Feature Description + description: What would you like ralph to do? What problem does it solve? + placeholder: | + I would like ralph to... - - type: textarea - id: solution - attributes: - label: Proposed Solution - description: Describe your ideal solution - placeholder: I would like ralph to... + Problem it solves: + ... validations: required: true - - type: textarea - id: alternatives - attributes: - label: Alternatives Considered - description: Any alternative solutions or features you've considered? - - - type: dropdown - id: category - attributes: - label: Feature Category - options: - - New Integration (Linear, Notion, GitHub, etc.) - - CLI Experience - - AI/LLM Enhancement - - Configuration - - Documentation - - Performance - - Other - validations: - required: true - - - type: dropdown - id: scope - attributes: - label: Scope - description: How significant is this change? - options: - - Small (minor tweak) - - Medium (new command or option) - - Large (major feature or new integration) - validations: - required: true - - - type: checkboxes - id: contribution - attributes: - label: Contribution - options: - - label: I would be willing to help implement this feature - required: false - - type: textarea id: additional attributes: label: Additional Context - description: Any other context, mockups, or examples + description: Examples, mockups, alternatives considered, or any other relevant info diff --git a/.github/workflows/prepare-release.yml b/.github/workflows/prepare-release.yml index 3db69e1..c18cf39 100644 --- a/.github/workflows/prepare-release.yml +++ b/.github/workflows/prepare-release.yml @@ -12,22 +12,16 @@ permissions: jobs: # NOTE: Auto-labeling (including candidate-release) is handled by auto-label.yml - # This workflow aggregates ALL merged candidate-release/release PRs since the last release - # - # Labels: - # candidate-release → beta bump (0.1.1-beta.16 → 0.1.1-beta.17) - # release → stable bump (0.1.1-beta.16 → 0.2.0) + # This workflow aggregates ALL merged candidate-release PRs since the last release + # and creates a stable release PR with the appropriate semver bump. - # Create/update release PR when a PR with candidate-release or release label is merged + # Create/update release PR when a PR with candidate-release label is merged create-release-pr: name: Create Release PR if: | github.event.action == 'closed' && github.event.pull_request.merged == true && - ( - contains(github.event.pull_request.labels.*.name, 'candidate-release') || - contains(github.event.pull_request.labels.*.name, 'release') - ) && + contains(github.event.pull_request.labels.*.name, 'candidate-release') && !startsWith(github.event.pull_request.head.ref, 'release/') runs-on: ubuntu-latest steps: @@ -64,9 +58,9 @@ jobs: echo "No release tags found, collecting all candidate-release PRs" fi - # Query all merged PRs with candidate-release or release label since the tag date + # Query all merged PRs with candidate-release label since the tag date # Exclude release branch PRs - CANDIDATE_JSON=$(gh pr list \ + PR_JSON=$(gh pr list \ --state merged \ --label "candidate-release" \ --base main \ @@ -74,16 +68,6 @@ jobs: --limit 100 \ --jq "[.[] | select(.mergedAt > \"$TAG_DATE\" and (.headRefName | startswith(\"release/\") | not))]" ) - STABLE_JSON=$(gh pr list \ - --state merged \ - --label "release" \ - --base main \ - --json number,title,mergedAt,headRefName \ - --limit 100 \ - --jq "[.[] | select(.mergedAt > \"$TAG_DATE\" and (.headRefName | startswith(\"release/\") | not))]" - ) - # Merge and deduplicate by PR number - PR_JSON=$(echo "$CANDIDATE_JSON $STABLE_JSON" | jq -s 'add | unique_by(.number)') PR_COUNT=$(echo "$PR_JSON" | jq length) echo "Found $PR_COUNT merged PRs since $LATEST_TAG" @@ -142,63 +126,28 @@ jobs: echo "Version bump: $BUMP (current: $CURRENT_VERSION)" echo "Changes: $(echo "$CHANGES" | jq -r '.[] | " - #\(.pr): \(.rawTitle)"')" - - name: Check if stable release - if: steps.collect.outputs.skip != 'true' - id: stable - run: | - IS_STABLE="${{ contains(github.event.pull_request.labels.*.name, 'release') }}" - echo "is_stable=$IS_STABLE" >> $GITHUB_OUTPUT - echo "Stable release: $IS_STABLE" - - name: Calculate new version if: steps.collect.outputs.skip != 'true' id: version env: CURRENT: ${{ steps.bump.outputs.current }} BUMP: ${{ steps.bump.outputs.bump }} - IS_STABLE: ${{ steps.stable.outputs.is_stable }} run: | - if [ "$IS_STABLE" = "true" ]; then - # Stable release: strip prerelease suffix, apply semver bump to base - BASE=$(echo "$CURRENT" | sed 's/-.*$//') - IFS='.' read -r MAJOR MINOR PATCH <<< "$BASE" - - case "$BUMP" in - major) - NEW_VERSION="$((MAJOR + 1)).0.0" - ;; - minor) - NEW_VERSION="${MAJOR}.$((MINOR + 1)).0" - ;; - patch) - NEW_VERSION="${MAJOR}.${MINOR}.$((PATCH + 1))" - ;; - esac - - echo "Stable release: $CURRENT -> $NEW_VERSION (bump: $BUMP)" - elif [[ "$CURRENT" == *"-"* ]]; then - # Beta release: bump the prerelease number - BASE=$(echo "$CURRENT" | sed 's/-.*$//') - PRE_TYPE=$(echo "$CURRENT" | sed 's/.*-\([a-z]*\).*/\1/') - PRE_NUM=$(echo "$CURRENT" | sed 's/.*\.\([0-9]*\)$/\1/') - NEW_PRE_NUM=$((PRE_NUM + 1)) - NEW_VERSION="${BASE}-${PRE_TYPE}.${NEW_PRE_NUM}" - else - # Already stable, apply semver bump - IFS='.' read -r MAJOR MINOR PATCH <<< "$CURRENT" - - case "$BUMP" in - major) - NEW_VERSION="$((MAJOR + 1)).0.0" - ;; - minor) - NEW_VERSION="${MAJOR}.$((MINOR + 1)).0" - ;; - patch) - NEW_VERSION="${MAJOR}.${MINOR}.$((PATCH + 1))" - ;; - esac - fi + # Strip any prerelease suffix (transition from old beta versions) + BASE=$(echo "$CURRENT" | sed 's/-.*$//') + IFS='.' read -r MAJOR MINOR PATCH <<< "$BASE" + + case "$BUMP" in + major) + NEW_VERSION="$((MAJOR + 1)).0.0" + ;; + minor) + NEW_VERSION="${MAJOR}.$((MINOR + 1)).0" + ;; + patch) + NEW_VERSION="${MAJOR}.${MINOR}.$((PATCH + 1))" + ;; + esac echo "new=$NEW_VERSION" >> $GITHUB_OUTPUT echo "New version will be: $NEW_VERSION (bump: $BUMP)" @@ -244,7 +193,6 @@ jobs: EXISTING_NUMBER: ${{ steps.check.outputs.number }} EXISTING_BRANCH: ${{ steps.check.outputs.branch }} EXISTING_VERSION: ${{ steps.check.outputs.version }} - IS_STABLE: ${{ steps.stable.outputs.is_stable }} run: | TODAY=$(date +%Y-%m-%d) RELEASE_BRANCH="release/v${NEW_VERSION}" @@ -300,18 +248,10 @@ jobs: # Build PR body with all included changes PR_CHANGES_LIST=$(echo "$CHANGES_JSON" | jq -r '.[] | "- #\(.pr): \(.rawTitle)"') - if [ "$IS_STABLE" = "true" ]; then - RELEASE_LABEL="Stable Release" - NPM_TAG_INFO="Package will be published to npm with \`latest\` tag" - else - RELEASE_LABEL="Release" - NPM_TAG_INFO="Package will be published to npm" - fi - PR_BODY=$(cat <> $GITHUB_OUTPUT - - if [[ "$VERSION" == *"-"* ]]; then - echo "is_prerelease=true" >> $GITHUB_OUTPUT - echo "npm_tag=$(echo $VERSION | sed 's/.*-\([a-z]*\).*/\1/')" >> $GITHUB_OUTPUT - else - echo "is_prerelease=false" >> $GITHUB_OUTPUT - echo "npm_tag=latest" >> $GITHUB_OUTPUT - fi - echo "Version: $VERSION" - name: Install dependencies @@ -61,15 +49,10 @@ jobs: run: pnpm test:run - name: Generate release notes - id: release_notes run: | VERSION=${{ steps.version.outputs.version }} - IS_PRERELEASE=${{ steps.version.outputs.is_prerelease }} - - # Get previous tag PREV_TAG=$(git describe --tags --abbrev=0 HEAD^ 2>/dev/null || echo "") - # Build release notes { echo "## What's Changed" echo "" @@ -82,23 +65,9 @@ jobs: echo "" echo "## Installation" echo "" - - if [ "$IS_PRERELEASE" == "true" ]; then - PRERELEASE_TYPE=$(echo "$VERSION" | sed 's/.*-\([a-z]*\).*/\1/') - echo "\`\`\`bash" - echo "npm install -g ralph-starter@$PRERELEASE_TYPE" - echo "\`\`\`" - echo "" - echo "Or install this specific version:" - echo "" - echo "\`\`\`bash" - echo "npm install -g ralph-starter@$VERSION" - echo "\`\`\`" - else - echo "\`\`\`bash" - echo "npm install -g ralph-starter" - echo "\`\`\`" - fi + echo "\`\`\`bash" + echo "npm install -g ralph-starter" + echo "\`\`\`" } > release_notes.md - name: Create GitHub Release @@ -107,23 +76,11 @@ jobs: tag_name: v${{ steps.version.outputs.version }} name: v${{ steps.version.outputs.version }} body_path: release_notes.md - prerelease: ${{ steps.version.outputs.is_prerelease }} generate_release_notes: true env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Publish to npm - run: | - NPM_TAG=${{ steps.version.outputs.npm_tag }} - pnpm publish --tag $NPM_TAG --no-git-checks --access public - env: - NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} - - - name: Add additional npm tags for prereleases - if: steps.version.outputs.is_prerelease == 'true' - run: | - VERSION=${{ steps.version.outputs.version }} - # Also tag as the specific prerelease type (e.g., beta, alpha) - npm dist-tag add ralph-starter@$VERSION ${{ steps.version.outputs.npm_tag }} + run: pnpm publish --tag latest --no-git-checks --access public env: NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 73ca33b..261ba77 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -149,12 +149,7 @@ jobs: run: pnpm build - name: Publish to npm - run: | - VERSION=${{ needs.release.outputs.version }} - # Publish with latest tag - pnpm publish --tag latest --no-git-checks - # Also add beta tag (latest and beta point to same version) - npm dist-tag add ralph-starter@$VERSION beta + run: pnpm publish --tag latest --no-git-checks env: NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} diff --git a/.github/workflows/stable-release.yml b/.github/workflows/stable-release.yml index 24d0776..a030d6e 100644 --- a/.github/workflows/stable-release.yml +++ b/.github/workflows/stable-release.yml @@ -1,14 +1,14 @@ -name: Stable Release +name: Manual Release on: workflow_dispatch: inputs: version: - description: 'Target stable version (e.g. 1.0.0, 0.2.0)' + description: 'Target version (e.g. 1.0.0, 0.3.0)' required: true type: string release_notes: - description: 'Curated release notes (markdown). Leave empty to auto-generate from beta changelogs.' + description: 'Curated release notes (markdown). Leave empty to auto-generate from changelog.' required: false type: string @@ -17,8 +17,8 @@ permissions: pull-requests: write jobs: - create-stable-release-pr: - name: Create Stable Release PR + create-release-pr: + name: Create Release PR runs-on: ubuntu-latest steps: - name: Checkout @@ -39,129 +39,20 @@ jobs: env: VERSION: ${{ inputs.version }} run: | - # Must not contain prerelease suffix - if [[ "$VERSION" == *"-"* ]]; then - echo "Error: Stable releases must not contain prerelease suffix (got: $VERSION)" - echo "Use the automated prepare-release workflow for beta releases." - exit 1 - fi - - # Must be valid semver + # Must be valid semver (no prerelease suffix) if ! [[ "$VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then echo "Error: Version must be valid semver (e.g. 1.0.0), got: $VERSION" exit 1 fi - - echo "Target stable version: $VERSION" - - - name: Consolidate beta changelog entries - id: changelog - env: - VERSION: ${{ inputs.version }} - CUSTOM_NOTES: ${{ inputs.release_notes }} - run: | - TODAY=$(date +%Y-%m-%d) - echo "today=$TODAY" >> $GITHUB_OUTPUT - - if [ -n "$CUSTOM_NOTES" ]; then - # User provided curated release notes — use them directly - echo "Using custom release notes" - echo "custom=true" >> $GITHUB_OUTPUT - else - # Auto-generate by collecting all beta entries from CHANGELOG.md - echo "Auto-generating consolidated changelog from beta entries" - - # Find the last stable version in the changelog (a version without prerelease suffix). - # CHANGELOG.md entries are in descending chronological order, so the first match - # is the most recent stable version. Use || true to prevent grep exit code 1 - # from aborting under set -eo pipefail when no stable version exists. - LAST_STABLE=$(grep -oP '## \[\K[0-9]+\.[0-9]+\.[0-9]+(?=\])' CHANGELOG.md | head -1 || true) - - if [ -n "$LAST_STABLE" ]; then - echo "Last stable version: $LAST_STABLE" - else - echo "No previous stable version found, consolidating all entries" - fi - - export LAST_STABLE - - # Extract all Added/Fixed/Changed/Documentation items from beta entries since last stable - node -e " - const fs = require('fs'); - const changelog = fs.readFileSync('CHANGELOG.md', 'utf8'); - const lines = changelog.split('\n'); - - const lastStable = process.env.LAST_STABLE || ''; - const items = { Added: [], Fixed: [], Changed: [], Documentation: [] }; - let currentType = null; - let inBetaSection = false; - - for (const line of lines) { - const versionMatch = line.match(/^## \[([^\]]+)\]/); - if (versionMatch) { - const ver = versionMatch[1]; - if (ver === lastStable) break; - inBetaSection = ver.includes('-'); - currentType = null; - continue; - } - - if (!inBetaSection) continue; - - const typeMatch = line.match(/^### (Added|Fixed|Changed|Documentation)/); - if (typeMatch) { - currentType = typeMatch[1]; - continue; - } - - if (currentType && line.startsWith('- ')) { - const item = line.substring(2).trim(); - if (!items[currentType].includes(item)) { - items[currentType].push(item); - } - } - } - - const changes = []; - for (const [type, entries] of Object.entries(items)) { - for (const entry of entries) { - const prMatch = entry.match(/#(\d+)/); - changes.push({ - type, - title: entry.replace(/\s*\(#\d+\)\s*$/, ''), - pr: prMatch ? parseInt(prMatch[1]) : 0, - rawTitle: entry - }); - } - } - - const b64 = Buffer.from(JSON.stringify(changes)).toString('base64'); - fs.writeFileSync('/tmp/changes_b64', b64); - fs.writeFileSync('/tmp/changes_count', String(changes.length)); - " - - CHANGES_B64=$(cat /tmp/changes_b64) - COUNT=$(cat /tmp/changes_count) - - if [ "$COUNT" -eq 0 ]; then - echo "No beta changelog entries found to consolidate" - exit 1 - fi - - echo "changes=$CHANGES_B64" >> $GITHUB_OUTPUT - echo "custom=false" >> $GITHUB_OUTPUT - echo "Collected $COUNT changelog items from beta entries" - fi + echo "Target version: $VERSION" - name: Create release branch and PR env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} VERSION: ${{ inputs.version }} - TODAY: ${{ steps.changelog.outputs.today }} - IS_CUSTOM: ${{ steps.changelog.outputs.custom }} CUSTOM_NOTES: ${{ inputs.release_notes }} - CHANGES_B64: ${{ steps.changelog.outputs.changes }} run: | + TODAY=$(date +%Y-%m-%d) RELEASE_BRANCH="release/v${VERSION}" # Configure git @@ -179,9 +70,8 @@ jobs: # Sync pnpm-lock.yaml with the updated package.json version pnpm install --lockfile-only - # Update CHANGELOG.md - if [ "$IS_CUSTOM" = "true" ]; then - # For custom notes, write directly to changelog + # Update CHANGELOG.md if custom notes provided + if [ -n "$CUSTOM_NOTES" ]; then node -e " const fs = require('fs'); const version = process.env.VERSION; @@ -202,54 +92,42 @@ jobs: fs.writeFileSync(changelogPath, changelog); console.log('Updated CHANGELOG.md with custom notes for v' + version); " - else - # Use the changelog script with consolidated changes - CHANGES_JSON=$(echo "$CHANGES_B64" | base64 -d) - NEW_VERSION="$VERSION" \ - TODAY="$TODAY" \ - CHANGES_JSON="$CHANGES_JSON" \ - node .github/scripts/update-changelog.cjs fi # Commit changes git add package.json pnpm-lock.yaml CHANGELOG.md - git commit -m "chore(release): prepare stable release v${VERSION}" + git commit -m "chore(release): prepare release v${VERSION}" # Push branch git push origin "$RELEASE_BRANCH" - # Build PR body to a temp file to avoid heredoc quoting issues + # Build PR body TMPFILE=$(mktemp) - - if [ "$IS_CUSTOM" = "true" ]; then + if [ -n "$CUSTOM_NOTES" ]; then CHANGES_SECTION="$CUSTOM_NOTES" else - CHANGES_JSON=$(echo "$CHANGES_B64" | base64 -d) - CHANGES_SECTION=$(echo "$CHANGES_JSON" | jq -r ' - group_by(.type) | .[] | - "**\(.[0].type)**\n\([ .[].title ] | map("- " + .) | join("\n"))" - ' 2>/dev/null || echo "See CHANGELOG.md for full details") + CHANGES_SECTION="See CHANGELOG.md for full details." fi cat > "$TMPFILE" <