Merge remote-tracking branch 'origin/release/12.3' into dev

pull/11474/head
ulferts 2 years ago
commit dec78c61c7
No known key found for this signature in database
GPG Key ID: A205708DE1284017
  1. 2
      app/models/custom_option.rb
  2. 15
      db/migrate/20221018160449_add_logged_by_to_cost_entries.rb
  3. 53
      docs/development/contribution-documentation/documentation-process/README.md
  4. BIN
      docs/development/contribution-documentation/documentation-process/branches-drop-down-list.png
  5. BIN
      docs/development/contribution-documentation/documentation-process/edit-the-pull-request.png
  6. BIN
      docs/development/contribution-documentation/documentation-process/open-pr-in-forked-repository.png
  7. BIN
      docs/development/contribution-documentation/documentation-process/select-the-new-release-branch.png
  8. 2
      docs/installation-and-operations/installation/docker/README.md
  9. BIN
      docs/installation-and-operations/installation/packaged/02d-ssl.png
  10. 83
      docs/installation-and-operations/installation/packaged/README.md
  11. 10
      modules/costs/app/models/cost_entry.rb
  12. 13
      modules/costs/spec/models/cost_entry_spec.rb
  13. 2
      modules/reporting/app/models/cost_query/sql_statement.rb
  14. 18
      spec/features/custom_fields/reorder_options_spec.rb

@ -30,8 +30,6 @@
# A custom option is a possible value for a given custom field
# which is restricted to a set of specific values.
class CustomOption < ApplicationRecord
acts_as_list
belongs_to :custom_field, touch: true
validates :value, presence: true, length: { maximum: 255 }

@ -0,0 +1,15 @@
class AddLoggedByToCostEntries < ActiveRecord::Migration[7.0]
def change
add_reference :cost_entries, :logged_by, foreign_key: { to_table: :users }, index: true
reversible do |dir|
dir.up do
CostEntry
.where.not(user_id: User.select(:id))
.update_all(user_id: DeletedUser.first.id)
CostEntry.update_all('logged_by_id = user_id')
end
end
end
end

@ -68,7 +68,7 @@ Open `https://github.com/[your-user]/openproject`. On the forked repository go t
![switch-the-default-branch-step-1](switch-the-default-branch-step-1.png)
Select `release/12.2` as default branch and confirm with **Update**
Select `release/12.3` as default branch and confirm with **Update**
*NOTE:* There will be an additional window. Press the button: **I understand, update the default branch.**
@ -76,13 +76,13 @@ Select `release/12.2` as default branch and confirm with **Update**
## Step 8: Sync fork and Update branches (update local repository)
Every time you start editing please make sure you have fetched the latest changes from GitHub.com. First you need to update your forked repository. There you select the branch you are working on, e.g. `release/12.2`. If there are updates in the main repository opf/openproject click on **Sync fork** and **Update branch**.
Every time you start editing please make sure you have fetched the latest changes from GitHub.com. First you need to update your forked repository. There you select the branch you are working on, e.g. `release/12.3`. If there are updates in the main repository opf/openproject click on **Sync fork** and **Update branch**.
![sync fork update branch](sync-fork-update-branch.png)
Now you have fetched the latest changes from the main repository and can go back to GitHub Desktop.
Finally you have to press **"Pull origin"**. Afterwards your local repository is updated to the latest commits of eg. `opf/openproject/release/12.2`
Finally you have to press **"Pull origin"**. Afterwards your local repository is updated to the latest commits of eg. `opf/openproject/release/12.3`
![pull-upstream-changes](pull-upstream-changes.png)
@ -104,11 +104,11 @@ In the next screen select **To contribute to the parent project**.
## Step 10: Create a new Git branch for your change
Select the latest release branch e.g. `release/12.2` as the current branch.
Select the latest release branch e.g. `release/12.3` as the current branch.
![create new branch - step 1](create-new-branch-step-1.png)
In the same drop down click on "New branch". In this window **insert a branch name that describes your changes** and **select the latest release branch** e.g. `release/12.2` the created branch is based on.
In the same drop down click on "New branch". In this window **insert a branch name that describes your changes** and **select the latest release branch** e.g. `release/12.3` the created branch is based on.
![create new branch - step 2](create-new-branch-step-2.png)
@ -148,7 +148,7 @@ A pull request is a workflow to ask for a review from the OpenProject team. With
Your Pull Request will be created in the browser **on github.com** Here select the latest release branch e.g. `release/12.2` in the **"base:"** dropdown on the left side. In the **"compare:"** dropdown select the branch you have changed.
Your Pull Request will be created in the browser **on github.com** Here select the latest release branch e.g. `release/12.3` in the **"base:"** dropdown on the left side. In the **"compare:"** dropdown select the branch you have changed.
![create pull request](create-pull-request.png)
@ -172,9 +172,9 @@ In the field "Reviewers" select "opf/doc-writers".
## Appendix A: How to import a new release branch into your fork
*(e.g. Release changes from `release/12.0` to `release 12.2`)*
*(e.g. Release changes from `release/12.2` to `release 12.3`)*
If a new release branch is generated on the upstream (opf) repository, the fork will NOT automatically fetch and merge and generate this release branch. With the following 'workaround' we get the new branch from the upstream (opf) repository and push it to our new origin (forked repository).
If a new release branch is generated on the upstream opf/openproject repository, the fork will NOT automatically fetch and merge and generate this release branch. With the following 'workaround' we get the new branch from the upstream (opf) repository and push it to our new origin (forked repository).
#### A) Change Remote Repository to UPSTREAM
@ -184,7 +184,7 @@ In GitHub Desktop choose menu "Repository -> Repository settings". This will ope
#### B) Fetch origin (in this case repository 'opf')
In GitHub Desktop **at Current branch the old branch is visible [1]** . After you press **Fetch origin [2]** you will be able to **select the new branch at Current branch** (e.g. `origin/release/12.2`
In GitHub Desktop **at Current branch the old branch is visible [1]** . After you press **Fetch origin [2]** you will be able to **select the new branch at Current branch** (e.g. `origin/release/12.3`
![rebase-your-fork-step-2](rebase-your-fork-step-2.png)
@ -199,3 +199,38 @@ In Github Desktop choose menu "Repository -> Repository settings". This will ope
In GitHub Desktop choose menu "Repository -> Push".
![rebase-your-fork-step-4](rebase-your-fork-step-4.png)
## Appendix B: How to change the Branch of an open Pull Request
If a new release branch is generated on the upstream opf/openproject repository, **and the steps in Appendix A were done** to get the new branch to the fork. We still might have open Pull Requests on the old, now outdated, release branch. The following steps show how to re-base your open Pull Requests to the new release branch. It is important, because otherwise your changes will not be synchronized with the online documentation on the webpage
#### A) Open the Pull Request in the forked repository
![open-pr-in-forked-repository](./open-pr-in-forked-repository.png)
#### B) Edit the Pull Request
Click on the Edit button on the right side of the Pull Request subject
![edit-the-pull-request](./edit-the-pull-request.png)
#### C) Open the Branches drop down list
![branches-drop-down-list](./branches-drop-down-list.png)
#### D) Select the new release branch
![select-the-new-release-branch](./select-the-new-release-branch.png)
#### E) Resolving Conflicts
It is possible that conflicts will be shown after you change the release branch, depending on how much time passed between the new release branch being created and the Pull Request being rebased.
If you change the branches, you need to do a rebase to the updated target branch and remove any commits that should not be in there. It's hard to document this as what you need to remove depends on the target branches. You can read up on how this works in general by searching for "rebasing" or "interactive rebase" for the git client of your choice. Reach out to us by mentioning or assigning an OpenProject developer to your PR in github if you still need help in rebasing your branch. Over time you'll learn what is necessary.

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

@ -356,6 +356,8 @@ described above.
Assuming the desired *server name* is `openproject.example.com` the configuration
will look like this:
> **Note:** There is [another example](../packaged/#external-ssl-tls-termination) for external SSL/TLS termination for **packaged** installations
```
<VirtualHost *:80>
ServerName openproject.example.com

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.0 KiB

After

Width:  |  Height:  |  Size: 26 KiB

@ -317,7 +317,7 @@ sudo yum install openproject
Then finish the installation by reading the [*Initial configuration*](#initial-configuration) section.
**Note:** On this distribution full-text extraction for attachments [*is not supported*](#full-text-extraction-not-supported) by default.
> **Note:** On this distribution full-text extraction for attachments [*is not supported*](#full-text-extraction-not-supported) by default.
## SUSE Linux Enterprise Server (SLES) Installation
@ -366,16 +366,15 @@ After you have successfully installed the OpenProject package, you can now perfo
To start the configuration wizard, please run the following command with `sudo`, or as root:
```bash
sudo openproject configure
sudo openproject reconfigure #interactive - manual choices are stored in /etc/openproject/installer.dat
sudo openproject configure #non-interactive - using values stored in /etc/openproject/installer.dat
```
**Notes:**
* In case you mistype or need to correct a configuration option, you can always safely cancel the configuration wizard by pressing `CTRL+C` and restart it by running `sudo openproject reconfigure`.
* Every time you will run the OpenProject wizard, your choices will be persisted in a configuration file at `/etc/openproject/installer.dat` and subsequent executions of `sudo openproject configure` will re-use these values, only showing you the wizard steps for options you have not yet been asked for.
* Every time you will run the OpenProject wizard, by using `sudo openproject reconfigure` your choices will be persisted in a configuration file at `/etc/openproject/installer.dat` and subsequent executions of `sudo openproject configure` will re-use these values, only showing you the wizard steps for options you have not yet been asked for.
* In case you want to run through all the wizard options again, you can do so by executing `sudo openproject reconfigure`. This will show all wizard steps, but again keep values you entered before showing in the input fields. You can skip dialogs you do not want to change simply by confirming them with `ENTER`.
* In the interactive way you can skip dialogs you do not want to change simply by confirming them with `ENTER`.
## Step 1: Select your OpenProject Edition
@ -411,6 +410,8 @@ The dialog allows you to choose from three options:
Choose this option if you want OpenProject to set up and configure a local database server manually. This is the best choice if you are unfamiliar with administering databases, or do not have a separate PostgreSQL database server installed that you want to connect to.
> **Note:** If you would like to use the database that was automatically installed by OpenProject at time of installation just choose `install` again
### Use an existing PostgreSQL database
Choose this option if you have a PostgreSQL database server installed either on the same host as the OpenProject package is being installed on, or on another server you can connect to from this machine.
@ -429,9 +430,9 @@ sudo openproject config:set DATABASE_URL="postgresql://[user[:password]@][host][
## Step 3: Apache2 web server and SSL termination
OpenProject comes with an internal ruby application server, but this server only listens on a local interface. To receive connections from the outside world, it needs a web server that will act as a proxy to forward incoming connections to the OpenProject application server.
OpenProject comes with an internal ruby application server, but this server only listens on a local interface, usually on port 6000. To receive connections from the outside world, it needs a web server that will act as a proxy to forward incoming connections to the OpenProject application server.
This wizard step allows you to auto-install an Apache2 web server to function as that proxy.
This wizard step allows you to auto-install an Apache2 web server to function as that reverse proxy.
![02a-apache](02a-apache.png)
@ -441,21 +442,25 @@ The available options are:
We recommend that you let OpenProject install and configure the outer web server, in which case we will install an Apache2 web server with a VirtualHost listening to the domain name you specify, optionally providing SSL/TLS termination.
In case you select to auto-install Apache2, multiple dialogs will request the parameters for setting it up:
> **Note:** In case you re-run `sudo openproject reconfigure` later it is mandatory to select `install` at the webserver again
In case you have selected to install Apache2, multiple dialogs will request the parameters for setting it up:
**Domain name**
#### Domain name
Enter the fully qualified domain where your OpenProject installation will be reached at. This will become the `ServerName` of your apache VirtualHost and is also used to generate full links from OpenProject, such as in emails.
Enter the fully qualified domain (FQDN) where your OpenProject installation will be reached at. This will become the `ServerName` of your apache VirtualHost and is also used to generate full links from OpenProject, such as in emails.
![02b-hostname](02b-hostname.png)
**Server path prefix**
#### Server path prefix
If you wish to install OpenProject under a server path prefix, such as `yourdomain.example.com/openproject`, please specify that prefix here with a leading slash. For example: `/openproject`. If OpenProject should respond to `http(s)://yourdomain.example.com` as specified in the previous dialog, simply leave this dialog empty and confirm by pressing `ENTER`.
![02c-prefix](02c-prefix.png)
**SSL/TLS configuration**
#### SSL/TLS configuration
> **Note:** With OpenProject version 12.2 **HTTPS confugration** was set to be **default** for every installation. **Now best practice is to proceed by selecting `yes` for using HTTPS (SSL/TLS)** and generating the needed certificates, otherwise you will have to manually deactivate HTTPS on the command line.
OpenProject can configure Apache to support HTTPS (SSL/TLS). If you have SSL certificates and want to use SSL/TLS (recommended), select **Yes**.
@ -469,11 +474,9 @@ In that case, you will be shown three additional dialogs to enter the certificat
Enabling this mode will result in OpenProject only responding to HTTPS requests, and upgrade any non-secured requests to HTTPS. It will also output HTTP Strict Transport Security (HSTS) headers to the client.
Enabling this mode will result in OpenProject only responding to HTTPS requests, and upgrade any non-secured requests to HTTPS. It will also output HTTP Strict Transport Security (HSTS) headers to the client.
**External SSL/TLS termination**
#### External SSL/TLS termination
> **Note**: If you terminate SSL externally before the request hits the OpenProject server, you need to follow the following instructions to avoid errors in routing. If you want to use SSL on the server running OpenProject, skip this section.
@ -488,9 +491,45 @@ If you have a separate server that is terminating SSL and only forwarding/proxyi
- Finally, to let OpenProject know that it should create links with 'https' when no request is available (for example, when sending emails), you need to set the following setting: `openproject config:set SERVER_PROTOCOL_FORCE_HTTPS="true"` followed by an `openproject configure`. This ensures that OpenProject responds correctly with secure cookies even though it was not configured for https in the server configuration.
Here an example for external SSL/TLS terminaltion with apache (httpd):
> **Note:** There is [another example](../docker/#1-virtual-host-root) for external SSL/TLS termination for **docker-compose** installations
### Skip (not recommended)
```bash
<VirtualHost *:443>
ServerName openproject.example.com
# Logging
LogLevel Warn
ErrorLog /var/log/httpd/openproject.example.com-error.log
CustomLog /var/log/httpd/openproject.example.com-access.log combined
# Reverse Proxy
ProxyPreserveHost On
ProxyRequests Off
ProxyPass / http://[OPENPROJECT-HOST-IP]/
ProxyPassReverse / http://[OPENPROJECT-HOST-IP]/
#ProxyPass / https://[OPENPROJECT-HOST-IP]/ # if openproject's internal apache2 server/ssl is YES
#ProxyPassReverse / https://[OPENPROJECT-HOST-IP]/ # if openproject's internal apache2 server/ssl is YES
# Request Header
RequestHeader set "X-Forwarded-Proto" https
# SSL Certificate that was created by LetsEncrypt
Include /etc/letsencrypt/options-ssl-apache.conf
SSLEngine On
#SSLProxyEngine On # if openproject's internal apache2 server/ssl is YES
SSLCertificateFile /etc/letsencrypt/live/openproject.example.com/cert.pem
SSLCertificateKeyFile /etc/letsencrypt/live/openproject.example.com/privkey.pem
SSLCertificateChainFile /etc/letsencrypt/live/openproject.example.com/chain.pem # optional
</VirtualHost>
```
### Skip Apache2 web server install (not recommended)
> **Note:** Skipping step 3 Apache2 web server install will ask later in step 7 for information about the hostname and HTTPS
The installer will not set up an external web server for accessing. You will need to either install and set up a web server such as Apache2 or Nginx to function as the web server forwarding to our internal server listening at `localhost:6000` by proxying.
@ -502,7 +541,7 @@ When installing with an existing Apache2, you can take a look at the source of o
[For a minimal nginx config, please see this gist](https://gist.github.com/seLain/375d16ccd4542e3727e97a7478187d3a) as as starting point.
**Please note:** If you reconfigure the OpenProject application and switch to `skip`, you might run into errors with the Apache configuration file, as that will not be automatically remove. Please double-check you removed references to the `openproject.conf` if you do reconfigure.
> **Please note:** If you reconfigure the OpenProject application and switch to `skip`, you might run into errors with the Apache configuration file, as that will not be automatically remove. Please double-check you removed references to the `openproject.conf` if you do reconfigure.
@ -527,9 +566,9 @@ OpenProject heavily relies on caching, which is why the wizard suggests you to i
![06-cache](06-cache.png)
## Step 7: Host name and Protocol (only when Apache installation was skipped)
## Step 7: Host name and Protocol (if step 3 was skipped)
This step is only shown if you decided to skip the Apache installation. OpenProject still needs to know what external host name you're running on, as well as if you're using HTTPS or not.
> **Note:** This step is only shown if you decided to skip step 3, the Apache2 installation. OpenProject still needs to know what external host name you're running on, as well as if you're using HTTPS or not.
First, enter the fully qualified domain where your OpenProject installation will be reached at. This will be used to generate full links from OpenProject, such as in emails.
@ -537,7 +576,7 @@ First, enter the fully qualified domain where your OpenProject installation will
Next, tell OpenProject whether you have SSL termination enabled somewhere in your stack. Please note that you need to set up protocol forwarding by the means mentioned in the "Skip Apache installation" step above.
Next, tell OpenProject whether you have SSL termination enabled somewhere in your stack. Please note that you need to set up protocol forwarding by the means mentioned in the [Skip Apache2 Installation](#skip-apache2-web-server-install-not-recommended-1) at step 3 above.
![HTTPS setting](07b-protocol.png)

@ -30,6 +30,7 @@ class CostEntry < ApplicationRecord
belongs_to :project
belongs_to :work_package
belongs_to :user
belongs_to :logged_by, class_name: 'User'
include ::Costs::DeletedUserFallback
belongs_to :cost_type
belongs_to :budget
@ -37,7 +38,7 @@ class CostEntry < ApplicationRecord
include ActiveModel::ForbiddenAttributesProtection
validates_presence_of :work_package_id, :project_id, :user_id, :cost_type_id, :units, :spent_on
validates_presence_of :work_package_id, :project_id, :user_id, :logged_by_id, :cost_type_id, :units, :spent_on
validates_numericality_of :units, allow_nil: false, message: :invalid
validates_length_of :comments, maximum: 255, allow_nil: true
@ -53,7 +54,12 @@ class CostEntry < ApplicationRecord
include Entry::SplashedDates
def after_initialize
if new_record? && cost_type.nil? && default_cost_type = CostType.default
return unless new_record?
# This belongs in a SetAttributesService, but cost_entries are not yet created as such
self.logged_by = User.current
if cost_type.nil? && default_cost_type = CostType.default
self.cost_type_id = default_cost_type.id
end
end

@ -361,6 +361,19 @@ describe CostEntry, type: :model do
end
end
describe '#logged_by' do
it 'validates' do
cost_entry.logged_by = nil
expect(cost_entry).not_to be_valid
expect(cost_entry.errors[:logged_by_id]).to be_present
end
it 'sets logged_by from current user' do
entry = User.execute_as(user2) { described_class.new logged_by: user }
expect(entry.logged_by).to eq(user2)
end
end
describe '#editable_by?' do
describe "WHEN the user has the edit_cost_entries permission
WHEN the cost entry is not created by the user" do

@ -111,7 +111,7 @@ class CostQuery::SqlStatement < Report::SqlStatement
#
# @param [CostQuery::SqlStatement] query The statement to adjust
def self.unify_cost_entries(query)
query.select :units, :cost_type_id, activity_id: -1, logged_by_id: -1
query.select :units, :cost_type_id, :logged_by_id, activity_id: -1
query.select cost_type: "cost_types.name"
query.join CostType
end

@ -1,6 +1,18 @@
require 'spec_helper'
require 'support/pages/custom_fields'
def get_possible_values(amount)
(1..amount).to_a.map { |x| "PREFIX #{x}" }
end
def get_shuffled_possible_values(amount)
get_possible_values(amount).shuffle(random: Random.new(2))
end
def get_possible_values_reordered(amount)
get_possible_values(amount).sort
end
describe 'Reordering custom options of a list custom field', js: true do
let(:user) { create :admin }
let(:cf_page) { Pages::CustomFields.new }
@ -9,7 +21,7 @@ describe 'Reordering custom options of a list custom field', js: true do
create(
:list_wp_custom_field,
name: "Platform",
possible_values: %w[Playstation Xbox Nintendo PC Switch Mobile Dreamcast]
possible_values: get_shuffled_possible_values(200)
)
end
@ -19,7 +31,7 @@ describe 'Reordering custom options of a list custom field', js: true do
it 'reorders the items alphabetically when pressed' do
expect(custom_field.custom_options.order(:position).pluck(:value))
.to eq %w[Playstation Xbox Nintendo PC Switch Mobile Dreamcast]
.to eq get_shuffled_possible_values(200)
cf_page.visit!
click_link custom_field.name
@ -28,6 +40,6 @@ describe 'Reordering custom options of a list custom field', js: true do
cf_page.accept_alert_dialog!
expect(page).to have_selector('.flash.notice', text: I18n.t(:notice_successful_update))
expect(custom_field.custom_options.order(:position).pluck(:value))
.to eq %w[Dreamcast Mobile Nintendo PC Playstation Switch Xbox]
.to eq get_possible_values_reordered(200)
end
end

Loading…
Cancel
Save