Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
1
Merge Requests
1
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
gitlab-ce
Commits
0bdd20eb
Commit
0bdd20eb
authored
Jul 28, 2021
by
Rémy Coutable
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ci: Distribute static-analysis tasks more intelligently
Signed-off-by:
Rémy Coutable
<
remy@rymai.me
>
parent
a762ccc6
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
65 additions
and
12 deletions
+65
-12
scripts/static-analysis
scripts/static-analysis
+65
-12
No files found.
scripts/static-analysis
View file @
0bdd20eb
...
@@ -19,18 +19,18 @@ class StaticAnalysis
...
@@ -19,18 +19,18 @@ class StaticAnalysis
# file that is generated by an EE installation, which can
# file that is generated by an EE installation, which can
# contain values that a FOSS installation won't find. To work
# contain values that a FOSS installation won't find. To work
# around this we will only enable this task on EE installations.
# around this we will only enable this task on EE installations.
TASKS_
BY_DURATIONS_SECONDS_DESC
=
{
TASKS_
WITH_DURATIONS_SECONDS
=
{
%w[bin/rake lint:haml]
=>
800
,
%w[bin/rake lint:haml]
=>
800
,
# We need to disable the cache for this cop since it creates files under tmp/feature_flags/*.used,
# We need to disable the cache for this cop since it creates files under tmp/feature_flags/*.used,
# the cache would prevent these files from being created.
# the cache would prevent these files from being created.
%w[bundle exec rubocop --only Gitlab/MarkUsedFeatureFlags --cache false]
=>
600
,
%w[bundle exec rubocop --only Gitlab/MarkUsedFeatureFlags --cache false]
=>
600
,
(
Gitlab
.
ee?
?
%w[bin/rake gettext:updated_check]
:
nil
)
=>
360
,
(
Gitlab
.
ee?
?
%w[bin/rake gettext:updated_check]
:
nil
)
=>
360
,
%w[yarn run lint:eslint:all]
=>
312
,
%w[yarn run lint:eslint:all]
=>
312
,
%w[bundle exec rubocop --parallel]
=>
300
,
%w[yarn run lint:prettier]
=>
162
,
%w[yarn run lint:prettier]
=>
162
,
%w[bin/rake gettext:lint]
=>
65
,
%w[bin/rake gettext:lint]
=>
65
,
%w[bundle exec license_finder]
=>
61
,
%w[bundle exec license_finder]
=>
61
,
%w[bin/rake lint:static_verification]
=>
45
,
%w[bin/rake lint:static_verification]
=>
45
,
%w[bundle exec rubocop --parallel]
=>
40
,
%w[bin/rake config_lint]
=>
26
,
%w[bin/rake config_lint]
=>
26
,
%w[bin/rake gitlab:sidekiq:all_queues_yml:check]
=>
15
,
%w[bin/rake gitlab:sidekiq:all_queues_yml:check]
=>
15
,
(
Gitlab
.
ee?
?
%w[bin/rake gitlab:sidekiq:sidekiq_queues_yml:check]
:
nil
)
=>
11
,
(
Gitlab
.
ee?
?
%w[bin/rake gitlab:sidekiq:sidekiq_queues_yml:check]
:
nil
)
=>
11
,
...
@@ -40,14 +40,21 @@ class StaticAnalysis
...
@@ -40,14 +40,21 @@ class StaticAnalysis
%w[scripts/lint-rugged]
=>
1
,
%w[scripts/lint-rugged]
=>
1
,
%w[scripts/gemfile_lock_changed.sh]
=>
1
,
%w[scripts/gemfile_lock_changed.sh]
=>
1
,
%w[scripts/frontend/check_no_partial_karma_jest.sh]
=>
1
%w[scripts/frontend/check_no_partial_karma_jest.sh]
=>
1
}.
reject
{
|
k
|
k
.
nil?
}.
sort_by
{
|
a
|
-
a
[
1
]
}.
to_h
.
keys
.
freeze
}.
reject
{
|
k
|
k
.
nil?
}.
freeze
def
run_tasks!
StaticAnalysisTasks
=
Struct
.
new
(
:tasks
,
:duration
)
tasks
=
tasks_to_run
((
ENV
[
'CI_NODE_INDEX'
]
||
1
).
to_i
,
(
ENV
[
'CI_NODE_TOTAL'
]
||
1
).
to_i
)
def
run_tasks!
(
options
=
{})
node_tasks
=
tasks_to_run
((
ENV
[
'CI_NODE_TOTAL'
]
||
1
).
to_i
,
debug:
options
[
:debug
])[(
ENV
[
'CI_NODE_INDEX'
]
||
1
).
to_i
-
1
]
if
options
[
:dry_run
]
puts
"Dry-run mode!"
return
end
static_analysis
=
Gitlab
::
Popen
::
Runner
.
new
static_analysis
=
Gitlab
::
Popen
::
Runner
.
new
static_analysis
.
run
(
tasks
)
do
|
cmd
,
&
run
|
static_analysis
.
run
(
node_tasks
.
tasks
)
do
|
cmd
,
&
run
|
puts
puts
puts
"$
#{
cmd
.
join
(
' '
)
}
"
puts
"$
#{
cmd
.
join
(
' '
)
}
"
...
@@ -107,16 +114,62 @@ class StaticAnalysis
...
@@ -107,16 +114,62 @@ class StaticAnalysis
.
count
{
|
result
|
!
ALLOWED_WARNINGS
.
include?
(
result
.
stderr
.
strip
)
}
.
count
{
|
result
|
!
ALLOWED_WARNINGS
.
include?
(
result
.
stderr
.
strip
)
}
end
end
def
tasks_to_run
(
node_index
,
node_total
)
def
tasks_to_run
(
node_total
,
debug:
false
)
tasks
=
[]
tasks_per_node
=
Array
.
new
(
node_total
)
{
StaticAnalysisTasks
.
new
([],
0
)
}
TASKS_BY_DURATIONS_SECONDS_DESC
.
each_with_index
do
|
task
,
i
|
tasks
<<
task
if
i
%
node_total
==
(
node_index
-
1
)
total_time
=
TASKS_WITH_DURATIONS_SECONDS
.
values
.
sum
.
to_f
ideal_time_per_job
=
total_time
/
node_total
tasks_by_duration_desc
=
TASKS_WITH_DURATIONS_SECONDS
.
sort_by
{
|
a
|
-
a
[
1
]
}.
to_h
p
"total_time:
#{
total_time
}
"
if
debug
p
"ideal_time_per_job:
#{
ideal_time_per_job
}
"
if
debug
tasks_by_duration_desc
.
each_with_index
do
|
(
task
,
duration
),
i
|
puts
"Assigning
#{
task
}
..."
if
debug
(
0
...
node_total
).
each
do
|
node_index
|
puts
"Current node:
#{
node_index
}
..."
if
debug
# Task is already longer than the ideal time
if
duration
>=
ideal_time_per_job
&&
tasks_per_node
[
node_index
].
tasks
.
empty?
puts
"Assigning
#{
task
}
to node
#{
node_index
}
(
#{
duration
}
s)."
if
debug
assign_task_to_node
(
tasks_by_duration_desc
,
tasks_per_node
[
node_index
],
task
,
duration
)
break
elsif
tasks_per_node
[
node_index
].
duration
+
duration
<=
ideal_time_per_job
puts
"Assigning
#{
task
}
to node
#{
node_index
}
(
#{
duration
}
s)."
if
debug
assign_task_to_node
(
tasks_by_duration_desc
,
tasks_per_node
[
node_index
],
task
,
duration
)
break
else
puts
"Node
#{
node_index
}
is already full (
#{
tasks_per_node
[
node_index
]
}
)"
if
debug
end
end
end
end
tasks
raise
"There are unassigned tasks:
#{
tasks_by_duration_desc
}
"
unless
tasks_by_duration_desc
.
empty?
tasks_per_node
.
each_with_index
do
|
node
,
i
|
puts
"
\n
Expected duration for node
#{
i
+
1
}
:
#{
node
.
duration
}
"
node
.
tasks
.
each
{
|
task
|
puts
"-
#{
task
.
join
(
' '
)
}
"
}
end
tasks_per_node
end
def
assign_task_to_node
(
remaining_tasks
,
node
,
task_name
,
duration
)
node
.
tasks
<<
task_name
node
.
duration
+=
duration
remaining_tasks
.
delete
(
task_name
)
end
end
end
end
if
$0
==
__FILE__
if
$0
==
__FILE__
StaticAnalysis
.
new
.
run_tasks!
options
=
{}
if
ARGV
.
include?
(
'--dry-run'
)
options
[
:dry_run
]
=
true
end
if
ARGV
.
include?
(
'--debug'
)
options
[
:debug
]
=
true
end
StaticAnalysis
.
new
.
run_tasks!
(
options
)
end
end
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment