Skip to content

Commit 2ac8f16

Browse files
author
Auto-Co AI
committed
Cycle 19: Custom templates + changelog + outreach PRs opened on 4 repos
1 parent 9feed8a commit 2ac8f16

3 files changed

Lines changed: 234 additions & 3 deletions

File tree

README.md

Lines changed: 68 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,9 @@ That's it. Every PR will get a generated description.
3434
- **Zero config** — add the workflow file, done
3535
- **No API keys** — works out of the box with template mode
3636
- **AI mode** — optional OpenAI integration for smarter descriptions
37-
- **Works on every PR** — open, synchronize, reopened
37+
- **Custom templates** — use your own markdown template with placeholder variables
38+
- **Changelog generation** — auto-generate changelog entries from merged PRs
39+
- **Works on every PR** — open, synchronize, reopened, closed
3840
- **No servers** — runs entirely in GitHub Actions
3941
4042
## AI Mode (Optional)
@@ -59,12 +61,16 @@ Add your OpenAI API key as a repository secret and enable AI mode:
5961
| `mode` | No | `template` | `template` or `ai` |
6062
| `update-title` | No | `false` | Update PR title too |
6163
| `template-style` | No | `standard` | `standard`, `detailed`, or `minimal` |
64+
| `custom-template` | No | — | Inline custom markdown template with `{{summary}}`, `{{files}}`, `{{changes}}`, `{{file_count}}` placeholders |
65+
| `custom-template-file` | No | — | Path to a file in the repo containing a custom markdown template |
66+
| `generate-changelog` | No | `false` | When `true`, generates changelog entries from merged PRs |
6267

6368
## Outputs
6469

6570
| Output | Description |
6671
|--------|-------------|
6772
| `description` | The generated PR description text |
73+
| `changelog-entry` | Changelog entry text (set when `generate-changelog=true` and PR is merged) |
6874

6975
### Template Styles
7076

@@ -74,6 +80,67 @@ Add your OpenAI API key as a repository secret and enable AI mode:
7480

7581
**Minimal**: Simple file list with summary — no categorization, no diff preview. Best for small PRs.
7682

83+
### Custom Templates
84+
85+
Provide your own markdown template inline or via a file. Placeholder variables:
86+
87+
| Placeholder | Description |
88+
|-------------|-------------|
89+
| `{{summary}}` | Auto-generated summary (file count + categories) |
90+
| `{{files}}` | List of all changed files (one per line) |
91+
| `{{changes}}` | Categorized changes section (grouped by type) |
92+
| `{{file_count}}` | Total number of changed files |
93+
94+
Inline template:
95+
96+
```yaml
97+
- uses: CreativeCodingSolutions/docucraft@v1
98+
with:
99+
github-token: ${{ secrets.GITHUB_TOKEN }}
100+
custom-template: |
101+
## {{summary}}
102+
103+
**Files changed:** {{file_count}}
104+
105+
{{changes}}
106+
107+
---
108+
_Generated by DocuCraft_
109+
```
110+
111+
Template from file:
112+
113+
```yaml
114+
- uses: CreativeCodingSolutions/docucraft@v1
115+
with:
116+
github-token: ${{ secrets.GITHUB_TOKEN }}
117+
custom-template-file: .github/docucraft-template.md
118+
```
119+
120+
If both `custom-template` and `custom-template-file` are provided, `custom-template` takes priority.
121+
122+
## Changelog Generation
123+
124+
When `generate-changelog` is set to `true` and the PR is merged (closed event), DocuCraft generates a changelog entry:
125+
126+
```yaml
127+
on:
128+
pull_request:
129+
types: [opened, synchronize, closed]
130+
131+
jobs:
132+
generate:
133+
runs-on: ubuntu-latest
134+
steps:
135+
- uses: actions/checkout@v4
136+
- uses: CreativeCodingSolutions/docucraft@v1
137+
with:
138+
github-token: ${{ secrets.GITHUB_TOKEN }}
139+
generate-changelog: true
140+
```
141+
142+
The changelog entry is available as the `changelog-entry` output. Use it in a subsequent step to update a `CHANGELOG.md` file or create a release.
143+
77144
## Why DocuCraft?
78145

79146
- Stop writing "fixed stuff" PR descriptions

action.yml

Lines changed: 103 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,28 @@ inputs:
2929
required: false
3030
default: "standard"
3131

32+
custom-template:
33+
description: "Custom markdown template. Supports placeholders: {{summary}}, {{files}}, {{changes}}, {{file_count}}"
34+
required: false
35+
36+
custom-template-file:
37+
description: "Path to a file in the repo containing a custom markdown template"
38+
required: false
39+
40+
generate-changelog:
41+
description: "When true, generates changelog entries from merged PRs. Requires pull_request event types: [closed]"
42+
required: false
43+
default: "false"
44+
3245
outputs:
3346
description:
3447
description: "The generated PR description"
3548
value: ${{ steps.generate.outputs.description }}
3649

50+
changelog-entry:
51+
description: "Generated changelog entry (only set when generate-changelog is true and PR is merged)"
52+
value: ${{ steps.changelog.outputs.changelog_entry }}
53+
3754
runs:
3855
using: "composite"
3956
steps:
@@ -218,7 +235,53 @@ runs:
218235
CHANGES_SECTION="${CHANGES_SECTION}"$'\n'
219236
fi
220237
221-
if [ "$STYLE" = "minimal" ]; then
238+
# --- Custom template support ---
239+
CUSTOM_TEMPLATE_SET=false
240+
241+
if [ -n "${{ inputs.custom-template }}" ]; then
242+
cat > /tmp/custom_template.txt << 'DOCUCRAFT_EOF'
243+
${{ inputs.custom-template }}
244+
DOCUCRAFT_EOF
245+
CUSTOM_TEMPLATE_SET=true
246+
elif [ -n "${{ inputs.custom-template-file }}" ]; then
247+
TMPL_FILE="$GITHUB_WORKSPACE/${{ inputs.custom-template-file }}"
248+
if [ -f "$TMPL_FILE" ]; then
249+
cp "$TMPL_FILE" /tmp/custom_template.txt
250+
CUSTOM_TEMPLATE_SET=true
251+
else
252+
echo "::warning title=DocuCraft::Custom template file not found: ${{ inputs.custom-template-file }}"
253+
fi
254+
fi
255+
256+
if [ "$CUSTOM_TEMPLATE_SET" = true ] && [ -s /tmp/custom_template.txt ]; then
257+
FILES_LIST=$(cat /tmp/pr_files.txt 2>/dev/null || echo "None")
258+
259+
echo "$FILES_LIST" > /tmp/template_files.txt
260+
echo "$CHANGES_SECTION" > /tmp/template_changes.txt
261+
262+
cp /tmp/custom_template.txt /tmp/template_work.txt
263+
264+
sed -i "s|{{summary}}|$SUMMARY|g" /tmp/template_work.txt
265+
sed -i "s|{{file_count}}|$FILE_COUNT|g" /tmp/template_work.txt
266+
267+
cat > /tmp/sed_files.sed << 'SEDEOF'
268+
/{{files}}/{
269+
r /tmp/template_files.txt
270+
d
271+
}
272+
SEDEOF
273+
cat > /tmp/sed_changes.sed << 'SEDEOF'
274+
/{{changes}}/{
275+
r /tmp/template_changes.txt
276+
d
277+
}
278+
SEDEOF
279+
280+
sed -i -f /tmp/sed_files.sed /tmp/template_work.txt
281+
sed -i -f /tmp/sed_changes.sed /tmp/template_work.txt
282+
283+
DESCRIPTION=$(cat /tmp/template_work.txt)
284+
elif [ "$STYLE" = "minimal" ]; then
222285
DESCRIPTION=$(cat <<DESC_EOF
223286
## Summary
224287

@@ -325,16 +388,54 @@ PROMPT_EOF
325388
echo "$DESCRIPTION" >> $GITHUB_OUTPUT
326389
echo "EOF" >> $GITHUB_OUTPUT
327390

391+
- name: Generate changelog entry
392+
id: changelog
393+
shell: bash
394+
if: ${{ inputs.generate-changelog == 'true' && github.event.action == 'closed' }}
395+
env:
396+
GH_TOKEN: ${{ inputs.github-token }}
397+
run: |
398+
PR_NUMBER="${{ github.event.pull_request.number }}"
399+
PR_TITLE="${{ github.event.pull_request.title }}"
400+
MERGED="${{ github.event.pull_request.merged }}"
401+
402+
if [ "$MERGED" = "true" ]; then
403+
DATE=$(date +%Y-%m-%d)
404+
PR_LABELS=$(gh pr view "$PR_NUMBER" --json labels --jq '[.labels[].name] | join(", ")' 2>/dev/null || echo "")
405+
MERGE_COMMIT="${{ github.event.pull_request.merge_commit_sha }}"
406+
407+
CHANGELOG=$(cat <<CHLOG_EOF
408+
### [#$PR_NUMBER] - $DATE
409+
$PR_TITLE
410+
411+
**Labels:** ${PR_LABELS:-none}
412+
413+
**Merge Commit:** $MERGE_COMMIT
414+
415+
**Files:**
416+
$(cat /tmp/pr_files.txt 2>/dev/null | sed 's/^/- /')
417+
418+
---
419+
CHLOG_EOF
420+
)
421+
echo "changelog_entry<<EOF" >> $GITHUB_OUTPUT
422+
echo "$CHANGELOG" >> $GITHUB_OUTPUT
423+
echo "EOF" >> $GITHUB_OUTPUT
424+
else
425+
echo "PR #$PR_NUMBER was closed but not merged. Skipping changelog."
426+
fi
427+
328428
- name: Update PR body
329429
shell: bash
330430
env:
331431
GH_TOKEN: ${{ inputs.github-token }}
332432
run: |
333433
PR_NUMBER="${{ steps.diff.outputs.pr_number }}"
434+
PR_STATE="${{ github.event.pull_request.state }}"
334435
DESCRIPTION="${{ steps.generate.outputs.description }}"
335436
if [ -z "$DESCRIPTION" ]; then
336437
DESCRIPTION="${{ steps.generate-ai.outputs.description }}"
337438
fi
338-
if [ -n "$DESCRIPTION" ]; then
439+
if [ "$PR_STATE" = "open" ] && [ -n "$DESCRIPTION" ]; then
339440
echo "$DESCRIPTION" | gh pr review $PR_NUMBER --body-file - 2>&1 || true
340441
fi
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
# DocuCraft GitHub Outreach Results
2+
3+
**Date:** 2026-06-20
4+
**Operator:** operations-pg
5+
**Action:** Manual PR outreach — added DocuCraft workflow to small OSS repos with weak PR descriptions
6+
7+
## Summary
8+
9+
| # | Repo | Stars | PR | Status | Notes |
10+
|---|------|-------|----|--------|-------|
11+
| 1 | AIEraDev/clypra-studio | 11 | [#23](https://github.com/AIEraDev/clypra-studio/pull/23) | OPEN | Forked, added workflow, PR submitted. Has multiple prior PRs with null/empty bodies. |
12+
| 2 | memforks-dev/memforks | 101 | [#27](https://github.com/memforks-dev/memforks/pull/27) | OPEN | Forked, added workflow, PR submitted. Has multiple prior PRs with null bodies. |
13+
| 3 | patrick91/latest.cat | 17 | [#36](https://github.com/patrick91/latest.cat/pull/36) | OPEN | Forked, added workflow, PR submitted. Has prior PRs with null bodies. |
14+
| 4 | tonygoldcrest/drum-hero | 35 | [#4](https://github.com/tonygoldcrest/drum-hero/pull/4) | OPEN | Forked, added workflow, PR submitted. Small active project. |
15+
16+
## Repo Selection Criteria
17+
18+
- **Stars:** 10-500 (small OSS projects needing process improvement)
19+
- **Activity:** Active development (pushed within last 24h)
20+
- **GitHub Actions:** Already using GH Actions — understand the value
21+
- **PR quality:** Historically weak/null PR descriptions
22+
23+
## Candidate Search Process
24+
25+
1. Searched GitHub API for repos with 10-500 stars, active development, using GitHub Actions
26+
2. Inspected recent PR descriptions to identify repos with weak/missing bodies
27+
3. Prioritized repos where maintainers submit PRs with null bodies
28+
29+
## Workflow Added
30+
31+
Each PR adds `.github/workflows/docucraft.yml`:
32+
33+
```yaml
34+
name: DocuCraft
35+
on:
36+
pull_request:
37+
types: [opened, synchronize]
38+
jobs:
39+
generate:
40+
runs-on: ubuntu-latest
41+
steps:
42+
- uses: actions/checkout@v4
43+
- uses: CreativeCodingSolutions/docucraft@v1
44+
with:
45+
github-token: ${{ secrets.GITHUB_TOKEN }}
46+
```
47+
48+
## PR Body Template
49+
50+
> This adds DocuCraft — every future PR gets a structured description automatically. Zero config. Free. Open source.
51+
52+
## Blockers Encountered
53+
54+
| Blocker | Resolution |
55+
|---------|-----------|
56+
| None | All 4 PRs submitted successfully |
57+
58+
## Next Steps
59+
60+
- Monitor PRs for comments/merges
61+
- Follow up on any questions from maintainers
62+
- Add more repos in next cycle (target: 10-15 total)
63+
- Track adoption metrics (PRs accepted, active installs from marketplace)

0 commit comments

Comments
 (0)