Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: namespacelabs/nscloud-checkout-action
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: v5
Choose a base ref
...
head repository: namespacelabs/nscloud-checkout-action
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: v6
Choose a head ref
  • 2 commits
  • 4 files changed
  • 2 contributors

Commits on Mar 5, 2025

  1. Add LFS download and caching support

    Part of: NSL-5255
    gmichelo committed Mar 5, 2025
    Copy the full SHA
    076c88a View commit details
  2. Merge pull request #10 from namespacelabs/giulio/lfs-caching-support

    Add LFS download and caching support
    gmichelo authored Mar 5, 2025
    Copy the full SHA
    63f88aa View commit details
Showing with 115 additions and 16 deletions.
  1. +4 −0 README.md
  2. +4 −0 action.yml
  3. +41 −8 dist/index.js
  4. +66 −8 src/main.ts
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -75,6 +75,10 @@ steps:
# Whether to configure the token or SSH key with the local git config
# Default: true
persist-credentials: ''

# Whether to download and cache Git-LFS files
# Default: false
lfs: ''
```
## Development
4 changes: 4 additions & 0 deletions action.yml
Original file line number Diff line number Diff line change
@@ -54,6 +54,10 @@ inputs:
`true` to dissociate the main checkout, `recursive` to dissociate the main checkout and
all submodules.
default: "false"

lfs:
description: 'Whether to download and cache Git-LFS files'
default: "false"

runs:
using: node20
49 changes: 41 additions & 8 deletions dist/index.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

74 changes: 66 additions & 8 deletions src/main.ts
Original file line number Diff line number Diff line change
@@ -55,12 +55,23 @@ See also https://namespace.so/docs/features/faster-github-actions#caching-git-re
)
if (!fs.existsSync(mirrorDir)) {
fs.mkdirSync(mirrorDir, { recursive: true })
await gitClone(config.owner, config.repo, mirrorDir, ['--mirror'])
await gitClone(
config.owner,
config.repo,
mirrorDir,
['--mirror'],
!config.downloadGitLFS
)
}

// Fetch commits for mirror
await gitFetch(mirrorDir)

// If Git LFS is required, download objects in cache
if (config.downloadGitLFS) {
await gitLFSFetch(mirrorDir, '', '')
}

// Prepare repo dir
let repoDir = workspacePath
if (config.targetPath) {
@@ -71,11 +82,13 @@ See also https://namespace.so/docs/features/faster-github-actions#caching-git-re
await exec.exec(`git config --global --add safe.directory ${repoDir}`)
const fetchDepthFlag = getFetchDepthFlag(config)
const dissociateFlag = config.dissociateMainRepo ? '--dissociate' : ''
await gitClone(config.owner, config.repo, repoDir, [
`--reference=${mirrorDir}`,
`${fetchDepthFlag}`,
`${dissociateFlag}`
])
await gitClone(
config.owner,
config.repo,
repoDir,
[`--reference=${mirrorDir}`, `${fetchDepthFlag}`, `${dissociateFlag}`],
!config.downloadGitLFS
)

// When ref is unspecified and for repositories different from the one where the workflow is running
// resolve their default branch and use it as `ref`
@@ -116,6 +129,15 @@ See also https://namespace.so/docs/features/faster-github-actions#caching-git-re
await gitSubmoduleUpdate(config, gitMirrorPath, repoDir)
}

// If Git LFS is required, download objects. This should use the mirror cached LFS objects.
if (config.downloadGitLFS) {
await gitLFSFetch(
`${repoDir}/.git`,
repoDir,
checkoutInfo.startPoint || checkoutInfo.ref
)
}

if (config.persistCredentials) {
// Persist authentication in local
await configGitRepoLocalAuth(config.token, repoDir)
@@ -145,6 +167,7 @@ interface IInputConfig {
dissociateMainRepo: boolean
dissociateSubmodules: boolean
persistCredentials: boolean
downloadGitLFS: boolean
}

function parseInputConfig(): IInputConfig {
@@ -225,6 +248,15 @@ function parseInputConfig(): IInputConfig {
}
core.debug(`persistCredentials = ${result.persistCredentials}`)

// Download and cache Git LFS objects
const downloadGitLFS = (core.getInput('lfs') || '').toUpperCase()
if (downloadGitLFS === 'TRUE') {
result.downloadGitLFS = true
} else {
result.downloadGitLFS = false
}
core.debug(`persistCredentials = ${result.downloadGitLFS}`)

return result
}

@@ -406,11 +438,25 @@ async function gitClone(
owner: string,
repo: string,
repoDir: string,
flags: string[]
flags: string[],
skipLFS: boolean
) {
// Copy over only the defined values from process.env
const cleanEnv: Record<string, string> = {}
Object.entries(process.env).forEach(([key, value]) => {
if (value !== undefined) {
cleanEnv[key] = value
}
})

// Git clone copies LFS objects from mirror if they exist by default. GIT_LFS_SKIP_SMUDGE=1 prevents that.
const envVars = skipLFS ? { ...cleanEnv, GIT_LFS_SKIP_SMUDGE: '1' } : cleanEnv

const flagString = flags.join(' ')
await exec.exec(
`git clone ${flagString} -- https://token@github.com/${owner}/${repo}.git ${repoDir}`
`git clone ${flagString} -- https://token@github.com/${owner}/${repo}.git ${repoDir}`,
[],
{ env: envVars }
)
}

@@ -420,6 +466,18 @@ async function gitFetch(gitDir: string) {
)
}

async function gitLFSFetch(gitDir: string, repoDir: string, ref: string) {
var flags: string[] = []
if (gitDir) {
flags.push(`--git-dir ${gitDir}`)
}
if (repoDir) {
flags.push(`--work-tree ${repoDir}`)
}
const flagString = flags.join(' ')
await exec.exec(`git ${flagString} lfs fetch origin ${ref}`)
}

async function gitSubmoduleUpdate(
config: IInputConfig,
mirrorDir: string,