diff --git a/.gitea/workflows/pull-request.yml b/.gitea/workflows/pull-request.yml index 81d8cf9..9786e5d 100644 --- a/.gitea/workflows/pull-request.yml +++ b/.gitea/workflows/pull-request.yml @@ -26,12 +26,40 @@ jobs: runs-on: windows-x64 steps: - # lfs: true is not a nicety: the exe icon lives in Git LFS, and without it - # the checkout leaves a text pointer that the build cannot read as an icon - name: Check out the sources uses: actions/checkout@v4 - with: - lfs: true + + # The exe icon lives in Git LFS, and without it the checkout leaves a text + # pointer that the build cannot read as an icon. + # + # The objects are fetched here rather than by `lfs: true` on the checkout: + # that way they arrive over a request the LFS endpoint accepts. See the + # comment on the header below + - name: Fetch the LFS objects + run: | + $ErrorActionPreference = 'Stop' + + # actions/checkout leaves its own token in the config as an + # http./.extraheader, and git-lfs sends that header on to the + # LFS endpoint, which turns down the token of a workflow: every object + # comes back 401 and the fetch gives up. The repository is public and + # its LFS objects are readable without a token at all, so the header + # simply goes. A private repository would need credentials of its own + # in lfs.url instead + $keys = git config --local --list --name-only | Where-Object { $_ -like '*.extraheader' } + foreach ($key in $keys) { git config --local --unset-all $key } + + git lfs pull + if ($LASTEXITCODE -ne 0) { throw "git lfs pull ended with exit code $LASTEXITCODE." } + + # A pointer left in place of a file shows itself much later and in a + # way that is hard to read back: the build breaks on the icon + $pointers = git lfs ls-files --name-only | + Where-Object { (Get-Content $_ -TotalCount 1) -like 'version https://git-lfs*' } + + if ($pointers) { + throw "Git LFS left pointers instead of files: $($pointers -join ', ')." + } - name: Show the toolchain run: dotnet --info diff --git a/.gitea/workflows/release.yml b/.gitea/workflows/release.yml index 2f90208..e4215da 100644 --- a/.gitea/workflows/release.yml +++ b/.gitea/workflows/release.yml @@ -21,13 +21,42 @@ jobs: runs-on: windows-x64 steps: - # lfs: true is not a nicety: the exe icon and the MSIX logos live in Git - # LFS, and without it the checkout leaves text pointers in their place — - # the build fails on the icon and the package would carry broken logos - name: Check out the sources uses: actions/checkout@v4 - with: - lfs: true + + # The exe icon and the MSIX logos live in Git LFS, and without them the + # checkout leaves text pointers in their place — the build fails on the + # icon and the package would carry broken logos. + # + # They are fetched here rather than by `lfs: true` on the checkout: that + # way the objects arrive over a request the LFS endpoint accepts. See the + # comment on the header below + - name: Fetch the LFS objects + run: | + $ErrorActionPreference = 'Stop' + + # actions/checkout leaves its own token in the config as an + # http./.extraheader, and git-lfs sends that header on to the + # LFS endpoint, which turns down the token of a workflow: every object + # comes back 401 and the fetch gives up. The repository is public and + # its LFS objects are readable without a token at all, so the header + # simply goes. A private repository would need credentials of its own + # in lfs.url instead + $keys = git config --local --list --name-only | Where-Object { $_ -like '*.extraheader' } + foreach ($key in $keys) { git config --local --unset-all $key } + + git lfs pull + if ($LASTEXITCODE -ne 0) { throw "git lfs pull ended with exit code $LASTEXITCODE." } + + # A pointer left in place of a file shows itself much later and in a + # way that is hard to read back: the icon breaks the build, and a logo + # quietly ends up broken inside the package + $pointers = git lfs ls-files --name-only | + Where-Object { (Get-Content $_ -TotalCount 1) -like 'version https://git-lfs*' } + + if ($pointers) { + throw "Git LFS left pointers instead of files: $($pointers -join ', ')." + } # The tag is the only place the version comes from: the Store takes four # numbers ending in zero, so anything else is stopped here rather than