@@ -36,16 +36,26 @@ jobs:
3636 private-key : ${{ secrets.DOCKER_GITHUB_BUILDER_WRITE_PRIVATE_KEY }}
3737 owner : docker
3838 repositories : github-builder
39+ -
40+ name : Checkout
41+ uses : actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
42+ with :
43+ token : ${{ steps.write-app.outputs.token }}
44+ fetch-depth : 0
45+ persist-credentials : false
3946 -
4047 name : Update dependency
48+ id : update
4149 uses : actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
4250 env :
4351 INPUT_DEP : ${{ matrix.dep }}
4452 with :
4553 github-token : ${{ steps.write-app.outputs.token }}
4654 script : |
4755 const dep = core.getInput('dep');
48-
56+ const fs = require('fs');
57+ const path = require('path');
58+
4959 const dependencyConfigs = {
5060 buildx: {
5161 key: 'BUILDX_VERSION',
99109 },
100110 sbom: {
101111 key: 'SBOM_IMAGE',
102- name: 'SBOM image',
112+ name: 'BuildKit Syft Scanner image',
103113 branch: 'deps/sbom-image',
104114 files: [
105115 '.github/workflows/build.yml',
@@ -147,7 +157,7 @@ jobs:
147157 },
148158 toolkit: {
149159 key: 'DOCKER_ACTIONS_TOOLKIT_MODULE',
150- name: 'docker/ actions-toolkit module',
160+ name: 'actions-toolkit module',
151161 branch: 'deps/docker-actions-toolkit-module',
152162 files: [
153163 '.github/workflows/build.yml',
@@ -215,20 +225,6 @@ jobs:
215225 return Buffer.from(data.content, data.encoding).toString('utf8');
216226 }
217227
218- async function getTextFile(github, owner, repo, path, ref) {
219- const response = await github.rest.repos.getContent({
220- owner,
221- repo,
222- path,
223- ref
224- });
225- return {
226- path,
227- sha: response.data.sha,
228- content: decodeContent(response.data)
229- };
230- }
231-
232228 function readEnvValue(content, key) {
233229 const pattern = new RegExp(`^ ${escapeRegExp(key)}: "([^"]*)"$`, 'm');
234230 const match = content.match(pattern);
@@ -266,74 +262,25 @@ jobs:
266262 return `${quoted.slice(0, -1).join(', ')}, and ${quoted.at(-1)}`;
267263 }
268264
269- async function findOpenPullRequest(github, context, branch, base) {
270- const pulls = await github.rest.pulls.list({
271- ...context.repo,
272- state: 'open',
273- head: `${context.repo.owner}:${branch}`,
274- base,
275- per_page: 100
276- });
277- return pulls.data[0] ?? null;
278- }
279-
280265 const config = dependencyConfigs[dep];
281266 if (!config) {
282267 core.setFailed(`Unknown dependency ${dep}`);
283268 return;
284269 }
285270
286- const repo = await github.rest.repos.get(context.repo);
287- const defaultBranch = repo.data.default_branch;
288- const branchRefName = `heads/${config.branch}`;
289- const openPullRequest = await findOpenPullRequest(github, context, config.branch, defaultBranch);
290-
291271 const target = await config.resolve({github});
292272 core.info(`Resolved ${config.key} to ${target.value} from ${config.sourceUrl}`);
293273
294- const baseFiles = await Promise.all(config.files.map((path) => getTextFile(github, context.repo.owner, context.repo.repo, path, defaultBranch)));
295- const baseValues = unique(baseFiles.map((file) => readEnvValue(file.content, config.key)));
296- const baseIsUpToDate = baseValues.every((value) => value === target.value);
297-
298- if (baseIsUpToDate) {
299- core.info(`${config.key} is already up to date on ${defaultBranch}`);
300- if (openPullRequest) {
301- await github.rest.pulls.update({
302- ...context.repo,
303- pull_number: openPullRequest.number,
304- state: 'closed'
305- });
306- core.notice(`Closed stale pull request #${openPullRequest.number}`);
307- }
308- return;
309- }
310-
311- let branchExists = false;
312- try {
313- await github.rest.git.getRef({
314- ...context.repo,
315- ref: branchRefName
316- });
317- branchExists = true;
318- } catch (error) {
319- if (error.status !== 404) {
320- throw error;
321- }
322- }
323-
324- const defaultRef = await github.rest.git.getRef({
325- ...context.repo,
326- ref: `heads/${defaultBranch}`
274+ const workingFiles = config.files.map((filePath) => {
275+ const absolutePath = path.join(process.env.GITHUB_WORKSPACE, filePath);
276+ const content = fs.readFileSync(absolutePath, 'utf8');
277+ return {
278+ path: filePath,
279+ absolutePath,
280+ content
281+ };
327282 });
328- const parentCommitSha = defaultRef.data.object.sha;
329-
330- // Always rebuild updater branches from the latest default branch head
331- // so stale dependency PRs do not accumulate merge conflicts.
332- const workingRef = defaultBranch;
333- const workingFiles = await Promise.all(
334- config.files.map((path) => getTextFile(github, context.repo.owner, context.repo.repo, path, workingRef))
335- );
336-
283+ const baseValues = unique(workingFiles.map((file) => readEnvValue(file.content, config.key)));
337284 const changes = [];
338285 for (const file of workingFiles) {
339286 const replacement = replaceEnvValue(file.content, config.key, target.value);
@@ -344,107 +291,40 @@ jobs:
344291 path: file.path,
345292 before: replacement.before,
346293 after: target.value,
347- content: replacement.content
294+ content: replacement.content,
295+ absolutePath: file.absolutePath
348296 });
349297 }
350298
351299 if (changes.length > 0) {
352- const parentCommit = await github.rest.git.getCommit({
353- ...context.repo,
354- commit_sha: parentCommitSha
355- });
356-
357- const tree = [];
358300 for (const change of changes) {
359- const blob = await github.rest.git.createBlob({
360- ...context.repo,
361- content: change.content,
362- encoding: 'utf-8'
363- });
364- tree.push({
365- path: change.path,
366- mode: '100644',
367- type: 'blob',
368- sha: blob.data.sha
369- });
370- }
371-
372- const newTree = await github.rest.git.createTree({
373- ...context.repo,
374- base_tree: parentCommit.data.tree.sha,
375- tree
376- });
377-
378- const commit = await github.rest.git.createCommit({
379- ...context.repo,
380- message: `chore(deps): bump ${config.key} to ${target.to}`,
381- tree: newTree.data.sha,
382- parents: [parentCommitSha]
383- });
384-
385- if (branchExists) {
386- await github.rest.git.updateRef({
387- ...context.repo,
388- ref: branchRefName,
389- sha: commit.data.sha,
390- force: true
391- });
392- } else {
393- await github.rest.git.createRef({
394- ...context.repo,
395- ref: `refs/${branchRefName}`,
396- sha: commit.data.sha
397- });
398- branchExists = true;
301+ fs.writeFileSync(change.absolutePath, change.content, 'utf8');
399302 }
400303 } else {
401- core.info(`No file changes needed on branch ${config.branch }`);
304+ core.info(`No workspace changes needed for ${config.key }`);
402305 }
403306
404- const comparison = await github.rest.repos.compareCommits({
405- ...context.repo,
406- base: defaultBranch,
407- head: config.branch
408- });
409-
410- if (comparison.data.ahead_by === 0) {
411- core.info(`Branch ${config.branch} does not differ from ${defaultBranch}`);
412- if (openPullRequest) {
413- await github.rest.pulls.update({
414- ...context.repo,
415- pull_number: openPullRequest.number,
416- state: 'closed'
417- });
418- core.notice(`Closed stale pull request #${openPullRequest.number}`);
419- }
420- return;
421- }
422-
423- const title = `chore(deps): bump ${config.name} to ${target.to}`;
424307 const beforeValue = formatList(baseValues);
425- const body = [
426- `This updates ${config.key} from ${beforeValue} to \`${target.value}\`.`,
427- '',
428- `The source of truth for this update is ${config.sourceUrl}.`
429- ].join('\n');
430-
431- if (openPullRequest) {
432- await github.rest.pulls.update({
433- ...context.repo,
434- pull_number: openPullRequest.number,
435- title,
436- body
437- });
438- core.notice(`Updated pull request #${openPullRequest.number}`);
439- return;
440- }
441-
442- const pullRequest = await github.rest.pulls.create({
443- ...context.repo,
444- title,
445- body,
446- head: config.branch,
447- base: defaultBranch
448- });
449-
450- core.notice(`Created pull request #${pullRequest.data.number}`);
308+ const commitMessage = `chore(deps): update ${config.name} to ${target.to}`;
309+
310+ core.setOutput('branch', config.branch);
311+ core.setOutput('commit-message', commitMessage);
312+ core.setOutput('key', config.key);
313+ core.setOutput('before-value', beforeValue);
314+ core.setOutput('target-value', target.value);
315+ core.setOutput('source-url', config.sourceUrl);
316+ -
317+ name : Create pull request
318+ uses : peter-evans/create-pull-request@5f6978faf089d4d20b00c7766989d076bb2fc7f1 # v8.1.1
319+ with :
320+ base : main
321+ branch : ${{ steps.update.outputs.branch }}
322+ token : ${{ steps.write-app.outputs.token }}
323+ commit-message : ${{ steps.update.outputs.commit-message }}
324+ title : ${{ steps.update.outputs.commit-message }}
325+ signoff : true
326+ delete-branch : true
327+ body : |
328+ This updates ${{ steps.update.outputs.key }} from ${{ steps.update.outputs.before-value }} to `${{ steps.update.outputs.target-value }}`.
329+
330+ The source of truth for this update is ${{ steps.update.outputs.source-url }}.
0 commit comments