diff --git a/.github/actions/check-run-action/action.yml b/.github/actions/check-run-action/action.yml index 139d52ad..93e1e00b 100644 --- a/.github/actions/check-run-action/action.yml +++ b/.github/actions/check-run-action/action.yml @@ -9,7 +9,6 @@ inputs: required: true owner: description: 'The owner of the target repository' - default: 'git-for-windows' repo: description: 'The name of the target repository' rev: diff --git a/.github/workflows/git-artifacts.yml b/.github/workflows/git-artifacts.yml index d93a99cf..cb3042b9 100644 --- a/.github/workflows/git-artifacts.yml +++ b/.github/workflows/git-artifacts.yml @@ -21,9 +21,10 @@ on: existing_git_tag: description: 'Existing tag to build from. Requires tag_git_workflow_run_id to be empty' required: false - build_extra_rev_for_existing_git_tag: - description: 'build-extra revision to use if building from an existing Git tag. Required if existing_git_tag is non-empty' + release_branch: + description: 'The branch name to use for this release (e.g. `git-2.44.x-releases`)' required: false + type: string env: GPG_OPTIONS: "--batch --yes --no-tty --list-options no-show-photos --verify-options no-show-photos --pinentry-mode loopback" @@ -31,11 +32,12 @@ env: USERPROFILE: "${{github.workspace}}\\home" ARTIFACTS_TO_BUILD: "${{github.event.inputs.artifacts}}" ARCHITECTURE: "${{github.event.inputs.architecture}}" - OWNER: git-for-windows + OWNER: ${{ github.repository_owner }} REPO: git TAG_GIT_WORKFLOW_RUN_ID: "${{github.event.inputs.tag_git_workflow_run_id}}" EXISTING_GIT_TAG: "${{github.event.inputs.existing_git_tag}}" - BUILD_EXTRA_REV_FOR_EXISTING_GIT_TAG: "${{github.event.inputs.build_extra_rev_for_existing_git_tag}}" + RELEASE_BRANCH: "${{github.event.inputs.release_branch}}" + GIT_OR_MINGIT: "Git" defaults: run: @@ -51,10 +53,59 @@ jobs: mingw_package_prefix: ${{steps.configure-environment.outputs.MINGW_PACKAGE_PREFIX}} sdk_repo_arch: ${{steps.configure-environment.outputs.SDK_REPO_ARCH}} check-run-state: ${{steps.check-run-state.outputs.check-run-state}} + release-branch: ${{steps.configure-environment.outputs.release-branch}} steps: - name: clone git-for-windows-automation uses: actions/checkout@v5 + - name: configure token + if: github.repository_visibility == 'private' + id: token + uses: actions/github-script@v7 + with: + result-encoding: string + script: | + const fs = require('fs') + if (!fs.existsSync(process.env.HOME)) fs.mkdirSync(process.env.HOME) + const { callGit, getPushAuthorizationHeader } = require('./repository-updates.js') + for (const repo of [ + 'build-extra', + 'git', + 'git-sdk-${{ env.ARCHITECTURE == 'x86_64' && '64' || (env.ARCHITECTURE == 'aarch64' && 'arm64' || '32') }}', + 'MINGW-packages' + ]) { + const header = await getPushAuthorizationHeader( + console, + core.setSecret, + ${{ secrets.GH_APP_ID }}, + ${{ toJSON(secrets.GH_APP_PRIVATE_KEY) }}, + process.env.OWNER, + repo + ) + console.log(callGit(['config', '--global', `http.https://github.com/${process.env.OWNER}/${repo}.extraHeader`, header])) + } + + // return an access token for use in the "wait if workflow run has not finished yet" step + if (process.env.EXISTING_GIT_TAG) return '' + const getAppInstallationId = require('./get-app-installation-id') + const installationId = await getAppInstallationId( + console, + ${{ secrets.GH_APP_ID }}, + ${{ toJSON(secrets.GH_APP_PRIVATE_KEY) }}, + context.repo.owner, + context.repo.repo + ) + + const getInstallationAccessToken = require('./get-installation-access-token') + const { token: accessToken } = await getInstallationAccessToken( + console, + ${{ secrets.GH_APP_ID }}, + ${{ toJSON(secrets.GH_APP_PRIVATE_KEY) }}, + installationId + ) + core.setSecret(accessToken) + return accessToken - name: Construct bundle-artifacts from existing tag + id: handle-existing-git-tag if: env.EXISTING_GIT_TAG != '' run: | die () { @@ -65,8 +116,26 @@ jobs: test -z "$TAG_GIT_WORKFLOW_RUN_ID" || die 'existing_git_tag cannot be used with tag_git_workflow_run_id!' - test -n "$BUILD_EXTRA_REV_FOR_EXISTING_GIT_TAG" || - die 'existing_git_tag needs build_extra_rev_for_existing_git_tag!' + if test mingit = "$ARTIFACTS_TO_BUILD" || test "mingit mingit-busybox" = "$ARTIFACTS_TO_BUILD" + then + GIT_OR_MINGIT=MinGit + echo "GIT_OR_MINGIT=MinGit" >>$GITHUB_ENV + fi + + if test -n "$RELEASE_BRANCH" + then + if test MinGit = "$GIT_OR_MINGIT" + then + RELEASE_BRANCH=mingit-"$(expr "$EXISTING_GIT_TAG" : 'v\?\([0-9]\+\.[0-9]\+\)\.\{0,1\}[0-9]*\(\.windows\.[0-9]*\)\?$')".x-releases && + test mingit-.x-releases != "$RELEASE_BRANCH" + else + RELEASE_BRANCH="${EXISTING_GIT_TAG%%.windows.*}" && + RELEASE_BRANCH=git-"${RELEASE_BRANCH#v}" && + test git- != "$RELEASE_BRANCH" + fi || + die "Could not determine release branch from '$EXISTING_GIT_TAG'" + echo "RELEASE_BRANCH=$RELEASE_BRANCH" >>$GITHUB_ENV + fi set -o pipefail && @@ -87,7 +156,7 @@ jobs: const { waitForWorkflowRunToFinish } = require('./workflow-runs') await waitForWorkflowRunToFinish( console, - '${{ secrets.GITHUB_TOKEN }}', + '${{ steps.token.outputs.result || secrets.GITHUB_TOKEN }}', context.repo.owner, context.repo.repo, process.env.TAG_GIT_WORKFLOW_RUN_ID @@ -97,9 +166,10 @@ jobs: if: env.TAG_GIT_WORKFLOW_RUN_ID != '' id: get-bundle-artifacts-url with: + github-token: ${{ steps.token.outputs.result || secrets.GITHUB_TOKEN }} script: | - if (process.env.EXISTING_GIT_TAG || process.env.BUILD_EXTRA_REV_FOR_EXISTING_GIT_TAG) { - throw new Error('tag_git_workflow_run_id cannot be used with existing_git_tag or build_extra_rev_for_existing_git_tag!') + if (process.env.EXISTING_GIT_TAG) { + throw new Error('tag_git_workflow_run_id cannot be used with existing_git_tag!') } const getDownloadURL = require('./get-workflow-run-artifact') const workflowRunId = process.env.TAG_GIT_WORKFLOW_RUN_ID @@ -116,6 +186,7 @@ jobs: unzip bundle-artifacts.zip -d bundle-artifacts echo "GIT_VERSION=$(cat bundle-artifacts/next_version)" >> $GITHUB_ENV echo "GIT_REV=$(cat bundle-artifacts/git-commit-oid)" >>$GITHUB_ENV + test ! -f bundle-artifacts/mingit-only || echo "GIT_OR_MINGIT=MinGit" >>$GITHUB_ENV - name: Mirror Check Run to ${{ env.OWNER }}/${{ env.REPO }} uses: ./.github/actions/check-run-action with: @@ -125,8 +196,8 @@ jobs: repo: ${{ env.REPO }} rev: ${{ env.GIT_REV }} check-run-name: "git-artifacts-${{ env.ARCHITECTURE }}" - title: "Build Git ${{ env.GIT_VERSION }} artifacts" - summary: "Build Git ${{ env.GIT_VERSION }} artifacts from commit ${{ env.GIT_REV }}${{ env.TAG_GIT_WORKFLOW_RUN_ID && format(' (tag-git run #{0})', env.TAG_GIT_WORKFLOW_RUN_ID) || '' }}" + title: "Build ${{ env.GIT_OR_MINGIT }} ${{ env.GIT_VERSION }} artifacts" + summary: "Build ${{ env.GIT_OR_MINGIT }} ${{ env.GIT_VERSION }} artifacts from commit ${{ env.GIT_REV }}${{ env.TAG_GIT_WORKFLOW_RUN_ID && format(' (tag-git run #{0})', env.TAG_GIT_WORKFLOW_RUN_ID) || '' }}" text: "For details, see [this run](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id}})." details-url: "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id}}" - name: Re-publish bundle-artifacts so the next job can easily use it @@ -167,27 +238,59 @@ jobs: echo "MINGW_PREFIX=$MINGW_PREFIX" >> $GITHUB_OUTPUT echo "MINGW_PACKAGE_PREFIX=$MINGW_PACKAGE_PREFIX" >> $GITHUB_ENV echo "MINGW_PACKAGE_PREFIX=$MINGW_PACKAGE_PREFIX" >> $GITHUB_OUTPUT + echo "SDK_REPO_ARCH=$SDK_REPO_ARCH" >> $GITHUB_ENV echo "SDK_REPO_ARCH=$SDK_REPO_ARCH" >> $GITHUB_OUTPUT test -n "$ARTIFACTS_TO_BUILD" || { ARTIFACTS_TO_BUILD="mingit" - test "$ARCHITECTURE" = i686 || ARTIFACTS_TO_BUILD="installer portable archive $ARTIFACTS_TO_BUILD" test "$ARCHITECTURE" = aarch64 || ARTIFACTS_TO_BUILD="$ARTIFACTS_TO_BUILD mingit-busybox" - test "$ARCHITECTURE" != x86_64 || ARTIFACTS_TO_BUILD="$ARTIFACTS_TO_BUILD nuget" + test -f bundle-artifacts/mingit-only || { + case "$ARCHITECTURE,$GIT_VERSION" in + i686,v2.49*|i686,v2[5-9][0-9]*) ;; # only build MinGit for i686 Git 2.49+ + *) + ARTIFACTS_TO_BUILD="installer portable archive $ARTIFACTS_TO_BUILD" + ;; + esac + test "$ARCHITECTURE" != x86_64 || ARTIFACTS_TO_BUILD="$ARTIFACTS_TO_BUILD nuget" + } } echo "ARTIFACTS_TO_BUILD=$ARTIFACTS_TO_BUILD" >> $GITHUB_ENV echo "PKG_CACHE_KEY=pkg-$GIT_VERSION-$ARCHITECTURE-$TAG_GIT_WORKFLOW_RUN_ID" >> $GITHUB_ENV + + if test -z "$RELEASE_BRANCH" + then + RELEASE_BRANCH="$(cat bundle-artifacts/release-branch)" + if test -z "$RELEASE_BRANCH" + then + echo "No release branch found in bundle-artifacts/release-branch" + exit 1 + fi + echo "RELEASE_BRANCH=$RELEASE_BRANCH" >> $GITHUB_ENV + fi + echo "release-branch=$RELEASE_BRANCH" >> $GITHUB_OUTPUT - name: Configure user run: USER_NAME="${{github.actor}}" && USER_EMAIL="${{github.actor}}@users.noreply.github.com" && - mkdir "$HOME" && + mkdir -p "$HOME" && git config --global user.name "$USER_NAME" && git config --global user.email "$USER_EMAIL" && echo "PACKAGER=$USER_NAME <$USER_EMAIL>" >> $GITHUB_ENV - uses: git-for-windows/setup-git-for-windows-sdk@v1 + if: env.OWNER == 'git-for-windows' && env.RELEASE_BRANCH == 'main' with: flavor: build-installers architecture: ${{env.architecture}} + - name: Set up Git for Windows SDK ${{ env.architecture }} (${{ env.RELEASE_BRANCH }}) + if: env.OWNER != 'git-for-windows' || env.RELEASE_BRANCH != 'main' + shell: bash + run: | + git -c checkout.workers=56 \ + clone --single-branch -b "$RELEASE_BRANCH" --depth 1 \ + https://github.com/$OWNER/git-sdk-$SDK_REPO_ARCH D:/git-sdk-$SDK_REPO_ARCH && + + cygpath -aw D:/git-sdk-$SDK_REPO_ARCH/usr/bin/core_perl >>$GITHUB_PATH && + cygpath -aw D:/git-sdk-$SDK_REPO_ARCH/usr/bin >>$GITHUB_PATH && + cygpath -aw D:/git-sdk-$SDK_REPO_ARCH/${MSYSTEM,,?}/bin >>$GITHUB_PATH - name: Create artifact build matrix uses: actions/github-script@v8 id: artifact-build-matrix @@ -196,7 +299,11 @@ jobs: core.info('Preparing artifact build matrix...') const createArtifactsMatrix = require('./create-artifacts-matrix') try { - const output = createArtifactsMatrix(process.env.ARTIFACTS_TO_BUILD, process.env.ARCHITECTURE) + const output = createArtifactsMatrix( + process.env.ARTIFACTS_TO_BUILD, + process.env.ARCHITECTURE, + ${{ github.repository_visibility == 'private' && 'true' || 'false' }} + ) core.info(`Will be using the following matrix: ${JSON.stringify(output)}`) return output } catch (e) { @@ -214,35 +321,33 @@ jobs: d=/usr/src/build-extra && if test ! -d $d/.git then - git clone --single-branch -b main https://github.com/git-for-windows/build-extra $d + git clone --single-branch -b "$RELEASE_BRANCH" https://github.com/$OWNER/build-extra $d else - git -C $d fetch https://github.com/git-for-windows/build-extra main && - git -C $d switch -C main FETCH_HEAD + git -C $d fetch https://github.com/$OWNER/build-extra "$RELEASE_BRANCH" && + git -C $d switch -C "$RELEASE_BRANCH" FETCH_HEAD fi && - if test -z "$BUILD_EXTRA_REV_FOR_EXISTING_GIT_TAG" + if test -z "$EXISTING_GIT_TAG" then - git -C $d -c pull.rebase=false pull "$PWD"/bundle-artifacts/build-extra.bundle main - else - git -C $d fetch origin "$BUILD_EXTRA_REV_FOR_EXISTING_GIT_TAG" && - git -C $d reset --hard "$BUILD_EXTRA_REV_FOR_EXISTING_GIT_TAG" + git -C $d -c pull.rebase=false pull "$PWD"/bundle-artifacts/build-extra.bundle "$RELEASE_BRANCH" fi - - name: Prepare git-for-windows/git clone with the tag + - name: Prepare ${{ env.OWNER }}/git clone with the tag if: steps.restore-cached-git-pkg.outputs.cache-hit != 'true' run: | set -x if test ! -d /usr/src/MINGW-packages then - git clone --depth 1 --single-branch -b main \ - https://github.com/git-for-windows/MINGW-packages /usr/src/MINGW-packages + git clone --depth 1 --single-branch -b "$RELEASE_BRANCH" \ + https://github.com/$OWNER/MINGW-packages /usr/src/MINGW-packages fi && cd /usr/src/MINGW-packages/mingw-w64-git && if test ! -d git then + # Must be a clone of git-for-windows/git.git, otherwise `makepkg-mingw` will complain git clone --bare https://github.com/git-for-windows/git.git git fi && if test ! -d src/git then - git clone --reference git https://github.com/git-for-windows/git src/git && + git clone --reference git https://github.com/$OWNER/$REPO src/git && echo ../../../../git/objects >src/git/.git/objects/info/alternates fi && cd src/git && @@ -283,6 +388,7 @@ jobs: with: app-id: ${{ secrets.GH_APP_ID }} private-key: ${{ secrets.GH_APP_PRIVATE_KEY }} + owner: ${{ env.OWNER }} append-text: 'About to build the `${{env.MINGW_PACKAGE_PREFIX}}-git` package' - name: Build ${{env.MINGW_PACKAGE_PREFIX}}-git timeout-minutes: 60 @@ -317,7 +423,17 @@ jobs: if test -z "$EXISTING_GIT_TAG" then git commit -s -m "mingw-w64-git: new version ($version)" PKGBUILD && - git bundle create "$b"/MINGW-packages.bundle origin/main..main + for seconds in 1 3 10 15 + do + GIT_TRACE2_EVENT=1 \ + git bundle create "$b"/MINGW-packages.bundle \ + "origin/$RELEASE_BRANCH..$RELEASE_BRANCH" && + break + # to ease debugging + git bundle verify "$b"/MINGW-packages.bundle ||: + sleep $seconds + done && + git bundle verify "$b"/MINGW-packages.bundle elif ! git update-index --ignore-submodules --refresh || ! git diff-files --ignore-submodules || ! git diff-index --cached --ignore-submodules HEAD @@ -325,7 +441,17 @@ jobs: echo "::warning::Uncommitted changes after build!" >&2 && git diff >&2 && git commit -s -m "mingw-w64-git: new version ($version)" PKGBUILD && - git bundle create "$b"/MINGW-packages.bundle main^..main + for seconds in 1 3 10 15 + do + GIT_TRACE2_EVENT=1 \ + git bundle create "$b"/MINGW-packages.bundle \ + "$RELEASE_BRANCH^..$RELEASE_BRANCH" && + break + # to ease debugging + git bundle verify "$b"/MINGW-packages.bundle ||: + sleep $seconds + done && + git bundle verify "$b"/MINGW-packages.bundle fi) - name: Cache ${{env.MINGW_PACKAGE_PREFIX}}-git if: steps.restore-cached-git-pkg.outputs.cache-hit != 'true' @@ -338,6 +464,7 @@ jobs: with: app-id: ${{ secrets.GH_APP_ID }} private-key: ${{ secrets.GH_APP_PRIVATE_KEY }} + owner: ${{ env.OWNER }} append-text: 'The `${{env.MINGW_PACKAGE_PREFIX}}-git` package was built successfully' - name: Publish ${{env.MINGW_PACKAGE_PREFIX}}-git uses: actions/upload-artifact@v4 @@ -354,6 +481,7 @@ jobs: with: app-id: ${{ secrets.GH_APP_ID }} private-key: ${{ secrets.GH_APP_PRIVATE_KEY }} + owner: ${{ env.OWNER }} append-text: "${{ format('Completed: {0}', job.status) }}." conclusion: ${{ job.status }} artifacts: @@ -364,6 +492,7 @@ jobs: MINGW_PREFIX: ${{ needs.pkg.outputs.mingw-prefix }} MINGW_PACKAGE_PREFIX: ${{ needs.pkg.outputs.mingw_package_prefix }} SDK_REPO_ARCH: ${{ needs.pkg.outputs.sdk_repo_arch }} + RELEASE_BRANCH: ${{ needs.pkg.outputs.release-branch }} strategy: fail-fast: false matrix: ${{ fromJSON(needs.pkg.outputs.artifact_matrix) }} @@ -389,14 +518,45 @@ jobs: name: bundle-artifacts path: bundle-artifacts - uses: git-for-windows/setup-git-for-windows-sdk@v1 + if: env.OWNER == 'git-for-windows' && env.RELEASE_BRANCH == 'main' with: flavor: build-installers architecture: ${{env.ARCHITECTURE}} + - name: configure token + if: github.repository_visibility == 'private' + uses: actions/github-script@v7 + with: + script: | + const fs = require('fs') + if (!fs.existsSync(process.env.HOME)) fs.mkdirSync(process.env.HOME) + const { callGit, getPushAuthorizationHeader } = require('./repository-updates.js') + for (const repo of ['build-extra', 'git-sdk-${{ env.ARCHITECTURE == 'x86_64' && '64' || (env.ARCHITECTURE == 'aarch64' && 'arm64' || '32') }}']) { + const header = await getPushAuthorizationHeader( + console, + core.setSecret, + ${{ secrets.GH_APP_ID }}, + ${{ toJSON(secrets.GH_APP_PRIVATE_KEY) }}, + process.env.OWNER, + repo + ) + console.log(callGit(['config', '--global', `http.https://github.com/${process.env.OWNER}/${repo}.extraHeader`, header])) + } + - name: Set up Git for Windows SDK ${{ env.architecture }} (${{ env.RELEASE_BRANCH }}) + if: env.OWNER != 'git-for-windows' || env.RELEASE_BRANCH != 'main' + shell: bash + run: | + git -c checkout.workers=56 \ + clone --single-branch -b "$RELEASE_BRANCH" --depth 1 \ + https://github.com/$OWNER/git-sdk-$SDK_REPO_ARCH D:/git-sdk-$SDK_REPO_ARCH && + + cygpath -aw D:/git-sdk-$SDK_REPO_ARCH/usr/bin/core_perl >>$GITHUB_PATH && + cygpath -aw D:/git-sdk-$SDK_REPO_ARCH/usr/bin >>$GITHUB_PATH && + cygpath -aw D:/git-sdk-$SDK_REPO_ARCH/${MSYSTEM,,?}/bin >>$GITHUB_PATH - name: Configure user run: USER_NAME="${{github.actor}}" && USER_EMAIL="${{github.actor}}@users.noreply.github.com" && - mkdir "$HOME" && + mkdir -p "$HOME" && git config --global user.name "$USER_NAME" && git config --global user.email "$USER_EMAIL" - name: Clone and update build-extra @@ -405,18 +565,15 @@ jobs: d=/usr/src/build-extra && if test ! -d $d/.git then - git clone --single-branch -b main https://github.com/git-for-windows/build-extra $d + git clone --single-branch -b "$RELEASE_BRANCH" https://github.com/$OWNER/build-extra $d else - git -C $d fetch https://github.com/git-for-windows/build-extra main && - git -C $d switch -C main FETCH_HEAD + git -C $d fetch https://github.com/$OWNER/build-extra "$RELEASE_BRANCH" && + git -C $d switch -C "$RELEASE_BRANCH" FETCH_HEAD fi && echo "result=$(cygpath -am "$d")" >> $GITHUB_OUTPUT && - if test -z "$BUILD_EXTRA_REV_FOR_EXISTING_GIT_TAG" + if test -z "$EXISTING_GIT_TAG" then - git -C $d -c pull.rebase=false pull "$PWD"/bundle-artifacts/build-extra.bundle main - else - git -C $d fetch origin "$BUILD_EXTRA_REV_FOR_EXISTING_GIT_TAG" && - git -C $d reset --hard "$BUILD_EXTRA_REV_FOR_EXISTING_GIT_TAG" + git -C $d -c pull.rebase=false pull "$PWD"/bundle-artifacts/build-extra.bundle "$RELEASE_BRANCH" fi - name: Prepare home directory for code-signing env: @@ -522,20 +679,26 @@ jobs: with: app-id: ${{ secrets.GH_APP_ID }} private-key: ${{ secrets.GH_APP_PRIVATE_KEY }} + owner: ${{ env.OWNER }} append-text: 'Built ${{ matrix.artifact.name }}' - name: Run the installer if: matrix.artifact.name == 'installer' shell: pwsh run: | $exePath = Get-ChildItem -Path artifacts/*.exe | %{$_.FullName} - $installer = Start-Process -PassThru -Wait -FilePath "$exePath" -ArgumentList "/SILENT /VERYSILENT /NORESTART /SUPPRESSMSGBOXES /ALLOWDOWNGRADE=1 /LOG=installer.log" + $installer = Start-Process -PassThru -Wait -FilePath "$exePath" -ArgumentList "/SILENT /VERYSILENT /NORESTART /SUPPRESSMSGBOXES /ALLOWDOWNGRADE=1 /ALLOWINSTALLING32ON64=1 /LOG=installer.log" $exitCode = $installer.ExitCode if ($exitCode -ne 0) { Write-Host "::error::Installer failed with exit code $exitCode!" exit 1 } - "$env:ProgramFiles\Git\usr\bin" | Out-File -Encoding ascii -Append $env:GITHUB_PATH - "$env:ProgramFiles\Git\${{env.MINGW_PREFIX}}\bin" | Out-File -Encoding ascii -Append $env:GITHUB_PATH + if ("${env:ARCHITECTURE}" -eq "i686") { + "${env:ProgramFiles(x86)}\Git\usr\bin" | Out-File -Encoding ascii -Append $env:GITHUB_PATH + "${env:ProgramFiles(x86)}\Git\${{env.MINGW_PREFIX}}\bin" | Out-File -Encoding ascii -Append $env:GITHUB_PATH + } else { + "$env:ProgramFiles\Git\usr\bin" | Out-File -Encoding ascii -Append $env:GITHUB_PATH + "$env:ProgramFiles\Git\${{env.MINGW_PREFIX}}\bin" | Out-File -Encoding ascii -Append $env:GITHUB_PATH + } - name: Publish installer log if: matrix.artifact.name == 'installer' && (failure() || success()) uses: actions/upload-artifact@v4 @@ -570,6 +733,7 @@ jobs: with: app-id: ${{ secrets.GH_APP_ID }} private-key: ${{ secrets.GH_APP_PRIVATE_KEY }} + owner: ${{ env.OWNER }} append-text: "${{ format('Completed: {0}', job.status) }}." conclusion: ${{ job.status }} sha256sums: @@ -604,5 +768,6 @@ jobs: with: app-id: ${{ secrets.GH_APP_ID }} private-key: ${{ secrets.GH_APP_PRIVATE_KEY }} + owner: ${{ env.OWNER }} append-text: "${{ job.status == 'success' && 'Done!' || format('Completed: {0}', job.status) }}." conclusion: ${{ job.status }} diff --git a/.github/workflows/tag-git.yml b/.github/workflows/tag-git.yml index 69475047..4e859bcf 100644 --- a/.github/workflows/tag-git.yml +++ b/.github/workflows/tag-git.yml @@ -1,5 +1,5 @@ name: tag-git -run-name: "Tag Git ${{ inputs.snapshot == 'true' && 'snapshot ' || '' }}at ${{ inputs.owner }}/${{ inputs.repo }}@${{ inputs.rev }}" +run-name: "Tag ${{ inputs.mingit-only == 'true' && 'Min' || '' }}Git ${{ inputs.snapshot == 'true' && 'snapshot ' || '' }}at ${{ inputs.owner }}/${{ inputs.repo }}@${{ inputs.rev }}" on: workflow_dispatch: @@ -11,22 +11,36 @@ on: owner: description: 'Optionally override from where to fetch the specified rev' required: true - default: git-for-windows + default: repo: description: 'Optionally override from where to fetch the specified rev' required: true default: git + release-branch: + description: 'The branch name to use for this release' + required: false + default: main + release-date: + description: 'Override the release date (defaults to today)' + required: false snapshot: description: 'A flag indicating whether this is a snapshot or a full Git for Windows release' required: true default: "true" + mingit-only: + description: 'A flag indicating whether this is a MinGit-only release (AKA MinGit backport)' + required: false + default: "false" env: GPG_OPTIONS: "--batch --yes --no-tty --list-options no-show-photos --verify-options no-show-photos --pinentry-mode loopback" - OWNER: "${{github.event.inputs.owner}}" + OWNER: "${{github.event.inputs.owner || github.repository_owner }}" REPO: "${{github.event.inputs.repo}}" REV: "${{github.event.inputs.rev}}" + RELEASE_BRANCH: "${{github.event.inputs.release-branch}}" + RELEASE_DATE: "${{github.event.inputs.release-date}}" SNAPSHOT: "${{github.event.inputs.snapshot}}" + MINGIT_ONLY: "${{github.event.inputs.mingit-only}}" CREATE_CHECK_RUN: "true" NODEJS_VERSION: 16 @@ -59,19 +73,38 @@ jobs: repo: ${{ env.REPO }} rev: ${{ env.REV }} check-run-name: "tag-git" - title: "Tag Git @${{ env.REV }}" - summary: "Tag Git @${{ env.REV }}" + title: "Tag ${{ env.MINGIT_ONLY == 'true' && 'Min' || '' }}Git @${{ env.REV }}" + summary: "Tag ${{ env.MINGIT_ONLY == 'true' && 'Min' || '' }}Git @${{ env.REV }}" text: "For details, see [this run](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id}})." details-url: "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id}}" + - name: configure token + if: github.repository_visibility == 'private' + uses: actions/github-script@v7 + with: + script: | + const fs = require('fs') + if (!fs.existsSync(process.env.HOME)) fs.mkdirSync(process.env.HOME) + const { callGit, getPushAuthorizationHeader } = require('./repository-updates.js') + for (const repo of ['build-extra', process.env.REPO]) { + const header = await getPushAuthorizationHeader( + console, + core.setSecret, + ${{ secrets.GH_APP_ID }}, + ${{ toJSON(secrets.GH_APP_PRIVATE_KEY) }}, + process.env.OWNER, + repo + ) + console.log(callGit(['config', '--global', `http.https://github.com/${process.env.OWNER}/${repo}.extraHeader`, header])) + } - name: Configure user - run: + run: | USER_NAME="${{github.actor}}" && USER_EMAIL="${{github.actor}}@users.noreply.github.com" && git config --global user.name "$USER_NAME" && git config --global user.email "$USER_EMAIL" && echo "PACKAGER=$USER_NAME <$USER_EMAIL>" >> $GITHUB_ENV - name: Clone build-extra - run: git clone --single-branch -b main https://github.com/git-for-windows/build-extra $RUNNER_TEMP/build-extra + run: git clone --single-branch -b "$RELEASE_BRANCH" https://github.com/$OWNER/build-extra $RUNNER_TEMP/build-extra - name: Prepare home directory for GPG signing if: env.GPGKEY != '' run: | @@ -93,15 +126,28 @@ jobs: GPGKEY: ${{secrets.GPGKEY}} run: | git clone --bare --filter=blob:none https://github.com/git/git && - git -C git.git fetch --tags --filter=blob:none "https://github.com/$OWNER/$REPO" main:refs/remotes/origin/main "$REV" && + if test git-for-windows != "$OWNER" + then + git --git-dir=git.git fetch --tags --filter=blob:none https://github.com/git-for-windows/git + fi && + git -C git.git fetch --tags --filter=blob:none "https://github.com/$OWNER/$REPO" "$RELEASE_BRANCH:refs/remotes/origin/$RELEASE_BRANCH" "$REV" && sh -x "$GITHUB_WORKSPACE/update-scripts/tag-git.sh" \ ${{ env.SNAPSHOT != 'true' && '--no-snapshot-version' || ''}} \ --git-dir="git.git" \ --build-extra-dir="$RUNNER_TEMP/build-extra" \ --artifacts-dir="$GITHUB_WORKSPACE/bundle-artifacts" \ + --release-branch="$RELEASE_BRANCH" \ + --release-date="$RELEASE_DATE" \ + $(test "$MINGIT_ONLY" = 'true' && echo '--mingit') \ "$REV" && + echo "$RELEASE_BRANCH" >bundle-artifacts/release-branch && + if test true = "$MINGIT_ONLY" + then + >bundle-artifacts/mingit-only + fi && + echo "tag-name=$(cat bundle-artifacts/next_version)" >>$GITHUB_OUTPUT && echo "Tag name: \`$(cat bundle-artifacts/next_version)\`" >>$GITHUB_STEP_SUMMARY - name: update check-run @@ -110,9 +156,9 @@ jobs: with: app-id: ${{ secrets.GH_APP_ID }} private-key: ${{ secrets.GH_APP_PRIVATE_KEY }} - title: "Tag Git ${{ steps.generate.outputs.tag-name }} @${{ env.REV }}" - summary: "Tag Git ${{ steps.generate.outputs.tag-name }} @${{ env.REV }}" - append-text: 'Tagged Git ${{ steps.generate.outputs.tag-name }}' + title: "Tag ${{ env.MINGIT_ONLY == 'true' && 'Min' || '' }}Git ${{ steps.generate.outputs.tag-name }} @${{ env.REV }}" + summary: "Tag ${{ env.MINGIT_ONLY == 'true' && 'Min' || '' }}Git ${{ steps.generate.outputs.tag-name }} @${{ env.REV }}" + append-text: "Tagged ${{ env.MINGIT_ONLY == 'true' && 'Min' || '' }}Git ${{ steps.generate.outputs.tag-name }}" - name: 'Publish Pipeline Artifact: bundle-artifacts' uses: actions/upload-artifact@v4 with: diff --git a/create-artifacts-matrix.js b/create-artifacts-matrix.js index 27670dd7..6457355e 100644 --- a/create-artifacts-matrix.js +++ b/create-artifacts-matrix.js @@ -1,4 +1,4 @@ -module.exports = (artifactsString, architecture) => { +module.exports = (artifactsString, architecture, allowI686) => { const artifacts = artifactsString.split(' ') if (artifacts.length < 1) { @@ -13,7 +13,7 @@ module.exports = (artifactsString, architecture) => { } ] - if (architecture !== 'i686') validArtifacts.unshift({ + if (allowI686 || architecture !== 'i686') validArtifacts.unshift({ name: 'installer', filePrefix: 'Git', fileExtension: 'exe' diff --git a/github-release.js b/github-release.js index 31b6a77f..d5ea34f9 100644 --- a/github-release.js +++ b/github-release.js @@ -209,8 +209,8 @@ const getGitArtifacts = async ( const urls = await getWorkflowRunArtifactsURLs(context, token, owner, repo, workflowRunId) for (const artifact of artifacts) { if (architecture.name === 'aarch64' && artifact.name === 'mingit-busybox') continue - if (architecture.name === 'i686' && !artifact.name.startsWith('mingit')) continue const name = `${artifact.name}-${architecture.name}` + if (architecture.name === 'i686' && !artifact.name.startsWith('mingit') && !urls && !fs.existsSync(name)) continue context.log(`Downloading ${name}`) await downloadAndUnZip(token, urls[name], name) diff --git a/update-scripts/tag-git.sh b/update-scripts/tag-git.sh index 4d5de870..7b089fa4 100755 --- a/update-scripts/tag-git.sh +++ b/update-scripts/tag-git.sh @@ -8,29 +8,76 @@ die () { git_git_dir=/usr/src/git/.git && build_extra_dir=/usr/src/build-extra && artifacts_dir= && +release_branch=main && +git_or_mingit="Git for Windows" && snapshot_version=t && +release_date= && while case "$1" in --git-dir=*) git_git_dir="${1#*=}";; --build-extra-dir=*) build_extra_dir="${1#*=}";; --artifacts-dir=*) artifacts_dir="${1#*=}";; +--release-branch=*) release_branch="${1#*=}";; +--mingit) git_or_mingit="MinGit for Windows";; --full|--full-version|--no-snapshot|--no-snapshot-version) snapshot_version=;; +--release-date=*) release_date="${1#*=}";; *) break;; -esac; do shift; done +esac; do shift; done || +die "Could not parse command-line options: $*" test $# = 1 || die "Usage: $0 [--no-snapshot-version] [--git-dir=