Skip to content

Commit b3282d3

Browse files
Pa/ek 844 optimizing perf fixing forks (#75)
* Optimizing perofmrace and fixing forks
1 parent 9fc8835 commit b3282d3

File tree

10 files changed

+1470
-12
lines changed

10 files changed

+1470
-12
lines changed

.github/workflows/test.yml

+70
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
name: Test
2+
on:
3+
push:
4+
branches:
5+
- main
6+
pull_request:
7+
jobs:
8+
test-check:
9+
name: runner / EkLine Reviewer (github-check)
10+
runs-on: ubuntu-latest
11+
steps:
12+
- uses: actions/checkout@v3
13+
- uses: ./
14+
with:
15+
github_token: ${{ secrets.github_token }}
16+
reporter: github-check
17+
content_dir: |
18+
./testdata
19+
ek_token: ${{ secrets.ek_token }}
20+
21+
test-pr-check:
22+
if: github.event_name == 'pull_request'
23+
name: runner / EkLine Reviewer (github-pr-check)
24+
runs-on: ubuntu-latest
25+
steps:
26+
- uses: actions/checkout@v3
27+
- uses: ./
28+
with:
29+
github_token: ${{ secrets.github_token }}
30+
reporter: github-pr-check
31+
level: warning
32+
content_dir: |
33+
./testdata
34+
ek_token: ${{ secrets.ek_token }}
35+
36+
test-pr-review:
37+
if: github.event_name == 'pull_request'
38+
name: runner / EkLine Reviewer (github-pr-review)
39+
runs-on: ubuntu-latest
40+
steps:
41+
- uses: actions/checkout@v3
42+
- uses: ./
43+
with:
44+
github_token: ${{ secrets.github_token }}
45+
reporter: github-pr-review
46+
level: error
47+
content_dir: |
48+
./testdata
49+
filter_mode: nofilter
50+
ek_token: ${{ secrets.ek_token }}
51+
ignore_rule: "EK00010,EK00003"
52+
exclude_directories: |
53+
./testdata/temp
54+
exclude_files: |
55+
./testdata/subdir/text.md
56+
57+
test-openapi:
58+
if: github.event_name == 'pull_request'
59+
name: runner / EkLine OpenAPI Reviewer
60+
runs-on: ubuntu-latest
61+
steps:
62+
- uses: actions/checkout@v3
63+
- uses: ./
64+
with:
65+
github_token: ${{ secrets.github_token }}
66+
reporter: github-pr-review
67+
level: error
68+
openapi_spec: 'testdata/openapi/test.yaml'
69+
ek_token: ${{ secrets.ek_token }}
70+
filter_mode: nofilter

entrypoint.sh

+119-9
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,54 @@ print_debug_info() {
1212
fi
1313
}
1414

15+
fetchBranchFromFork() {
16+
local fork_remote="$1"
17+
local source_branch="$2"
18+
local target_branch="$3"
19+
20+
if [ "$INPUT_DEBUG" = "true" ]; then
21+
echo "Available branches in ${fork_remote} remote:"
22+
git ls-remote --heads "${fork_remote}"
23+
fi
24+
25+
if git fetch "${fork_remote}" "${source_branch}:${target_branch}" 2>/dev/null; then
26+
echo "Successfully fetched branch from fork"
27+
return 0
28+
fi
29+
30+
if git fetch "${fork_remote}" "refs/heads/${source_branch}:refs/heads/${target_branch}" 2>/dev/null; then
31+
echo "Successfully fetched branch using refs/heads prefix"
32+
return 0
33+
fi
34+
35+
echo "Failed to fetch branch ${source_branch} from ${fork_remote}. Aborting."
36+
return 1
37+
}
38+
39+
setupForkRemote() {
40+
local remote_name="$1"
41+
local remote_url="$2"
42+
43+
echo "Setting up ${remote_name} remote with URL: ${remote_url}"
44+
45+
if git remote | grep -q "^${remote_name}$"; then
46+
local current_url
47+
current_url=$(git remote get-url "${remote_name}" 2>/dev/null)
48+
49+
if [ "$current_url" != "$remote_url" ]; then
50+
echo "Remote ${remote_name} exists with different URL, updating it"
51+
git remote remove "${remote_name}"
52+
git remote add "${remote_name}" "${remote_url}" || { echo "Failed to add ${remote_name} as remote"; return 1; }
53+
else
54+
echo "Remote ${remote_name} already exists with correct URL"
55+
fi
56+
else
57+
git remote add "${remote_name}" "${remote_url}" || { echo "Failed to add ${remote_name} as remote"; return 1; }
58+
fi
59+
60+
return 0
61+
}
62+
1563
print_debug_info
1664

1765
setGithubPullRequestId() {
@@ -107,38 +155,100 @@ fi
107155
if [ "${pull_request_id}" ]; then
108156
if [ "$GITLAB_CI" = "true" ]; then
109157
if [ "$CI_MERGE_REQUEST_SOURCE_PROJECT_URL" = "$CI_PROJECT_URL" ]; then
158+
echo "Same-project merge request"
110159
git fetch origin "${base_branch}:${base_branch}" "${head_branch}:${head_branch}" || { echo "Failed to fetch branches from the repository"; exit 1; }
111160
else
161+
echo "Processing cross-project merge request from fork"
162+
echo "Base branch: ${base_branch}, Head branch: ${head_branch}"
163+
echo "Source project URL: ${CI_MERGE_REQUEST_SOURCE_PROJECT_URL}"
164+
112165
git fetch origin "${base_branch}:${base_branch}" || { echo "Failed to fetch base branch ${base_branch} from upstream"; exit 1; }
113-
git remote add fork "${CI_MERGE_REQUEST_SOURCE_PROJECT_URL}" || { echo "Failed to add fork as remote"; exit 1; }
114-
git fetch fork "${head_branch}:${head_branch}" || { echo "Failed to fetch head branch ${head_branch} from fork"; exit 1; }
166+
167+
if ! setupForkRemote "fork" "${CI_MERGE_REQUEST_SOURCE_PROJECT_URL}"; then
168+
exit 1
169+
fi
170+
171+
if ! fetchBranchFromFork "fork" "${head_branch}" "${head_branch}"; then
172+
exit 1
173+
fi
115174
fi
116175
elif [ "$GITHUB_ACTIONS" = "true" ]; then
117176
if [ -f "$GITHUB_EVENT_PATH" ]; then
118-
head_repo_url=$(cat "$GITHUB_EVENT_PATH" | grep '"clone_url"' | head -n 1 | awk -F '"clone_url":' '{print $2}' | tr -d '", ')
119-
base_repo_url=$(cat "$GITHUB_EVENT_PATH" | grep '"repo"' | head -n 1 | awk -F '"url":' '{print $2}' | tr -d '", ')
177+
head_repo_url=$(cat "$GITHUB_EVENT_PATH" | jq -r '.pull_request.head.repo.clone_url')
178+
base_repo_url=$(cat "$GITHUB_EVENT_PATH" | jq -r '.pull_request.base.repo.clone_url')
120179

180+
if [ "$INPUT_DEBUG" = "true" ]; then
181+
echo "head_repo_url: $head_repo_url"
182+
echo "base_repo_url: $base_repo_url"
183+
cat "$GITHUB_EVENT_PATH"
184+
fi
185+
121186
if [ "$head_repo_url" != "$base_repo_url" ]; then
122187
echo "PR is from a forked repository: $head_repo_url"
188+
123189
git fetch origin "${base_branch}:${base_branch}" || { echo "Failed to fetch base branch ${base_branch} from upstream"; exit 1; }
124190

125-
git remote add fork "$head_repo_url" || { echo "Failed to add fork as remote"; exit 1; }
126-
git fetch fork "${head_branch}:${head_branch}" || { echo "Failed to fetch head branch ${head_branch} from fork"; exit 1; }
191+
if ! setupForkRemote "fork" "$head_repo_url"; then
192+
exit 1
193+
fi
194+
195+
if ! fetchBranchFromFork "fork" "${head_branch}" "${head_branch}"; then
196+
exit 1
197+
fi
198+
else
199+
git fetch origin "${base_branch}:${base_branch}" "${head_branch}:${head_branch}" || { echo "Failed to fetch branches from origin"; exit 1; }
127200
fi
201+
else
202+
git fetch origin "${base_branch}:${base_branch}" "${head_branch}:${head_branch}" || { echo "Failed to fetch branches from origin"; exit 1; }
128203
fi
129204
elif [ "$CI" = "true" ] && [ -n "$BITBUCKET_BUILD_NUMBER" ]; then
130205
origin_url=$(git remote get-url origin)
131206
upstream_url=$(git remote get-url upstream 2>/dev/null || echo "")
132207
if [ "$origin_url" != "$upstream_url" ] && [ "$upstream_url" != "" ] ; then
208+
echo "Processing Bitbucket cross-repository PR"
209+
133210
git fetch upstream "${base_branch}:${base_branch}" || { echo "Failed to fetch base branch ${base_branch} from upstream"; exit 1; }
134-
git fetch origin "${head_branch}:${head_branch}" || { echo "Failed to fetch head branch ${head_branch} from fork"; exit 1; }
211+
212+
# Bitbucket Pipelines automatically configures origin to point to the fork
213+
echo "Using existing origin as fork remote"
214+
215+
if ! fetchBranchFromFork "origin" "${head_branch}" "${head_branch}"; then
216+
exit 1
217+
fi
135218
else
136219
git checkout --detach || { echo "Failed to detach HEAD"; exit 1; }
220+
git fetch origin "${base_branch}:${base_branch}" "${head_branch}:${head_branch}" || { echo "Failed to fetch branches from origin"; exit 1; }
137221
fi
138222
fi
139-
git fetch origin "${base_branch}:${base_branch}" "${head_branch}:${head_branch}" || { echo "Failed to fetch branches"; exit 1; }
223+
140224
if [ -f "$(git rev-parse --git-dir)/shallow" ]; then
141-
git fetch --unshallow || { echo "Failed to unshallow the repository"; exit 1; }
225+
if [ -n "${base_branch}" ] && [ -n "${head_branch}" ]; then
226+
echo "Repository is shallow, attempting to fetch history..."
227+
228+
# Function to unshallow the repository
229+
unshallow_repo() {
230+
echo "Unshallowing the entire repository..."
231+
git fetch --unshallow || { echo "Failed to unshallow the repository"; exit 1; }
232+
echo "Repository fully unshallowed."
233+
}
234+
235+
# Try to fetch recent history first
236+
if ! months_ago=$(cd /code && npm run get:dateMonthsAgo --silent -- 3); then
237+
echo "Failed to get date, falling back to full unshallow"
238+
unshallow_repo
239+
elif ! git fetch --shallow-since="$months_ago"; then
240+
echo "Failed to fetch commits for the last 3 months, falling back to full unshallow"
241+
unshallow_repo
242+
elif ! git diff --quiet "${base_branch}" "${head_branch}" 2>/dev/null; then
243+
echo "History not sufficient. Falling back to full unshallow."
244+
unshallow_repo
245+
else
246+
echo "Successfully fetched necessary history."
247+
fi
248+
else
249+
echo "Repository is shallow but branch info unavailable. Unshallowing the entire repository..."
250+
git fetch --unshallow || { echo "Failed to unshallow the repository"; exit 1; }
251+
fi
142252
fi
143253
if [ -n "${base_branch}" ] && [ -n "${head_branch}" ]; then
144254
changed_files=$(git diff --name-only "${base_branch}" "${head_branch}") || { echo "Failed to get changed files: ${base_branch}..${head_branch}"; exit 1; }

package-lock.json

+3-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+5-2
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@
22
"name": "ekline-github-action",
33
"scripts": {
44
"comment:github": "TS_NODE_FILES=true npm i && npx ts-node ./src/github.ts",
5-
"get:userId": "TS_NODE_FILES=true npm i && npx ts-node ./src/getUserId.ts"
5+
"get:userId": "TS_NODE_FILES=true npm i && npx ts-node ./src/getUserId.ts",
6+
"get:dateMonthsAgo": "TS_NODE_FILES=true npm i && npx ts-node ./src/dateUtils.ts"
67
},
78
"dependencies": {
89
"@octokit/rest": "^20.1.1",
9-
"@types/node": "^20.12.12",
1010
"csv-parse": "^5.3.5",
1111
"csv-to-sql-script": "^1.0.0",
1212
"csv2sql-lite": "^0.0.6",
@@ -15,5 +15,8 @@
1515
"execa": "^9.1.0",
1616
"ts-node": "^10.9.1",
1717
"typescript": "^4.9.5"
18+
},
19+
"devDependencies": {
20+
"@types/node": "^20.12.12"
1821
}
1922
}

src/dateUtils.ts

+55
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
/**
2+
* Date utility functions for the GitHub Action
3+
*/
4+
5+
/**
6+
* Calculates a date X months ago from the current date
7+
* @param monthsAgo - Number of months to go back
8+
* @returns Date in YYYY-MM-DD format (first day of the month)
9+
*/
10+
export const getDateMonthsAgo = (monthsAgo: number): string => {
11+
const date = new Date();
12+
date.setMonth(date.getMonth() - monthsAgo);
13+
const year = date.getFullYear();
14+
15+
// Format month with leading zero if needed
16+
const month = (date.getMonth() + 1).toString().padStart(2, '0');
17+
18+
return `${year}-${month}-01`;
19+
};
20+
21+
/**
22+
* Parses command line arguments and returns the months ago value
23+
* @param args - Command line arguments
24+
* @returns The number of months ago
25+
*/
26+
const parseArgs = (args: string[]): number => {
27+
const monthsArg = args[2];
28+
29+
if (!monthsArg) {
30+
console.error('Usage: node dateUtils.js <months_ago>');
31+
process.exit(1);
32+
}
33+
34+
const monthsAgo = parseInt(monthsArg, 10);
35+
if (isNaN(monthsAgo)) {
36+
console.error('Error: months_ago must be a number');
37+
process.exit(1);
38+
}
39+
40+
return monthsAgo;
41+
};
42+
43+
/**
44+
* Main function that runs when this file is executed directly
45+
*/
46+
const main = async (): Promise<void> => {
47+
const monthsAgo = parseArgs(process.argv);
48+
console.log(getDateMonthsAgo(monthsAgo));
49+
};
50+
51+
// Execute main function
52+
main().catch((error) => {
53+
console.error('Error:', error);
54+
process.exit(1);
55+
});

0 commit comments

Comments
 (0)