2020 runs-on : ubuntu-latest
2121 outputs :
2222 version : ${{ steps.read_version.outputs.value }}
23- needs_release : ${{ steps.create_tag.outputs.tag_existed != 'true' }}
23+ tag_name : ${{ steps.create_tag.outputs.tag_name }}
24+ needs_release : ${{ steps.create_tag.outputs.release_published != 'true' }}
2425 cn_release_stdout : ${{ steps.create_cn_release.outputs.stdout }}
25- gh_release_url : ${{ steps.create_gh_release.outputs.url }}
26+ gh_release_url : ${{ steps.create_gh_release.outputs.url || steps.create_tag.outputs.release_url }}
2627 permissions :
2728 contents : write
2829 id-token : write
3637 file : ${{ env.APP_CARGO_TOML }}
3738 field : " package.version"
3839
39- - name : Create tag
40+ - name : Prepare release
4041 id : create_tag
41- if : ${{ steps.create_tag.outputs.tag_existed != 'true' }}
4242 uses : actions/github-script@v7
4343 with :
4444 script : |
@@ -47,48 +47,88 @@ jobs:
4747
4848 const TAG_EXISTED = "tag_existed";
4949 const TAG_NAME = "tag_name";
50+ const RELEASE_PUBLISHED = "release_published";
51+ const RELEASE_URL = "release_url";
5052
5153 core.setOutput(TAG_NAME, tag);
5254
5355 async function main() {
5456 let tagExisted = true;
57+ let tagSha = "";
58+ let releasePublished = false;
59+ let releaseUrl = "";
5560
5661 try {
57- await github.rest.git.getRef({
62+ const tagRefResponse = await github.rest.git.getRef({
5863 ref: tagRef,
5964 owner: context.repo.owner,
6065 repo: context.repo.repo,
6166 });
6267
6368 tagExisted = true;
64- core.notice(`Release skipped as tag '${tag}' already exists. Update the version in '${{ env.APP_CARGO_TOML }}' before starting another release.`);
69+ tagSha = tagRefResponse.data.object.sha;
70+ core.notice(`Tag '${tag}' already exists. Reusing it for this release run.`);
6571 } catch (error) {
6672 if ("status" in error && error.status === 404) tagExisted = false;
6773 else throw error;
6874 }
6975
70- core.setOutput(TAG_EXISTED, tagExisted);
71-
7276 if (!tagExisted)
7377 await github.rest.git.createRef({
7478 ref: `refs/${tagRef}`,
7579 owner: context.repo.owner,
7680 repo: context.repo.repo,
7781 sha: context.sha,
7882 });
83+
84+ const releases = await github.paginate(github.rest.repos.listReleases, {
85+ owner: context.repo.owner,
86+ repo: context.repo.repo,
87+ per_page: 100,
88+ });
89+
90+ const release = releases.find((release) => release.tag_name === tag);
91+
92+ if (release) {
93+ releaseUrl = release.html_url;
94+ releasePublished = !release.draft;
95+
96+ if (releasePublished)
97+ core.notice(`Release skipped because '${tag}' is already published: ${releaseUrl}`);
98+ else
99+ core.notice(`Draft release '${tag}' already exists. Continuing build and upload.`);
100+ }
101+
102+ if (tagExisted && !releasePublished && tagSha !== context.sha) {
103+ await github.rest.git.updateRef({
104+ ref: tagRef,
105+ owner: context.repo.owner,
106+ repo: context.repo.repo,
107+ sha: context.sha,
108+ force: true,
109+ });
110+
111+ core.notice(`Updated unpublished tag '${tag}' to ${context.sha}.`);
112+ }
113+
114+ core.setOutput(TAG_EXISTED, tagExisted);
115+ core.setOutput(RELEASE_PUBLISHED, releasePublished);
116+ core.setOutput(RELEASE_URL, releaseUrl);
79117 }
80118
81- main();
119+ await main();
82120
83121 - name : Create draft CN release
84122 id : create_cn_release
123+ if : ${{ steps.create_tag.outputs.release_published != 'true' }}
85124 uses : crabnebula-dev/cloud-release@v0
86125 with :
87126 command : release draft ${{ env.CN_APPLICATION }} ${{ steps.read_version.outputs.value }} --framework tauri
88127 api-key : ${{ secrets.CN_API_KEY }}
89128
90129 - name : Create draft GH release
91130 id : create_gh_release
131+ if : ${{ steps.create_tag.outputs.release_published != 'true' }}
92132 # TODO: Change to stable version when available
93133 uses : softprops/action-gh-release@v2
94134 with :
98138 generate_release_notes : true
99139
100140 - name : Update Discord interaction
101- if : ${{ inputs.interactionId != '' }}
141+ if : ${{ inputs.interactionId != '' && steps.create_tag.outputs.release_published != 'true' }}
102142 uses : actions/github-script@v7
103143 with :
104144 script : |
@@ -143,14 +183,16 @@ jobs:
143183 - target : aarch64-apple-darwin
144184 runner : macos-latest-xlarge
145185 - target : x86_64-pc-windows-msvc
146- runner : windows-latest
186+ runner : windows-2022
147187 env :
148188 TURBO_TOKEN : ${{ secrets.TURBO_TOKEN }}
149189 TURBO_TEAM : ${{ secrets.TURBO_TEAM }}
150190 runs-on : ${{ matrix.settings.runner }}
151191 steps :
152192 - name : Checkout repository
153193 uses : actions/checkout@v4
194+ with :
195+ ref : ${{ needs.draft.outputs.tag_name }}
154196
155197 - name : Create API Key File
156198 run : echo "${{ secrets.APPLE_API_KEY_FILE }}" > api.p8
@@ -188,11 +230,21 @@ jobs:
188230 echo 'VITE_SERVER_URL=${{ secrets.NEXT_PUBLIC_WEB_URL }}' >> .env
189231 echo 'RUST_TARGET_TRIPLE=${{ matrix.settings.target }}' >> .env
190232
233+ - name : Run cap-setup
234+ shell : bash
235+ run : pnpm -w cap-setup
236+ env :
237+ RUST_TARGET_TRIPLE : ${{ matrix.settings.target }}
238+ APPLE_SIGNING_IDENTITY : ${{ secrets.APPLE_SIGNING_IDENTITY }}
239+ APPLE_KEYCHAIN : ${{ runner.temp }}/build.keychain
240+
241+ - name : Build cap-muxer sidecar
242+ shell : bash
243+ run : ./scripts/build-cap-muxer.sh ${{ matrix.settings.target }}
244+
191245 - name : Build app
192246 working-directory : apps/desktop
193- run : |
194- pnpm -w cap-setup
195- pnpm build:tauri --target ${{ matrix.settings.target }} --config src-tauri/tauri.prod.conf.json
247+ run : pnpm build:tauri --target ${{ matrix.settings.target }} --config src-tauri/tauri.prod.conf.json
196248 env :
197249 # https://github.com/tauri-apps/tauri-action/issues/740
198250 CI : false
@@ -208,6 +260,7 @@ jobs:
208260 APPLE_KEYCHAIN : ${{ runner.temp }}/build.keychain
209261 TAURI_SIGNING_PRIVATE_KEY : ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }}
210262 TAURI_SIGNING_PRIVATE_KEY_PASSWORD : ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }}
263+ RUST_TARGET_TRIPLE : ${{ matrix.settings.target }}
211264
212265 - name : Upload unsigned Windows installer
213266 if : ${{ runner.os == 'Windows' }}
0 commit comments