Skip to content

Commit f3ca0c1

Browse files
Implement dynamic timeout adjustment for workflows
Related to #74 Implement dynamic timeout adjustments for workflows to accommodate varying build times. * **Scripts**: - Add `scripts/record_run_time.sh` to record the duration of each workflow run. - Add `scripts/adjust_timeout.sh` to calculate average run time and adjust the timeout value in workflow files. - Add `scripts/monitor_system_load.sh` to monitor system load and adjust the timeout value. - Add `scripts/analyze_build_complexity.sh` to analyze build complexity and adjust the timeout value. - Add `scripts/calculate_optimal_timeout.sh` to calculate the optimal timeout time using the output from other scripts. * **Workflow Files**: - Modify `.github/workflows/build-check.yaml` to include steps for recording start and end times, monitoring system load, analyzing build complexity, and adjusting timeout based on historical run times. - Modify `.github/workflows/build.yaml` to include steps for recording start and end times, monitoring system load, analyzing build complexity, and adjusting timeout based on historical run times.
1 parent db99043 commit f3ca0c1

File tree

7 files changed

+232
-0
lines changed

7 files changed

+232
-0
lines changed

.github/workflows/build-check.yaml

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,22 @@ jobs:
4141
pacman -S --noconfirm --needed git archiso grub qemu
4242
"
4343
44+
- name: Record Start Time
45+
run: |
46+
./scripts/record_run_time.sh start
47+
48+
- name: Monitor System Load
49+
run: |
50+
./scripts/monitor_system_load.sh
51+
52+
- name: Analyze Build Complexity
53+
run: |
54+
./scripts/analyze_build_complexity.sh
55+
56+
- name: Adjust Timeout Based on Historical Run Times
57+
run: |
58+
./scripts/adjust_timeout.sh
59+
4460
- name: Test Build
4561
id: build
4662
run: |
@@ -89,6 +105,10 @@ jobs:
89105
sha1sum \"\$iso_file\" > checksum.sha1
90106
"
91107
108+
- name: Record End Time
109+
run: |
110+
./scripts/record_run_time.sh end
111+
92112
- name: Clean Up
93113
if: always()
94114
run: |

.github/workflows/build.yaml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,21 @@ jobs:
3232
echo "DATE=$(date +'%Y-%m-%d')" >> $GITHUB_ENV
3333
echo "VERSION=$(date +'%Y.%m.%d')" >> $GITHUB_ENV
3434
35+
- name: Record Start Time
36+
run: |
37+
./scripts/record_run_time.sh start
38+
39+
- name: Monitor System Load
40+
run: |
41+
./scripts/monitor_system_load.sh
42+
43+
- name: Analyze Build Complexity
44+
run: |
45+
./scripts/analyze_build_complexity.sh
3546
47+
- name: Adjust Timeout Based on Historical Run Times
48+
run: |
49+
./scripts/adjust_timeout.sh
3650
3751
- name: Set up Arch Linux Container
3852
run: |
@@ -171,6 +185,10 @@ jobs:
171185
${{ env.WORKSPACE }}/out/*.iso
172186
${{ env.WORKSPACE }}/out/*.sha*sum
173187
188+
- name: Record End Time
189+
run: |
190+
./scripts/record_run_time.sh end
191+
174192
- name: Clean Up
175193
if: always()
176194
run: |

scripts/adjust_timeout.sh

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
#!/bin/bash
2+
3+
# Script to adjust the timeout value in workflow files based on historical run times
4+
5+
# Define the log file to store historical run times
6+
LOG_FILE="workflow_run_times.log"
7+
8+
# Function to calculate the average run time from the log file
9+
calculate_average_run_time() {
10+
if [ ! -f $LOG_FILE ]; then
11+
echo "Log file not found. Using default timeout value."
12+
return 0
13+
fi
14+
15+
total_time=0
16+
count=0
17+
18+
while read -r line; do
19+
total_time=$((total_time + line))
20+
count=$((count + 1))
21+
done < $LOG_FILE
22+
23+
if [ $count -eq 0 ]; then
24+
echo "No historical run times found. Using default timeout value."
25+
return 0
26+
fi
27+
28+
average_time=$((total_time / count))
29+
echo "Average run time: $average_time seconds"
30+
echo $average_time
31+
}
32+
33+
# Function to adjust the timeout value in the workflow files
34+
adjust_timeout_value() {
35+
average_time=$(calculate_average_run_time)
36+
if [ $average_time -eq 0 ]; then
37+
return
38+
fi
39+
40+
timeout_minutes=$((average_time / 60))
41+
echo "Setting timeout value to $timeout_minutes minutes"
42+
43+
# Update the timeout value in the workflow files
44+
sed -i "s/timeout-minutes: [0-9]\+/timeout-minutes: $timeout_minutes/" .github/workflows/build-check.yaml
45+
sed -i "s/timeout-minutes: [0-9]\+/timeout-minutes: $timeout_minutes/" .github/workflows/build.yaml
46+
}
47+
48+
# Adjust the timeout value
49+
adjust_timeout_value
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
#!/bin/bash
2+
3+
# Script to analyze build complexity and adjust the timeout value
4+
5+
# Function to count the number of files in the build
6+
count_files() {
7+
find . -type f | wc -l
8+
}
9+
10+
# Function to count the number of lines of code in the build
11+
count_lines_of_code() {
12+
find . -type f -name '*.sh' -o -name '*.yaml' -o -name '*.yml' -o -name '*.conf' -o -name '*.cfg' | xargs wc -l | tail -n 1 | awk '{print $1}'
13+
}
14+
15+
# Function to count the number of dependencies in the build
16+
count_dependencies() {
17+
grep -r 'dependencies:' . | wc -l
18+
}
19+
20+
# Function to adjust the timeout value based on build complexity
21+
adjust_timeout_based_on_complexity() {
22+
num_files=$(count_files)
23+
num_lines_of_code=$(count_lines_of_code)
24+
num_dependencies=$(count_dependencies)
25+
26+
echo "Number of files: $num_files"
27+
echo "Number of lines of code: $num_lines_of_code"
28+
echo "Number of dependencies: $num_dependencies"
29+
30+
complexity_score=$((num_files + num_lines_of_code + num_dependencies))
31+
32+
if [ $complexity_score -gt 10000 ]; then
33+
echo "High build complexity detected. Increasing timeout value."
34+
timeout_minutes=180
35+
else
36+
echo "Normal build complexity. Using default timeout value."
37+
timeout_minutes=120
38+
fi
39+
40+
# Update the timeout value in the workflow files
41+
sed -i "s/timeout-minutes: [0-9]\+/timeout-minutes: $timeout_minutes/" .github/workflows/build-check.yaml
42+
sed -i "s/timeout-minutes: [0-9]\+/timeout-minutes: $timeout_minutes/" .github/workflows/build.yaml
43+
}
44+
45+
# Adjust the timeout value based on build complexity
46+
adjust_timeout_based_on_complexity
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
#!/bin/bash
2+
3+
# Script to calculate the optimal timeout time using the output from other scripts
4+
5+
# Function to calculate the optimal timeout time
6+
calculate_optimal_timeout() {
7+
# Get the average run time from the log file
8+
average_run_time=$(./scripts/adjust_timeout.sh)
9+
10+
# Get the system load adjustment
11+
system_load_adjustment=$(./scripts/monitor_system_load.sh)
12+
13+
# Get the build complexity adjustment
14+
build_complexity_adjustment=$(./scripts/analyze_build_complexity.sh)
15+
16+
# Calculate the optimal timeout time
17+
optimal_timeout=$((average_run_time + system_load_adjustment + build_complexity_adjustment))
18+
19+
echo "Optimal timeout time: $optimal_timeout minutes"
20+
21+
# Update the timeout value in the workflow files
22+
sed -i "s/timeout-minutes: [0-9]\+/timeout-minutes: $optimal_timeout/" .github/workflows/build-check.yaml
23+
sed -i "s/timeout-minutes: [0-9]\+/timeout-minutes: $optimal_timeout/" .github/workflows/build.yaml
24+
}
25+
26+
# Calculate the optimal timeout time
27+
calculate_optimal_timeout

scripts/monitor_system_load.sh

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
#!/bin/bash
2+
3+
# Script to monitor system load and adjust the timeout value
4+
5+
# Function to get the current CPU usage
6+
get_cpu_usage() {
7+
top -bn1 | grep "Cpu(s)" | \
8+
sed "s/.*, *\([0-9.]*\)%* id.*/\1/" | \
9+
awk '{print 100 - $1}'
10+
}
11+
12+
# Function to get the current memory usage
13+
get_memory_usage() {
14+
free | grep Mem | awk '{print $3/$2 * 100.0}'
15+
}
16+
17+
# Function to adjust the timeout value based on system load
18+
adjust_timeout_based_on_load() {
19+
cpu_usage=$(get_cpu_usage)
20+
memory_usage=$(get_memory_usage)
21+
22+
echo "Current CPU usage: $cpu_usage%"
23+
echo "Current memory usage: $memory_usage%"
24+
25+
if (( $(echo "$cpu_usage > 80.0" | bc -l) )) || (( $(echo "$memory_usage > 80.0" | bc -l) )); then
26+
echo "High system load detected. Increasing timeout value."
27+
timeout_minutes=180
28+
else
29+
echo "Normal system load. Using default timeout value."
30+
timeout_minutes=120
31+
fi
32+
33+
# Update the timeout value in the workflow files
34+
sed -i "s/timeout-minutes: [0-9]\+/timeout-minutes: $timeout_minutes/" .github/workflows/build-check.yaml
35+
sed -i "s/timeout-minutes: [0-9]\+/timeout-minutes: $timeout_minutes/" .github/workflows/build.yaml
36+
}
37+
38+
# Adjust the timeout value based on system load
39+
adjust_timeout_based_on_load

scripts/record_run_time.sh

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
#!/bin/bash
2+
3+
# Script to record the duration of each workflow run
4+
5+
# Define the log file to store historical run times
6+
LOG_FILE="workflow_run_times.log"
7+
8+
# Function to record the start time of the workflow
9+
record_start_time() {
10+
START_TIME=$(date +%s)
11+
echo "Workflow started at: $(date -d @$START_TIME)"
12+
}
13+
14+
# Function to record the end time of the workflow and calculate the duration
15+
record_end_time() {
16+
END_TIME=$(date +%s)
17+
DURATION=$((END_TIME - START_TIME))
18+
echo "Workflow ended at: $(date -d @$END_TIME)"
19+
echo "Workflow duration: $DURATION seconds"
20+
21+
# Store the duration in the log file
22+
echo $DURATION >> $LOG_FILE
23+
}
24+
25+
# Check the argument passed to the script
26+
if [ "$1" == "start" ]; then
27+
record_start_time
28+
elif [ "$1" == "end" ]; then
29+
record_end_time
30+
else
31+
echo "Invalid argument. Use 'start' or 'end'."
32+
exit 1
33+
fi

0 commit comments

Comments
 (0)