Compare commits

...

30 Commits

Author SHA1 Message Date
f626d210e8 linting 2024-08-15 20:37:17 -04:00
fa37431cef npm ci and npm run release 2024-08-15 20:34:01 -04:00
3412bb46a4 Exclude the .git directory by default 2024-08-15 20:29:20 -04:00
834a144ee9 Merge pull request #594 from actions/robherley/4.3.6
Revert to @actions/artifact 2.1.8
2024-08-06 10:41:08 -04:00
134dcf33c0 v4.3.6 2024-08-06 10:24:34 -04:00
73a0b9c954 revert back to @actions/artifact 2.1.8 2024-08-06 10:23:43 -04:00
89ef406dd8 Merge pull request #588 from actions/robherley/4.3.5
Bump @actions/artifact to v2.1.9
2024-08-02 09:59:06 -04:00
23d796df36 license updates 2024-08-01 15:50:32 -04:00
e445c64bc2 bump @actions/artifact to v2.1.9 2024-08-01 15:46:49 -04:00
0b2256b8c0 Merge pull request #584 from actions/robherley/bump-pkgs
Update @actions/artifact version, bump dependencies
2024-07-05 11:11:13 -04:00
488dcefb9b licensed cache 2024-07-05 14:39:15 +00:00
04c51f5766 ncc 2024-07-05 13:55:51 +00:00
32a9e276a8 bump @actions/artifact and npm audit 2024-07-05 13:51:02 +00:00
552bf3722c new version 2024-04-23 11:22:42 -07:00
79616d2ded Merge pull request #565 from actions/eggyhead/use-artifact-v2.1.6
updating toolkit artifact dependency to 2.1.6
2024-04-22 09:19:03 -07:00
65462800fd updating package version 2024-04-22 08:10:47 -07:00
c004fb4bf6 Merge branch 'main' into eggyhead/use-artifact-v2.1.6 2024-04-22 08:08:40 -07:00
90aba496fc updating toolkit artifact dependency to 2.1.6 2024-04-22 08:06:58 -07:00
b06cde36fc Merge pull request #563 from actions/eggyhead/release-4.3.2
updating to release 4.3.2
2024-04-18 08:13:48 -07:00
1746f4ab65 Revert "updating to release 4.3.2"
This reverts commit 31685d04a0.

updating to release 4.3.2
2024-04-18 15:05:07 +00:00
31685d04a0 updating to release 4.3.2 2024-04-18 14:56:48 +00:00
18bf333cd2 Merge pull request #562 from actions/eggyhead/update-artifact-v215
updating `@actions/artifact` dependency to v2.1.5 and `@actions/core` to v1.0.1
2024-04-17 15:05:29 -07:00
dac413befa update package lock version 2024-04-17 21:24:58 +00:00
bb3b4a3cdb updating package version 2024-04-17 20:38:47 +00:00
3e3da837d2 updating artifact and core dependencies 2024-04-17 17:00:25 +00:00
e35774f165 Merge pull request #561 from actions/robherley/deprecation-notice
Update readme with v3/v2/v1 deprecation notice
2024-04-16 17:12:57 -04:00
e63ea677fb Update readme with v3/v2/v1 deprecation notice
- https://github.blog/changelog/2024-02-13-deprecation-notice-v1-and-v2-of-the-artifact-actions/
- https://github.blog/changelog/2024-04-16-deprecation-notice-v3-of-the-artifact-actions/
2024-04-16 16:48:37 -04:00
ef09cdac3e Merge pull request #523 from andrewakim/andrewakim/migration-readme-fix
Minor fix to the migration readme
2024-02-15 14:06:33 -05:00
00e36f94d8 Minor fix to the migration readme 2024-02-15 11:01:40 -08:00
4c0ff1c489 Update release-new-action-version.yml (#516) 2024-02-05 17:19:59 -05:00
22 changed files with 39480 additions and 32151 deletions

View File

@ -22,7 +22,7 @@ jobs:
steps:
- name: Update the ${{ env.TAG_NAME }} tag
id: update-major-tag
uses: actions/publish-action@v0.2.1
uses: actions/publish-action@v0.3.0
with:
source-tag: ${{ env.TAG_NAME }}
slack-webhook: ${{ secrets.SLACK_WEBHOOK }}

View File

@ -1,6 +1,6 @@
---
name: "@actions/artifact"
version: 2.1.1
version: 2.1.8
type: npm
summary:
homepage:

View File

@ -1,6 +1,6 @@
---
name: "@actions/core"
version: 1.10.0
version: 1.10.1
type: npm
summary:
homepage:

View File

@ -1,5 +1,11 @@
# `@actions/upload-artifact`
> [!WARNING]
> actions/upload-artifact@v3 is scheduled for deprecation on **November 30, 2024**. [Learn more.](https://github.blog/changelog/2024-04-16-deprecation-notice-v3-of-the-artifact-actions/)
> Similarly, v1/v2 are scheduled for deprecation on **June 30, 2024**.
> Please update your workflow to use v4 of the artifact actions.
> This deprecation will not impact any existing versions of GitHub Enterprise Server being used by customers.
Upload [Actions Artifacts](https://docs.github.com/en/actions/using-workflows/storing-workflow-data-as-artifacts) from your Workflow Runs. Internally powered by [@actions/artifact](https://github.com/actions/toolkit/tree/main/packages/artifact) package.
See also [download-artifact](https://github.com/actions/download-artifact).
@ -10,6 +16,7 @@ See also [download-artifact](https://github.com/actions/download-artifact).
- [Breaking Changes](#breaking-changes)
- [Usage](#usage)
- [Inputs](#inputs)
- [Uploading the `.git` directory](#uploading-the-git-directory)
- [Outputs](#outputs)
- [Examples](#examples)
- [Upload an Individual File](#upload-an-individual-file)
@ -58,6 +65,7 @@ There is also a new sub-action, `actions/upload-artifact/merge`. For more info,
Due to how Artifacts are created in this new version, it is no longer possible to upload to the same named Artifact multiple times. You must either split the uploads into multiple Artifacts with different names, or only upload once. Otherwise you _will_ encounter an error.
3. Limit of Artifacts for an individual job. Each job in a workflow run now has a limit of 500 artifacts.
4. With `v4.4` and later, the `.git` directory is excluded by default.
For assistance with breaking changes, see [MIGRATION.md](docs/MIGRATION.md).
@ -103,6 +111,30 @@ For assistance with breaking changes, see [MIGRATION.md](docs/MIGRATION.md).
overwrite:
```
#### Uploading the `.git` directory
By default, files in a `.git` directory are ignored in the uploaded artifact.
This is intended to prevent accidentally uploading Git credentials into an artifact that could then
be extracted.
If files in the `.git` directory are needed, ensure that `actions/checkout` is being used with
`persist-credentials: false`.
```yaml
jobs:
upload:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
persist-credentials: false # Ensure credentials are not saved in `.git/config`
- uses: actions/upload-artifact@v4
with:
path: .
include-git-directory: true
```
### Outputs
| Name | Description | Example |

View File

@ -61,6 +61,12 @@ const lonelyFilePath = path.join(
'lonely-file.txt'
)
const gitConfigPath = path.join(root, '.git', 'config')
const gitHeadPath = path.join(root, '.git', 'HEAD')
const nestedGitConfigPath = path.join(root, 'repository-name', '.git', 'config')
const nestedGitHeadPath = path.join(root, 'repository-name', '.git', 'HEAD')
describe('Search', () => {
beforeAll(async () => {
// mock all output so that there is less noise when running tests
@ -93,6 +99,11 @@ describe('Search', () => {
recursive: true
})
await fs.mkdir(path.join(root, '.git'))
await fs.mkdir(path.join(root, 'repository-name', '.git'), {
recursive: true
})
await fs.writeFile(searchItem1Path, 'search item1 file')
await fs.writeFile(searchItem2Path, 'search item2 file')
await fs.writeFile(searchItem3Path, 'search item3 file')
@ -110,9 +121,17 @@ describe('Search', () => {
await fs.writeFile(amazingFileInFolderHPath, 'amazing file')
await fs.writeFile(lonelyFilePath, 'all by itself')
await fs.writeFile(gitConfigPath, 'git config file')
await fs.writeFile(gitHeadPath, 'git head file')
await fs.writeFile(nestedGitConfigPath, 'nested git config file')
await fs.writeFile(nestedGitHeadPath, 'nested git head file')
/*
Directory structure of files that get created:
root/
.git/
config
HEAD
folder-a/
folder-b/
folder-c/
@ -136,6 +155,10 @@ describe('Search', () => {
folder-j/
folder-k/
lonely-file.txt
repository-name/
.git/
config
HEAD
search-item5.txt
*/
})
@ -352,4 +375,18 @@ describe('Search', () => {
)
expect(searchResult.filesToUpload.includes(lonelyFilePath)).toEqual(true)
})
it('Excludes .git directory by default', async () => {
const searchResult = await findFilesToUpload(root)
expect(searchResult.filesToUpload.length).toEqual(13)
expect(searchResult.filesToUpload).not.toContain(gitConfigPath)
})
it('Includes .git directory when includeGitDirectory is true', async () => {
const searchResult = await findFilesToUpload(root, {
includeGitDirectory: true
})
expect(searchResult.filesToUpload.length).toEqual(17)
expect(searchResult.filesToUpload).toContain(gitConfigPath)
})
})

View File

@ -40,6 +40,9 @@ inputs:
If false, the action will fail if an artifact for the given name already exists.
Does not fail if the artifact does not exist.
default: 'false'
include-git-directory:
description: 'Include files in the .git directory in the artifact.'
default: 'false'
outputs:
artifact-id:

34186
dist/merge/index.js vendored

File diff suppressed because it is too large Load Diff

36040
dist/upload/index.js vendored

File diff suppressed because it is too large Load Diff

View File

@ -189,7 +189,8 @@ jobs:
- name: Create a File
run: echo "hello from ${{ matrix.runs-on }}" > file-${{ matrix.runs-on }}.txt
- name: Upload Artifact
uses: actions/upload-artifact@v3
- uses: actions/upload-artifact@v3
+ uses: actions/upload-artifact@v4
with:
- name: all-my-files
+ name: my-artifact-${{ matrix.runs-on }}
@ -206,3 +207,41 @@ jobs:
```
Note that this will download all artifacts to a temporary directory and reupload them as a single artifact. For more information on inputs and other use cases for `actions/upload-artifact/merge@v4`, see [the action documentation](../merge/README.md).
## `.git` Directory
By default, files in the `.git` directory are ignored to avoid unintentionally uploading
credentials.
In versions of this action before `v4.4.0`, files in the `.git` directory were included by default.
If this directory is required, ensure credentials are not saved in `.git/config` and then
enable the `include-git-directory` input.
```yaml
jobs:
upload:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Upload Artifact
uses: actions/upload-artifact@v3
with:
path: .
```
```diff
jobs:
upload:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
+ with:
+ persist-credentials: false
- name: Upload Artifact
- uses: actions/upload-artifact@v3
+ uses: actions/upload-artifact@v4
with:
path: .
+ include-git-directory: true
```

View File

@ -5,6 +5,7 @@ Merge multiple [Actions Artifacts](https://docs.github.com/en/actions/using-work
- [`@actions/upload-artifact/merge`](#actionsupload-artifactmerge)
- [Usage](#usage)
- [Inputs](#inputs)
- [Uploading the `.git` directory](#uploading-the-git-directory)
- [Outputs](#outputs)
- [Examples](#examples)
- [Combining all artifacts in a workflow run](#combining-all-artifacts-in-a-workflow-run)
@ -59,6 +60,44 @@ For most cases, this may not be the most efficient solution. See [the migration
compression-level:
```
#### Uploading the `.git` directory
By default, files in a `.git` directory are ignored in the merged artifact.
This is intended to prevent accidentally uploading Git credentials into an artifact that could then
be extracted.
If files in the `.git` directory are needed, ensure that `actions/checkout` is being used with
`persist-credentials: false`.
```yaml
jobs:
upload:
runs-on: ubuntu-latest
strategy:
matrix:
foo: [a, b, c]
steps:
- uses: actions/checkout@v4
with:
persist-credentials: false # Ensure credentials are not saved in `.git/config`
- name: Upload
uses: actions/upload-artifact@v4
with:
name: my-artifact-${{ matrix.foo }}
path: .
include-git-directory: true
merge:
runs-on: ubuntu-latest
steps:
- uses: actions/upload-artifact/merge@v4
with:
include-git-directory: true
```
### Outputs
| Name | Description | Example |

View File

@ -36,6 +36,9 @@ inputs:
If true, the artifacts that were merged will be deleted.
If false, the artifacts will still exist.
default: 'false'
include-git-directory:
description: 'Include files in the .git directory in the merged artifact.'
default: 'false'
outputs:
artifact-id:

1172
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
{
"name": "upload-artifact",
"version": "4.3.0",
"version": "4.4.0",
"description": "Upload an Actions Artifact in a workflow run",
"main": "dist/upload/index.js",
"scripts": {
@ -29,8 +29,8 @@
},
"homepage": "https://github.com/actions/upload-artifact#readme",
"dependencies": {
"@actions/artifact": "^2.1.1",
"@actions/core": "^1.10.0",
"@actions/artifact": "2.1.8",
"@actions/core": "^1.10.1",
"@actions/github": "^6.0.0",
"@actions/glob": "^0.3.0",
"@actions/io": "^1.1.2",

View File

@ -5,5 +5,6 @@ export enum Inputs {
SeparateDirectories = 'separate-directories',
RetentionDays = 'retention-days',
CompressionLevel = 'compression-level',
DeleteMerged = 'delete-merged'
DeleteMerged = 'delete-merged',
IncludeGitDirectory = 'include-git-directory'
}

View File

@ -10,6 +10,7 @@ export function getInputs(): MergeInputs {
const pattern = core.getInput(Inputs.Pattern, {required: true})
const separateDirectories = core.getBooleanInput(Inputs.SeparateDirectories)
const deleteMerged = core.getBooleanInput(Inputs.DeleteMerged)
const includeGitDirectory = core.getBooleanInput(Inputs.IncludeGitDirectory)
const inputs = {
name,
@ -17,7 +18,8 @@ export function getInputs(): MergeInputs {
separateDirectories,
deleteMerged,
retentionDays: 0,
compressionLevel: 6
compressionLevel: 6,
includeGitDirectory
} as MergeInputs
const retentionDaysStr = core.getInput(Inputs.RetentionDays)

View File

@ -62,7 +62,9 @@ export async function run(): Promise<void> {
options.compressionLevel = inputs.compressionLevel
}
const searchResult = await findFilesToUpload(tmpDir)
const searchResult = await findFilesToUpload(tmpDir, {
includeGitDirectory: inputs.includeGitDirectory
})
await uploadArtifact(
inputs.name,

View File

@ -30,4 +30,9 @@ export interface MergeInputs {
* If false, the artifacts will be merged into the root of the destination.
*/
separateDirectories: boolean
/**
* Include files in the `.git` directory in the artifact
*/
includeGitDirectory: boolean
}

View File

@ -78,15 +78,21 @@ function getMultiPathLCA(searchPaths: string[]): string {
return path.join(...commonPaths)
}
export interface SearchOptions {
/**
* Indicates whether files in the .git directory should be included in the artifact
*
* @default false
*/
includeGitDirectory: boolean
}
export async function findFilesToUpload(
searchPath: string,
globOptions?: glob.GlobOptions
searchOptions?: SearchOptions
): Promise<SearchResult> {
const searchResults: string[] = []
const globber = await glob.create(
searchPath,
globOptions || getDefaultGlobOptions()
)
const globber = await glob.create(searchPath, getDefaultGlobOptions())
const rawSearchResults: string[] = await globber.glob()
/*
@ -104,6 +110,12 @@ export async function findFilesToUpload(
// isDirectory() returns false for symlinks if using fs.lstat(), make sure to use fs.stat() instead
if (!fileStats.isDirectory()) {
debug(`File:${searchResult} was found using the provided searchPath`)
if (!searchOptions?.includeGitDirectory && inGitDirectory(searchResult)) {
debug(`Ignoring ${searchResult} because it is in the .git directory`)
continue
}
searchResults.push(searchResult)
// detect any files that would be overwritten because of case insensitivity
@ -155,3 +167,15 @@ export async function findFilesToUpload(
rootDirectory: searchPaths[0]
}
}
function inGitDirectory(filePath: string): boolean {
// The .git directory is a directory, so we need to check if the file path is a directory
// and if it is a .git directory
for (const part of filePath.split(path.sep)) {
if (part === '.git') {
return true
}
}
return false
}

View File

@ -5,7 +5,8 @@ export enum Inputs {
IfNoFilesFound = 'if-no-files-found',
RetentionDays = 'retention-days',
CompressionLevel = 'compression-level',
Overwrite = 'overwrite'
Overwrite = 'overwrite',
IncludeGitDirectory = 'include-git-directory'
}
export enum NoFileOptions {

View File

@ -9,6 +9,7 @@ export function getInputs(): UploadInputs {
const name = core.getInput(Inputs.Name)
const path = core.getInput(Inputs.Path, {required: true})
const overwrite = core.getBooleanInput(Inputs.Overwrite)
const includeGitDirectory = core.getBooleanInput(Inputs.IncludeGitDirectory)
const ifNoFilesFound = core.getInput(Inputs.IfNoFilesFound)
const noFileBehavior: NoFileOptions = NoFileOptions[ifNoFilesFound]
@ -27,7 +28,8 @@ export function getInputs(): UploadInputs {
artifactName: name,
searchPath: path,
ifNoFilesFound: noFileBehavior,
overwrite: overwrite
overwrite: overwrite,
includeGitDirectory: includeGitDirectory
} as UploadInputs
const retentionDaysStr = core.getInput(Inputs.RetentionDays)

View File

@ -24,7 +24,9 @@ async function deleteArtifactIfExists(artifactName: string): Promise<void> {
export async function run(): Promise<void> {
const inputs = getInputs()
const searchResult = await findFilesToUpload(inputs.searchPath)
const searchResult = await findFilesToUpload(inputs.searchPath, {
includeGitDirectory: inputs.includeGitDirectory
})
if (searchResult.filesToUpload.length === 0) {
// No files were found, different use cases warrant different types of behavior if nothing is found
switch (inputs.ifNoFilesFound) {

View File

@ -30,4 +30,9 @@ export interface UploadInputs {
* Whether or not to replace an existing artifact with the same name
*/
overwrite: boolean
/**
* Include files in the `.git` directory in the artifact
*/
includeGitDirectory: boolean
}