Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fe3085894a | ||
|
|
f7e934116a | ||
|
|
f548e57e54 | ||
|
|
3d3c42e5aa | ||
|
|
28802689a1 | ||
|
|
12cd2235ef | ||
|
|
62661c4e71 | ||
|
|
e8d4307400 | ||
|
|
631c942040 | ||
|
|
4f1f4aec02 | ||
|
|
ba097532fb | ||
|
|
b9e0990d21 | ||
|
|
e8cb398be4 | ||
|
|
5de26ee9b1 | ||
|
|
79102f2503 |
@@ -1,3 +0,0 @@
|
||||
dist/
|
||||
lib/
|
||||
node_modules/
|
||||
@@ -1,53 +0,0 @@
|
||||
{
|
||||
"plugins": ["jest", "@typescript-eslint"],
|
||||
"extends": ["plugin:github/recommended"],
|
||||
"parser": "@typescript-eslint/parser",
|
||||
"parserOptions": {
|
||||
"ecmaVersion": 9,
|
||||
"sourceType": "module",
|
||||
"project": "./tsconfig.json"
|
||||
},
|
||||
"rules": {
|
||||
"eslint-comments/no-use": "off",
|
||||
"import/no-namespace": "off",
|
||||
"no-unused-vars": "off",
|
||||
"@typescript-eslint/no-unused-vars": "error",
|
||||
"@typescript-eslint/explicit-member-accessibility": ["error", {"accessibility": "no-public"}],
|
||||
"@typescript-eslint/no-require-imports": "error",
|
||||
"@typescript-eslint/array-type": "error",
|
||||
"@typescript-eslint/await-thenable": "error",
|
||||
"camelcase": "off",
|
||||
"@typescript-eslint/explicit-function-return-type": ["error", {"allowExpressions": true}],
|
||||
"@typescript-eslint/func-call-spacing": ["error", "never"],
|
||||
"@typescript-eslint/no-array-constructor": "error",
|
||||
"@typescript-eslint/no-empty-interface": "error",
|
||||
"@typescript-eslint/no-explicit-any": "error",
|
||||
"@typescript-eslint/no-extraneous-class": "error",
|
||||
"@typescript-eslint/no-floating-promises": "error",
|
||||
"@typescript-eslint/no-for-in-array": "error",
|
||||
"@typescript-eslint/no-inferrable-types": "error",
|
||||
"@typescript-eslint/no-misused-new": "error",
|
||||
"@typescript-eslint/no-namespace": "error",
|
||||
"@typescript-eslint/no-non-null-assertion": "warn",
|
||||
"@typescript-eslint/no-unnecessary-qualifier": "error",
|
||||
"@typescript-eslint/no-unnecessary-type-assertion": "error",
|
||||
"@typescript-eslint/no-useless-constructor": "error",
|
||||
"@typescript-eslint/no-var-requires": "error",
|
||||
"@typescript-eslint/prefer-for-of": "warn",
|
||||
"@typescript-eslint/prefer-function-type": "warn",
|
||||
"@typescript-eslint/prefer-includes": "error",
|
||||
"@typescript-eslint/prefer-string-starts-ends-with": "error",
|
||||
"@typescript-eslint/promise-function-async": "error",
|
||||
"@typescript-eslint/require-array-sort-compare": "error",
|
||||
"@typescript-eslint/restrict-plus-operands": "error",
|
||||
"semi": "off",
|
||||
"@typescript-eslint/semi": ["error", "never"],
|
||||
"@typescript-eslint/type-annotation-spacing": "error",
|
||||
"@typescript-eslint/unbound-method": "error"
|
||||
},
|
||||
"env": {
|
||||
"node": true,
|
||||
"es6": true,
|
||||
"jest/globals": true
|
||||
}
|
||||
}
|
||||
@@ -1,51 +0,0 @@
|
||||
# `dist/index.js` is a special file in Actions.
|
||||
# When you reference an action with `uses:` in a workflow,
|
||||
# `index.js` is the code that will run.
|
||||
# For our project, we generate this file through a build process
|
||||
# from other source files.
|
||||
# We need to make sure the checked-in `index.js` actually matches what we expect it to be.
|
||||
name: Check dist
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
paths-ignore:
|
||||
- '**.md'
|
||||
pull_request:
|
||||
paths-ignore:
|
||||
- '**.md'
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
check-dist:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
|
||||
- name: Set Node.js 24.x
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 24.x
|
||||
|
||||
- name: Install dependencies
|
||||
run: npm ci
|
||||
|
||||
- name: Rebuild the index.js file
|
||||
run: npm run build
|
||||
|
||||
- name: Compare the expected and actual dist/ directories
|
||||
run: |
|
||||
if [ "$(git diff --ignore-space-at-eol dist/ | wc -l)" -gt "0" ]; then
|
||||
echo "Detected uncommitted changes after build. See status below:"
|
||||
git diff
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# If dist/ was different than expected, upload the expected version as an artifact
|
||||
- uses: actions/upload-artifact@v4
|
||||
if: ${{ failure() && steps.diff.conclusion == 'failure' }}
|
||||
with:
|
||||
name: dist
|
||||
path: dist/
|
||||
@@ -1,58 +0,0 @@
|
||||
# For most projects, this workflow file will not need changing; you simply need
|
||||
# to commit it to your repository.
|
||||
#
|
||||
# You may wish to alter this file to override the set of languages analyzed,
|
||||
# or to provide custom queries or build logic.
|
||||
#
|
||||
# ******** NOTE ********
|
||||
# We have attempted to detect the languages in your repository. Please check
|
||||
# the `language` matrix defined below to confirm you have the correct set of
|
||||
# supported CodeQL languages.
|
||||
#
|
||||
name: "CodeQL"
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ main ]
|
||||
pull_request:
|
||||
# The branches below must be a subset of the branches above
|
||||
branches: [ main ]
|
||||
schedule:
|
||||
- cron: '28 9 * * 0'
|
||||
|
||||
jobs:
|
||||
analyze:
|
||||
name: Analyze
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
actions: read
|
||||
contents: read
|
||||
security-events: write
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
language: [ 'javascript' ]
|
||||
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ]
|
||||
# Learn more:
|
||||
# https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v3
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
# If you wish to specify custom queries, you can do so here or in a config file.
|
||||
# By default, queries listed here will override any specified in a config file.
|
||||
# Prefix the list here with "+" to use these queries and those in the config file.
|
||||
# queries: ./path/to/local/query, your-org/your-repo/queries@main
|
||||
|
||||
- run: npm ci
|
||||
- run: npm run build
|
||||
- run: rm -rf dist # We want code scanning to analyze lib instead (individual .js files)
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v3
|
||||
@@ -1,14 +0,0 @@
|
||||
name: Licensed
|
||||
|
||||
on:
|
||||
push: {branches: main}
|
||||
pull_request: {branches: main}
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
name: Check licenses
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- run: npm ci
|
||||
- run: npm run licensed-check
|
||||
@@ -1,20 +0,0 @@
|
||||
name: 'Publish Immutable Action Version'
|
||||
|
||||
on:
|
||||
release:
|
||||
types: [published]
|
||||
|
||||
jobs:
|
||||
publish:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
id-token: write
|
||||
packages: write
|
||||
|
||||
steps:
|
||||
- name: Checking out
|
||||
uses: actions/checkout@v6
|
||||
- name: Publish
|
||||
id: publish
|
||||
uses: actions/publish-immutable-action@v0.0.4
|
||||
@@ -1,357 +0,0 @@
|
||||
name: Build and Test
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- releases/*
|
||||
|
||||
|
||||
# Note that when you see patterns like "ref: test-data/v2/basic" within this workflow,
|
||||
# these refer to "test-data" branches on this actions/checkout repo.
|
||||
# (For example, test-data/v2/basic -> https://github.com/actions/checkout/tree/test-data/v2/basic)
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 24.x
|
||||
- uses: actions/checkout@v6
|
||||
- run: npm ci
|
||||
- run: npm run build
|
||||
- run: npm run format-check
|
||||
- run: npm run lint
|
||||
- run: npm test
|
||||
- name: Verify no unstaged changes
|
||||
run: __test__/verify-no-unstaged-changes.sh
|
||||
|
||||
test:
|
||||
strategy:
|
||||
matrix:
|
||||
runs-on: [ubuntu-latest, macos-latest, windows-latest]
|
||||
runs-on: ${{ matrix.runs-on }}
|
||||
|
||||
steps:
|
||||
# Clone this repo
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
|
||||
# Basic checkout
|
||||
- name: Checkout basic
|
||||
uses: ./
|
||||
with:
|
||||
ref: test-data/v2/basic
|
||||
path: basic
|
||||
- name: Verify basic
|
||||
shell: bash
|
||||
run: __test__/verify-basic.sh
|
||||
|
||||
# Clean
|
||||
- name: Modify work tree
|
||||
shell: bash
|
||||
run: __test__/modify-work-tree.sh
|
||||
- name: Checkout clean
|
||||
uses: ./
|
||||
with:
|
||||
ref: test-data/v2/basic
|
||||
path: basic
|
||||
- name: Verify clean
|
||||
shell: bash
|
||||
run: __test__/verify-clean.sh
|
||||
|
||||
# Side by side
|
||||
- name: Checkout side by side 1
|
||||
uses: ./
|
||||
with:
|
||||
ref: test-data/v2/side-by-side-1
|
||||
path: side-by-side-1
|
||||
- name: Checkout side by side 2
|
||||
uses: ./
|
||||
with:
|
||||
ref: test-data/v2/side-by-side-2
|
||||
path: side-by-side-2
|
||||
- name: Verify side by side
|
||||
shell: bash
|
||||
run: __test__/verify-side-by-side.sh
|
||||
|
||||
# Filter
|
||||
- name: Fetch filter
|
||||
uses: ./
|
||||
with:
|
||||
filter: 'blob:none'
|
||||
path: fetch-filter
|
||||
|
||||
- name: Verify fetch filter
|
||||
run: __test__/verify-fetch-filter.sh
|
||||
|
||||
# Fetch tags
|
||||
- name: Checkout with fetch-tags
|
||||
uses: ./
|
||||
with:
|
||||
ref: test-data/v2/basic
|
||||
path: fetch-tags-test
|
||||
fetch-tags: true
|
||||
- name: Verify fetch-tags
|
||||
shell: bash
|
||||
run: __test__/verify-fetch-tags.sh
|
||||
|
||||
# Sparse checkout
|
||||
- name: Sparse checkout
|
||||
uses: ./
|
||||
with:
|
||||
sparse-checkout: |
|
||||
__test__
|
||||
.github
|
||||
dist
|
||||
path: sparse-checkout
|
||||
|
||||
- name: Verify sparse checkout
|
||||
run: __test__/verify-sparse-checkout.sh
|
||||
|
||||
# Disabled sparse checkout in existing checkout
|
||||
- name: Disabled sparse checkout
|
||||
uses: ./
|
||||
with:
|
||||
path: sparse-checkout
|
||||
|
||||
- name: Verify disabled sparse checkout
|
||||
shell: bash
|
||||
run: set -x && ls -l sparse-checkout/src/git-command-manager.ts
|
||||
|
||||
# Sparse checkout (non-cone mode)
|
||||
- name: Sparse checkout (non-cone mode)
|
||||
uses: ./
|
||||
with:
|
||||
sparse-checkout: |
|
||||
/__test__/
|
||||
/.github/
|
||||
/dist/
|
||||
sparse-checkout-cone-mode: false
|
||||
path: sparse-checkout-non-cone-mode
|
||||
|
||||
- name: Verify sparse checkout (non-cone mode)
|
||||
run: __test__/verify-sparse-checkout-non-cone-mode.sh
|
||||
|
||||
# LFS
|
||||
- name: Checkout LFS
|
||||
uses: ./
|
||||
with:
|
||||
repository: actions/checkout # hardcoded, otherwise doesn't work from a fork
|
||||
ref: test-data/v2/lfs
|
||||
path: lfs
|
||||
lfs: true
|
||||
- name: Verify LFS
|
||||
shell: bash
|
||||
run: __test__/verify-lfs.sh
|
||||
|
||||
# Submodules false
|
||||
- name: Checkout submodules false
|
||||
uses: ./
|
||||
with:
|
||||
ref: test-data/v2/submodule-ssh-url
|
||||
path: submodules-false
|
||||
- name: Verify submodules false
|
||||
run: __test__/verify-submodules-false.sh
|
||||
|
||||
# Submodules one level
|
||||
- name: Checkout submodules true
|
||||
uses: ./
|
||||
with:
|
||||
ref: test-data/v2/submodule-ssh-url
|
||||
path: submodules-true
|
||||
submodules: true
|
||||
- name: Verify submodules true
|
||||
run: __test__/verify-submodules-true.sh
|
||||
|
||||
# Submodules recursive
|
||||
- name: Checkout submodules recursive
|
||||
uses: ./
|
||||
with:
|
||||
ref: test-data/v2/submodule-ssh-url
|
||||
path: submodules-recursive
|
||||
submodules: recursive
|
||||
- name: Verify submodules recursive
|
||||
run: __test__/verify-submodules-recursive.sh
|
||||
|
||||
# Worktree credentials
|
||||
- name: Checkout for worktree test
|
||||
uses: ./
|
||||
with:
|
||||
path: worktree-test
|
||||
- name: Verify worktree credentials
|
||||
shell: bash
|
||||
run: __test__/verify-worktree.sh worktree-test worktree-branch
|
||||
|
||||
# Worktree credentials in container step
|
||||
- name: Verify worktree credentials in container step
|
||||
if: runner.os == 'Linux'
|
||||
uses: docker://bitnami/git:latest
|
||||
with:
|
||||
args: bash __test__/verify-worktree.sh worktree-test container-worktree-branch
|
||||
|
||||
# Basic checkout using REST API
|
||||
- name: Remove basic
|
||||
if: runner.os != 'windows'
|
||||
run: rm -rf basic
|
||||
- name: Remove basic (Windows)
|
||||
if: runner.os == 'windows'
|
||||
shell: cmd
|
||||
run: rmdir /s /q basic
|
||||
- name: Override git version
|
||||
if: runner.os != 'windows'
|
||||
run: __test__/override-git-version.sh
|
||||
- name: Override git version (Windows)
|
||||
if: runner.os == 'windows'
|
||||
run: __test__\\override-git-version.cmd
|
||||
- name: Checkout basic using REST API
|
||||
uses: ./
|
||||
with:
|
||||
ref: test-data/v2/basic
|
||||
path: basic
|
||||
- name: Verify basic
|
||||
run: __test__/verify-basic.sh --archive
|
||||
|
||||
test-proxy:
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: ghcr.io/actions/test-ubuntu-git:main.20240221.114913.703z
|
||||
options: --dns 127.0.0.1
|
||||
services:
|
||||
squid-proxy:
|
||||
image: ubuntu/squid:latest
|
||||
ports:
|
||||
- 3128:3128
|
||||
env:
|
||||
https_proxy: http://squid-proxy:3128
|
||||
steps:
|
||||
# Clone this repo
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
|
||||
# Basic checkout using git
|
||||
- name: Checkout basic
|
||||
uses: ./
|
||||
with:
|
||||
ref: test-data/v2/basic
|
||||
path: basic
|
||||
- name: Verify basic
|
||||
run: __test__/verify-basic.sh
|
||||
|
||||
# Basic checkout using REST API
|
||||
- name: Remove basic
|
||||
run: rm -rf basic
|
||||
- name: Override git version
|
||||
run: __test__/override-git-version.sh
|
||||
- name: Basic checkout using REST API
|
||||
uses: ./
|
||||
with:
|
||||
ref: test-data/v2/basic
|
||||
path: basic
|
||||
- name: Verify basic
|
||||
run: __test__/verify-basic.sh --archive
|
||||
|
||||
test-bypass-proxy:
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
https_proxy: http://no-such-proxy:3128
|
||||
no_proxy: api.github.com,github.com
|
||||
steps:
|
||||
# Clone this repo
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
|
||||
# Basic checkout using git
|
||||
- name: Checkout basic
|
||||
uses: ./
|
||||
with:
|
||||
ref: test-data/v2/basic
|
||||
path: basic
|
||||
- name: Verify basic
|
||||
run: __test__/verify-basic.sh
|
||||
- name: Remove basic
|
||||
run: rm -rf basic
|
||||
|
||||
# Basic checkout using REST API
|
||||
- name: Override git version
|
||||
run: __test__/override-git-version.sh
|
||||
- name: Checkout basic using REST API
|
||||
uses: ./
|
||||
with:
|
||||
ref: test-data/v2/basic
|
||||
path: basic
|
||||
- name: Verify basic
|
||||
run: __test__/verify-basic.sh --archive
|
||||
|
||||
test-git-container:
|
||||
runs-on: ubuntu-latest
|
||||
container: bitnami/git:latest
|
||||
steps:
|
||||
# Clone this repo
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
path: localClone
|
||||
|
||||
# Basic checkout using git
|
||||
- name: Checkout basic
|
||||
uses: ./localClone
|
||||
with:
|
||||
ref: test-data/v2/basic
|
||||
- name: Verify basic
|
||||
run: |
|
||||
if [ ! -f "./basic-file.txt" ]; then
|
||||
echo "Expected basic file does not exist"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Verify .git folder
|
||||
if [ ! -d "./.git" ]; then
|
||||
echo "Expected ./.git folder to exist"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Verify auth token
|
||||
git config --global --add safe.directory "*"
|
||||
git fetch --no-tags --depth=1 origin +refs/heads/main:refs/remotes/origin/main
|
||||
|
||||
# needed to make checkout post cleanup succeed
|
||||
- name: Fix Checkout v6
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
path: localClone
|
||||
|
||||
test-output:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
# Clone this repo
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
path: actions-checkout
|
||||
|
||||
# Basic checkout using git
|
||||
- name: Checkout basic
|
||||
id: checkout
|
||||
uses: ./actions-checkout
|
||||
with:
|
||||
path: cloned-using-local-action
|
||||
ref: test-data/v2/basic
|
||||
|
||||
# Verify output
|
||||
- name: Verify output
|
||||
run: |
|
||||
echo "Commit: ${{ steps.checkout.outputs.commit }}"
|
||||
echo "Ref: ${{ steps.checkout.outputs.ref }}"
|
||||
|
||||
if [ "${{ steps.checkout.outputs.ref }}" != "test-data/v2/basic" ]; then
|
||||
echo "Expected ref to be test-data/v2/basic"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ "${{ steps.checkout.outputs.commit }}" != "82f71901cf8c021332310dcc8cdba84c4193ff5d" ]; then
|
||||
echo "Expected commit to be 82f71901cf8c021332310dcc8cdba84c4193ff5d"
|
||||
exit 1
|
||||
fi
|
||||
@@ -1,36 +0,0 @@
|
||||
name: Update Main Version
|
||||
run-name: Move ${{ github.event.inputs.major_version }} to ${{ github.event.inputs.target }}
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
target:
|
||||
description: The tag or reference to use
|
||||
required: true
|
||||
major_version:
|
||||
type: choice
|
||||
description: The major version to update
|
||||
options:
|
||||
- v5
|
||||
- v4
|
||||
- v3
|
||||
- v2
|
||||
|
||||
jobs:
|
||||
tag:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
# Note this update workflow can also be used as a rollback tool.
|
||||
# For that reason, it's best to pin `actions/checkout` to a known, stable version
|
||||
# (typically, about two releases back).
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Git config
|
||||
run: |
|
||||
git config user.name "github-actions[bot]"
|
||||
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
|
||||
- name: Tag new target
|
||||
run: git tag -f ${{ github.event.inputs.major_version }} ${{ github.event.inputs.target }}
|
||||
- name: Push new tag
|
||||
run: git push origin ${{ github.event.inputs.major_version }} --force
|
||||
@@ -1,59 +0,0 @@
|
||||
name: Publish test-ubuntu-git Container
|
||||
|
||||
on:
|
||||
# Use an on demand workflow trigger.
|
||||
# (Forked copies of actions/checkout won't have permission to update GHCR.io/actions,
|
||||
# so avoid trigger events that run automatically.)
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
publish:
|
||||
description: 'Publish to ghcr.io? (main branch only)'
|
||||
type: boolean
|
||||
required: true
|
||||
default: false
|
||||
|
||||
env:
|
||||
REGISTRY: ghcr.io
|
||||
IMAGE_NAME: actions/test-ubuntu-git
|
||||
|
||||
jobs:
|
||||
build-and-push-image:
|
||||
runs-on: ubuntu-latest
|
||||
# Sets the permissions granted to the `GITHUB_TOKEN` for the actions in this job.
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v6
|
||||
|
||||
# Use `docker/login-action` to log in to GHCR.io.
|
||||
# Once published, the packages are scoped to the account defined here.
|
||||
- name: Log in to the ghcr.io container registry
|
||||
uses: docker/login-action@v3.3.0
|
||||
with:
|
||||
registry: ${{ env.REGISTRY }}
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Format Timestamp
|
||||
id: timestamp
|
||||
# Use `date` with a custom format to achieve the key=value format GITHUB_OUTPUT expects.
|
||||
run: date -u "+now=%Y%m%d.%H%M%S.%3NZ" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Issue Image Publish Warning
|
||||
if: ${{ inputs.publish && github.ref_name != 'main' }}
|
||||
run: echo "::warning::test-ubuntu-git images can only be published from the actions/checkout 'main' branch. Workflow will continue with push/publish disabled."
|
||||
|
||||
# Use `docker/build-push-action` to build (and optionally publish) the image.
|
||||
- name: Build Docker Image (with optional Push)
|
||||
uses: docker/build-push-action@v6.5.0
|
||||
with:
|
||||
context: .
|
||||
file: images/test-ubuntu-git.Dockerfile
|
||||
# For now, attempts to push to ghcr.io must target the `main` branch.
|
||||
# In the future, consider also allowing attempts from `releases/*` branches.
|
||||
push: ${{ inputs.publish && github.ref_name == 'main' }}
|
||||
tags: |
|
||||
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.ref_name }}.${{ steps.timestamp.outputs.now }}
|
||||
+7
-6
@@ -1,13 +1,14 @@
|
||||
# Changelog
|
||||
|
||||
## v7.0.1
|
||||
* Skip running unsafe pr check if input is default by @aiqiaoy in https://github.com/actions/checkout/pull/2518
|
||||
* Trim only ascii whitespace for branch by @aiqiaoy in https://github.com/actions/checkout/pull/2521
|
||||
* Escape values passed to --unset by @aiqiaoy in https://github.com/actions/checkout/pull/2530
|
||||
* Various dependency updates
|
||||
|
||||
## v7.0.0
|
||||
* Block checking out fork PR for pull_request_target and workflow_run by @aiqiaoy in https://github.com/actions/checkout/pull/2454
|
||||
* Bump actions/publish-immutable-action from 0.0.3 to 0.0.4 in the minor-actions-dependencies group across 1 directory by @dependabot[bot] in https://github.com/actions/checkout/pull/2458
|
||||
* Bump flatted from 3.3.1 to 3.4.2 by @dependabot[bot] in https://github.com/actions/checkout/pull/2460
|
||||
* Bump js-yaml from 4.1.0 to 4.2.0 by @dependabot[bot] in https://github.com/actions/checkout/pull/2461
|
||||
* Bump @actions/core and @actions/tool-cache and Remove uuid by @dependabot[bot] in https://github.com/actions/checkout/pull/2459
|
||||
* upgrade module to esm and update dependencies by @aiqiaoy in https://github.com/actions/checkout/pull/2463
|
||||
* Bump the minor-npm-dependencies group across 1 directory with 3 updates by @dependabot[bot] in https://github.com/actions/checkout/pull/2462
|
||||
* Various dependency updates
|
||||
|
||||
## v6.0.3
|
||||
* Fix checkout init for SHA-256 repositories by @yaananth in https://github.com/actions/checkout/pull/2439
|
||||
|
||||
@@ -1,388 +1,37 @@
|
||||
[](https://github.com/actions/checkout/actions/workflows/test.yml)
|
||||
# actions-checkout — actions 本地镜像(mu-ref)
|
||||
|
||||
# Checkout v7
|
||||
- 上游: https://github.com/actions/checkout (GitHub 公开仓库的只读镜像)
|
||||
- 引用方式(workflow 内绝对 URL):
|
||||
```yaml
|
||||
uses: https://git.moneywood.site/mu-ref/actions-checkout@v4
|
||||
```
|
||||
- 标签: 上游全部 tag(v4 为流动标签,随上游发布移动)
|
||||
|
||||
## What's new
|
||||
## 防护规则(每次同步后必须复核,违反其一即回归 2026-08-26 调度事故)
|
||||
|
||||
- Safer fork pull request handling: checkout now refuses to check out fork pull request code by default when the workflow is triggered by `pull_request_target` or `workflow_run`. These triggers run with the base repository's `GITHUB_TOKEN`, secrets, and runner access, where executing a fork's code commonly leads to "pwn request" vulnerabilities.
|
||||
- To opt in after [reviewing the risks](https://gh.io/securely-using-pull_request_target), set the new `allow-unsafe-pr-checkout: true` input.
|
||||
- Migrated `actions/checkout` to ESM to support new versions of the `@actions/*` packages.
|
||||
- Updated direct and transitive dependencies, including security fixes for known vulnerabilities.
|
||||
1. 本仓 Actions 保持禁用(repo 设置 has_actions=false;事故证明它挡不住已登记的 schedule,必须配合第 2 条)
|
||||
2. 仓内不得存在任何 workflow 文件(.github/workflows/ 已剥离;Gitea 1.24.7 不会随文件删除清理 schedule 登记)
|
||||
|
||||
# Checkout v6
|
||||
## 同步步骤(更新上游时执行)
|
||||
|
||||
## What's new
|
||||
|
||||
- Improved credential security: `persist-credentials` now stores credentials in a separate file under `$RUNNER_TEMP` instead of directly in `.git/config`
|
||||
- No workflow changes required — `git fetch`, `git push`, etc. continue to work automatically
|
||||
- Running authenticated git commands from a [Docker container action](https://docs.github.com/actions/sharing-automations/creating-actions/creating-a-docker-container-action) requires Actions Runner [v2.329.0](https://github.com/actions/runner/releases/tag/v2.329.0) or later
|
||||
|
||||
# Checkout v5
|
||||
|
||||
## What's new
|
||||
|
||||
- Updated to the node24 runtime
|
||||
- This requires a minimum Actions Runner version of [v2.327.1](https://github.com/actions/runner/releases/tag/v2.327.1) to run.
|
||||
|
||||
# Checkout v4
|
||||
|
||||
This action checks-out your repository under `$GITHUB_WORKSPACE`, so your workflow can access it.
|
||||
|
||||
Only a single commit is fetched by default, for the ref/SHA that triggered the workflow. Set `fetch-depth: 0` to fetch all history for all branches and tags. Refer [here](https://docs.github.com/actions/using-workflows/events-that-trigger-workflows) to learn which commit `$GITHUB_SHA` points to for different events.
|
||||
|
||||
The auth token is persisted in the local git config. This enables your scripts to run authenticated git commands. The token is removed during post-job cleanup. Set `persist-credentials: false` to opt-out.
|
||||
|
||||
When Git 2.18 or higher is not in your PATH, falls back to the REST API to download the files.
|
||||
|
||||
### Note
|
||||
|
||||
Thank you for your interest in this GitHub action, however, right now we are not taking contributions.
|
||||
|
||||
We continue to focus our resources on strategic areas that help our customers be successful while making developers' lives easier. While GitHub Actions remains a key part of this vision, we are allocating resources towards other areas of Actions and are not taking contributions to this repository at this time. The GitHub public roadmap is the best place to follow along for any updates on features we’re working on and what stage they’re in.
|
||||
|
||||
We are taking the following steps to better direct requests related to GitHub Actions, including:
|
||||
|
||||
1. We will be directing questions and support requests to our [Community Discussions area](https://github.com/orgs/community/discussions/categories/actions)
|
||||
|
||||
2. High Priority bugs can be reported through Community Discussions or you can report these to our support team https://support.github.com/contact/bug-report.
|
||||
|
||||
3. Security Issues should be handled as per our [security.md](security.md)
|
||||
|
||||
We will still provide security updates for this project and fix major breaking changes during this time.
|
||||
|
||||
You are welcome to still raise bugs in this repo.
|
||||
|
||||
# What's new
|
||||
|
||||
Please refer to the [release page](https://github.com/actions/checkout/releases/latest) for the latest release notes.
|
||||
|
||||
# Usage
|
||||
|
||||
<!-- start usage -->
|
||||
```yaml
|
||||
- uses: actions/checkout@v7
|
||||
with:
|
||||
# Repository name with owner. For example, actions/checkout
|
||||
# Default: ${{ github.repository }}
|
||||
repository: ''
|
||||
|
||||
# The branch, tag or SHA to checkout. When checking out the repository that
|
||||
# triggered a workflow, this defaults to the reference or SHA for that event.
|
||||
# Otherwise, uses the default branch.
|
||||
ref: ''
|
||||
|
||||
# Personal access token (PAT) used to fetch the repository. The PAT is configured
|
||||
# with the local git config, which enables your scripts to run authenticated git
|
||||
# commands. The post-job step removes the PAT.
|
||||
#
|
||||
# We recommend using a service account with the least permissions necessary. Also
|
||||
# when generating a new PAT, select the least scopes necessary.
|
||||
#
|
||||
# [Learn more about creating and using encrypted secrets](https://help.github.com/en/actions/automating-your-workflow-with-github-actions/creating-and-using-encrypted-secrets)
|
||||
#
|
||||
# Default: ${{ github.token }}
|
||||
token: ''
|
||||
|
||||
# SSH key used to fetch the repository. The SSH key is configured with the local
|
||||
# git config, which enables your scripts to run authenticated git commands. The
|
||||
# post-job step removes the SSH key.
|
||||
#
|
||||
# We recommend using a service account with the least permissions necessary.
|
||||
#
|
||||
# [Learn more about creating and using encrypted secrets](https://help.github.com/en/actions/automating-your-workflow-with-github-actions/creating-and-using-encrypted-secrets)
|
||||
ssh-key: ''
|
||||
|
||||
# Known hosts in addition to the user and global host key database. The public SSH
|
||||
# keys for a host may be obtained using the utility `ssh-keyscan`. For example,
|
||||
# `ssh-keyscan github.com`. The public key for github.com is always implicitly
|
||||
# added.
|
||||
ssh-known-hosts: ''
|
||||
|
||||
# Whether to perform strict host key checking. When true, adds the options
|
||||
# `StrictHostKeyChecking=yes` and `CheckHostIP=no` to the SSH command line. Use
|
||||
# the input `ssh-known-hosts` to configure additional hosts.
|
||||
# Default: true
|
||||
ssh-strict: ''
|
||||
|
||||
# The user to use when connecting to the remote SSH host. By default 'git' is
|
||||
# used.
|
||||
# Default: git
|
||||
ssh-user: ''
|
||||
|
||||
# Whether to configure the token or SSH key with the local git config
|
||||
# Default: true
|
||||
persist-credentials: ''
|
||||
|
||||
# Relative path under $GITHUB_WORKSPACE to place the repository
|
||||
path: ''
|
||||
|
||||
# Whether to execute `git clean -ffdx && git reset --hard HEAD` before fetching
|
||||
# Default: true
|
||||
clean: ''
|
||||
|
||||
# Partially clone against a given filter. Overrides sparse-checkout if set.
|
||||
# Default: null
|
||||
filter: ''
|
||||
|
||||
# Do a sparse checkout on given patterns. Each pattern should be separated with
|
||||
# new lines.
|
||||
# Default: null
|
||||
sparse-checkout: ''
|
||||
|
||||
# Specifies whether to use cone-mode when doing a sparse checkout.
|
||||
# Default: true
|
||||
sparse-checkout-cone-mode: ''
|
||||
|
||||
# Number of commits to fetch. 0 indicates all history for all branches and tags.
|
||||
# Default: 1
|
||||
fetch-depth: ''
|
||||
|
||||
# Whether to fetch tags, even if fetch-depth > 0.
|
||||
# Default: false
|
||||
fetch-tags: ''
|
||||
|
||||
# Whether to show progress status output when fetching.
|
||||
# Default: true
|
||||
show-progress: ''
|
||||
|
||||
# Whether to download Git-LFS files
|
||||
# Default: false
|
||||
lfs: ''
|
||||
|
||||
# Whether to checkout submodules: `true` to checkout submodules or `recursive` to
|
||||
# recursively checkout submodules.
|
||||
#
|
||||
# When the `ssh-key` input is not provided, SSH URLs beginning with
|
||||
# `git@github.com:` are converted to HTTPS.
|
||||
#
|
||||
# Default: false
|
||||
submodules: ''
|
||||
|
||||
# Add repository path as safe.directory for Git global config by running `git
|
||||
# config --global --add safe.directory <path>`
|
||||
# Default: true
|
||||
set-safe-directory: ''
|
||||
|
||||
# The base URL for the GitHub instance that you are trying to clone from, will use
|
||||
# environment defaults to fetch from the same instance that the workflow is
|
||||
# running from unless specified. Example URLs are https://github.com or
|
||||
# https://my-ghes-server.example.com
|
||||
github-server-url: ''
|
||||
|
||||
# Required to check out fork pull request code from a workflow triggered by
|
||||
# `pull_request_target` or `workflow_run`. These workflows run with the base
|
||||
# repository's GITHUB_TOKEN, secrets, default-branch cache scope, and runner
|
||||
# access; fetching and executing a fork's code in that trusted context commonly
|
||||
# leads to "pwn request" vulnerabilities. Set to `true` only after reviewing the
|
||||
# risks at https://gh.io/securely-using-pull_request_target.
|
||||
# Default: false
|
||||
allow-unsafe-pr-checkout: ''
|
||||
```
|
||||
<!-- end usage -->
|
||||
|
||||
# Scenarios
|
||||
|
||||
- [Checkout V5](#checkout-v5)
|
||||
- [What's new](#whats-new)
|
||||
- [Checkout V4](#checkout-v4)
|
||||
- [Note](#note)
|
||||
- [What's new](#whats-new-1)
|
||||
- [Usage](#usage)
|
||||
- [Scenarios](#scenarios)
|
||||
- [Fetch only the root files](#fetch-only-the-root-files)
|
||||
- [Fetch only the root files and `.github` and `src` folder](#fetch-only-the-root-files-and-github-and-src-folder)
|
||||
- [Fetch only a single file](#fetch-only-a-single-file)
|
||||
- [Fetch all history for all tags and branches](#fetch-all-history-for-all-tags-and-branches)
|
||||
- [Checkout a different branch](#checkout-a-different-branch)
|
||||
- [Checkout HEAD^](#checkout-head)
|
||||
- [Checkout multiple repos (side by side)](#checkout-multiple-repos-side-by-side)
|
||||
- [Checkout multiple repos (nested)](#checkout-multiple-repos-nested)
|
||||
- [Checkout multiple repos (private)](#checkout-multiple-repos-private)
|
||||
- [Checkout pull request HEAD commit instead of merge commit](#checkout-pull-request-head-commit-instead-of-merge-commit)
|
||||
- [Checkout pull request on closed event](#checkout-pull-request-on-closed-event)
|
||||
- [Push a commit using the built-in token](#push-a-commit-using-the-built-in-token)
|
||||
- [Push a commit to a PR using the built-in token](#push-a-commit-to-a-pr-using-the-built-in-token)
|
||||
- [Recommended permissions](#recommended-permissions)
|
||||
- [License](#license)
|
||||
|
||||
## Fetch only the root files
|
||||
|
||||
```yaml
|
||||
- uses: actions/checkout@v7
|
||||
with:
|
||||
sparse-checkout: .
|
||||
```bash
|
||||
REPO=actions-checkout
|
||||
SRC=https://github.com/actions/checkout.git
|
||||
git clone --mirror "$SRC" /tmp/mirror-$REPO.git
|
||||
# 1) 剥掉 GitHub 的 PR 引用(Gitea hook 拒绝 refs/pull/*)
|
||||
git -C /tmp/mirror-$REPO.git for-each-ref --format='delete %(refname)' refs/pull | git -C /tmp/mirror-$REPO.git update-ref --stdin
|
||||
# 2) 剥掉 .github/workflows(上游 CI 不得在 Gitea 执行)
|
||||
rm -rf /tmp/wt-$REPO && git clone -q /tmp/mirror-$REPO.git /tmp/wt-$REPO
|
||||
git -C /tmp/wt-$REPO checkout -q main
|
||||
git -C /tmp/wt-$REPO rm -r -q .github/workflows
|
||||
git -C /tmp/wt-$REPO -c user.name=dsh-mulm -c user.email=dsh-mulm@est.local commit -q -m 'chore: strip upstream CI workflows'
|
||||
git -C /tmp/wt-$REPO push -q gitea-dsh:mu-ref/$REPO.git main --tags
|
||||
# 3) 复核防护规则(缺一不可)
|
||||
curl -s -H "Authorization: token $GITEA_TOKEN" http://127.0.0.1:3300/api/v1/repos/mu-ref/$REPO | jq '{has_actions}'
|
||||
git ls-tree gitea-dsh:mu-ref/$REPO.git main --name-only | grep -q '.github' && echo 'FAIL: workflow dir present' || echo OK
|
||||
git ls-remote gitea-dsh:mu-ref/$REPO.git refs/tags/v4
|
||||
```
|
||||
|
||||
## Fetch only the root files and `.github` and `src` folder
|
||||
## 事故记录
|
||||
|
||||
```yaml
|
||||
- uses: actions/checkout@v7
|
||||
with:
|
||||
sparse-checkout: |
|
||||
.github
|
||||
src
|
||||
```
|
||||
|
||||
## Fetch only a single file
|
||||
|
||||
```yaml
|
||||
- uses: actions/checkout@v7
|
||||
with:
|
||||
sparse-checkout: |
|
||||
README.md
|
||||
sparse-checkout-cone-mode: false
|
||||
```
|
||||
|
||||
## Fetch all history for all tags and branches
|
||||
|
||||
```yaml
|
||||
- uses: actions/checkout@v7
|
||||
with:
|
||||
fetch-depth: 0
|
||||
```
|
||||
|
||||
## Checkout a different branch
|
||||
|
||||
```yaml
|
||||
- uses: actions/checkout@v7
|
||||
with:
|
||||
ref: my-branch
|
||||
```
|
||||
|
||||
## Checkout HEAD^
|
||||
|
||||
```yaml
|
||||
- uses: actions/checkout@v7
|
||||
with:
|
||||
fetch-depth: 2
|
||||
- run: git checkout HEAD^
|
||||
```
|
||||
|
||||
## Checkout multiple repos (side by side)
|
||||
|
||||
```yaml
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v7
|
||||
with:
|
||||
path: main
|
||||
|
||||
- name: Checkout tools repo
|
||||
uses: actions/checkout@v7
|
||||
with:
|
||||
repository: my-org/my-tools
|
||||
path: my-tools
|
||||
```
|
||||
> - If your secondary repository is private or internal you will need to add the option noted in [Checkout multiple repos (private)](#Checkout-multiple-repos-private)
|
||||
|
||||
## Checkout multiple repos (nested)
|
||||
|
||||
```yaml
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v7
|
||||
|
||||
- name: Checkout tools repo
|
||||
uses: actions/checkout@v7
|
||||
with:
|
||||
repository: my-org/my-tools
|
||||
path: my-tools
|
||||
```
|
||||
> - If your secondary repository is private or internal you will need to add the option noted in [Checkout multiple repos (private)](#Checkout-multiple-repos-private)
|
||||
|
||||
## Checkout multiple repos (private)
|
||||
|
||||
```yaml
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v7
|
||||
with:
|
||||
path: main
|
||||
|
||||
- name: Checkout private tools
|
||||
uses: actions/checkout@v7
|
||||
with:
|
||||
repository: my-org/my-private-tools
|
||||
token: ${{ secrets.GH_PAT }} # `GH_PAT` is a secret that contains your PAT
|
||||
path: my-tools
|
||||
```
|
||||
|
||||
> - `${{ github.token }}` is scoped to the current repository, so if you want to checkout a different repository that is private you will need to provide your own [PAT](https://help.github.com/en/github/authenticating-to-github/creating-a-personal-access-token-for-the-command-line).
|
||||
|
||||
|
||||
## Checkout pull request HEAD commit instead of merge commit
|
||||
|
||||
```yaml
|
||||
- uses: actions/checkout@v7
|
||||
with:
|
||||
ref: ${{ github.event.pull_request.head.sha }}
|
||||
```
|
||||
|
||||
## Checkout pull request on closed event
|
||||
|
||||
```yaml
|
||||
on:
|
||||
pull_request:
|
||||
branches: [main]
|
||||
types: [opened, synchronize, closed]
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v7
|
||||
```
|
||||
|
||||
## Push a commit using the built-in token
|
||||
|
||||
```yaml
|
||||
on: push
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v7
|
||||
- run: |
|
||||
date > generated.txt
|
||||
# Note: the following account information will not work on GHES
|
||||
git config user.name "github-actions[bot]"
|
||||
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
|
||||
git add .
|
||||
git commit -m "generated"
|
||||
git push
|
||||
```
|
||||
*NOTE:* The user email is `{user.id}+{user.login}@users.noreply.github.com`. See users API: https://api.github.com/users/github-actions%5Bbot%5D
|
||||
|
||||
## Push a commit to a PR using the built-in token
|
||||
|
||||
In a pull request trigger, `ref` is required as GitHub Actions checks out in detached HEAD mode, meaning it doesn’t check out your branch by default.
|
||||
|
||||
```yaml
|
||||
on: pull_request
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v7
|
||||
with:
|
||||
ref: ${{ github.head_ref }}
|
||||
- run: |
|
||||
date > generated.txt
|
||||
# Note: the following account information will not work on GHES
|
||||
git config user.name "github-actions[bot]"
|
||||
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
|
||||
git add .
|
||||
git commit -m "generated"
|
||||
git push
|
||||
```
|
||||
|
||||
*NOTE:* The user email is `{user.id}+{user.login}@users.noreply.github.com`. See users API: https://api.github.com/users/github-actions%5Bbot%5D
|
||||
|
||||
# Recommended permissions
|
||||
|
||||
When using the `checkout` action in your GitHub Actions workflow, it is recommended to set the following `GITHUB_TOKEN` permissions to ensure proper functionality, unless alternative auth is provided via the `token` or `ssh-key` inputs:
|
||||
|
||||
```yaml
|
||||
permissions:
|
||||
contents: read
|
||||
```
|
||||
|
||||
# License
|
||||
|
||||
The scripts and documentation in this project are released under the [MIT License](LICENSE)
|
||||
- 2026-08-26: 初版镜像(est org)把上游 .github/workflows 一并推入,codeql.yml 的 schedule 被 Gitea 1.24.7 以 ~30 秒间隔重复执行,CodeQL job 挂起 17–30 分钟/个,4 并发占满 tn runner,阻断全平台 CI。处置:删仓重建 + 剥离 workflow + 禁用 Actions,最终归位 mu-ref。详见 Est-Platform-Coordination 交接文档第四节(reviews/gitea-build-pitfalls-handoff-2026-08-26.md)。
|
||||
|
||||
@@ -24,9 +24,20 @@ const mockGithubContext: any = {
|
||||
payload: {}
|
||||
}
|
||||
|
||||
// Replicate @actions/core getInput behavior: it trims whitespace by default
|
||||
// (String.prototype.trim(), which strips characters such as a leading U+FEFF BOM)
|
||||
// unless trimWhitespace is explicitly set to false.
|
||||
const getInputImpl = (name: string, options?: {trimWhitespace?: boolean}) => {
|
||||
const val = inputs[name] ?? ''
|
||||
if (options && options.trimWhitespace === false) {
|
||||
return val
|
||||
}
|
||||
return typeof val === 'string' ? val.trim() : val
|
||||
}
|
||||
|
||||
// Mock @actions/core before loading input-helper
|
||||
jest.unstable_mockModule('@actions/core', () => ({
|
||||
getInput: jest.fn((name: string) => inputs[name]),
|
||||
getInput: jest.fn(getInputImpl),
|
||||
getBooleanInput: jest.fn((name: string) => inputs[name]),
|
||||
getMultilineInput: jest.fn((name: string) =>
|
||||
inputs[name] ? String(inputs[name]).split('\n').filter(Boolean) : []
|
||||
@@ -76,9 +87,7 @@ describe('input-helper tests', () => {
|
||||
inputs = {}
|
||||
jest.clearAllMocks()
|
||||
// Re-apply default mocks
|
||||
;(core.getInput as jest.Mock<any>).mockImplementation(
|
||||
(name: string) => inputs[name]
|
||||
)
|
||||
;(core.getInput as jest.Mock<any>).mockImplementation(getInputImpl as any)
|
||||
mockDirectoryExistsSync.mockImplementation(
|
||||
(p: string) => p === gitHubWorkspace
|
||||
)
|
||||
@@ -176,8 +185,84 @@ describe('input-helper tests', () => {
|
||||
expect(settings.commit).toBeFalsy()
|
||||
})
|
||||
|
||||
it('does not reclassify a ref as sha when a BOM is prefixed', async () => {
|
||||
// A fork branch named "<U+FEFF>" + 40 hex chars. core.getInput trims the
|
||||
// BOM by default, which previously collapsed this into a bare SHA and
|
||||
// bypassed the unsafe fork PR checkout guard.
|
||||
inputs.ref = '\uFEFF522d932fae5296da51fdf431934425ecf891c6a2'
|
||||
const settings: IGitSourceSettings = await inputHelper.getInputs()
|
||||
expect(settings.commit).toBeFalsy()
|
||||
expect(settings.ref).toBe('522d932fae5296da51fdf431934425ecf891c6a2')
|
||||
})
|
||||
|
||||
it('does not reclassify a sha-256 ref as sha when a BOM is prefixed', async () => {
|
||||
inputs.ref =
|
||||
'\uFEFF1111111111222222222233333333334444444444555555555566666666667777'
|
||||
const settings: IGitSourceSettings = await inputHelper.getInputs()
|
||||
expect(settings.commit).toBeFalsy()
|
||||
expect(settings.ref).toBe(
|
||||
'1111111111222222222233333333334444444444555555555566666666667777'
|
||||
)
|
||||
})
|
||||
|
||||
it('treats a sha surrounded by ascii whitespace as a commit', async () => {
|
||||
// ASCII whitespace can only come from the workflow author's YAML (git ref
|
||||
// names cannot contain it), so trimming it and treating the value as a
|
||||
// commit is safe.
|
||||
inputs.ref = ' 1111111111222222222233333333334444444444 '
|
||||
const settings: IGitSourceSettings = await inputHelper.getInputs()
|
||||
expect(settings.ref).toBeFalsy()
|
||||
expect(settings.commit).toBe('1111111111222222222233333333334444444444')
|
||||
})
|
||||
|
||||
it('sets workflow organization ID', async () => {
|
||||
const settings: IGitSourceSettings = await inputHelper.getInputs()
|
||||
expect(settings.workflowOrganizationId).toBe(123456)
|
||||
})
|
||||
|
||||
describe('unsafe PR checkout guard', () => {
|
||||
const forkPayload = {
|
||||
repository: {id: 100},
|
||||
pull_request: {
|
||||
head: {
|
||||
sha: '1234567890123456789012345678901234567890',
|
||||
repo: {id: 200, full_name: 'attacker/fork'}
|
||||
},
|
||||
merge_commit_sha: 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'
|
||||
}
|
||||
}
|
||||
|
||||
it('allows the default self-checkout on a fork pull_request_target', async () => {
|
||||
const originalEvent = mockGithubContext.eventName
|
||||
const originalPayload = mockGithubContext.payload
|
||||
try {
|
||||
mockGithubContext.eventName = 'pull_request_target'
|
||||
mockGithubContext.payload = forkPayload
|
||||
// Simulate a rebase/fast-forward merge where the base tip (event SHA)
|
||||
// equals the PR head SHA. The default self-checkout must still succeed.
|
||||
mockGithubContext.sha = '1234567890123456789012345678901234567890'
|
||||
const settings: IGitSourceSettings = await inputHelper.getInputs()
|
||||
expect(settings.commit).toBe('1234567890123456789012345678901234567890')
|
||||
} finally {
|
||||
mockGithubContext.eventName = originalEvent
|
||||
mockGithubContext.payload = originalPayload
|
||||
}
|
||||
})
|
||||
|
||||
it('refuses an explicit fork repository on pull_request_target', async () => {
|
||||
const originalEvent = mockGithubContext.eventName
|
||||
const originalPayload = mockGithubContext.payload
|
||||
try {
|
||||
mockGithubContext.eventName = 'pull_request_target'
|
||||
mockGithubContext.payload = forkPayload
|
||||
inputs.repository = 'attacker/fork'
|
||||
await expect(inputHelper.getInputs()).rejects.toThrow(
|
||||
/Refusing to check out fork pull request code/
|
||||
)
|
||||
} finally {
|
||||
mockGithubContext.eventName = originalEvent
|
||||
mockGithubContext.payload = originalPayload
|
||||
}
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
Vendored
+32
-9
@@ -35913,7 +35913,7 @@ class GitCommandManager {
|
||||
else {
|
||||
args.push(globalConfig ? '--global' : '--local');
|
||||
}
|
||||
args.push('--unset', configKey, configValue);
|
||||
args.push('--unset', configKey, regexp_helper_escape(configValue));
|
||||
const output = await this.execGit(args, true);
|
||||
return output.exitCode === 0;
|
||||
}
|
||||
@@ -42100,6 +42100,22 @@ async function getInputs() {
|
||||
`${github_context.repo.owner}/${github_context.repo.repo}`.toUpperCase();
|
||||
// Source branch, source version
|
||||
result.ref = getInput('ref');
|
||||
// core.getInput()'s default trim strips a range of Unicode characters such as a
|
||||
// leading BOM (U+FEFF) or NBSP (U+00A0). Those are valid in a git ref name, so
|
||||
// a fork branch named "<BOM>" + 40 hex chars would trim down to a bare SHA and
|
||||
// be silently reclassified as a commit, bypassing the unsafe fork PR checkout
|
||||
// guard.
|
||||
//
|
||||
// The trim below strips only the ASCII whitespace characters which are all forbidden
|
||||
// in a git branch name.
|
||||
// \t U+0009 horizontal tab - ASCII control, forbidden in ref names
|
||||
// \n U+000A line feed - ASCII control, forbidden in ref names
|
||||
// \v U+000B vertical tab - ASCII control, forbidden in ref names
|
||||
// \f U+000C form feed - ASCII control, forbidden in ref names
|
||||
// \r U+000D carriage return - ASCII control, forbidden in ref names
|
||||
// ' ' U+0020 space - forbidden in ref names
|
||||
const asciiTrimmedRef = getInput('ref', { trimWhitespace: false })
|
||||
.replace(/^[\t\n\v\f\r ]+|[\t\n\v\f\r ]+$/g, '');
|
||||
if (!result.ref) {
|
||||
if (isWorkflowRepository) {
|
||||
result.ref = github_context.ref;
|
||||
@@ -42112,8 +42128,8 @@ async function getInputs() {
|
||||
}
|
||||
}
|
||||
// SHA?
|
||||
else if (result.ref.match(/^(?:[0-9a-fA-F]{40}|[0-9a-fA-F]{64})$/)) {
|
||||
result.commit = result.ref;
|
||||
else if (asciiTrimmedRef.match(/^(?:[0-9a-fA-F]{40}|[0-9a-fA-F]{64})$/)) {
|
||||
result.commit = asciiTrimmedRef;
|
||||
result.ref = '';
|
||||
}
|
||||
core_debug(`ref = '${result.ref}'`);
|
||||
@@ -42191,12 +42207,19 @@ async function getInputs() {
|
||||
(getInput('allow-unsafe-pr-checkout') || 'false').toUpperCase() ===
|
||||
'TRUE';
|
||||
core_debug(`allow unsafe PR checkout = ${result.allowUnsafePrCheckout}`);
|
||||
assertSafePrCheckout({
|
||||
qualifiedRepository,
|
||||
ref: result.ref,
|
||||
commit: result.commit,
|
||||
allowUnsafePrCheckout: result.allowUnsafePrCheckout
|
||||
});
|
||||
// The default self-checkout (this repository with no explicit ref) always
|
||||
// resolves to the trusted ref/commit GitHub set for the triggering event, so
|
||||
// the fork-checkout guard only needs to run when the caller customized the
|
||||
// repository or ref.
|
||||
const isDefaultCheckout = isWorkflowRepository && !getInput('ref');
|
||||
if (!isDefaultCheckout) {
|
||||
assertSafePrCheckout({
|
||||
qualifiedRepository,
|
||||
ref: result.ref,
|
||||
commit: result.commit,
|
||||
allowUnsafePrCheckout: result.allowUnsafePrCheckout
|
||||
});
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
import github from 'eslint-plugin-github'
|
||||
import jest from 'eslint-plugin-jest'
|
||||
|
||||
const githubConfigs = github.getFlatConfigs()
|
||||
|
||||
export default [
|
||||
{
|
||||
ignores: ['**/node_modules/**', '**/lib/**', '**/dist/**']
|
||||
},
|
||||
githubConfigs.recommended,
|
||||
...githubConfigs.typescript,
|
||||
{
|
||||
files: ['**/*.ts'],
|
||||
languageOptions: {
|
||||
parserOptions: {
|
||||
project: './tsconfig.json'
|
||||
}
|
||||
},
|
||||
rules: {
|
||||
'eslint-comments/no-use': 'off',
|
||||
'import/no-namespace': 'off',
|
||||
'no-unused-vars': 'off',
|
||||
'@typescript-eslint/no-unused-vars': 'error',
|
||||
'@typescript-eslint/explicit-member-accessibility': [
|
||||
'error',
|
||||
{accessibility: 'no-public'}
|
||||
],
|
||||
'@typescript-eslint/no-require-imports': 'error',
|
||||
'@typescript-eslint/array-type': 'error',
|
||||
'@typescript-eslint/await-thenable': 'error',
|
||||
camelcase: 'off',
|
||||
'@typescript-eslint/explicit-function-return-type': [
|
||||
'error',
|
||||
{allowExpressions: true}
|
||||
],
|
||||
'@typescript-eslint/no-array-constructor': 'error',
|
||||
'@typescript-eslint/no-explicit-any': 'error',
|
||||
'@typescript-eslint/no-extraneous-class': 'error',
|
||||
'@typescript-eslint/no-floating-promises': 'error',
|
||||
'@typescript-eslint/no-for-in-array': 'error',
|
||||
'@typescript-eslint/no-inferrable-types': 'error',
|
||||
'@typescript-eslint/no-misused-new': 'error',
|
||||
'@typescript-eslint/no-namespace': 'error',
|
||||
'@typescript-eslint/no-non-null-assertion': 'warn',
|
||||
'@typescript-eslint/no-unnecessary-qualifier': 'error',
|
||||
'@typescript-eslint/no-unnecessary-type-assertion': 'error',
|
||||
'@typescript-eslint/no-useless-constructor': 'error',
|
||||
'@typescript-eslint/prefer-for-of': 'warn',
|
||||
'@typescript-eslint/prefer-function-type': 'warn',
|
||||
'@typescript-eslint/prefer-includes': 'error',
|
||||
'@typescript-eslint/prefer-string-starts-ends-with': 'error',
|
||||
'@typescript-eslint/promise-function-async': 'error',
|
||||
'@typescript-eslint/require-array-sort-compare': 'error',
|
||||
'@typescript-eslint/restrict-plus-operands': 'error',
|
||||
'@typescript-eslint/unbound-method': 'error'
|
||||
}
|
||||
},
|
||||
{
|
||||
files: ['__test__/**/*.ts'],
|
||||
...jest.configs['flat/recommended']
|
||||
}
|
||||
]
|
||||
Generated
+1915
-1076
File diff suppressed because it is too large
Load Diff
+6
-6
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "checkout",
|
||||
"version": "7.0.0",
|
||||
"version": "7.0.1",
|
||||
"description": "checkout action",
|
||||
"type": "module",
|
||||
"main": "lib/main.js",
|
||||
@@ -41,12 +41,12 @@
|
||||
"devDependencies": {
|
||||
"@types/jest": "^29.5.12",
|
||||
"@types/node": "^24.1.0",
|
||||
"@typescript-eslint/eslint-plugin": "^7.9.0",
|
||||
"@typescript-eslint/parser": "^7.9.0",
|
||||
"@typescript-eslint/eslint-plugin": "^8.54.0",
|
||||
"@typescript-eslint/parser": "^8.54.0",
|
||||
"@vercel/ncc": "^0.44.0",
|
||||
"eslint": "^8.57.0",
|
||||
"eslint-plugin-github": "^4.10.2",
|
||||
"eslint-plugin-jest": "^28.8.2",
|
||||
"eslint": "^9.39.2",
|
||||
"eslint-plugin-github": "^6.0.0",
|
||||
"eslint-plugin-jest": "^29.12.1",
|
||||
"jest": "^29.7.0",
|
||||
"js-yaml": "^4.2.0",
|
||||
"prettier": "^3.8.4",
|
||||
|
||||
@@ -510,7 +510,7 @@ class GitCommandManager {
|
||||
} else {
|
||||
args.push(globalConfig ? '--global' : '--local')
|
||||
}
|
||||
args.push('--unset', configKey, configValue)
|
||||
args.push('--unset', configKey, regexpHelper.escape(configValue))
|
||||
|
||||
const output = await this.execGit(args, true)
|
||||
return output.exitCode === 0
|
||||
|
||||
+32
-8
@@ -59,6 +59,23 @@ export async function getInputs(): Promise<IGitSourceSettings> {
|
||||
|
||||
// Source branch, source version
|
||||
result.ref = core.getInput('ref')
|
||||
// core.getInput()'s default trim strips a range of Unicode characters such as a
|
||||
// leading BOM (U+FEFF) or NBSP (U+00A0). Those are valid in a git ref name, so
|
||||
// a fork branch named "<BOM>" + 40 hex chars would trim down to a bare SHA and
|
||||
// be silently reclassified as a commit, bypassing the unsafe fork PR checkout
|
||||
// guard.
|
||||
//
|
||||
// The trim below strips only the ASCII whitespace characters which are all forbidden
|
||||
// in a git branch name.
|
||||
// \t U+0009 horizontal tab - ASCII control, forbidden in ref names
|
||||
// \n U+000A line feed - ASCII control, forbidden in ref names
|
||||
// \v U+000B vertical tab - ASCII control, forbidden in ref names
|
||||
// \f U+000C form feed - ASCII control, forbidden in ref names
|
||||
// \r U+000D carriage return - ASCII control, forbidden in ref names
|
||||
// ' ' U+0020 space - forbidden in ref names
|
||||
const asciiTrimmedRef = core
|
||||
.getInput('ref', {trimWhitespace: false})
|
||||
.replace(/^[\t\n\v\f\r ]+|[\t\n\v\f\r ]+$/g, '')
|
||||
if (!result.ref) {
|
||||
if (isWorkflowRepository) {
|
||||
result.ref = github.context.ref
|
||||
@@ -72,8 +89,8 @@ export async function getInputs(): Promise<IGitSourceSettings> {
|
||||
}
|
||||
}
|
||||
// SHA?
|
||||
else if (result.ref.match(/^(?:[0-9a-fA-F]{40}|[0-9a-fA-F]{64})$/)) {
|
||||
result.commit = result.ref
|
||||
else if (asciiTrimmedRef.match(/^(?:[0-9a-fA-F]{40}|[0-9a-fA-F]{64})$/)) {
|
||||
result.commit = asciiTrimmedRef
|
||||
result.ref = ''
|
||||
}
|
||||
core.debug(`ref = '${result.ref}'`)
|
||||
@@ -168,12 +185,19 @@ export async function getInputs(): Promise<IGitSourceSettings> {
|
||||
'TRUE'
|
||||
core.debug(`allow unsafe PR checkout = ${result.allowUnsafePrCheckout}`)
|
||||
|
||||
unsafePrCheckoutHelper.assertSafePrCheckout({
|
||||
qualifiedRepository,
|
||||
ref: result.ref,
|
||||
commit: result.commit,
|
||||
allowUnsafePrCheckout: result.allowUnsafePrCheckout
|
||||
})
|
||||
// The default self-checkout (this repository with no explicit ref) always
|
||||
// resolves to the trusted ref/commit GitHub set for the triggering event, so
|
||||
// the fork-checkout guard only needs to run when the caller customized the
|
||||
// repository or ref.
|
||||
const isDefaultCheckout = isWorkflowRepository && !core.getInput('ref')
|
||||
if (!isDefaultCheckout) {
|
||||
unsafePrCheckoutHelper.assertSafePrCheckout({
|
||||
qualifiedRepository,
|
||||
ref: result.ref,
|
||||
commit: result.commit,
|
||||
allowUnsafePrCheckout: result.allowUnsafePrCheckout
|
||||
})
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user