Skip to content

Commit 890a6fb

Browse files
feat(docker): Support dangling Docker images
Docker images that were overwritten by a new one with the same name and tag do not have a name or tag. Docker images that were pulled by digest do not have a tag. Support the former by falling back on their ID and the latter by using their name. These changes prevent the action from crashing on such images. Continue using both the name and tag for images that have them so that they are retained upon restoring the cache.
1 parent 85c8315 commit 890a6fb

File tree

6 files changed

+26
-16
lines changed

6 files changed

+26
-16
lines changed

.github/workflows/test.yaml

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -87,14 +87,15 @@ jobs:
8787
uses: ./
8888
with:
8989
key: docker-cache-test-${{ matrix.os }}-${{ github.run_id }}-${{ github.run_attempt }}
90-
- name: Build an empty test Docker image.
90+
- name: Build one tagged and one dangling empty test Docker image.
9191
run: |
9292
if [[ "${{ matrix.os }}" =~ 'windows' ]]; then
9393
DOCKERFILE='Dockerfile.windows'
9494
else
9595
DOCKERFILE='Dockerfile'
9696
fi
97-
docker build --tag empty . --file "$DOCKERFILE"
97+
docker build --tag empty . --file "$DOCKERFILE" # Dangling image
98+
docker build --tag empty --no-cache . --file "$DOCKERFILE" # Tagged image
9899
shell: bash
99100
restore-cache:
100101
name: Restore Cache
@@ -115,10 +116,15 @@ jobs:
115116
uses: ./
116117
with:
117118
key: docker-cache-test-${{ matrix.os }}-${{github.run_id }}-${{ github.run_attempt }}
118-
- name: Verify Docker loaded empty image from cache.
119+
- name: Verify Docker loaded both empty images from cache.
119120
run: |
120-
description="$(docker inspect --format '{{ index .Config.Labels "description" }}' empty)"
121-
[[ $description == 'empty image' ]]
121+
function emptyImageExists() {
122+
id="$(docker images --quiet --filter "label=description=empty image" "$@")"
123+
[[ -n "$id" ]]
124+
}
125+
emptyImageExists empty
126+
emptyImageExists --filter "dangling=true"
127+
122128
shell: bash
123129
- name: Delete test cache if permitted (i.e., workflow not triggered from fork).
124130
if: always()

dist/main/index.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/post/index.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/docker.test.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,11 @@ const assertCalledInOrder = <T extends FunctionLike>(
5050
};
5151

5252
describe("Docker images", (): void => {
53+
const LIST_COMMAND =
54+
"docker image list --format '" +
55+
'{{ if ne .Repository "<none>" }}{{ .Repository }}' +
56+
`{{ if ne .Tag "<none>" }}:{{ .Tag }}{{ end }}{{ else }}{{ .ID }}{{ end }}'`;
57+
5358
const assertLoadDockerImages = (key: string, cacheHit: boolean): void => {
5459
expect(core.getInput).lastCalledWith("key", { required: true });
5560
expect(cache.restoreCache).lastCalledWith([docker.DOCKER_IMAGES_PATH], key);
@@ -64,9 +69,7 @@ describe("Docker images", (): void => {
6469
`docker load --input ${docker.DOCKER_IMAGES_PATH}`,
6570
);
6671
} else {
67-
expect(util.execBashCommand).lastCalledWith(
68-
'docker image list --format "{{ .Repository }}:{{ .Tag }}"',
69-
);
72+
expect(util.execBashCommand).lastCalledWith(LIST_COMMAND);
7073
}
7174
expect(util.execBashCommand).toHaveBeenCalledTimes(1);
7275
};
@@ -106,10 +109,7 @@ describe("Docker images", (): void => {
106109
1,
107110
"Listing Docker images.",
108111
);
109-
expect(util.execBashCommand).nthCalledWith<[string]>(
110-
1,
111-
'docker image list --format "{{ .Repository }}:{{ .Tag }}"',
112-
);
112+
expect(util.execBashCommand).nthCalledWith<[string]>(1, LIST_COMMAND);
113113
}
114114
}
115115
}

src/docker.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@ const CACHE_HIT = "cache-hit";
77
const DOCKER_IMAGES_LIST = "docker-images-list";
88
const DOCKER_IMAGES_PATH = "~/.docker-images.tar";
99
const LIST_COMMAND =
10-
'docker image list --format "{{ .Repository }}:{{ .Tag }}"';
10+
"docker image list --format '" +
11+
'{{ if ne .Repository "<none>" }}{{ .Repository }}' +
12+
`{{ if ne .Tag "<none>" }}:{{ .Tag }}{{ end }}{{ else }}{{ .ID }}{{ end }}'`;
1113

1214
const loadDockerImages = async (): Promise<void> => {
1315
const requestedKey = getInput("key", { required: true });

src/integration.test.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,9 @@ const getKey = (paths: string[], primaryKey: string): string =>
3131
describe("Integration Test", (): void => {
3232
const EXEC_OPTIONS = { shell: "/usr/bin/bash" };
3333
const LIST_COMMAND =
34-
'docker image list --format "{{ .Repository }}:{{ .Tag }}"';
34+
"docker image list --format '" +
35+
'{{ if ne .Repository "<none>" }}{{ .Repository }}' +
36+
`{{ if ne .Tag "<none>" }}:{{ .Tag }}{{ end }}{{ else }}{{ .ID }}{{ end }}'`;
3537

3638
let loadCommand: string;
3739
let inMemoryCache: Map<string, string>;

0 commit comments

Comments
 (0)