Skip to content

Commit 13b50f0

Browse files
author
Dani Llewellyn
authored
Merge pull request #18 from diddlesnaps/add-store-credentials-support
Add store-credentials and environment support
2 parents 9e8d933 + 4d4b222 commit 13b50f0

File tree

9 files changed

+409
-209
lines changed

9 files changed

+409
-209
lines changed

.github/workflows/test.yml

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ jobs:
1919
strategy:
2020
matrix:
2121
base:
22-
- core
2322
- core18
2423
- core20
2524
- core22
@@ -33,20 +32,58 @@ jobs:
3332
- ''
3433
- 'true'
3534
- 'false'
35+
runner:
36+
- ubuntu-latest
3637
include:
38+
- base: core
39+
arch: ''
40+
usePodman: 'false'
41+
runner: ubuntu-20.04
42+
- base: core
43+
arch: ''
44+
usePodman: 'true'
45+
runner: ubuntu-20.04
3746
- base: core
3847
arch: i386
3948
usePodman: 'false'
49+
runner: ubuntu-20.04
4050
- base: core
4151
arch: i386
4252
usePodman: 'true'
53+
runner: ubuntu-20.04
54+
- base: core
55+
arch: amd64
56+
usePodman: 'false'
57+
runner: ubuntu-20.04
58+
- base: core
59+
arch: amd64
60+
usePodman: 'true'
61+
runner: ubuntu-20.04
62+
- base: core
63+
arch: armhf
64+
usePodman: 'false'
65+
runner: ubuntu-20.04
66+
- base: core
67+
arch: armhf
68+
usePodman: 'true'
69+
runner: ubuntu-20.04
70+
- base: core
71+
arch: arm64
72+
usePodman: 'false'
73+
runner: ubuntu-20.04
74+
- base: core
75+
arch: arm64
76+
usePodman: 'true'
77+
runner: ubuntu-20.04
4378
- base: core18
4479
arch: i386
4580
usePodman: 'false'
81+
runner: ubuntu-latest
4682
- base: core18
4783
arch: i386
4884
usePodman: 'true'
49-
runs-on: ubuntu-latest
85+
runner: ubuntu-latest
86+
runs-on: ${{ matrix.runner }}
5087
steps:
5188
- uses: docker/setup-qemu-action@v2
5289
- uses: actions/checkout@v3

README.md

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ notes
7676
-----
7777

7878
* `s390x` is broken at the moment.
79-
* `core20` & `core22` builds do not support `i386` architecture because Ubuntu has dropped support for `i386` in Ubuntu 20.04 and later.
79+
* Builds for `core20`, and later, do not support `i386` architecture because Ubuntu has dropped support for `i386` in Ubuntu 20.04 and later.
8080
* `core` builds do not support `s390x` architecture because Ubuntu does not have support for `s390x` before Ubuntu 18.04.
8181

8282
## Action inputs
@@ -143,3 +143,27 @@ to indicate an alternative architecture from any of those supported by
143143
the `snapcraft` utility. At the time of writing the supported
144144
architectures are `amd64`, `i386`, `arm64`, `armhf`, `ppc64el` and `s390x`.
145145
This is most-useful when used with GitHub Actions' `matrix` feature.
146+
147+
### `environment`
148+
149+
Add environment variables to the Snapcraft build context. Each
150+
variable needs to be specified on a separate line. For example:
151+
152+
```yaml
153+
with:
154+
environment: |
155+
FOO=bar
156+
BAZ=qux
157+
```
158+
### `store-auth`
159+
160+
Set the `SNAPCRAFT_STORE_CREDENTIALS` environment variable. This
161+
is useful when using the `snapcraft push` command.
162+
163+
You should not save the token into the yaml file directly, but use
164+
the GitHub Actions secrets feature:
165+
166+
```yaml
167+
with:
168+
store-auth: ${{ secrets.STORE_AUTH }}
169+
```

__tests__/build.test.ts

Lines changed: 154 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import * as exec from '@actions/exec'
88
import * as build from '../src/build'
99
import * as tools from '../src/tools'
1010

11-
const default_base = 'core20'
11+
const default_base = 'core22'
1212

1313
afterEach(() => {
1414
jest.restoreAllMocks()
@@ -21,8 +21,9 @@ test('SnapcraftBuilder expands tilde in project root', () => {
2121
'stable',
2222
'',
2323
'',
24-
'',
25-
false
24+
[],
25+
false,
26+
''
2627
)
2728
expect(builder.projectRoot).toBe(os.homedir())
2829

@@ -32,8 +33,9 @@ test('SnapcraftBuilder expands tilde in project root', () => {
3233
'stable',
3334
'',
3435
'',
35-
'',
36-
false
36+
[],
37+
false,
38+
''
3739
)
3840
expect(builder.projectRoot).toBe(path.join(os.homedir(), 'foo/bar'))
3941
})
@@ -65,7 +67,7 @@ for (const base of ['core', 'core18', 'core20', 'core22']) {
6567
}
6668
for (const [base, arch, channel] of matrix) {
6769
test(`SnapcraftBuilder.build runs a snap build using Docker with base: ${base}; and arch: ${arch}`, async () => {
68-
expect.assertions(3)
70+
expect.assertions(4)
6971

7072
const ensureDockerExperimentalMock = jest
7173
.spyOn(tools, 'ensureDockerExperimental')
@@ -75,6 +77,9 @@ for (const [base, arch, channel] of matrix) {
7577
.mockImplementation(
7678
async (projectRoot: string): Promise<string> => Promise.resolve(base)
7779
)
80+
const detectCGroupsV1Mock = jest
81+
.spyOn(tools, 'detectCGroupsV1')
82+
.mockImplementation(async (): Promise<boolean> => Promise.resolve(true))
7883
const execMock = jest
7984
.spyOn(exec, 'exec')
8085
.mockImplementation(
@@ -90,8 +95,9 @@ for (const [base, arch, channel] of matrix) {
9095
'stable',
9196
'',
9297
arch,
93-
'',
94-
false
98+
[],
99+
false,
100+
''
95101
)
96102
await builder.build()
97103

@@ -102,6 +108,11 @@ for (const [base, arch, channel] of matrix) {
102108

103109
expect(ensureDockerExperimentalMock).toHaveBeenCalled()
104110
expect(detectBaseMock).toHaveBeenCalled()
111+
if (base === 'core') {
112+
expect(detectCGroupsV1Mock).toHaveBeenCalled()
113+
} else {
114+
expect(detectCGroupsV1Mock).not.toHaveBeenCalled()
115+
}
105116
expect(execMock).toHaveBeenCalledWith(
106117
'docker',
107118
[
@@ -130,8 +141,7 @@ for (const [base, arch, channel] of matrix) {
130141
})
131142

132143
test(`SnapcraftBuilder.build runs a snap build using Podman with base: ${base}; and arch: ${arch}`, async () => {
133-
expect.assertions(3)
134-
144+
expect.assertions(4)
135145
const ensureDockerExperimentalMock = jest
136146
.spyOn(tools, 'ensureDockerExperimental')
137147
.mockImplementation(async (): Promise<void> => Promise.resolve())
@@ -140,6 +150,9 @@ for (const [base, arch, channel] of matrix) {
140150
.mockImplementation(
141151
async (projectRoot: string): Promise<string> => Promise.resolve(base)
142152
)
153+
const detectCGroupsV1Mock = jest
154+
.spyOn(tools, 'detectCGroupsV1')
155+
.mockImplementation(async (): Promise<boolean> => Promise.resolve(true))
143156
const execMock = jest
144157
.spyOn(exec, 'exec')
145158
.mockImplementation(
@@ -155,13 +168,19 @@ for (const [base, arch, channel] of matrix) {
155168
'stable',
156169
'',
157170
arch,
158-
'',
159-
true
171+
[],
172+
true,
173+
''
160174
)
161175
await builder.build()
162176

163177
expect(ensureDockerExperimentalMock).not.toHaveBeenCalled()
164178
expect(detectBaseMock).toHaveBeenCalled()
179+
if (base === 'core') {
180+
expect(detectCGroupsV1Mock).toHaveBeenCalled()
181+
} else {
182+
expect(detectCGroupsV1Mock).not.toHaveBeenCalled()
183+
}
165184
expect(execMock).toHaveBeenCalledWith(
166185
'sudo podman',
167186
[
@@ -214,8 +233,9 @@ test('SnapcraftBuilder.build can disable build info', async () => {
214233
'stable',
215234
'',
216235
'',
217-
'',
218-
false
236+
[],
237+
false,
238+
''
219239
)
220240
await builder.build()
221241

@@ -266,8 +286,62 @@ test('SnapcraftBuilder.build can pass additional arguments', async () => {
266286
'stable',
267287
'--foo --bar',
268288
'',
289+
[],
290+
false,
291+
''
292+
)
293+
await builder.build()
294+
295+
expect(execMock).toHaveBeenCalledWith(
296+
'docker',
297+
[
298+
'run',
299+
'--rm',
300+
'--tty',
301+
'--privileged',
302+
'--volume',
303+
`${process.cwd()}:/data`,
304+
'--workdir',
305+
'/data',
306+
'--env',
307+
`SNAPCRAFT_IMAGE_INFO={"build_url":"https://github.com/user/repo/actions/runs/42"}`,
308+
'--env',
309+
'USE_SNAPCRAFT_CHANNEL=stable',
310+
`diddledani/snapcraft:${default_base}`,
311+
'snapcraft',
312+
'--foo',
313+
'--bar'
314+
],
315+
expect.anything()
316+
)
317+
})
318+
319+
test('SnapcraftBuilder.build can pass extra environment variables', async () => {
320+
expect.assertions(1)
321+
322+
const ensureDockerExperimentalMock = jest
323+
.spyOn(tools, 'ensureDockerExperimental')
324+
.mockImplementation(async (): Promise<void> => Promise.resolve())
325+
const detectBaseMock = jest
326+
.spyOn(tools, 'detectBase')
327+
.mockImplementation(
328+
async (projectRoot: string): Promise<string> => default_base
329+
)
330+
const execMock = jest
331+
.spyOn(exec, 'exec')
332+
.mockImplementation(
333+
async (program: string, args?: string[]): Promise<number> => 0
334+
)
335+
336+
const builder = new build.SnapcraftBuilder(
337+
'.',
338+
false,
339+
'stable',
340+
'--foo --bar',
269341
'',
270-
false
342+
['FOO=bar', 'BAZ=qux'],
343+
false,
344+
''
271345
)
272346
await builder.build()
273347

@@ -283,6 +357,10 @@ test('SnapcraftBuilder.build can pass additional arguments', async () => {
283357
'--workdir',
284358
'/data',
285359
'--env',
360+
'FOO=bar',
361+
'--env',
362+
'BAZ=qux',
363+
'--env',
286364
`SNAPCRAFT_IMAGE_INFO={"build_url":"https://github.com/user/repo/actions/runs/42"}`,
287365
'--env',
288366
'USE_SNAPCRAFT_CHANNEL=stable',
@@ -295,6 +373,61 @@ test('SnapcraftBuilder.build can pass additional arguments', async () => {
295373
)
296374
})
297375

376+
test('SnapcraftBuilder.build adds store credentials', async () => {
377+
expect.assertions(1)
378+
379+
const ensureDockerExperimentalMock = jest
380+
.spyOn(tools, 'ensureDockerExperimental')
381+
.mockImplementation(async (): Promise<void> => Promise.resolve())
382+
const detectBaseMock = jest
383+
.spyOn(tools, 'detectBase')
384+
.mockImplementation(
385+
async (projectRoot: string): Promise<string> => default_base
386+
)
387+
const execMock = jest
388+
.spyOn(exec, 'exec')
389+
.mockImplementation(
390+
async (program: string, args?: string[]): Promise<number> => 0
391+
)
392+
393+
const builder = new build.SnapcraftBuilder(
394+
'.',
395+
false,
396+
'stable',
397+
'--foo --bar',
398+
'',
399+
[],
400+
false,
401+
'TEST_STORE_CREDENTIALS'
402+
)
403+
await builder.build()
404+
405+
expect(execMock).toHaveBeenCalledWith(
406+
'docker',
407+
[
408+
'run',
409+
'--rm',
410+
'--tty',
411+
'--privileged',
412+
'--volume',
413+
`${process.cwd()}:/data`,
414+
'--workdir',
415+
'/data',
416+
'--env',
417+
`SNAPCRAFT_IMAGE_INFO={"build_url":"https://github.com/user/repo/actions/runs/42"}`,
418+
'--env',
419+
'USE_SNAPCRAFT_CHANNEL=stable',
420+
'--env',
421+
'SNAPCRAFT_STORE_CREDENTIALS=TEST_STORE_CREDENTIALS',
422+
`diddledani/snapcraft:${default_base}`,
423+
'snapcraft',
424+
'--foo',
425+
'--bar'
426+
],
427+
expect.anything()
428+
)
429+
})
430+
298431
test('SnapcraftBuilder.outputSnap fails if there are no snaps', async () => {
299432
expect.assertions(2)
300433

@@ -305,8 +438,9 @@ test('SnapcraftBuilder.outputSnap fails if there are no snaps', async () => {
305438
'stable',
306439
'',
307440
'',
308-
'',
309-
false
441+
[],
442+
false,
443+
''
310444
)
311445

312446
const readdir = jest
@@ -331,8 +465,9 @@ test('SnapcraftBuilder.outputSnap returns the first snap', async () => {
331465
'stable',
332466
'',
333467
'',
334-
'',
335-
false
468+
[],
469+
false,
470+
''
336471
)
337472

338473
const readdir = jest

0 commit comments

Comments
 (0)