diff --git a/.github/workflows/ci-artifacts.yml b/.github/workflows/ci-artifacts.yml new file mode 100644 index 0000000000..c47d60de2f --- /dev/null +++ b/.github/workflows/ci-artifacts.yml @@ -0,0 +1,127 @@ +name: ci-artifacts + +on: + push: + branches: + - main + pull_request: + +# For the continuous `ci-artifacts` release +permissions: + contents: write + +env: + LC_CTYPE: C.UTF-8 + +jobs: + build-installers-artifact: + if: github.repository_owner == 'git-for-windows' && github.event_name == 'push' && github.ref == 'refs/heads/main' + runs-on: windows-latest + steps: + - name: clone git-sdk-32 + run: | + git init --bare git-sdk-32.git && + git --git-dir=git-sdk-32.git remote add origin https://github.com/${{github.repository}} && + git --git-dir=git-sdk-32.git config remote.origin.promisor true && + git --git-dir=git-sdk-32.git config remote.origin.partialCloneFilter blob:none && + git --git-dir=git-sdk-32.git fetch --depth=1 origin ${{github.sha}} && + git --git-dir=git-sdk-32.git update-ref --no-deref HEAD ${{github.sha}} + - name: clone build-extra + run: git clone --depth=1 --single-branch -b main https://github.com/git-for-windows/build-extra + - name: build git-sdk-32-build-installers + shell: bash + run: sh -x ./build-extra/please.sh create-sdk-artifact --sdk=git-sdk-32.git build-installers + - name: compress artifact + shell: bash + run: | + mkdir build-installers-artifacts && + (cd build-installers && /c/Windows/system32/tar.exe --zstd --options=zstd:compression-level=10 \ + -cf ../build-installers-artifacts/git-sdk-i686-build-installers.tar.zst * .[0-9A-Za-z]*) + - name: upload build-installers artifacts + uses: actions/upload-artifact@v6 + with: + name: build-installers + path: build-installers-artifacts + + publish-release-assets: + if: github.event_name == 'push' && github.ref == 'refs/heads/main' + runs-on: ubuntu-latest + needs: + - build-installers-artifact + steps: + - name: download build-installers artifacts + uses: actions/download-artifact@v5 + with: + name: build-installers + path: ${{github.workspace}} + - name: publish release assets + uses: actions/github-script@v8 + with: + script: | + const req = { owner: context.repo.owner, repo: context.repo.repo } + // find or create the GitHub release named `ci-artifacts` + const release = await (async () => { + try { + return await github.rest.repos.getReleaseByTag({ ...req, tag: 'ci-artifacts' }); + } catch (e) { + if (e.status === 404) { + // create the `ci-artifacts` GitHub release based on the current revision + const workflowRunsURL = `${context.serverUrl}/${ + process.env.GITHUB_WORKFLOW_REF.replace(/\/\.github\/workflows\/([^@]+).*/, '/actions/workflows/$1') + }` + return await github.rest.repos.createRelease({ + ... req, + tag_name: 'ci-artifacts', + body: `Continuous release of \`ci-artifacts\` + + This release is automatically updated by the [ci-artifacts](${workflowRunsURL}) workflow. + + For technical reasons, allow up to a minute for release assets to be missing while they are updated.`, + }); + } + throw e; + } + })() + + const fs = require('fs') + for (const fileName of [ + 'git-sdk-i686-build-installers.tar.zst', + ]) { + console.log(`Uploading ${fileName}`) + const uploadReq = { + ...req, + release_id: release.data.id, + name: fileName, + headers: { + 'content-length': (await fs.promises.stat(fileName)).size, + }, + data: fs.createReadStream(fileName), + } + + // if the asset does not yet exist, simply upload it + const originalAsset = release.data.assets.filter(asset => asset.name === fileName).pop() + if (!originalAsset) { + const asset = await github.rest.repos.uploadReleaseAsset(uploadReq) + console.log(`Uploaded to ${asset.data.browser_download_url}`) + continue + } + + // otherwise upload it using a temporary file name, + // then delete the old asset + // and then rename the new asset; + // this way, the asset is not missing for a long time + const asset = await github.rest.repos.uploadReleaseAsset({ ...uploadReq, name: `tmp.${fileName}` }) + await github.rest.repos.deleteReleaseAsset({ ...req, asset_id: originalAsset.id }) + const updatedAsset = await github.rest.repos.updateReleaseAsset({...req, + asset_id: asset.data.id, + name: fileName, + label: fileName, + }) + console.log(`Updated ${updatedAsset.data.browser_download_url}`) + } + + await github.rest.git.updateRef({ + ...req, + ref: 'tags/ci-artifacts', + sha: process.env.GITHUB_SHA, + })