Skip to content

Commit b2998d0

Browse files
Release OpenProject 10.6.3
2 parents 633e577 + fc3c853 commit b2998d0

File tree

173 files changed

+630
-697
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

173 files changed

+630
-697
lines changed

.github/workflows/docker.yml

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
name: Docker
2+
on:
3+
# Scheduled workflows run on the latest commit on the default or base branch
4+
schedule:
5+
- cron: '20 2 * * *' # Daily at 02:20
6+
7+
push:
8+
tags:
9+
- v*
10+
jobs:
11+
publish:
12+
# restrict this job to base repo for now
13+
if: github.repository == 'opf/openproject'
14+
runs-on: ubuntu-latest
15+
steps:
16+
- uses: actions/checkout@master
17+
- name: Publish to registry
18+
uses: elgohr/Publish-Docker-Github-Action@master
19+
with:
20+
name: openproject/community-test
21+
username: ${{ secrets.DOCKER_USERNAME }}
22+
password: ${{ secrets.DOCKER_PASSWORD }}
23+
tag_semver: true
24+
cache: ${{ github.event_name != 'schedule' }}

.pkgr.yml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,6 @@ targets:
1111
- catdoc
1212
debian-10:
1313
<<: *debian9
14-
ubuntu-14.04:
15-
<<: *debian9
1614
ubuntu-16.04:
1715
<<: *debian9
1816
ubuntu-18.04:

Gemfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,7 @@ gem 'aws-sdk-core', '~> 3.91.0'
178178
# File upload via fog + screenshots on travis
179179
gem 'aws-sdk-s3', '~> 1.61.0'
180180

181-
gem 'openproject-token', '~> 2.0'
181+
gem 'openproject-token', '~> 2.1.2'
182182

183183
gem 'plaintext', '~> 0.3.2'
184184

Gemfile.lock

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -654,7 +654,7 @@ GEM
654654
validate_email
655655
validate_url
656656
webfinger (>= 1.0.1)
657-
openproject-token (2.0)
657+
openproject-token (2.1.2)
658658
activemodel
659659
parallel (1.19.1)
660660
parallel_tests (2.32.0)
@@ -1062,7 +1062,7 @@ DEPENDENCIES
10621062
openproject-pdf_export!
10631063
openproject-recaptcha!
10641064
openproject-reporting!
1065-
openproject-token (~> 2.0)
1065+
openproject-token (~> 2.1.2)
10661066
openproject-translations!
10671067
openproject-two_factor_authentication!
10681068
openproject-webhooks!

app/models/custom_field/order_statements.rb

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -90,17 +90,16 @@ def coalesce_select_custom_value_as_string
9090
# COALESCE is here to make sure that blank and NULL values are sorted equally
9191
[
9292
<<-SQL
93-
COALESCE(#{select_custom_value_as_string}, '')
93+
COALESCE(#{select_custom_value_as_string}, '')
9494
SQL
9595
]
9696
end
9797

9898
def select_custom_value_as_string
9999
<<-SQL
100100
(SELECT cv_sort.value FROM #{CustomValue.table_name} cv_sort
101-
WHERE cv_sort.customized_type='#{self.class.customized_class.name}'
102-
AND cv_sort.customized_id=#{self.class.customized_class.table_name}.id
103-
AND cv_sort.custom_field_id=#{id} LIMIT 1)
101+
WHERE #{cv_sort_only_custom_field_condition_sql}
102+
LIMIT 1)
104103
SQL
105104
end
106105

@@ -109,8 +108,7 @@ def select_custom_option_position
109108
(SELECT co_sort.position FROM #{CustomOption.table_name} co_sort
110109
LEFT JOIN #{CustomValue.table_name} cv_sort
111110
ON co_sort.id = CAST(cv_sort.value AS decimal(60,3))
112-
WHERE cv_sort.custom_field_id=#{id}
113-
AND cv_sort.customized_id=#{self.class.customized_class.table_name}.id
111+
WHERE #{cv_sort_only_custom_field_condition_sql}
114112
LIMIT 1
115113
)
116114
SQL
@@ -119,9 +117,7 @@ def select_custom_option_position
119117
def select_custom_values_as_group
120118
<<-SQL
121119
COALESCE((SELECT string_agg(cv_sort.value, '.') FROM #{CustomValue.table_name} cv_sort
122-
WHERE cv_sort.customized_type='#{self.class.customized_class.name}'
123-
AND cv_sort.customized_id=#{self.class.customized_class.table_name}.id
124-
AND cv_sort.custom_field_id=#{id}
120+
WHERE #{cv_sort_only_custom_field_condition_sql}
125121
AND cv_sort.value IS NOT NULL), '')
126122
SQL
127123
end
@@ -131,18 +127,14 @@ def select_custom_values_joined_options_as_group
131127
COALESCE((SELECT string_agg(co_sort.value, '.' ORDER BY co_sort.position ASC) FROM #{CustomOption.table_name} co_sort
132128
LEFT JOIN #{CustomValue.table_name} cv_sort
133129
ON cv_sort.value IS NOT NULL AND co_sort.id = cv_sort.value::numeric
134-
WHERE cv_sort.customized_type='#{self.class.customized_class.name}'
135-
AND cv_sort.customized_id=#{self.class.customized_class.table_name}.id
136-
AND cv_sort.custom_field_id=#{id}), '')
130+
WHERE #{cv_sort_only_custom_field_condition_sql}), '')
137131
SQL
138132
end
139133

140134
def select_custom_value_as_decimal
141135
<<-SQL
142136
(SELECT CAST(cv_sort.value AS decimal(60,3)) FROM #{CustomValue.table_name} cv_sort
143-
WHERE cv_sort.customized_type='#{self.class.customized_class.name}'
144-
AND cv_sort.customized_id=#{self.class.customized_class.table_name}.id
145-
AND cv_sort.custom_field_id=#{id}
137+
WHERE #{cv_sort_only_custom_field_condition_sql}
146138
AND cv_sort.value <> ''
147139
AND cv_sort.value IS NOT NULL
148140
LIMIT 1)
@@ -164,4 +156,14 @@ def order_by_version_sql(column)
164156
LIMIT 1)
165157
SQL
166158
end
159+
160+
private
161+
162+
def cv_sort_only_custom_field_condition_sql
163+
<<-SQL
164+
cv_sort.customized_type='#{self.class.customized_class.name}'
165+
AND cv_sort.customized_id=#{self.class.customized_class.table_name}.id
166+
AND cv_sort.custom_field_id=#{id}
167+
SQL
168+
end
167169
end

app/models/project.rb

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,9 @@ class Project < ApplicationRecord
155155
validates :name,
156156
presence: true,
157157
length: { maximum: 255 }
158+
159+
before_validation :remove_white_spaces_from_project_name
160+
158161
# TODO: we temporarily disable this validation because it leads to failed tests
159162
# it implicitly assumes a db:seed-created standard type to be present and currently
160163
# neither development nor deployment setups are prepared for this
@@ -573,4 +576,8 @@ def shared_versions_base_scope
573576
.includes(:project)
574577
.references(:projects)
575578
end
579+
580+
def remove_white_spaces_from_project_name
581+
self.name = name.squish unless self.name.nil?
582+
end
576583
end

app/services/groups/add_users_service.rb

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,8 @@ def add_to_user_and_projects_cte
8383
SELECT members.project_id AS project_id,
8484
members.user_id AS user_id,
8585
members.id AS member_id,
86-
member_roles.role_id AS role_id
86+
member_roles.role_id AS role_id,
87+
member_roles.id AS member_role_id
8788
FROM #{MemberRole.table_name} member_roles
8889
JOIN #{Member.table_name} members
8990
ON members.id = member_roles.member_id AND members.user_id = :group_id
@@ -103,12 +104,13 @@ def add_to_user_and_projects_cte
103104
-- even if they already exist as members (e.g., added individually) to ensure we add all roles
104105
-- to mark that we reset the created_at date since replacing the member
105106
ON CONFLICT(project_id, user_id) DO UPDATE SET created_on = CURRENT_TIMESTAMP
106-
RETURNING id, user_id
107+
RETURNING id, user_id, project_id
107108
)
108109
-- copy the member roles of the group
109110
INSERT INTO #{MemberRole.table_name} (member_id, role_id, inherited_from)
110-
SELECT new_members.id, group_roles.role_id, group_roles.member_id
111-
FROM group_roles, new_members
111+
SELECT new_members.id, group_roles.role_id, group_roles.member_role_id
112+
FROM group_roles
113+
JOIN new_members ON group_roles.project_id = new_members.project_id
112114
-- Ignore if the role was already inserted by us
113115
ON CONFLICT DO NOTHING
114116
SQL
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
OpenProject::Application.configure do
2+
config.after_initialize do
3+
slow_sql_threshold = OpenProject::Configuration.sql_slow_query_threshold.to_i
4+
return if slow_sql_threshold == 0
5+
6+
ActiveSupport::Notifications.subscribe("sql.active_record") do |_name, start, finish, _id, data|
7+
# Skip transaction that may be blocked
8+
next if data[:sql].match(/BEGIN|COMMIT/)
9+
10+
# Skip smaller durations
11+
duration = ((finish - start) * 1000).round(4)
12+
next if duration <= slow_sql_threshold
13+
14+
payload = {
15+
duration: duration,
16+
time: start.iso8601,
17+
cached: !!data[:cache],
18+
sql: data[:sql],
19+
}
20+
21+
sql_log_string = data[:sql].strip.gsub(/(^([\s]+)?$\n)/, "")
22+
OpenProject.logger.warn "Encountered slow SQL (#{payload[:duration]} ms): #{sql_log_string}",
23+
payload: payload,
24+
# Hash of the query for reference/fingerprinting
25+
reference: Digest::SHA1.hexdigest(data[:sql])
26+
rescue StandardError => e
27+
OpenProject.logger.error "Failed to record slow SQL query: #{e}"
28+
end
29+
end
30+
end

config/locales/crowdin/ar.yml

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -418,7 +418,6 @@ ar:
418418
types: "الأنواع"
419419
versions: "الإصدارات"
420420
work_packages: "مجموعات العمل"
421-
templated: 'Template project'
422421
projects/status:
423422
code: 'الحالة'
424423
explanation: 'Status description'
@@ -490,7 +489,6 @@ ar:
490489
parent_work_package: "الجذر"
491490
priority: "الأولوية"
492491
progress: "التقدم (%)"
493-
schedule_manually: "Schedule manually"
494492
spent_hours: "الوقت المستهلك"
495493
spent_time: "الوقت المستهلك"
496494
subproject: "مشروع فرعي"
@@ -900,7 +898,6 @@ ar:
900898
- "تشرين الأول"
901899
- "تشرين الثاني"
902900
- "كانون الأول"
903-
abbr_week: 'Wk'
904901
day_names:
905902
- "الأحد"
906903
- "الاثنين"
@@ -2031,12 +2028,6 @@ ar:
20312028
warning_one: وسيكون أعضاء المشروع إلى نقل مستودعات للمشروع.
20322029
warning_two: لن تعد تعمل الارتباطات الموجودة في المشروع.
20332030
title: تغيير معرف المشروع
2034-
template:
2035-
copying: >
2036-
Your project is being created from the selected template project. You will be notified by mail as soon as the project is available.
2037-
use_template: 'Use template'
2038-
make_template: 'Set as template'
2039-
remove_from_templates: 'Remove from templates'
20402031
archive:
20412032
are_you_sure: "هل أنت متأكد من أنك تريد أرشفة المشروع '%{name}'؟"
20422033
archived: "Archived"

config/locales/crowdin/bg.yml

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -414,7 +414,6 @@ bg:
414414
types: "Видове"
415415
versions: "Версии"
416416
work_packages: "Работен пакет"
417-
templated: 'Template project'
418417
projects/status:
419418
code: 'Състояние'
420419
explanation: 'Status description'
@@ -486,7 +485,6 @@ bg:
486485
parent_work_package: "Горна категория"
487486
priority: "Приоритет"
488487
progress: "Прогрес (%)"
489-
schedule_manually: "Schedule manually"
490488
spent_hours: "Отработено време"
491489
spent_time: "Отработено време"
492490
subproject: "Подпроект"
@@ -884,7 +882,6 @@ bg:
884882
- "окт"
885883
- "ное"
886884
- "Декември"
887-
abbr_week: 'Wk'
888885
day_names:
889886
- "Неделя"
890887
- "Понеделник"
@@ -1947,12 +1944,6 @@ bg:
19471944
warning_one: Members of the project will have to relocate the project's repositories.
19481945
warning_two: Existing links to the project will no longer work.
19491946
title: Change the project's identifier
1950-
template:
1951-
copying: >
1952-
Your project is being created from the selected template project. You will be notified by mail as soon as the project is available.
1953-
use_template: 'Use template'
1954-
make_template: 'Set as template'
1955-
remove_from_templates: 'Remove from templates'
19561947
archive:
19571948
are_you_sure: "Наистина ли искате да архивирате на проекта \"%{name}\"?"
19581949
archived: "Archived"

0 commit comments

Comments
 (0)