-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcreate-pr-scripts.js
More file actions
164 lines (133 loc) · 6.33 KB
/
create-pr-scripts.js
File metadata and controls
164 lines (133 loc) · 6.33 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
const fs = require('fs');
const { getFileContent, getLatestCommit, createBranch, createBlob, createTree, commitChanges, pushCommit, createPR } = require('./github-api');
const { hasMetadata, replaceOrPrependFrontmatter } = require('./file-operation');
async function processAIContent(owner, repo, githubToken) {
let tree = [];
try {
// Read the ai_content.txt file
const content = fs.readFileSync('ai_content.txt', 'utf8');
// Check if content is empty or contains warning message
if (!content || content.trim() === '') {
throw new Error('ai_content.txt is empty - no content to process');
}
// Check for warning messages from ai-scripts.js
if (content.includes('--- Warning ---') || content.includes('No files were found to process')) {
console.log('AI scripts reported no files to process:', content.trim());
throw new Error('No files were found by AI processing - skipping PR creation');
}
// Split the content using the regex pattern
const files = content.split(/--- File: (?=.*? ---)/);
// Remove empty first element if exists
if (files[0].trim() === '') {
files.shift();
}
// Check if we have any valid file sections
if (files.length === 0) {
throw new Error('No valid file sections found in ai_content.txt');
}
let processedFiles = 0;
for (const file of files) {
if (!file.trim()) continue;
const pathMatch = file.match(/(.*?) ---\n([\s\S]*)/);
if (!pathMatch) {
console.warn(`Skipping invalid file section: ${file.substring(0, 50)}...`);
continue;
}
const [, path, suggestion] = pathMatch;
if (!path || !suggestion.trim()) {
console.warn(`Skipping file with empty path or content: ${path}`);
continue;
}
console.log("Processing path:", path);
let fileContent = await getFileContent(owner, repo, path, githubToken);
fileContent = replaceOrPrependFrontmatter(fileContent, suggestion.trim());
let blob = await createBlob(owner, repo, fileContent, githubToken);
tree.push({ path: path, mode: '100644', type: 'blob', sha: blob.sha });
processedFiles++;
}
if (processedFiles === 0) {
throw new Error('No valid files were processed - no changes to commit');
}
console.log(`Successfully processed ${processedFiles} files for PR`);
return tree;
} catch (error) {
console.error('Error processing AI content:', error);
throw error;
}
}
module.exports = async ({ core, githubToken, owner, repo, targetBranch }) => {
// Validate required parameters
if (!repo) {
throw new Error('Missing required parameter: repo must be specified');
}
// Use provided values or fallback to defaults where appropriate
const ownerName = owner || "AdobeDocs";
const repoName = repo;
const targetBranchName = targetBranch || "main";
// Generate branch name with current date/time
const now = new Date();
const timestamp = now.toISOString().replace(/[:.]/g, '-').replace('T', '-').substring(0, 19);
const branchName = `ai-metadata-${timestamp}`;
const branchRef = `heads/${branchName}`;
const mainRef = `heads/${targetBranchName}`;
const token = githubToken || process.env.GITHUB_TOKEN;
if (!token) {
throw new Error('Missing required parameter: githubToken must be provided or GITHUB_TOKEN environment variable must be set');
}
console.log(`Creating branch: ${branchName}`);
try {
// First, try to process AI content to check if there's anything to do
const treeArray = await processAIContent(ownerName, repoName, token);
// get latest commit sha from main branch
const latestCommit = await getLatestCommit(ownerName, repoName, mainRef, token);
// create a new branch from the latest commit
const createdBranch = await createBranch(ownerName, repoName, branchRef, latestCommit.object.sha, token);
// get the tree SHA from the latest commit
const baseCommitSha = createdBranch.object.sha;
const baseCommitResponse = await fetch(`https://api.github.com/repos/${ownerName}/${repoName}/git/commits/${baseCommitSha}`, {
headers: {
'accept': 'application/vnd.github+json',
'authorization': `Bearer ${token}`
}
}).then(res => res.json());
const baseTreeSha = baseCommitResponse.tree.sha;
const tree = await createTree(ownerName, repoName, baseTreeSha, treeArray, token);
const commit = await commitChanges(ownerName, repoName, tree.sha, createdBranch.object.sha, token);
const pushCommitResult = await pushCommit(ownerName, repoName, branchRef, commit.sha, token);
const pr = await createPR(ownerName, repoName, branchName, targetBranchName, token);
console.log('PR created successfully:', pr);
} catch (error) {
// Check if this is a "no content" error - if so, exit gracefully
if (error.message && (
error.message.includes('No files were found by AI processing') ||
error.message.includes('no content to process') ||
error.message.includes('No valid files were processed')
)) {
console.log('No content changes detected - skipping PR creation');
console.log('Reason:', error.message);
return; // Exit gracefully instead of throwing
}
console.error('Error in create-pr-scripts:', error);
throw error;
}
};
// Keep backwards compatibility - if run directly, use environment variables
if (require.main === module) {
const owner = process.env.GITHUB_OWNER;
const repo = process.env.GITHUB_REPO;
const githubToken = process.env.GITHUB_TOKEN;
const targetBranch = process.env.TARGET_BRANCH;
if (!repo) {
console.error('Error: GITHUB_REPO environment variable must be set when running directly');
process.exit(1);
}
module.exports({
githubToken,
owner,
repo,
targetBranch
}).catch(error => {
console.error('Error:', error.message);
process.exit(1);
});
}