Skip to content

Commit 97ccbd8

Browse files
onedr0prjaegers
andauthored
ci: refactor container size diff action to use github-script (#908)
* ci: refactor container size diff action to Node.js Hi 👋 I came across your composite action and found it useful so I decided to re-write it using github action script instead. Free free to discard this PR if you are happy with bash but I thought I should share. Thanks! Signed-off-by: Devin Buhl <[email protected]> * Delete .github/actions/container-size-diff/container-size-diff.sh Signed-off-by: Devin Buhl <[email protected]> * Update .github/actions/container-size-diff/action.yml Signed-off-by: Devin Buhl <[email protected]> * Use environment variables for container inputs Signed-off-by: Devin Buhl <[email protected]> * Refactor container size diff action with new dependencies Signed-off-by: Devin Buhl <[email protected]> * Fix percentage calculation formatting in action.yml Signed-off-by: Devin Buhl <[email protected]> --------- Signed-off-by: Devin Buhl <[email protected]> Co-authored-by: Ron <[email protected]>
1 parent 616126f commit 97ccbd8

File tree

2 files changed

+118
-77
lines changed

2 files changed

+118
-77
lines changed

.github/actions/container-size-diff/action.yml

Lines changed: 118 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,123 @@ runs:
1919
using: "composite"
2020
steps:
2121
- run: |
22-
EOF=$(dd if=/dev/urandom bs=15 count=1 status=none | base64)
23-
echo "markdown<<${EOF}" >> "${GITHUB_OUTPUT}"
24-
echo "$(${GITHUB_ACTION_PATH}/container-size-diff.sh ${INPUT_FROM_CONTAINER} ${INPUT_TO_CONTAINER})" >> "${GITHUB_OUTPUT}"
25-
echo "${EOF}" >> "${GITHUB_OUTPUT}"
26-
id: size-diff
22+
cat > package.json << 'EOF'
23+
{
24+
"dependencies": {
25+
"execa": "^9.6.0",
26+
"filesize": "^11.0.2",
27+
"lodash": "^4.0.0",
28+
"markdown-table": "^3.0.4"
29+
}
30+
}
31+
EOF
32+
shell: bash
33+
34+
- uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5.0.0
35+
with:
36+
cache: npm
37+
cache-dependency-path: package.json
38+
node-version: 22.x
39+
40+
- run: npm install
2741
shell: bash
42+
43+
- uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
44+
id: size-diff
2845
env:
29-
INPUT_FROM_CONTAINER: ${{ inputs.from-container }}
30-
INPUT_TO_CONTAINER: ${{ inputs.to-container }}
46+
FROM_CONTAINER: ${{ inputs.from-container }}
47+
TO_CONTAINER: ${{ inputs.to-container }}
48+
with:
49+
script: |
50+
const { execaSync } = require("execa");
51+
const { filesize } = require("filesize");
52+
const { markdownTable } = require("markdown-table");
53+
const _ = require("lodash");
54+
55+
const fromContainer = process.env.FROM_CONTAINER;
56+
const toContainer = process.env.TO_CONTAINER;
57+
58+
async function getSizes(container) {
59+
try {
60+
const { stdout } = execaSync("docker", ["manifest", "inspect", "-v", container]);
61+
const manifests = _.castArray(JSON.parse(stdout.trim()));
62+
63+
return _(manifests)
64+
.map(m => {
65+
const platform = _.get(m, 'Descriptor.platform', {});
66+
67+
const key = _.compact([
68+
platform.os,
69+
platform.architecture,
70+
platform.variant,
71+
platform["os.version"]
72+
])
73+
.join("/");
74+
75+
const layers = _.get(m, 'OCIManifest.layers') || _.get(m, 'layers', []);
76+
const total = _.sumBy(layers, 'size');
77+
78+
return [key, total];
79+
})
80+
.fromPairs()
81+
.value();
82+
} catch (e) {
83+
core.error(`Failed to inspect ${container}: ${e.message}`);
84+
return {};
85+
}
86+
}
87+
88+
const fromSizes = await getSizes(fromContainer);
89+
const toSizes = await getSizes(toContainer);
90+
91+
const platforms = _(fromSizes)
92+
.keys()
93+
.union(_.keys(toSizes))
94+
.filter(platform => platform && !platform.includes("unknown"))
95+
.sort()
96+
.value();
97+
98+
const platformRow = (platform) => {
99+
const previous = _.get(fromSizes, platform, 0);
100+
const current = _.get(toSizes, platform, 0);
101+
const change = current - previous;
102+
103+
const percentage = previous
104+
? `${change >= 0 ? "+" : ""}${_.round(change / previous * 100, 2)}%`
105+
: current ? "+∞" : "+0.00%";
106+
107+
const icon = _.cond([
108+
[change => change < 0, _.constant("🔽")],
109+
[change => change > 0, _.constant("🔼")],
110+
[_.stubTrue, _.constant("🔄")]
111+
])(change);
112+
113+
return [
114+
platform,
115+
filesize(previous),
116+
filesize(current),
117+
`${change >= 0 ? "+" : ""}${filesize(Math.abs(change))} (${percentage})`,
118+
icon
119+
];
120+
};
121+
122+
const rows = [
123+
["OS/Platform", "Previous", "Current", "Change", "Trend"],
124+
..._.map(platforms, platformRow)
125+
];
126+
127+
const output = `## 📦 Container Size Analysis
128+
129+
> [!NOTE]
130+
> Comparing \`${fromContainer}\` ➔ \`${toContainer}\`
131+
132+
### 📈 Size Comparison Table
133+
134+
${markdownTable(rows, { align: ["l", "c", "c", "c", "c"] })}`;
135+
136+
core.setOutput("markdown", output);
137+
138+
output += `| ${platform} | ${formatBytes(fromSize)} | ${formatBytes(toSize)} | ${sign}${formatBytes(Math.abs(delta))} (${percentChange}%) | ${icon} |\n`;
139+
}
140+
141+
core.setOutput('markdown', output);

.github/actions/container-size-diff/container-size-diff.sh

Lines changed: 0 additions & 70 deletions
This file was deleted.

0 commit comments

Comments
 (0)