diff --git a/.github/pin-github-actions-shas.js b/.github/pin-github-actions-shas.js new file mode 100755 index 00000000000000..90a662c284b2bf --- /dev/null +++ b/.github/pin-github-actions-shas.js @@ -0,0 +1,137 @@ +#!/usr/bin/env node + +const { execFileSync } = require('node:child_process'); +const fs = require('node:fs'); + +const pinningMessage = `ci: pin GitHub Actions to satisfy downstream policy + +Microsoft Git inherits workflows that upstream maintains using symbolic +Action refs. Downstream organizational policy requires full commit IDs +instead, adding pin maintenance to this project's maintainers' workload. + +Keep pins aligned with the original upstream Action refs in a fresh +downstream snapshot, independent of any earlier pinning commit. +`; + +function git(...args) { + return execFileSync('git', ['--no-pager', ...args], { + encoding: 'utf8', + stdio: ['ignore', 'pipe', 'pipe'], + maxBuffer: 16 * 1024 * 1024 + }).trim(); +} + +const isSHA = value => /^[0-9a-f]{40}$/i.test(value); +const uses = /^( *-? *uses: *)(["']?)([\w./-]+)@([^ \t"'\r\n]+)\2([^\r\n]*)/gm; +const useLine = new RegExp(uses.source); + +function findOriginalActionRef(file, actionName, workflowHistory) { + for (const patch of workflowHistory.split('\0')) { + const removed = patch.replace(/^-/gm, ''); + const versions = [...removed.matchAll(uses)] + .filter(use => use[3] === actionName && + !isSHA(use[4])) + .map(use => use[4]); + if (!versions.length) + continue; + const [version] = versions; + if (versions.some(candidate => candidate !== version)) + throw new Error('Ambiguous Action ref: ' + + `${file}, ${actionName}`); + return version; + } + throw new Error(`Cannot recover Action ref: ${file}, ${actionName}`); +} + +function readWorkflow(file) { + const text = fs.readFileSync(file, 'utf8'); + const parts = text.split(/(^ *-? *uses:[^\r\n]*)/m); + const matches = parts.map(part => part.match(useLine)) + .filter(use => use && !use[3].startsWith('./')); + const workflowHistory = matches.some(use => isSHA(use[4])) + ? git('log', '--follow', '-p', '-U0', + '-Guses:.*@', '--no-ext-diff', '--no-textconv', + '--format=%x00', '--', file) + : ''; + const actionRefs = matches.map(use => { + const actionName = use[3]; + const version = isSHA(use[4]) ? + findOriginalActionRef( + file, actionName, workflowHistory) : + use[4]; + const actionRepo = actionName.split('/').slice(0, 2).join('/'); + return { + use, actionName, version, + pinKey: `${actionRepo}@${version}` + }; + }); + return { file, text, parts, actionRefs }; +} + +function resolveActionSHA(actionName, version) { + const actionRepo = actionName.split('/').slice(0, 2).join('/'); + const actionTagRef = `refs/tags/${version}`; + const output = git('ls-remote', '--quiet', + `https://github.com/${actionRepo}`, + actionTagRef, `${actionTagRef}^{}`, `refs/heads/${version}`); + const actionRepoRefs = Object.fromEntries(output.split('\n') + .map(line => line.split('\t').reverse())); + const sha = actionRepoRefs[`${actionTagRef}^{}`] || + actionRepoRefs[actionTagRef] || + actionRepoRefs[`refs/heads/${version}`]; + if (!sha || !isSHA(sha)) + throw new Error('Cannot resolve Action ref: ' + + `${actionName}@${version}`); + return sha; +} + +function substitute({ file, text, parts, actionRefs }, pins) { + const replacements = new Map(actionRefs.map(actionRef => { + const { use, version, pinKey } = actionRef; + const [, prefix, quote, actionName, , suffix] = use; + const sha = pins[pinKey]; + let note = suffix.trim().replace(/^#\s*/, ''); + if (note.startsWith(`${version}; `)) + note = note.slice(version.length + 2); + else if (note === version || /^v?\d[\w.+-]*$/.test(note)) + note = ''; + const pinned = `${prefix}${quote}${actionName}@${sha}${quote}` + + ` # ${version}` + (note ? `; ${note}` : ''); + return [use[0], pinned]; + })); + const updated = parts.map(part => replacements.get(part) ?? part) + .join(''); + return updated === text ? null : [file, updated]; +} + +try { + process.chdir(git('rev-parse', '--show-toplevel')); + const files = git('ls-files', '-z', '--', '.github/workflows') + .split('\0').filter(file => /\.ya?ml$/.test(file)); + if (git('status', '--porcelain', '--untracked-files=no', + '--', '.github/workflows')) + throw new Error('Workflow files have uncommitted changes'); + const workflows = files.map(readWorkflow); + const actionRefs = workflows.flatMap(workflow => workflow.actionRefs); + const uniquePins = new Map(actionRefs.map(actionRef => + [actionRef.pinKey, actionRef])); + const pins = Object.fromEntries([...uniquePins.values()].map( + ({ pinKey, actionName, version }) => + [pinKey, resolveActionSHA(actionName, version)])); + const changed = workflows.map(workflow => substitute(workflow, pins)) + .filter(Boolean); + if (changed.length) { + const message = git('rev-parse', '--git-path', + 'COMMIT_EDITMSG'); + fs.writeFileSync(message, pinningMessage); + for (const [file, text] of changed) + fs.writeFileSync(file, text); + console.log(git('commit', '--signoff', '-F', message, + '--', ...changed.map(([file]) => file))); + } else { + console.log('Action pins are up to date.'); + } +} catch (error) { + console.error(`error: ${error.message}`); + process.exitCode = 1; +} diff --git a/.github/pin-github-actions-shas.test.js b/.github/pin-github-actions-shas.test.js new file mode 100644 index 00000000000000..da21c74688dffb --- /dev/null +++ b/.github/pin-github-actions-shas.test.js @@ -0,0 +1,88 @@ +const assert = require('node:assert/strict'); +const { execFileSync } = require('node:child_process'); +const fs = require('node:fs'); +const os = require('node:os'); +const path = require('node:path'); +const { test } = require('node:test'); +const { pathToFileURL } = require('node:url'); + +test('fresh pinning commits preserve unrelated work', t => { + const directory = fs.mkdtempSync(path.join(os.tmpdir(), 'pin test-')); + t.after(() => fs.rmSync(directory, { recursive: true })); + const env = Object.fromEntries(Object.entries(process.env) + .filter(([key]) => !/^GIT_/i.test(key))); + env.GIT_CONFIG_NOSYSTEM = '1'; + env.GIT_CONFIG_GLOBAL = os.devNull; + const git = (...args) => execFileSync('git', args, { + cwd: directory, env, encoding: 'utf8', + stdio: ['ignore', 'pipe', 'pipe'] + }).trim(); + git('init', '-q', '--initial-branch=test', '--object-format=sha1'); + git('config', 'user.name', 'Pin Test'); + git('config', 'user.email', 'pins@example.com'); + const workflows = path.join(directory, '.github/workflows'); + fs.mkdirSync(workflows, { recursive: true }); + const file = path.join(workflows, 'main.yml'); + const write = text => fs.writeFileSync(file, text); + const read = () => fs.readFileSync(file, 'utf8'); + const run = () => execFileSync(process.execPath, + [path.join(__dirname, 'pin-github-actions-shas.js')], + { cwd: directory, env, stdio: ['ignore', 'pipe', 'pipe'] }); + const workflow = `on: push +jobs: + test: + runs-on: ubuntu-latest + steps: + - uses: 'example/action@v1' + - uses: example/action/subpath@v2 + if: false + - uses: ./local-action + reusable: + uses: example/action/.github/workflows/test.yaml@master +`.replace(/\n/g, '\r\n'); + write(workflow); + const another = path.join(workflows, 'another.yaml'); + fs.writeFileSync(another, workflow.replace('@v1', '@v2')); + const unrelated = path.join(directory, 'unrelated'); + fs.writeFileSync(unrelated, 'original\n'); + git('add', '--', '.github/workflows', 'unrelated'); + git('commit', '-qm', 'Upstream workflows'); + const first = git('rev-parse', 'HEAD'); + git('tag', 'v1'); + git('tag', '-am', 'Annotated version', 'v2'); + git('commit', '--allow-empty', '-qm', 'Update action'); + const second = git('rev-parse', 'HEAD'); + const pinned = v1 => workflow + .replace(/@v1'/, `@${v1}' # v1`) + .replace('@v2', `@${first} # v2`) + .replace('@master', `@${second} # master`); + git('branch', 'master'); + git('branch', 'v1'); + git('config', `url.${pathToFileURL(directory).href}.insteadOf`, + 'https://github.com/example/action'); + fs.writeFileSync(unrelated, 'staged change\n'); + git('add', '--', 'unrelated'); + const expectedSubject = + 'ci: pin GitHub Actions to satisfy downstream policy'; + run(); + assert.equal(git('log', '-1', '--format=%s'), expectedSubject); + assert.equal(git('rev-parse', 'HEAD^'), second); + assert.equal(read(), pinned(first)); + assert.match(git('log', '-1', '--format=%B'), + /Signed-off-by: Pin Test /); + write(read().replace(/# v[12]/g, '# v0.0.0')); + git('commit', '-qm', 'Release labels', '--', '.github/workflows'); + git('tag', '-f', 'v1', second); + const beforeRefresh = git('rev-parse', 'HEAD'); + run(); + assert.equal(git('log', '-1', '--format=%s'), expectedSubject); + assert.equal(git('rev-parse', 'HEAD^'), beforeRefresh); + assert.equal(read(), pinned(second)); + assert.equal(fs.readFileSync(another, 'utf8'), + pinned(first).replace('# v1', '# v2')); + const head = git('rev-parse', 'HEAD'); + run(); + assert.equal(git('rev-parse', 'HEAD'), head); + assert.equal(git('diff', '--cached', '--name-only'), 'unrelated'); + assert.equal(git('show', 'HEAD:unrelated'), 'original'); +}); diff --git a/.github/workflows/check-style.yml b/.github/workflows/check-style.yml index 72e66762601413..c7120680cf7580 100644 --- a/.github/workflows/check-style.yml +++ b/.github/workflows/check-style.yml @@ -20,7 +20,7 @@ jobs: jobname: ClangFormat runs-on: ubuntu-latest steps: - - uses: actions/checkout@v7 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 with: fetch-depth: 0 diff --git a/.github/workflows/check-whitespace.yml b/.github/workflows/check-whitespace.yml index 7a35b67a636acc..9a511801a780e3 100644 --- a/.github/workflows/check-whitespace.yml +++ b/.github/workflows/check-whitespace.yml @@ -19,7 +19,7 @@ jobs: check-whitespace: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v7 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 with: fetch-depth: 0 diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 1ab0b2d68f6a98..a05883eb3c3679 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -23,7 +23,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v6 + uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6 - name: Install dependencies run: ci/install-dependencies.sh @@ -34,7 +34,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@v4 + uses: github/codeql-action/init@6f2ac81f5cd81fe351a197ba0b00d91d03cd2aee # v4 with: languages: ${{ matrix.language }} config-file: ./.github/codeql/codeql-config.yml @@ -46,7 +46,7 @@ jobs: make -j$(nproc) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v4 + uses: github/codeql-action/analyze@6f2ac81f5cd81fe351a197ba0b00d91d03cd2aee # v4 with: upload: False output: sarif-results @@ -56,12 +56,12 @@ jobs: run: ls -la sarif-results - name: publish sarif for debugging - uses: actions/upload-artifact@v7 + uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7 with: name: sarif-results-${{ matrix.language }} path: sarif-results - name: Upload SARIF - uses: github/codeql-action/upload-sarif@v4 + uses: github/codeql-action/upload-sarif@6f2ac81f5cd81fe351a197ba0b00d91d03cd2aee # v4 with: sarif_file: sarif-results/${{ matrix.language }}.sarif diff --git a/.github/workflows/coverity.yml b/.github/workflows/coverity.yml index 283d1cd74b9059..2d441e9f127335 100644 --- a/.github/workflows/coverity.yml +++ b/.github/workflows/coverity.yml @@ -39,10 +39,10 @@ jobs: COVERITY_PLATFORM: overridden-below NO_RUST: Yup steps: - - uses: actions/checkout@v7 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 - name: install minimal Git for Windows SDK if: contains(matrix.os, 'windows') - uses: git-for-windows/setup-git-for-windows-sdk@v2 + uses: git-for-windows/setup-git-for-windows-sdk@aed153d1258c311b680b81584a72a1a4807401f0 # v2 - run: ci/install-dependencies.sh if: contains(matrix.os, 'ubuntu') || contains(matrix.os, 'macos') env: @@ -99,7 +99,7 @@ jobs: # A cache miss will add ~30s to create, but a cache hit will save minutes. - name: restore the Coverity Build Tool id: cache - uses: actions/cache/restore@v6 + uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6 with: path: ${{ runner.temp }}/cov-analysis key: cov-build-${{ env.COVERITY_LANGUAGE }}-${{ env.COVERITY_PLATFORM }}-${{ steps.lookup.outputs.hash }} @@ -142,7 +142,7 @@ jobs: esac - name: cache the Coverity Build Tool if: steps.cache.outputs.cache-hit != 'true' - uses: actions/cache/save@v6 + uses: actions/cache/save@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6 with: path: ${{ runner.temp }}/cov-analysis key: cov-build-${{ env.COVERITY_LANGUAGE }}-${{ env.COVERITY_PLATFORM }}-${{ steps.lookup.outputs.hash }} diff --git a/.github/workflows/l10n.yml b/.github/workflows/l10n.yml index 114a12a9e59f60..6dbbb4a2f6bd42 100644 --- a/.github/workflows/l10n.yml +++ b/.github/workflows/l10n.yml @@ -63,7 +63,7 @@ jobs: origin \ ${{ github.ref }} \ $args - - uses: actions/setup-go@v6 + - uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16 # v6 with: go-version: '>=1.16' cache: false @@ -92,7 +92,7 @@ jobs: cat git-po-helper.out exit $exit_code - name: Create comment in pull request for report - uses: mshick/add-pr-comment@v3 + uses: mshick/add-pr-comment@ec328af66588ab8f77cdeb2c264f14aba45bbf59 # v3 if: >- always() && github.event_name == 'pull_request_target' && diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 2c02644ebeda77..62f1609d6fb212 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -65,7 +65,7 @@ jobs: echo "skip_concurrent=$skip_concurrent" >>$GITHUB_OUTPUT - name: skip if the commit or tree was already tested id: skip-if-redundant - uses: actions/github-script@v9 + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9 if: steps.check-ref.outputs.enabled == 'yes' with: github-token: ${{secrets.GITHUB_TOKEN}} @@ -114,8 +114,8 @@ jobs: group: windows-build-${{ github.ref }} cancel-in-progress: ${{ needs.ci-config.outputs.skip_concurrent == 'yes' }} steps: - - uses: actions/checkout@v7 - - uses: git-for-windows/setup-git-for-windows-sdk@v2 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 + - uses: git-for-windows/setup-git-for-windows-sdk@aed153d1258c311b680b81584a72a1a4807401f0 # v2 - name: Install GCC-compatible Rust target shell: bash run: | @@ -149,7 +149,7 @@ jobs: - name: zip up tracked files run: git archive -o artifacts/tracked.tar.gz HEAD - name: upload tracked files and build artifacts - uses: actions/upload-artifact@v7 + uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7 with: name: windows-artifacts path: artifacts @@ -166,14 +166,14 @@ jobs: cancel-in-progress: ${{ needs.ci-config.outputs.skip_concurrent == 'yes' }} steps: - name: download tracked files and build artifacts - uses: actions/download-artifact@v8 + uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8 with: name: windows-artifacts path: ${{github.workspace}} - name: extract tracked files and build artifacts shell: bash run: tar xf artifacts.tar.gz && tar xf tracked.tar.gz - - uses: git-for-windows/setup-git-for-windows-sdk@v2 + - uses: git-for-windows/setup-git-for-windows-sdk@aed153d1258c311b680b81584a72a1a4807401f0 # v2 - name: test shell: bash run: . /etc/profile && ci/run-test-slice.sh $((${{matrix.nr}} + 1)) 10 @@ -183,7 +183,7 @@ jobs: run: ci/print-test-failures.sh - name: Upload failed tests' directories if: failure() && env.FAILED_TEST_ARTIFACTS != '' - uses: actions/upload-artifact@v7 + uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7 with: name: failed-tests-windows-${{ matrix.nr }} path: ${{env.FAILED_TEST_ARTIFACTS}} @@ -202,20 +202,20 @@ jobs: group: vs-build-${{ github.ref }}-${{ matrix.arch }} cancel-in-progress: ${{ needs.ci-config.outputs.skip_concurrent == 'yes' }} steps: - - uses: actions/checkout@v7 - - uses: git-for-windows/setup-git-for-windows-sdk@v2 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 + - uses: git-for-windows/setup-git-for-windows-sdk@aed153d1258c311b680b81584a72a1a4807401f0 # v2 - name: initialize vcpkg - uses: actions/checkout@v7 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 with: repository: 'microsoft/vcpkg' path: 'compat/vcbuild/vcpkg' - name: download vcpkg artifacts - uses: git-for-windows/get-azure-pipelines-artifact@v0 + uses: git-for-windows/get-azure-pipelines-artifact@2e424b98e1251b725d6064c5f1a9f854a33e5b88 # v0 with: repository: git/git definitionId: 9 - name: add msbuild to PATH - uses: microsoft/setup-msbuild@v3 + uses: microsoft/setup-msbuild@30375c66a4eea26614e0d39710365f22f8b0af57 # v3 - name: copy dlls to root shell: cmd run: compat\vcbuild\vcpkg_copy_dlls.bat release ${{ matrix.arch }}-windows @@ -242,7 +242,7 @@ jobs: - name: zip up tracked files run: git archive -o artifacts/tracked.tar.gz HEAD - name: upload tracked files and build artifacts - uses: actions/upload-artifact@v7 + uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7 with: name: vs-artifacts-${{ matrix.arch }} path: artifacts @@ -258,9 +258,9 @@ jobs: group: vs-test-${{ matrix.nr }}-${{ github.ref }} cancel-in-progress: ${{ needs.ci-config.outputs.skip_concurrent == 'yes' }} steps: - - uses: git-for-windows/setup-git-for-windows-sdk@v2 + - uses: git-for-windows/setup-git-for-windows-sdk@aed153d1258c311b680b81584a72a1a4807401f0 # v2 - name: download tracked files and build artifacts - uses: actions/download-artifact@v8 + uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8 with: name: vs-artifacts-x64 path: ${{github.workspace}} @@ -278,7 +278,7 @@ jobs: run: ci/print-test-failures.sh - name: Upload failed tests' directories if: failure() && env.FAILED_TEST_ARTIFACTS != '' - uses: actions/upload-artifact@v7 + uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7 with: name: failed-tests-windows-vs-${{ matrix.nr }} path: ${{env.FAILED_TEST_ARTIFACTS}} @@ -292,8 +292,8 @@ jobs: group: windows-meson-build-${{ github.ref }} cancel-in-progress: ${{ needs.ci-config.outputs.skip_concurrent == 'yes' }} steps: - - uses: actions/checkout@v7 - - uses: actions/setup-python@v6 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 + - uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6 - name: Set up dependencies shell: pwsh run: pip install meson ninja @@ -304,7 +304,7 @@ jobs: shell: pwsh run: meson compile -C build - name: Upload build artifacts - uses: actions/upload-artifact@v7 + uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7 with: name: windows-meson-artifacts path: build @@ -320,13 +320,13 @@ jobs: group: windows-meson-test-${{ matrix.nr }}-${{ github.ref }} cancel-in-progress: ${{ needs.ci-config.outputs.skip_concurrent == 'yes' }} steps: - - uses: actions/checkout@v7 - - uses: actions/setup-python@v6 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 + - uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6 - name: Set up dependencies shell: pwsh run: pip install meson ninja - name: Download build artifacts - uses: actions/download-artifact@v8 + uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8 with: name: windows-meson-artifacts path: build @@ -339,7 +339,7 @@ jobs: run: ci/print-test-failures.sh - name: Upload failed tests' directories if: failure() && env.FAILED_TEST_ARTIFACTS != '' - uses: actions/upload-artifact@v7 + uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7 with: name: failed-tests-windows-meson-${{ matrix.nr }} path: ${{env.FAILED_TEST_ARTIFACTS}} @@ -375,7 +375,7 @@ jobs: TEST_OUTPUT_DIRECTORY: ${{github.workspace}}/t runs-on: ${{matrix.vector.pool}} steps: - - uses: actions/checkout@v7 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 - run: ci/install-dependencies.sh - run: ci/run-build-and-tests.sh - name: print test failures @@ -383,7 +383,7 @@ jobs: run: ci/print-test-failures.sh - name: Upload failed tests' directories if: failure() && env.FAILED_TEST_ARTIFACTS != '' - uses: actions/upload-artifact@v7 + uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7 with: name: failed-tests-${{matrix.vector.jobname}} path: ${{env.FAILED_TEST_ARTIFACTS}} @@ -396,7 +396,7 @@ jobs: CI_JOB_IMAGE: ubuntu-latest runs-on: ubuntu-latest steps: - - uses: actions/checkout@v7 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 - run: ci/install-dependencies.sh - run: ci/run-build-and-minimal-fuzzers.sh dockerized: @@ -475,7 +475,7 @@ jobs: else apt-get -q update && apt-get -q -y install git fi - - uses: actions/checkout@v7 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 - run: ci/install-dependencies.sh - run: useradd builder --create-home - run: chown -R builder . @@ -487,7 +487,7 @@ jobs: sudo --preserve-env --set-home --user=builder ci/print-test-failures.sh - name: Upload failed tests' directories if: failure() && env.FAILED_TEST_ARTIFACTS != '' - uses: actions/upload-artifact@v7 + uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7 with: name: failed-tests-${{matrix.vector.jobname}} path: ${{env.FAILED_TEST_ARTIFACTS}} @@ -502,7 +502,7 @@ jobs: group: static-analysis-${{ github.ref }} cancel-in-progress: ${{ needs.ci-config.outputs.skip_concurrent == 'yes' }} steps: - - uses: actions/checkout@v7 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 - run: ci/install-dependencies.sh - run: ci/run-static-analysis.sh - run: ci/check-directional-formatting.bash @@ -518,7 +518,7 @@ jobs: group: rust-analysis-${{ github.ref }} cancel-in-progress: ${{ needs.ci-config.outputs.skip_concurrent == 'yes' }} steps: - - uses: actions/checkout@v7 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 - run: ci/install-dependencies.sh - run: ci/run-rust-checks.sh sparse: @@ -532,7 +532,7 @@ jobs: group: sparse-${{ github.ref }} cancel-in-progress: ${{ needs.ci-config.outputs.skip_concurrent == 'yes' }} steps: - - uses: actions/checkout@v7 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 - name: Install other dependencies run: ci/install-dependencies.sh - run: make sparse @@ -548,6 +548,6 @@ jobs: CI_JOB_IMAGE: ubuntu-latest runs-on: ubuntu-latest steps: - - uses: actions/checkout@v7 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 - run: ci/install-dependencies.sh - run: ci/test-documentation.sh diff --git a/.github/workflows/nano-server.yml b/.github/workflows/nano-server.yml index 60e056a44bf8cc..625e064c570a0c 100644 --- a/.github/workflows/nano-server.yml +++ b/.github/workflows/nano-server.yml @@ -14,8 +14,8 @@ jobs: IMAGE: mcr.microsoft.com/powershell:nanoserver-ltsc2022 steps: - - uses: actions/checkout@v7 - - uses: git-for-windows/setup-git-for-windows-sdk@v2 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 + - uses: git-for-windows/setup-git-for-windows-sdk@aed153d1258c311b680b81584a72a1a4807401f0 # v2 - name: build Git shell: bash run: make -j15 diff --git a/.github/workflows/scalar-functional-tests.yml b/.github/workflows/scalar-functional-tests.yml index 672c505877b115..7fd7c612b8ee02 100644 --- a/.github/workflows/scalar-functional-tests.yml +++ b/.github/workflows/scalar-functional-tests.yml @@ -37,11 +37,11 @@ jobs: steps: - name: Check out Git's source code - uses: actions/checkout@v6 + uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6 - name: Setup build tools on Windows if: runner.os == 'Windows' - uses: git-for-windows/setup-git-for-windows-sdk@v2 + uses: git-for-windows/setup-git-for-windows-sdk@aed153d1258c311b680b81584a72a1a4807401f0 # v2 - name: Update the Git wrapper for UCRT64 if: runner.os == 'Windows' @@ -134,7 +134,7 @@ jobs: case "$(scalar version 2>&1)" in *.vfs.*) echo Good;; *) exit 1;; esac - name: Check out Scalar's source code - uses: actions/checkout@v6 + uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6 with: fetch-depth: 0 # Indicate full history so Nerdbank.GitVersioning works. path: scalar @@ -155,7 +155,7 @@ jobs: mv $props.new $props - name: Setup .NET - uses: actions/setup-dotnet@v5 + uses: actions/setup-dotnet@26b0ec14cb23fa6904739307f278c14f94c95bf1 # v5 with: dotnet-version: '9.0.306' @@ -232,7 +232,7 @@ jobs: - name: Archive Trace2 Logs if: ( success() || failure() ) && ( steps.trace2_zip_unix.conclusion == 'success' || steps.trace2_zip_windows.conclusion == 'success' ) - uses: actions/upload-artifact@v7 + uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7 with: name: ${{ env.TRACE2_BASENAME }}.zip path: scalar/${{ env.TRACE2_BASENAME }}.zip @@ -244,6 +244,6 @@ jobs: # Git for Windows, which runs a slightly incompatible MSYS2 runtime). - name: action-tmate if: env.DEBUG_WITH_TMATE == 'true' && failure() - uses: mxschmitt/action-tmate@v3 + uses: mxschmitt/action-tmate@35b54afac29c97fb54faba5b513f8fbd1882f113 # v3 with: limit-access-to-actor: true diff --git a/.github/workflows/vfs-functional-tests.yml b/.github/workflows/vfs-functional-tests.yml index 7c927ff3e4b6fe..44b20fa98008b2 100644 --- a/.github/workflows/vfs-functional-tests.yml +++ b/.github/workflows/vfs-functional-tests.yml @@ -22,10 +22,10 @@ jobs: steps: - name: Check out Git's source code - uses: actions/checkout@v6 + uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6 - name: Setup build tools - uses: git-for-windows/setup-git-for-windows-sdk@v2 + uses: git-for-windows/setup-git-for-windows-sdk@aed153d1258c311b680b81584a72a1a4807401f0 # v2 with: architecture: ${{ matrix.architecture }} @@ -107,7 +107,7 @@ jobs: fi - name: Upload Git artifact - uses: actions/upload-artifact@v7 + uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7 with: name: MicrosoftGit-${{ matrix.architecture }} path: MicrosoftGit @@ -122,13 +122,13 @@ jobs: steps: - name: Download x86_64 build - uses: actions/download-artifact@v8 + uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8 with: name: MicrosoftGit-x86_64 path: MicrosoftGit - name: Download aarch64 build - uses: actions/download-artifact@v8 + uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8 with: name: MicrosoftGit-aarch64 path: MicrosoftGit @@ -163,7 +163,7 @@ jobs: BATCH - name: Upload Git artifact - uses: actions/upload-artifact@v7 + uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7 with: name: MicrosoftGit path: MicrosoftGit @@ -210,7 +210,7 @@ jobs: functional_tests: name: Functional Tests needs: package - uses: microsoft/VFSForGit/.github/workflows/functional-tests.yaml@master + uses: microsoft/VFSForGit/.github/workflows/functional-tests.yaml@c5ea3d5dc5e44f51ffa7876f46409dfe650de851 # master with: vfs_repository: microsoft/VFSForGit vfs_run_id: ${{ needs.package.outputs.vfs_run_id }}