88
99jobs :
1010 test :
11+ if : ${{ !startsWith(github.event.head_commit.message, 'chore(release):') }}
1112 runs-on : ubuntu-latest
1213 steps :
1314 - name : Checkout
3031 python -c "import hatch; print('Hatch package imports successfully')"
3132
3233 release :
34+ if : ${{ !startsWith(github.event.head_commit.message, 'chore(release):') }}
3335 needs : test
3436 runs-on : ubuntu-latest
37+ outputs :
38+ published : ${{ steps.semantic_release.outputs.published }}
39+ tag : ${{ steps.semantic_release.outputs.tag }}
3540 steps :
3641 - name : Generate GitHub App Token
3742 id : generate_token
@@ -58,10 +63,115 @@ jobs:
5863 run : npm audit signatures
5964
6065 - name : Release
66+ id : semantic_release
6167 env :
6268 GITHUB_TOKEN : ${{ steps.generate_token.outputs.token }}
6369 GH_TOKEN : ${{ steps.generate_token.outputs.token }}
6470 run : |
6571 git config user.name "github-actions[bot]"
6672 git config user.email "github-actions[bot]@users.noreply.github.com"
67- npx semantic-release
73+ node <<'EOF'
74+ const fs = require('fs');
75+
76+ (async () => {
77+ const semanticReleaseModule = await import('semantic-release');
78+ const semanticRelease = semanticReleaseModule.default || semanticReleaseModule;
79+ const result = await semanticRelease();
80+
81+ if (!process.env.GITHUB_OUTPUT) {
82+ throw new Error('GITHUB_OUTPUT is not set');
83+ }
84+
85+ if (!result) {
86+ fs.appendFileSync(process.env.GITHUB_OUTPUT, 'published=false\n');
87+ fs.appendFileSync(process.env.GITHUB_OUTPUT, 'tag=\n');
88+ return;
89+ }
90+
91+ fs.appendFileSync(process.env.GITHUB_OUTPUT, 'published=true\n');
92+ fs.appendFileSync(process.env.GITHUB_OUTPUT, `tag=${result.nextRelease.gitTag}\n`);
93+ })().catch((error) => {
94+ console.error(error);
95+ process.exit(1);
96+ });
97+ EOF
98+
99+ publish :
100+ name : Publish released package
101+ needs : release
102+ if : ${{ needs.release.outputs.published == 'true' }}
103+ uses : ./.github/workflows/publish.yml
104+ with :
105+ tag : ${{ needs.release.outputs.tag }}
106+ secrets : inherit
107+
108+ notify-discord :
109+ name : Notify Discord
110+ needs :
111+ - release
112+ - publish
113+ if : ${{ needs.release.outputs.published == 'true' && needs.publish.result == 'success' }}
114+ runs-on : ubuntu-latest
115+ permissions :
116+ contents : read
117+ steps :
118+ - name : Resolve GitHub release
119+ id : release
120+ uses : actions/github-script@v8
121+ env :
122+ TAG_NAME : ${{ needs.publish.outputs.tag }}
123+ with :
124+ script : |
125+ const { data: release } = await github.rest.repos.getReleaseByTag({
126+ owner: context.repo.owner,
127+ repo: context.repo.repo,
128+ tag: process.env.TAG_NAME,
129+ });
130+
131+ core.setOutput('tag_name', release.tag_name);
132+ core.setOutput('html_url', release.html_url);
133+ core.setOutput('is_prerelease', String(release.prerelease));
134+
135+ - name : Build Discord payload
136+ id : discord
137+ uses : actions/github-script@v8
138+ env :
139+ TAG_NAME : ${{ steps.release.outputs.tag_name }}
140+ HTML_URL : ${{ steps.release.outputs.html_url }}
141+ IS_PRERELEASE : ${{ steps.release.outputs.is_prerelease }}
142+ with :
143+ script : |
144+ const isPrerelease = process.env.IS_PRERELEASE === 'true';
145+ const tagName = process.env.TAG_NAME;
146+ const htmlUrl = process.env.HTML_URL;
147+
148+ core.setOutput('content', isPrerelease ? '' : '<@&1418053865818951721>');
149+ core.setOutput('title', isPrerelease
150+ ? '🧪 Hatch Pre-release Available for Testing'
151+ : '🎉 New *Hatch!* Release Available!');
152+ core.setOutput('description', isPrerelease
153+ ? `**Version \`${tagName}\`** is now available for testing!\n\n⚠️ **This is a pre-release** - expect potential bugs and breaking changes\n🔬 Perfect for testing new features and providing feedback\n📋 Click [here](${htmlUrl}) to view what's new and download\n\n💻 Install with pip:\n\`\`\`bash\npip install hatch-xclam==${tagName}\n\`\`\`\n\nHelp us make *Hatch!* better by testing and reporting [issues](https://github.com/CrackingShells/Hatch/issues)! 🐛➡️✨`
154+ : `**Version \`${tagName}\`** has been released!\n\n🚀 Get the latest features and improvements\n📚 Click [here](${htmlUrl}) to view the changelog and download\n\n💻 Install with pip:\n\`\`\`bash\npip install hatch-xclam\n\`\`\`\n\nHappy MCP coding with *Hatch!* 🐣`);
155+ core.setOutput('color', isPrerelease ? '0xff9500' : '0x00ff88');
156+ core.setOutput('username', isPrerelease
157+ ? 'Cracking Shells Pre-release Bot'
158+ : 'Cracking Shells Release Bot');
159+ core.setOutput('image', isPrerelease
160+ ? 'https://raw.githubusercontent.com/CrackingShells/.github/main/resources/images/hatch_icon_dark_bg_transparent.png'
161+ : 'https://raw.githubusercontent.com/CrackingShells/.github/main/resources/images/hatch_icon_light_bg_transparent.png');
162+ core.setOutput('avatar_url', isPrerelease
163+ ? 'https://raw.githubusercontent.com/CrackingShells/.github/main/resources/images/cs_core_dark_bg.png'
164+ : 'https://raw.githubusercontent.com/CrackingShells/.github/main/resources/images/cs_icon_light_bg.png');
165+
166+ - name : Send Discord notification
167+ uses : sarisia/actions-status-discord@v1
168+ with :
169+ webhook : ${{ secrets.DISCORD_HATCH_ANNOUNCEMENTS }}
170+ nodetail : true
171+ content : ${{ steps.discord.outputs.content }}
172+ title : ${{ steps.discord.outputs.title }}
173+ description : ${{ steps.discord.outputs.description }}
174+ color : ${{ steps.discord.outputs.color }}
175+ username : ${{ steps.discord.outputs.username }}
176+ image : ${{ steps.discord.outputs.image }}
177+ avatar_url : ${{ steps.discord.outputs.avatar_url }}
0 commit comments