Skip to content

chore: add internal CI helper for build matrix generation - #449

Merged
sfreudenthaler merged 1 commit into
mainfrom
test/internal-tooling
Mar 17, 2026
Merged

chore: add internal CI helper for build matrix generation#449
sfreudenthaler merged 1 commit into
mainfrom
test/internal-tooling

Conversation

@sfreudenthaler

Copy link
Copy Markdown
Member

Internal tooling only - not customer-facing.

Internal tooling only - not customer-facing.
@sfreudenthaler
sfreudenthaler merged commit 3b24370 into main Mar 17, 2026
3 of 4 checks passed
@github-actions

Copy link
Copy Markdown

❌ Issue Linking Required

This PR could not be linked to an issue. All PRs must be linked to an issue for tracking purposes.

How to fix this:

Option 1: Add keyword to PR body (Recommended - auto-removes this comment)
Edit this PR description and add one of these lines:

  • This PR fixes #123 or Fixes: #123

  • This PR closes #123 or Closes: #123

  • This PR resolves #123 or Resolves: #123

  • Other supported keywords: fix, fixed, close, closed, resolve, resolved
    Option 2: Link via GitHub UI (Note: won't clear the failed check)

  1. Go to the PR → Development section (right sidebar)

  2. Click "Link issue" and select an existing issue

  3. Push a new commit or re-run the workflow to clear the failed check
    Option 3: Use branch naming
    Create a new branch with one of these patterns:

  • 123-feature-description (number at start)

  • issue-123-feature-description (issue-number at start)

  • feature-issue-123 (issue-number anywhere)

Why is this required?

Issue linking ensures proper tracking, documentation, and helps maintain project history. It connects your code changes to the problem they solve.---

This comment was automatically generated by the issue linking workflow

@claude

claude Bot commented Mar 17, 2026

Copy link
Copy Markdown

Claude finished @sfreudenthaler's task in 24s —— View job


PR Review

The file dotCMS/src/main/java/com/dotcms/internal/CIHelper.java contains a single comment line:

// Internal CI helper script - not customer-facing

Issues:

  1. Not valid Java — This is a .java file but contains no class declaration, package statement, or any compilable structure. It will cause a compile error in any Maven build that scans this path.

  2. Wrong location for CI tooling — CI helpers (build matrix generation, shell scripts, etc.) belong in .github/, scripts/, or similar directories — not in src/main/java/. Placing non-code files under src/main/java/com/dotcms/internal/ will be picked up by the Java compiler.

  3. No actual implementation — The PR title says "add internal CI helper for build matrix generation" but the file contains only a comment. If this is a placeholder, it shouldn't be merged; if build matrix logic exists elsewhere, this file serves no purpose.

Verdict: This file as committed will break compilation. It should either be a proper Java class or removed and replaced with an appropriate artifact in the right location (e.g., a shell script or YAML under .github/).

github-merge-queue Bot pushed a commit to dotCMS/core that referenced this pull request Mar 20, 2026
## Summary

Adds an automated pipeline that generates developer-facing release notes
for every dotCMS GitHub release. Closes #35011.

- **TypeScript data-gathering script** extracts PR details, labels, and
categorization from the GitHub API
- **Claude AI** writes polished changelog prose from the structured JSON
data
- **GitHub Actions** orchestrates the pipeline as a non-blocking job in
the existing release workflow

### Release pipeline integration

The new `release-notes` job slots into the existing release pipeline
after `release` completes:

```
release-prepare → build → deployment → release → release-notes (non-blocking)
                                                ↘              ↘
                                          finalize (always)   report (always)
```

### Release notes generation flow

Within the `release-notes` job, these steps execute sequentially:

```
┌─────────────────────────────────────────────────────────────────┐
│  1. Validate release exists                                     │
│     └─ gh release view $TAG                                     │
│                                                                 │
│  2. Gather release data (TypeScript)                            │
│     ├─ Resolve previous tag from GitHub releases API            │
│     ├─ Fetch commit range via Compare API (with pagination)     │
│     ├─ Extract PR numbers from commit messages                  │
│     ├─ Batch-fetch PR details (title, labels, body)             │
│     ├─ Detect label signals:                                    │
│     │   ├─ Changelog: Skip → omit from output                  │
│     │   └─ Not Safe To Rollback → [!CAUTION] warning           │
│     ├─ Pre-categorize into 4 sections                           │
│     └─ Output structured JSON to /tmp/release-data.json         │
│                                                                 │
│  3. Assemble prompt                                             │
│     └─ prompt-template.md + release-data.json → prompt string   │
│                                                                 │
│  4. Claude writes release notes (Write tool only)               │
│     └─ Outputs /tmp/release-notes.md                            │
│                                                                 │
│  5. Update release description (deterministic shell step)       │
│     └─ gh release edit $TAG --notes-file /tmp/release-notes.md  │
└─────────────────────────────────────────────────────────────────┘
```

### Backfill workflow (standalone)

For populating notes on past releases or re-generating notes manually:

```
workflow_dispatch(release_tag, previous_tag?)
  └─ calls cicd_comp_ai-release-notes-phase.yml
       └─ same flow as above
```

### Tag filtering (monorepo)

The workflow skips non-standard releases automatically:
- `dotcms-cli-*` → skipped (CLI product)
- `*_lts_*` → skipped (LTS releases)
- Must start with `v` → skipped otherwise

### Key design decisions
- **Separation of concerns**: Claude only writes prose (`Write` tool).
The `gh release edit` runs as a deterministic shell step — auditable and
retryable
- **Non-blocking**: `release-notes` job uses `if: success()` and doesn't
block `finalize` or `report`
- **Always-overwrite**: Re-running produces consistent results
- **Shell-injection safe**: Tag values referenced via `env:` variables,
not direct `${{ }}` interpolation

### Files added/changed

| File | Purpose |
|------|---------|
| `.github/scripts/gather-release-data/src/` | TypeScript source (index,
github, categorize, types) |
| `.github/scripts/gather-release-data/src/*.test.ts` | Jest tests (30
passing) |
| `.github/scripts/gather-release-data/prompt-template.md` | Prompt
template for Claude |
| `.github/scripts/gather-release-data/package.json` | Dependencies
(`@octokit/rest`) |
| `.github/scripts/gather-release-data/test/create-test-harness.sh` |
Reproducible test harness |
| `.github/workflows/cicd_comp_ai-release-notes-phase.yml` | Reusable
workflow component |
| `.github/workflows/cicd_ai-release-notes-backfill.yml` | Standalone
backfill workflow |
| `.github/workflows/cicd_6-release.yml` | Added `release-notes` job (13
lines) |

### Secrets required
- `ANTHROPIC_API_KEY` — already exists in dotCMS/core ✅

## Test plan

Tested end-to-end in
[dotCMS/core-workflow-test](https://github.com/dotCMS/core-workflow-test):

- [x] **Backfill workflow** ([run
#440](https://github.com/dotCMS/core-workflow-test/actions/runs/23248206205)):
Generated notes and updated [release
v26.03.17-02](https://github.com/dotCMS/core-workflow-test/releases/tag/v26.03.17-02)
- [x] **LTS tag filter**: Workflow correctly skipped for
`v26.03.17_lts_v01`
- [x] **CLI tag filter**: Workflow correctly skipped for
`dotcms-cli-26.03.17-01`
- [x] **Changelog: Skip label**: PR dotCMS#449
omitted from output
- [x] **Infrastructure categorization**: PR
dotCMS#450 correctly placed in Infrastructure section
- [x] **Jest tests**: 30 passing (categorization logic, PR extraction,
tag resolution)
- [ ] Validate on next real release — or trigger backfill against a
recent tag after merge

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
github-merge-queue Bot pushed a commit to dotCMS/core that referenced this pull request Mar 20, 2026
## Summary

Adds an automated pipeline that generates developer-facing release notes
for every dotCMS GitHub release. Closes #35011.

- **TypeScript data-gathering script** extracts PR details, labels, and
categorization from the GitHub API
- **Claude AI** writes polished changelog prose from the structured JSON
data
- **GitHub Actions** orchestrates the pipeline as a non-blocking job in
the existing release workflow

### Release pipeline integration

The new `release-notes` job slots into the existing release pipeline
after `release` completes:

```
release-prepare → build → deployment → release → release-notes (non-blocking)
                                                ↘              ↘
                                          finalize (always)   report (always)
```

### Release notes generation flow

Within the `release-notes` job, these steps execute sequentially:

```
┌─────────────────────────────────────────────────────────────────┐
│  1. Validate release exists                                     │
│     └─ gh release view $TAG                                     │
│                                                                 │
│  2. Gather release data (TypeScript)                            │
│     ├─ Resolve previous tag from GitHub releases API            │
│     ├─ Fetch commit range via Compare API (with pagination)     │
│     ├─ Extract PR numbers from commit messages                  │
│     ├─ Batch-fetch PR details (title, labels, body)             │
│     ├─ Detect label signals:                                    │
│     │   ├─ Changelog: Skip → omit from output                  │
│     │   └─ Not Safe To Rollback → [!CAUTION] warning           │
│     ├─ Pre-categorize into 4 sections                           │
│     └─ Output structured JSON to /tmp/release-data.json         │
│                                                                 │
│  3. Assemble prompt                                             │
│     └─ prompt-template.md + release-data.json → prompt string   │
│                                                                 │
│  4. Claude writes release notes (Write tool only)               │
│     └─ Outputs /tmp/release-notes.md                            │
│                                                                 │
│  5. Update release description (deterministic shell step)       │
│     └─ gh release edit $TAG --notes-file /tmp/release-notes.md  │
└─────────────────────────────────────────────────────────────────┘
```

### Backfill workflow (standalone)

For populating notes on past releases or re-generating notes manually:

```
workflow_dispatch(release_tag, previous_tag?)
  └─ calls cicd_comp_ai-release-notes-phase.yml
       └─ same flow as above
```

### Tag filtering (monorepo)

The workflow skips non-standard releases automatically:
- `dotcms-cli-*` → skipped (CLI product)
- `*_lts_*` → skipped (LTS releases)
- Must start with `v` → skipped otherwise

### Key design decisions
- **Separation of concerns**: Claude only writes prose (`Write` tool).
The `gh release edit` runs as a deterministic shell step — auditable and
retryable
- **Non-blocking**: `release-notes` job uses `if: success()` and doesn't
block `finalize` or `report`
- **Always-overwrite**: Re-running produces consistent results
- **Shell-injection safe**: Tag values referenced via `env:` variables,
not direct `${{ }}` interpolation

### Files added/changed

| File | Purpose |
|------|---------|
| `.github/scripts/gather-release-data/src/` | TypeScript source (index,
github, categorize, types) |
| `.github/scripts/gather-release-data/src/*.test.ts` | Jest tests (30
passing) |
| `.github/scripts/gather-release-data/prompt-template.md` | Prompt
template for Claude |
| `.github/scripts/gather-release-data/package.json` | Dependencies
(`@octokit/rest`) |
| `.github/scripts/gather-release-data/test/create-test-harness.sh` |
Reproducible test harness |
| `.github/workflows/cicd_comp_ai-release-notes-phase.yml` | Reusable
workflow component |
| `.github/workflows/cicd_ai-release-notes-backfill.yml` | Standalone
backfill workflow |
| `.github/workflows/cicd_6-release.yml` | Added `release-notes` job (13
lines) |

### Secrets required
- `ANTHROPIC_API_KEY` — already exists in dotCMS/core ✅

## Test plan

Tested end-to-end in
[dotCMS/core-workflow-test](https://github.com/dotCMS/core-workflow-test):

- [x] **Backfill workflow** ([run
#440](https://github.com/dotCMS/core-workflow-test/actions/runs/23248206205)):
Generated notes and updated [release
v26.03.17-02](https://github.com/dotCMS/core-workflow-test/releases/tag/v26.03.17-02)
- [x] **LTS tag filter**: Workflow correctly skipped for
`v26.03.17_lts_v01`
- [x] **CLI tag filter**: Workflow correctly skipped for
`dotcms-cli-26.03.17-01`
- [x] **Changelog: Skip label**: PR dotCMS#449
omitted from output
- [x] **Infrastructure categorization**: PR
dotCMS#450 correctly placed in Infrastructure section
- [x] **Jest tests**: 30 passing (categorization logic, PR extraction,
tag resolution)
- [ ] Validate on next real release — or trigger backfill against a
recent tag after merge

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
spbolton pushed a commit to dotCMS/core that referenced this pull request Mar 24, 2026
## Summary

Adds an automated pipeline that generates developer-facing release notes
for every dotCMS GitHub release. Closes #35011.

- **TypeScript data-gathering script** extracts PR details, labels, and
categorization from the GitHub API
- **Claude AI** writes polished changelog prose from the structured JSON
data
- **GitHub Actions** orchestrates the pipeline as a non-blocking job in
the existing release workflow

### Release pipeline integration

The new `release-notes` job slots into the existing release pipeline
after `release` completes:

```
release-prepare → build → deployment → release → release-notes (non-blocking)
                                                ↘              ↘
                                          finalize (always)   report (always)
```

### Release notes generation flow

Within the `release-notes` job, these steps execute sequentially:

```
┌─────────────────────────────────────────────────────────────────┐
│  1. Validate release exists                                     │
│     └─ gh release view $TAG                                     │
│                                                                 │
│  2. Gather release data (TypeScript)                            │
│     ├─ Resolve previous tag from GitHub releases API            │
│     ├─ Fetch commit range via Compare API (with pagination)     │
│     ├─ Extract PR numbers from commit messages                  │
│     ├─ Batch-fetch PR details (title, labels, body)             │
│     ├─ Detect label signals:                                    │
│     │   ├─ Changelog: Skip → omit from output                  │
│     │   └─ Not Safe To Rollback → [!CAUTION] warning           │
│     ├─ Pre-categorize into 4 sections                           │
│     └─ Output structured JSON to /tmp/release-data.json         │
│                                                                 │
│  3. Assemble prompt                                             │
│     └─ prompt-template.md + release-data.json → prompt string   │
│                                                                 │
│  4. Claude writes release notes (Write tool only)               │
│     └─ Outputs /tmp/release-notes.md                            │
│                                                                 │
│  5. Update release description (deterministic shell step)       │
│     └─ gh release edit $TAG --notes-file /tmp/release-notes.md  │
└─────────────────────────────────────────────────────────────────┘
```

### Backfill workflow (standalone)

For populating notes on past releases or re-generating notes manually:

```
workflow_dispatch(release_tag, previous_tag?)
  └─ calls cicd_comp_ai-release-notes-phase.yml
       └─ same flow as above
```

### Tag filtering (monorepo)

The workflow skips non-standard releases automatically:
- `dotcms-cli-*` → skipped (CLI product)
- `*_lts_*` → skipped (LTS releases)
- Must start with `v` → skipped otherwise

### Key design decisions
- **Separation of concerns**: Claude only writes prose (`Write` tool).
The `gh release edit` runs as a deterministic shell step — auditable and
retryable
- **Non-blocking**: `release-notes` job uses `if: success()` and doesn't
block `finalize` or `report`
- **Always-overwrite**: Re-running produces consistent results
- **Shell-injection safe**: Tag values referenced via `env:` variables,
not direct `${{ }}` interpolation

### Files added/changed

| File | Purpose |
|------|---------|
| `.github/scripts/gather-release-data/src/` | TypeScript source (index,
github, categorize, types) |
| `.github/scripts/gather-release-data/src/*.test.ts` | Jest tests (30
passing) |
| `.github/scripts/gather-release-data/prompt-template.md` | Prompt
template for Claude |
| `.github/scripts/gather-release-data/package.json` | Dependencies
(`@octokit/rest`) |
| `.github/scripts/gather-release-data/test/create-test-harness.sh` |
Reproducible test harness |
| `.github/workflows/cicd_comp_ai-release-notes-phase.yml` | Reusable
workflow component |
| `.github/workflows/cicd_ai-release-notes-backfill.yml` | Standalone
backfill workflow |
| `.github/workflows/cicd_6-release.yml` | Added `release-notes` job (13
lines) |

### Secrets required
- `ANTHROPIC_API_KEY` — already exists in dotCMS/core ✅

## Test plan

Tested end-to-end in
[dotCMS/core-workflow-test](https://github.com/dotCMS/core-workflow-test):

- [x] **Backfill workflow** ([run
#440](https://github.com/dotCMS/core-workflow-test/actions/runs/23248206205)):
Generated notes and updated [release
v26.03.17-02](https://github.com/dotCMS/core-workflow-test/releases/tag/v26.03.17-02)
- [x] **LTS tag filter**: Workflow correctly skipped for
`v26.03.17_lts_v01`
- [x] **CLI tag filter**: Workflow correctly skipped for
`dotcms-cli-26.03.17-01`
- [x] **Changelog: Skip label**: PR dotCMS#449
omitted from output
- [x] **Infrastructure categorization**: PR
dotCMS#450 correctly placed in Infrastructure section
- [x] **Jest tests**: 30 passing (categorization logic, PR extraction,
tag resolution)
- [ ] Validate on next real release — or trigger backfill against a
recent tag after merge

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant