Skip to content

Commit c0d0f6b

Browse files
Merge pull request #150 from IntersectMBO/chore/update-post-release-to-x
chore: update post-release-to-x workflow
2 parents 274792a + 8f95354 commit c0d0f6b

File tree

1 file changed

+123
-31
lines changed

1 file changed

+123
-31
lines changed

.github/workflows/post-release-to-x.yml

Lines changed: 123 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -9,88 +9,180 @@ on:
99
jobs:
1010
notify:
1111
runs-on: ubuntu-latest
12-
if: ${{ github.event.workflow_run.conclusion == 'success' }}
12+
13+
# Run if: workflow_dispatch (manual) OR workflow_run completed successfully
14+
if: ${{ github.event_name == 'workflow_dispatch' || github.event.workflow_run.conclusion == 'success' }}
1315
steps:
16+
- name: Checkout
17+
uses: actions/checkout@v4
18+
1419
- name: Get latest release with changes
1520
id: release
1621
run: |
1722
# Get the latest @evolution-sdk release with actual changes (not just dependency updates)
1823
RELEASES=$(gh api /repos/${{ github.repository }}/releases --jq '[.[] | select(.tag_name | startswith("@evolution-sdk/"))]')
19-
24+
2025
# Variables to track packages
2126
FALLBACK_TAG=""
2227
FALLBACK_URL=""
28+
FALLBACK_VERSION=""
2329
EVOLUTION_TAG=""
2430
EVOLUTION_URL=""
25-
31+
EVOLUTION_VERSION=""
32+
2633
for i in $(seq 0 10); do
2734
RELEASE=$(echo $RELEASES | jq ".[$i]")
2835
if [ "$RELEASE" = "null" ]; then
2936
break
3037
fi
31-
38+
3239
CREATED=$(echo $RELEASE | jq -r .created_at)
3340
CREATED_TIMESTAMP=$(date -d "$CREATED" +%s)
3441
NOW=$(date +%s)
3542
AGE=$((NOW - CREATED_TIMESTAMP))
36-
43+
3744
# If created in last hour, check if it has real changes (not just dependency updates)
3845
if [ $AGE -lt 3600 ]; then
3946
BODY=$(echo $RELEASE | jq -r .body)
40-
TAG=$(echo $RELEASE | jq -r .tag_name)
41-
URL=$(echo $RELEASE | jq -r .html_url)
42-
47+
RELEASE_TAG=$(echo $RELEASE | jq -r .tag_name)
48+
RELEASE_URL=$(echo $RELEASE | jq -r .html_url)
49+
4350
# Check for actual changes (not just "Updated dependencies")
4451
CHANGES_SECTION=$(echo "$BODY" | grep -A 100 "Patch Changes\|Minor Changes\|Major Changes" | tail -n +2)
4552
REAL_CHANGES=$(echo "$CHANGES_SECTION" | grep -v "Updated dependencies" | grep -v "^[[:space:]]*-[[:space:]]*@" | grep -v "^[[:space:]]*$" | head -1)
46-
53+
4754
if [ -n "$REAL_CHANGES" ]; then
55+
# Extract version number (remove scoped package prefix)
56+
VERSION=${RELEASE_TAG##*@}
57+
4858
# Check if this is the main evolution package
49-
if [[ "$TAG" == "@evolution-sdk/evolution@"* ]]; then
59+
if [[ "$RELEASE_TAG" == "@evolution-sdk/evolution@"* ]]; then
5060
if [ -z "$EVOLUTION_TAG" ]; then
51-
EVOLUTION_TAG=$TAG
52-
EVOLUTION_URL=$URL
61+
EVOLUTION_TAG=$RELEASE_TAG
62+
EVOLUTION_URL=$RELEASE_URL
63+
EVOLUTION_VERSION=$VERSION
5364
fi
5465
else
5566
# Save as fallback if we haven't found one yet
5667
if [ -z "$FALLBACK_TAG" ]; then
57-
FALLBACK_TAG=$TAG
58-
FALLBACK_URL=$URL
68+
FALLBACK_TAG=$RELEASE_TAG
69+
FALLBACK_URL=$RELEASE_URL
70+
FALLBACK_VERSION=$VERSION
5971
fi
6072
fi
6173
fi
6274
fi
6375
done
64-
76+
6577
# Prioritize evolution package, fall back to other packages
6678
if [ -n "$EVOLUTION_TAG" ]; then
67-
CLEAN_TAG=$(echo $EVOLUTION_TAG | sed 's/^@//; s/@/ /')
68-
echo "tag=$CLEAN_TAG" >> $GITHUB_OUTPUT
79+
echo "tag=$EVOLUTION_TAG" >> $GITHUB_OUTPUT
6980
echo "url=$EVOLUTION_URL" >> $GITHUB_OUTPUT
81+
echo "version=$EVOLUTION_VERSION" >> $GITHUB_OUTPUT
7082
echo "found=true" >> $GITHUB_OUTPUT
7183
elif [ -n "$FALLBACK_TAG" ]; then
72-
CLEAN_TAG=$(echo $FALLBACK_TAG | sed 's/^@//; s/@/ /')
73-
echo "tag=$CLEAN_TAG" >> $GITHUB_OUTPUT
84+
echo "tag=$FALLBACK_TAG" >> $GITHUB_OUTPUT
7485
echo "url=$FALLBACK_URL" >> $GITHUB_OUTPUT
86+
echo "version=$FALLBACK_VERSION" >> $GITHUB_OUTPUT
7587
echo "found=true" >> $GITHUB_OUTPUT
7688
else
7789
echo "found=false" >> $GITHUB_OUTPUT
7890
fi
7991
env:
8092
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
81-
82-
- name: Tweet new release
93+
94+
- name: Extract code from CHANGELOG
8395
if: steps.release.outputs.found == 'true'
84-
uses: nearform-actions/github-action-notify-twitter@v1
96+
id: extract
97+
run: |
98+
VERSION="${{ steps.release.outputs.version }}"
99+
100+
# Extract first code block from this version's section
101+
awk -v ver="$VERSION" '
102+
index($0, "## " ver) == 1 { found_version=1; next }
103+
found_version && /^## [0-9]/ { exit }
104+
found_version && /```typescript/ { in_code=1; next }
105+
found_version && /```/ && in_code { exit }
106+
in_code { print }
107+
' packages/evolution/CHANGELOG.md > /tmp/snippet.ts
108+
109+
if [ -s /tmp/snippet.ts ]; then
110+
echo "has_code=true" >> $GITHUB_OUTPUT
111+
else
112+
echo "has_code=false" >> $GITHUB_OUTPUT
113+
fi
114+
115+
- name: Setup Node.js
116+
if: steps.release.outputs.found == 'true' && steps.extract.outputs.has_code == 'true'
117+
uses: actions/setup-node@v4
85118
with:
86-
message: |
87-
📦 New Release: ${{ steps.release.outputs.tag }}
119+
node-version: '22'
88120

89-
Check out what's new 👇
90-
${{ steps.release.outputs.url }}
121+
- name: Generate code image
122+
if: steps.release.outputs.found == 'true' && steps.extract.outputs.has_code == 'true'
123+
run: |
124+
npx -y carbon-now-cli /tmp/snippet.ts \
125+
--save-to . \
126+
--save-as release-snippet \
127+
--headless \
128+
--settings '{"theme":"blackboard","backgroundColor":"#FD4B1B","windowTheme":"none","windowControls":true,"fontFamily":"JetBrains Mono","fontSize":"14px","lineNumbers":false,"paddingVertical":"40px","paddingHorizontal":"40px","dropShadow":true,"dropShadowOffsetY":"10px","dropShadowBlurRadius":"30px","exportSize":"2x","watermark":false}'
91129
92-
Happy building!
93-
twitter-app-key: ${{ secrets.TWITTER_API_KEY }}
94-
twitter-app-secret: ${{ secrets.TWITTER_API_SECRET }}
95-
twitter-access-token: ${{ secrets.TWITTER_ACCESS_TOKEN }}
96-
twitter-access-token-secret: ${{ secrets.TWITTER_ACCESS_TOKEN_SECRET }}
130+
- name: Post to X with image
131+
if: steps.release.outputs.found == 'true' && steps.extract.outputs.has_code == 'true'
132+
run: |
133+
npm install twitter-api-v2
134+
node -e "
135+
const { TwitterApi } = require('twitter-api-v2');
136+
const client = new TwitterApi({
137+
appKey: process.env.TWITTER_API_KEY,
138+
appSecret: process.env.TWITTER_API_SECRET,
139+
accessToken: process.env.TWITTER_ACCESS_TOKEN,
140+
accessSecret: process.env.TWITTER_ACCESS_TOKEN_SECRET,
141+
});
142+
(async () => {
143+
const mediaId = await client.v1.uploadMedia('./release-snippet.png');
144+
await client.v2.tweet({
145+
text: 'Evolution SDK v${{ steps.release.outputs.version }} out now\n${{ steps.release.outputs.url }}\nHappy building!',
146+
media: { media_ids: [mediaId] }
147+
});
148+
})()
149+
.then(() => process.exit(0))
150+
.catch(err => {
151+
console.error(err);
152+
process.exit(1);
153+
});
154+
"
155+
env:
156+
TWITTER_API_KEY: ${{ secrets.TWITTER_API_KEY }}
157+
TWITTER_API_SECRET: ${{ secrets.TWITTER_API_SECRET }}
158+
TWITTER_ACCESS_TOKEN: ${{ secrets.TWITTER_ACCESS_TOKEN }}
159+
TWITTER_ACCESS_TOKEN_SECRET: ${{ secrets.TWITTER_ACCESS_TOKEN_SECRET }}
160+
161+
- name: Post to X without image
162+
if: steps.release.outputs.found == 'true' && steps.extract.outputs.has_code == 'false'
163+
run: |
164+
npm install twitter-api-v2@1
165+
node -e "
166+
const { TwitterApi } = require('twitter-api-v2');
167+
const client = new TwitterApi({
168+
appKey: process.env.TWITTER_API_KEY,
169+
appSecret: process.env.TWITTER_API_SECRET,
170+
accessToken: process.env.TWITTER_ACCESS_TOKEN,
171+
accessSecret: process.env.TWITTER_ACCESS_TOKEN_SECRET,
172+
});
173+
(async () => {
174+
await client.v2.tweet({
175+
text: 'Evolution SDK v${{ steps.release.outputs.version }} out now\n${{ steps.release.outputs.url }}\nHappy building!'
176+
});
177+
})()
178+
.then(() => process.exit(0))
179+
.catch(err => {
180+
console.error(err);
181+
process.exit(1);
182+
});
183+
"
184+
env:
185+
TWITTER_API_KEY: ${{ secrets.TWITTER_API_KEY }}
186+
TWITTER_API_SECRET: ${{ secrets.TWITTER_API_SECRET }}
187+
TWITTER_ACCESS_TOKEN: ${{ secrets.TWITTER_ACCESS_TOKEN }}
188+
TWITTER_ACCESS_TOKEN_SECRET: ${{ secrets.TWITTER_ACCESS_TOKEN_SECRET }}

0 commit comments

Comments
 (0)