Skip to content

Commit 4af70dc

Browse files
committed
ci(update-deps): switch to create-pull-request action to fix api limitation
Signed-off-by: CrazyMax <[email protected]>
1 parent cbca310 commit 4af70dc

1 file changed

Lines changed: 53 additions & 169 deletions

File tree

.github/workflows/.update-deps.yml

Lines changed: 53 additions & 169 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@ on:
44
workflow_dispatch:
55
schedule:
66
- cron: "0 9 * * *"
7+
push:
8+
branches:
9+
- 'main'
710

811
permissions:
912
contents: read
@@ -36,16 +39,26 @@ jobs:
3639
private-key: ${{ secrets.DOCKER_GITHUB_BUILDER_WRITE_PRIVATE_KEY }}
3740
owner: docker
3841
repositories: github-builder
42+
-
43+
name: Checkout
44+
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
45+
with:
46+
token: ${{ steps.write-app.outputs.token }}
47+
fetch-depth: 0
48+
persist-credentials: false
3949
-
4050
name: Update dependency
51+
id: update
4152
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
4253
env:
4354
INPUT_DEP: ${{ matrix.dep }}
4455
with:
4556
github-token: ${{ steps.write-app.outputs.token }}
4657
script: |
4758
const dep = core.getInput('dep');
48-
59+
const fs = require('fs');
60+
const path = require('path');
61+
4962
const dependencyConfigs = {
5063
buildx: {
5164
key: 'BUILDX_VERSION',
@@ -99,7 +112,7 @@ jobs:
99112
},
100113
sbom: {
101114
key: 'SBOM_IMAGE',
102-
name: 'SBOM image',
115+
name: 'BuildKit Syft Scanner image',
103116
branch: 'deps/sbom-image',
104117
files: [
105118
'.github/workflows/build.yml',
@@ -147,7 +160,7 @@ jobs:
147160
},
148161
toolkit: {
149162
key: 'DOCKER_ACTIONS_TOOLKIT_MODULE',
150-
name: 'docker/actions-toolkit module',
163+
name: 'actions-toolkit module',
151164
branch: 'deps/docker-actions-toolkit-module',
152165
files: [
153166
'.github/workflows/build.yml',
@@ -215,20 +228,6 @@ jobs:
215228
return Buffer.from(data.content, data.encoding).toString('utf8');
216229
}
217230
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-
232231
function readEnvValue(content, key) {
233232
const pattern = new RegExp(`^ ${escapeRegExp(key)}: "([^"]*)"$`, 'm');
234233
const match = content.match(pattern);
@@ -266,74 +265,25 @@ jobs:
266265
return `${quoted.slice(0, -1).join(', ')}, and ${quoted.at(-1)}`;
267266
}
268267
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-
280268
const config = dependencyConfigs[dep];
281269
if (!config) {
282270
core.setFailed(`Unknown dependency ${dep}`);
283271
return;
284272
}
285273
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-
291274
const target = await config.resolve({github});
292275
core.info(`Resolved ${config.key} to ${target.value} from ${config.sourceUrl}`);
293276
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}`
277+
const workingFiles = config.files.map((filePath) => {
278+
const absolutePath = path.join(process.env.GITHUB_WORKSPACE, filePath);
279+
const content = fs.readFileSync(absolutePath, 'utf8');
280+
return {
281+
path: filePath,
282+
absolutePath,
283+
content
284+
};
327285
});
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-
286+
const baseValues = unique(workingFiles.map((file) => readEnvValue(file.content, config.key)));
337287
const changes = [];
338288
for (const file of workingFiles) {
339289
const replacement = replaceEnvValue(file.content, config.key, target.value);
@@ -344,107 +294,41 @@ jobs:
344294
path: file.path,
345295
before: replacement.before,
346296
after: target.value,
347-
content: replacement.content
297+
content: replacement.content,
298+
absolutePath: file.absolutePath
348299
});
349300
}
350301
351302
if (changes.length > 0) {
352-
const parentCommit = await github.rest.git.getCommit({
353-
...context.repo,
354-
commit_sha: parentCommitSha
355-
});
356-
357-
const tree = [];
358303
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;
304+
fs.writeFileSync(change.absolutePath, change.content, 'utf8');
399305
}
306+
core.info(`New ${config.name} ${target.value} found`);
400307
} else {
401-
core.info(`No file changes needed on branch ${config.branch}`);
308+
core.info(`No workspace changes needed for ${config.key}`);
402309
}
403310
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}`;
424311
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}`);
312+
const commitMessage = `chore(deps): update ${config.name} to ${target.to}`;
313+
314+
core.setOutput('branch', config.branch);
315+
core.setOutput('commit-message', commitMessage);
316+
core.setOutput('key', config.key);
317+
core.setOutput('before-value', beforeValue);
318+
core.setOutput('target-value', target.value);
319+
core.setOutput('source-url', config.sourceUrl);
320+
-
321+
name: Create pull request
322+
uses: peter-evans/create-pull-request@5f6978faf089d4d20b00c7766989d076bb2fc7f1 # v8.1.1
323+
with:
324+
base: main
325+
branch: ${{ steps.update.outputs.branch }}
326+
token: ${{ steps.write-app.outputs.token }}
327+
commit-message: ${{ steps.update.outputs.commit-message }}
328+
title: ${{ steps.update.outputs.commit-message }}
329+
signoff: true
330+
delete-branch: true
331+
body: |
332+
This updates ${{ steps.update.outputs.key }} from ${{ steps.update.outputs.before-value }} to `${{ steps.update.outputs.target-value }}`.
333+
334+
The source of truth for this update is ${{ steps.update.outputs.source-url }}.

0 commit comments

Comments
 (0)