Skip to content

Commit 932779c

Browse files
Aiqiao YanAiqiao Yan
authored andcommitted
Initial commit to create @actions/cache package
1 parent 0471ed4 commit 932779c

19 files changed

+1763
-0
lines changed

README.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,15 @@ $ npm install @actions/artifact --save
8282
```
8383
<br/>
8484

85+
:dart: [@actions/cache](packages/cache)
86+
87+
Provides functions to interact with actions cache. Read more [here](packages/cache)
88+
89+
```bash
90+
$ npm install @actions/artifact --save
91+
```
92+
<br/>
93+
8594
## Creating an Action with the Toolkit
8695

8796
:question: [Choosing an action type](docs/action-types.md)

packages/cache/CONTRIBUTIONS.md

Whitespace-only changes.

packages/cache/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# `@actions/cache`

packages/cache/RELEASES.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# @actions/cache Releases
2+
3+
### 0.0.0
4+
5+
- Initial release
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
hello world
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import {getCacheVersion} from '../src/internal/cacheHttpClient'
2+
import {CompressionMethod} from '../src/internal/constants'
3+
4+
test('getCacheVersion with path input and compression method undefined returns version', async () => {
5+
const inputPath = 'node_modules'
6+
const result = getCacheVersion(inputPath)
7+
expect(result).toEqual(
8+
'b3e0c6cb5ecf32614eeb2997d905b9c297046d7cbf69062698f25b14b4cb0985'
9+
)
10+
})
11+
12+
test('getCacheVersion with zstd compression returns version', async () => {
13+
const inputPath = 'node_modules'
14+
const result = getCacheVersion(inputPath, CompressionMethod.Zstd)
15+
16+
expect(result).toEqual(
17+
'273877e14fd65d270b87a198edbfa2db5a43de567c9a548d2a2505b408befe24'
18+
)
19+
})
20+
21+
test('getCacheVersion with gzip compression does not change vesion', async () => {
22+
const inputPath = 'node_modules'
23+
const result = getCacheVersion(inputPath, CompressionMethod.Gzip)
24+
25+
expect(result).toEqual(
26+
'b3e0c6cb5ecf32614eeb2997d905b9c297046d7cbf69062698f25b14b4cb0985'
27+
)
28+
})
Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
import * as core from '@actions/core'
2+
import * as io from '@actions/io'
3+
import {promises as fs} from 'fs'
4+
import * as os from 'os'
5+
import * as path from 'path'
6+
import {v4 as uuidV4} from 'uuid'
7+
import * as cacheUtils from '../src/internal/cacheUtils'
8+
9+
jest.mock('@actions/core')
10+
jest.mock('os')
11+
12+
function getTempDir(): string {
13+
return path.join(__dirname, '_temp', 'cacheUtils')
14+
}
15+
16+
afterAll(async () => {
17+
delete process.env['GITHUB_WORKSPACE']
18+
await io.rmRF(getTempDir())
19+
})
20+
21+
test('getArchiveFileSize returns file size', () => {
22+
const filePath = path.join(__dirname, '__fixtures__', 'helloWorld.txt')
23+
24+
const size = cacheUtils.getArchiveFileSize(filePath)
25+
26+
expect(size).toBe(11)
27+
})
28+
29+
test('logWarning logs a message with a warning prefix', () => {
30+
const message = 'A warning occurred.'
31+
32+
const infoMock = jest.spyOn(core, 'info')
33+
34+
cacheUtils.logWarning(message)
35+
36+
expect(infoMock).toHaveBeenCalledWith(`[warning]${message}`)
37+
})
38+
39+
test('resolvePaths with no ~ in path', async () => {
40+
const filePath = '.cache'
41+
42+
// Create the following layout:
43+
// cwd
44+
// cwd/.cache
45+
// cwd/.cache/file.txt
46+
47+
const root = path.join(getTempDir(), 'no-tilde')
48+
// tarball entries will be relative to workspace
49+
process.env['GITHUB_WORKSPACE'] = root
50+
51+
await fs.mkdir(root, {recursive: true})
52+
const cache = path.join(root, '.cache')
53+
await fs.mkdir(cache, {recursive: true})
54+
await fs.writeFile(path.join(cache, 'file.txt'), 'cached')
55+
56+
const originalCwd = process.cwd()
57+
58+
try {
59+
process.chdir(root)
60+
61+
const resolvedPath = await cacheUtils.resolvePaths([filePath])
62+
63+
const expectedPath = [filePath]
64+
expect(resolvedPath).toStrictEqual(expectedPath)
65+
} finally {
66+
process.chdir(originalCwd)
67+
}
68+
})
69+
70+
test('resolvePaths with ~ in path', async () => {
71+
const cacheDir = uuidV4()
72+
const filePath = `~/${cacheDir}`
73+
// Create the following layout:
74+
// ~/uuid
75+
// ~/uuid/file.txt
76+
77+
const homedir = jest.requireActual('os').homedir()
78+
const homedirMock = jest.spyOn(os, 'homedir')
79+
homedirMock.mockReturnValue(homedir)
80+
81+
const target = path.join(homedir, cacheDir)
82+
await fs.mkdir(target, {recursive: true})
83+
await fs.writeFile(path.join(target, 'file.txt'), 'cached')
84+
85+
const root = getTempDir()
86+
process.env['GITHUB_WORKSPACE'] = root
87+
88+
try {
89+
const resolvedPath = await cacheUtils.resolvePaths([filePath])
90+
91+
const expectedPath = [path.relative(root, target)]
92+
expect(resolvedPath).toStrictEqual(expectedPath)
93+
} finally {
94+
await io.rmRF(target)
95+
}
96+
})
97+
98+
test('resolvePaths with home not found', async () => {
99+
const filePath = '~/.cache/yarn'
100+
const homedirMock = jest.spyOn(os, 'homedir')
101+
homedirMock.mockReturnValue('')
102+
103+
await expect(cacheUtils.resolvePaths([filePath])).rejects.toThrow(
104+
'Unable to determine HOME directory'
105+
)
106+
})
107+
108+
test('resolvePaths inclusion pattern returns found', async () => {
109+
const pattern = '*.ts'
110+
// Create the following layout:
111+
// inclusion-patterns
112+
// inclusion-patterns/miss.txt
113+
// inclusion-patterns/test.ts
114+
115+
const root = path.join(getTempDir(), 'inclusion-patterns')
116+
// tarball entries will be relative to workspace
117+
process.env['GITHUB_WORKSPACE'] = root
118+
119+
await fs.mkdir(root, {recursive: true})
120+
await fs.writeFile(path.join(root, 'miss.txt'), 'no match')
121+
await fs.writeFile(path.join(root, 'test.ts'), 'match')
122+
123+
const originalCwd = process.cwd()
124+
125+
try {
126+
process.chdir(root)
127+
128+
const resolvedPath = await cacheUtils.resolvePaths([pattern])
129+
130+
const expectedPath = ['test.ts']
131+
expect(resolvedPath).toStrictEqual(expectedPath)
132+
} finally {
133+
process.chdir(originalCwd)
134+
}
135+
})
136+
137+
test('resolvePaths exclusion pattern returns not found', async () => {
138+
const patterns = ['*.ts', '!test.ts']
139+
// Create the following layout:
140+
// exclusion-patterns
141+
// exclusion-patterns/miss.txt
142+
// exclusion-patterns/test.ts
143+
144+
const root = path.join(getTempDir(), 'exclusion-patterns')
145+
// tarball entries will be relative to workspace
146+
process.env['GITHUB_WORKSPACE'] = root
147+
148+
await fs.mkdir(root, {recursive: true})
149+
await fs.writeFile(path.join(root, 'miss.txt'), 'no match')
150+
await fs.writeFile(path.join(root, 'test.ts'), 'no match')
151+
152+
const originalCwd = process.cwd()
153+
154+
try {
155+
process.chdir(root)
156+
157+
const resolvedPath = await cacheUtils.resolvePaths(patterns)
158+
159+
const expectedPath: string[] = []
160+
expect(resolvedPath).toStrictEqual(expectedPath)
161+
} finally {
162+
process.chdir(originalCwd)
163+
}
164+
})
165+
166+
test('unlinkFile unlinks file', async () => {
167+
const testDirectory = await fs.mkdtemp('unlinkFileTest')
168+
const testFile = path.join(testDirectory, 'test.txt')
169+
await fs.writeFile(testFile, 'hello world')
170+
171+
await cacheUtils.unlinkFile(testFile)
172+
173+
// This should throw as testFile should not exist
174+
await expect(fs.stat(testFile)).rejects.toThrow()
175+
176+
await fs.rmdir(testDirectory)
177+
})

0 commit comments

Comments
 (0)