Skip to content

Commit 20d4876

Browse files
authored
Include filenames in git ls-tree output (#2)
Removes the need of generating an additional hash for only filenames
1 parent ad178a3 commit 20d4876

File tree

5 files changed

+25
-122
lines changed

5 files changed

+25
-122
lines changed

.github/workflows/ci.yml

Lines changed: 8 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -22,26 +22,18 @@ jobs:
2222
extra_tree_objects: |
2323
test/.dockerignore
2424
test/Dockerfile
25-
extra_values: |
26-
test/.dockerignore
27-
test/Dockerfile
2825
# Expected hash generated from command below
29-
# {\
30-
# git ls-tree -r --format='%(objectname)' --full-tree HEAD \
31-
# test/a/b \
32-
# test/context/file \
33-
# test/filename \
34-
# test/.dockerignore \
35-
# test/Dockerfile\
36-
# ; \
37-
# printf "test/a/b\ntest/context/file\ntest/filename\ntest/.dockerignore\ntest/Dockerfile" | \
38-
# git hash-object --stdin\
39-
# ;\
40-
# } | git hash-object --stdin
26+
# git ls-tree -r --format='%(objectname) %(path)' --full-tree HEAD \
27+
# test/a/b \
28+
# test/context/file \
29+
# test/filename \
30+
# test/.dockerignore \
31+
# test/Dockerfile | \
32+
# git hash-object --stdin
4133
- name: Check
4234
run: |
4335
echo "${{ toJson(steps.generate) }}"
44-
if [ "${{ steps.generate.outputs.hash }}" != "6d09883618bd309806be67847737b1a5a4aa1f40" ]; then
36+
if [ "${{ steps.generate.outputs.hash }}" != "6c867c528d4bf0844d5176f78f6abfee0adfff2b" ]; then
4537
echo "::error::Invalid hash value"
4638
exit 1
4739
fi

action.yml

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,6 @@ inputs:
1212
extra_tree_objects:
1313
description: "Tree objects (files) to be included in addition to the docker image context"
1414
required: false
15-
extra_values:
16-
description: "Additional values that should be included when generating the hash"
17-
required: false
1815

1916
outputs:
2017
hash:

dist/index.js

Lines changed: 4 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -3954,12 +3954,10 @@ async function run() {
39543954
try {
39553955
const build_context = core.getInput("build_context");
39563956
const extra_tree_objects = core.getMultilineInput("extra_tree_objects");
3957-
const extra_values = core.getMultilineInput("extra_values");
39583957

3959-
core.startGroup(`Input`);
3958+
core.startGroup(`Parsed config values`);
39603959
core.info(build_context);
39613960
core.info(extra_tree_objects);
3962-
core.info(extra_values);
39633961
core.endGroup();
39643962

39653963
await core.group(`Build context image`, async () => {
@@ -3995,12 +3993,10 @@ async function run() {
39953993
core.startGroup(`Collect all file object names from git tree`);
39963994
const tree_object_paths = image_context.split("\n");
39973995
tree_object_paths.push(...extra_tree_objects);
3998-
// TODO: If we format `%(path)` as well, there's no need for the follow up
3999-
// `hash-object` of filenames below, right?
40003996
const ls_tree_cmd = [
40013997
"ls-tree",
40023998
"-r",
4003-
"--format=%(objectname)",
3999+
"--format=%(objectname) %(path)",
40044000
"--full-tree",
40054001
"HEAD",
40064002
];
@@ -4010,41 +4006,10 @@ async function run() {
40104006
});
40114007
core.endGroup();
40124008

4013-
if (
4014-
tree_object_names.stdout.trim().split("\n").length !==
4015-
tree_object_paths.length
4016-
) {
4017-
core.setFailed(
4018-
`Object paths did not match the intended amount of objects in the tree (${
4019-
tree_object_names.stdout.trim().split("\n").length
4020-
} != ${tree_object_paths.length})`
4021-
);
4022-
return;
4023-
}
4024-
4025-
core.startGroup(`Generate filenames hash`);
4026-
const filenames = image_context.split("\n");
4027-
filenames.push(...extra_values);
4028-
core.info(filenames.join("\n"));
4029-
const filenames_hashes = await exec.getExecOutput(
4030-
"git",
4031-
["hash-object", "--stdin"],
4032-
{
4033-
failOnStdErr: true,
4034-
input: Buffer.from(filenames.join("\n"), "utf-8"),
4035-
}
4036-
);
4037-
core.endGroup();
4038-
4039-
core.startGroup(`Generate hash from filenames and git tree object names`);
4009+
core.startGroup(`Generate hash from git tree objects`);
40404010
const hash = await exec.getExecOutput("git", ["hash-object", "--stdin"], {
40414011
failOnStdErr: true,
4042-
input: Buffer.from(
4043-
// Only trim "prefixing" part before join, so that the resulting line has a
4044-
// newline as suffix.
4045-
[tree_object_names.stdout.trim(), filenames_hashes.stdout].join("\n"),
4046-
"utf-8"
4047-
),
4012+
input: Buffer.from(tree_object_names.stdout, "utf-8"),
40484013
});
40494014
core.endGroup();
40504015

src/action.js

Lines changed: 4 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,10 @@ async function run() {
99
try {
1010
const build_context = core.getInput("build_context");
1111
const extra_tree_objects = core.getMultilineInput("extra_tree_objects");
12-
const extra_values = core.getMultilineInput("extra_values");
1312

14-
core.startGroup(`Input`);
13+
core.startGroup(`Parsed config values`);
1514
core.info(build_context);
1615
core.info(extra_tree_objects);
17-
core.info(extra_values);
1816
core.endGroup();
1917

2018
await core.group(`Build context image`, async () => {
@@ -50,12 +48,10 @@ async function run() {
5048
core.startGroup(`Collect all file object names from git tree`);
5149
const tree_object_paths = image_context.split("\n");
5250
tree_object_paths.push(...extra_tree_objects);
53-
// TODO: If we format `%(path)` as well, there's no need for the follow up
54-
// `hash-object` of filenames below, right?
5551
const ls_tree_cmd = [
5652
"ls-tree",
5753
"-r",
58-
"--format=%(objectname)",
54+
"--format=%(objectname) %(path)",
5955
"--full-tree",
6056
"HEAD",
6157
];
@@ -65,41 +61,10 @@ async function run() {
6561
});
6662
core.endGroup();
6763

68-
if (
69-
tree_object_names.stdout.trim().split("\n").length !==
70-
tree_object_paths.length
71-
) {
72-
core.setFailed(
73-
`Object paths did not match the intended amount of objects in the tree (${
74-
tree_object_names.stdout.trim().split("\n").length
75-
} != ${tree_object_paths.length})`
76-
);
77-
return;
78-
}
79-
80-
core.startGroup(`Generate filenames hash`);
81-
const filenames = image_context.split("\n");
82-
filenames.push(...extra_values);
83-
core.info(filenames.join("\n"));
84-
const filenames_hashes = await exec.getExecOutput(
85-
"git",
86-
["hash-object", "--stdin"],
87-
{
88-
failOnStdErr: true,
89-
input: Buffer.from(filenames.join("\n"), "utf-8"),
90-
}
91-
);
92-
core.endGroup();
93-
94-
core.startGroup(`Generate hash from filenames and git tree object names`);
64+
core.startGroup(`Generate hash from git tree objects`);
9565
const hash = await exec.getExecOutput("git", ["hash-object", "--stdin"], {
9666
failOnStdErr: true,
97-
input: Buffer.from(
98-
// Only trim "prefixing" part before join, so that the resulting line has a
99-
// newline as suffix.
100-
[tree_object_names.stdout.trim(), filenames_hashes.stdout].join("\n"),
101-
"utf-8"
102-
),
67+
input: Buffer.from(tree_object_names.stdout, "utf-8"),
10368
});
10469
core.endGroup();
10570

src/action.test.js

Lines changed: 9 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -10,39 +10,23 @@ describe("run", () => {
1010
process.env["INPUT_BUILD_CONTEXT"] = "./test";
1111
process.env["INPUT_EXTRA_TREE_OBJECTS"] =
1212
"test/.dockerignore\ntest/Dockerfile";
13-
process.env["INPUT_EXTRA_VALUES"] = "test/.dockerignore\ntest/Dockerfile";
1413
// Expected hash generated from command below
15-
// {\
16-
// git ls-tree -r --format='%(objectname)' --full-tree HEAD \
17-
// test/a/b \
18-
// test/context/file \
19-
// test/filename \
20-
// test/.dockerignore \
21-
// test/Dockerfile\
22-
// ; \
23-
// printf "test/a/b\ntest/context/file\ntest/filename\ntest/.dockerignore\ntest/Dockerfile" | \
24-
// git hash-object --stdin\
25-
// ;\
26-
// } | git hash-object --stdin
14+
// git ls-tree -r --format='%(objectname) %(path)' --full-tree HEAD \
15+
// test/a/b \
16+
// test/context/file \
17+
// test/filename \
18+
// test/.dockerignore \
19+
// test/Dockerfile | \
20+
// git hash-object --stdin
2721
await run();
2822
// See https://github.com/actions/toolkit/issues/777 regarding the newline..
2923
expect(process.stdout.write).toHaveBeenLastCalledWith(
30-
`::set-output name=hash::6d09883618bd309806be67847737b1a5a4aa1f40\n`
24+
`::set-output name=hash::6c867c528d4bf0844d5176f78f6abfee0adfff2b\n`
3125
);
3226
// Expect a second run to produce the same output
3327
await run();
3428
expect(process.stdout.write).toHaveBeenLastCalledWith(
35-
`::set-output name=hash::6d09883618bd309806be67847737b1a5a4aa1f40\n`
36-
);
37-
}, 30000);
38-
39-
test("errors when extra tree objects doesn't match", async () => {
40-
const { run } = require("./action");
41-
process.env["INPUT_BUILD_CONTEXT"] = "./test";
42-
process.env["INPUT_EXTRA_TREE_OBJECTS"] = "non_matching_stuff";
43-
await run();
44-
expect(process.stdout.write).toHaveBeenLastCalledWith(
45-
`::error::Object paths did not match the intended amount of objects in the tree (3 != 4)\n`
29+
`::set-output name=hash::6c867c528d4bf0844d5176f78f6abfee0adfff2b\n`
4630
);
4731
}, 30000);
4832

0 commit comments

Comments
 (0)