diff --git a/.github/actions/windows-tests/action.yml b/.github/actions/windows-tests/action.yml index d856c7f5de29..89c745c6a593 100644 --- a/.github/actions/windows-tests/action.yml +++ b/.github/actions/windows-tests/action.yml @@ -42,6 +42,7 @@ runs: shell: bash - uses: dawidd6/action-download-artifact@b6e2e70617bc3265edd6dab6c906732b2f1ae151 # v21 + id: ossl-download with: repo: pyca/infra workflow: build-windows-openssl.yml @@ -50,6 +51,15 @@ runs: name: "openssl-${{ inputs.openssl-name }}" path: "C:/openssl-${{ inputs.openssl-name }}/" github_token: ${{ github.token }} + # The fresh extraction gives the headers new mtimes on every run, which + # invalidates openssl-sys's cargo fingerprint (it registers + # rerun-if-changed on the include dir) despite identical content. + - name: Pin OpenSSL artifact mtimes + run: python .github/bin/pin_artifact_mtimes.py "C:/openssl-${OPENSSL_NAME}" "${ARTIFACT_CREATED_AT}" + env: + OPENSSL_NAME: ${{ inputs.openssl-name }} + ARTIFACT_CREATED_AT: ${{ fromJSON(steps.ossl-download.outputs.artifacts)[0].created_at }} + shell: bash - name: Configure run: | echo "OPENSSL_DIR=C:/openssl-${OPENSSL_NAME}" >> $GITHUB_ENV diff --git a/.github/bin/pin_artifact_mtimes.py b/.github/bin/pin_artifact_mtimes.py new file mode 100644 index 000000000000..e452084527d1 --- /dev/null +++ b/.github/bin/pin_artifact_mtimes.py @@ -0,0 +1,32 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. + +# Set every file in a downloaded artifact to the artifact's own creation +# time. openssl-sys's build script registers cargo:rerun-if-changed on the +# OpenSSL include directory, and cargo evaluates that by mtime, so a +# freshly extracted artifact with identical content would otherwise +# invalidate the cargo cache on every CI run. Using the artifact's +# created_at means an unchanged artifact always looks the same, while a +# rebuilt artifact gets a new timestamp and correctly triggers a rebuild. + +import datetime +import os +import sys + + +def main(root: str, created_at: str) -> None: + mtime = datetime.datetime.fromisoformat( + created_at.replace("Z", "+00:00") + ).timestamp() + count = 0 + for dirpath, _, filenames in os.walk(root): + for filename in filenames: + path = os.path.join(dirpath, filename) + os.utime(path, (mtime, mtime)) + count += 1 + print(f"pinned {count} files in {root} to {created_at}") + + +if __name__ == "__main__": + main(sys.argv[1], sys.argv[2]) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5469e9c75457..3710395a8886 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -315,6 +315,7 @@ jobs: uses: ./.github/actions/fetch-vectors - uses: dawidd6/action-download-artifact@b6e2e70617bc3265edd6dab6c906732b2f1ae151 # v21 + id: ossl-download with: repo: pyca/infra workflow: build-macos-openssl.yml @@ -323,6 +324,13 @@ jobs: name: openssl-macos-universal2 path: "../openssl-macos-universal2/" github_token: ${{ secrets.GITHUB_TOKEN }} + # The fresh extraction gives the headers new mtimes on every run, which + # invalidates openssl-sys's cargo fingerprint (it registers + # rerun-if-changed on the include dir) despite identical content. + - name: Pin OpenSSL artifact mtimes + run: python .github/bin/pin_artifact_mtimes.py ../openssl-macos-universal2/ "$ARTIFACT_CREATED_AT" + env: + ARTIFACT_CREATED_AT: ${{ fromJSON(steps.ossl-download.outputs.artifacts)[0].created_at }} - name: Build nox environment run: | OPENSSL_DIR=$(readlink -f ../openssl-macos-universal2/) \