climaybe 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,136 @@
1
+ # climaybe — Release PR Check (Single-store)
2
+ # Runs when a PR is opened from staging → main.
3
+ # Generates an AI changelog, creates a pre-release patch tag to lock the current state,
4
+ # and posts the changelog as a PR comment.
5
+
6
+ name: Release PR Check
7
+
8
+ on:
9
+ pull_request:
10
+ branches: [main]
11
+ types: [opened, synchronize, reopened]
12
+
13
+ # Prevent concurrent runs for the same PR
14
+ concurrency:
15
+ group: release-pr-${{ github.event.pull_request.number }}
16
+ cancel-in-progress: true
17
+
18
+ jobs:
19
+ # Gate: only run for PRs from staging
20
+ check-source:
21
+ runs-on: ubuntu-latest
22
+ outputs:
23
+ is_staging: ${{ steps.check.outputs.is_staging }}
24
+ steps:
25
+ - id: check
26
+ run: |
27
+ if [[ "${{ github.head_ref }}" == "staging" ]]; then
28
+ echo "is_staging=true" >> $GITHUB_OUTPUT
29
+ else
30
+ echo "is_staging=false" >> $GITHUB_OUTPUT
31
+ fi
32
+
33
+ # Lock the current state with a pre-release patch tag
34
+ pre-release-tag:
35
+ needs: check-source
36
+ if: needs.check-source.outputs.is_staging == 'true'
37
+ runs-on: ubuntu-latest
38
+ outputs:
39
+ last_tag: ${{ steps.tag.outputs.last_tag }}
40
+ new_tag: ${{ steps.tag.outputs.new_tag }}
41
+ permissions:
42
+ contents: write
43
+ steps:
44
+ - uses: actions/checkout@v4
45
+ with:
46
+ ref: main
47
+ fetch-depth: 0
48
+ token: ${{ secrets.GITHUB_TOKEN }}
49
+
50
+ - name: Configure git
51
+ run: |
52
+ git config user.name "github-actions[bot]"
53
+ git config user.email "github-actions[bot]@users.noreply.github.com"
54
+
55
+ - name: Create pre-release patch tag
56
+ id: tag
57
+ run: |
58
+ LATEST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "v0.0.0")
59
+ echo "last_tag=$LATEST_TAG" >> $GITHUB_OUTPUT
60
+
61
+ # Check if there are commits since the last tag
62
+ COMMITS_SINCE=$(git rev-list ${LATEST_TAG}..HEAD --count 2>/dev/null || echo "0")
63
+
64
+ if [ "$COMMITS_SINCE" -gt "0" ]; then
65
+ # Bump patch to lock current state
66
+ VERSION="${LATEST_TAG#v}"
67
+ IFS='.' read -r MAJOR MINOR PATCH <<< "$VERSION"
68
+ PATCH=$((PATCH + 1))
69
+ NEW_TAG="v${MAJOR}.${MINOR}.${PATCH}"
70
+
71
+ git tag -a "$NEW_TAG" -m "Pre-release lock before staging merge"
72
+ git push origin "$NEW_TAG"
73
+ echo "new_tag=$NEW_TAG" >> $GITHUB_OUTPUT
74
+ echo "Created pre-release tag: $NEW_TAG"
75
+ else
76
+ echo "new_tag=$LATEST_TAG" >> $GITHUB_OUTPUT
77
+ echo "No new commits since $LATEST_TAG, skipping tag."
78
+ fi
79
+
80
+ # Generate changelog via AI
81
+ changelog:
82
+ needs: [check-source, pre-release-tag]
83
+ if: needs.check-source.outputs.is_staging == 'true'
84
+ uses: ./.github/workflows/ai-changelog.yml
85
+ with:
86
+ base_ref: ${{ needs.pre-release-tag.outputs.last_tag }}
87
+ head_ref: ${{ github.event.pull_request.head.sha }}
88
+ secrets:
89
+ GEMINI_API_KEY: ${{ secrets.GEMINI_API_KEY }}
90
+
91
+ # Post changelog as PR comment
92
+ comment:
93
+ needs: [check-source, changelog, pre-release-tag]
94
+ if: needs.check-source.outputs.is_staging == 'true'
95
+ runs-on: ubuntu-latest
96
+ permissions:
97
+ pull-requests: write
98
+ steps:
99
+ - name: Post changelog comment
100
+ uses: actions/github-script@v7
101
+ with:
102
+ script: |
103
+ const tag = '${{ needs.pre-release-tag.outputs.new_tag }}';
104
+ const changelog = `${{ needs.changelog.outputs.changelog }}`;
105
+
106
+ const body = `## Release Changelog\n\n` +
107
+ `**Pre-release tag:** \`${tag}\`\n\n` +
108
+ `---\n\n${changelog}\n\n` +
109
+ `---\n*Generated by climaybe*`;
110
+
111
+ // Find existing bot comment
112
+ const { data: comments } = await github.rest.issues.listComments({
113
+ owner: context.repo.owner,
114
+ repo: context.repo.repo,
115
+ issue_number: context.issue.number,
116
+ });
117
+
118
+ const existing = comments.find(c =>
119
+ c.user.type === 'Bot' && c.body.includes('Generated by climaybe')
120
+ );
121
+
122
+ if (existing) {
123
+ await github.rest.issues.updateComment({
124
+ owner: context.repo.owner,
125
+ repo: context.repo.repo,
126
+ comment_id: existing.id,
127
+ body,
128
+ });
129
+ } else {
130
+ await github.rest.issues.createComment({
131
+ owner: context.repo.owner,
132
+ repo: context.repo.repo,
133
+ issue_number: context.issue.number,
134
+ body,
135
+ });
136
+ }