diff --git a/.devcontainer/.env b/.devcontainer/.env
new file mode 100644
index 0000000000..d86563608b
--- /dev/null
+++ b/.devcontainer/.env
@@ -0,0 +1,7 @@
+APP_PORT=8000
+SELENIUM_PORT_1=4444
+SELENIUM_PORT_2=5900
+MAILCATCHER_PORT=1080
+RAILS_DB_ADAPTER=postgresql
+POSTGRES_PORT=5433
+MYSQL_PORT=3307
\ No newline at end of file
diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile
new file mode 100644
index 0000000000..f4adf9bb64
--- /dev/null
+++ b/.devcontainer/Dockerfile
@@ -0,0 +1,17 @@
+# [Choice] Ruby version (use -bullseye variants on local arm64/Apple Silicon): 3, 3.1, 3.0, 2, 2.7, 2.6, 3-bullseye, 3.1-bullseye, 3.0-bullseye, 2-bullseye, 2.7-bullseye, 2.6-bullseye, 3-buster, 3.1-buster, 3.0-buster, 2-buster, 2.7-buster, 2.6-buster
+ARG VARIANT=3.1-bullseye
+FROM mcr.microsoft.com/vscode/devcontainers/ruby:${VARIANT}
+
+# Default value to allow debug server to serve content over GitHub Codespace's port forwarding service
+# The value is a comma-separated list of allowed domains
+ENV RAILS_DEVELOPMENT_HOSTS=".githubpreview.dev"
+
+# [Choice] Node.js version: lts/*, 16, 14, 12, 10
+ARG NODE_VERSION="lts/*"
+RUN su vscode -c "source /usr/local/share/nvm/nvm.sh && nvm install ${NODE_VERSION} 2>&1"
+
+# [Optional] Uncomment this section to install additional OS packages.
+RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
+ && apt-get -y install --no-install-recommends bzr gsfonts imagemagick libmagick++-dev
+
+EXPOSE $APP_PORT
diff --git a/.devcontainer/create-db-user.sql b/.devcontainer/create-db-user.sql
new file mode 100644
index 0000000000..24417a9bd4
--- /dev/null
+++ b/.devcontainer/create-db-user.sql
@@ -0,0 +1,2 @@
+CREATE USER vscode CREATEDB;
+CREATE DATABASE vscode WITH OWNER vscode;
\ No newline at end of file
diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json
new file mode 100644
index 0000000000..766143e1b5
--- /dev/null
+++ b/.devcontainer/devcontainer.json
@@ -0,0 +1,55 @@
+// Update the VARIANT arg in docker-compose.yml to pick a Ruby version
+{
+ "name": "Redmine dev mirror",
+ "dockerComposeFile": "docker-compose.yml",
+ "service": "app",
+ "workspaceFolder": "/workspace",
+ "shutdownAction": "stopCompose",
+ // Configure tool-specific properties.
+ "customizations": {
+ // Configure properties specific to VS Code.
+ "vscode": {
+ // Add the IDs of extensions you want installed when the container is created.
+ "extensions": [
+ "rebornix.ruby",
+ "eamodio.gitlens",
+ "kaiwood.endwise",
+ "mtxr.sqltools",
+ "mtxr.sqltools-driver-pg",
+ "mtxr.sqltools-driver-mysql",
+ "ms-vsliveshare.vsliveshare"
+ ],
+ "settings": {
+ "workbench.colorCustomizations": {
+ "activityBar.background": "#ab3e3e"
+ },
+ "sqltools.connections": [
+ {
+ "previewLimit": 50,
+ "server": "postgresdb",
+ "port": 5432,
+ "driver": "PostgreSQL",
+ "name": "app_development",
+ "database": "app_development",
+ "username": "postgres",
+ "password": "postgres"
+ },
+ {
+ "previewLimit": 50,
+ "server": "mysqldb",
+ "port": 3306,
+ "driver": "MySQL",
+ "name": "app_development",
+ "database": "app_development",
+ "username": "root",
+ "password": "password"
+ },
+ ]
+ }
+ }
+ },
+ "postCreateCommand": "bash .devcontainer/scripts/postCreateCommand.sh",
+ "postStartCommand": "bash .devcontainer/scripts/postStartCommand.sh",
+ // Comment out to connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root.
+ "remoteUser": "vscode"
+}
\ No newline at end of file
diff --git a/.devcontainer/docker-compose.yml b/.devcontainer/docker-compose.yml
new file mode 100644
index 0000000000..057d05732a
--- /dev/null
+++ b/.devcontainer/docker-compose.yml
@@ -0,0 +1,78 @@
+version: '3'
+services:
+
+ # PostgreSQL
+ postgresdb:
+ image: postgres:14
+ restart: on-failure:5
+ volumes:
+ - ./create-db-user.sql:/docker-entrypoint-initdb.d/create-db-user.sql
+ environment:
+ POSTGRES_USER: postgres
+ POSTGRES_PASSWORD: postgres
+ ports:
+ - $POSTGRES_PORT:5432
+
+ # MySQL
+ # mysqldb:
+ # image: mysql:5
+ # platform: linux/amd64
+ # restart: on-failure:5
+ # environment:
+ # MYSQL_ROOT_PASSWORD: password
+ # ports:
+ # - $MYSQL_PORT:3306
+
+ app:
+ build:
+ context: ..
+ dockerfile: .devcontainer/Dockerfile
+ args:
+ APP_PORT: $APP_PORT
+ # Update 'VARIANT' to pick a version of Ruby: 3, 3.1, 3.0, 2, 2.7, 2.6
+ # Append -bullseye or -buster to pin to an OS version.
+ # Use -bullseye variants on local arm64/Apple Silicon.
+ VARIANT: "3.0-bullseye"
+ # Optional Node.js version to install
+ NODE_VERSION: "14"
+ environment:
+ # PostgreSQL
+ RAILS_DB_ADAPTER: postgresql
+ RAILS_DB_HOST: postgresdb
+ RAILS_DB: app
+ RAILS_DB_USERNAME: postgres
+ RAILS_DB_PASSWORD: postgres
+ RAILS_DB_ENCODING: utf8
+ RAILS_ENV: development
+ # # MySQL
+ # RAILS_DB_ADAPTER: mysql2
+ # RAILS_DB_HOST: mysqldb
+ # RAILS_DB: app
+ # RAILS_DB_USERNAME: root
+ # RAILS_DB_PASSWORD: password
+ # RAILS_DB_ENCODING: utf8mb4
+ # RAILS_ENV: development
+ env_file: .env
+ tty: true
+ ports:
+ - $APP_PORT:3000
+ depends_on:
+ - postgresdb
+ # - mysqldb
+ command: sleep infinity
+ volumes:
+ - ..:/workspace:cached
+
+ # For selenium test
+ # chrome:
+ # M1の場合はselenium/standalone-chrome-debugが動かないため、seleniarm/standalone-chromium:latestを代わりに使うこと。
+ # image: selenium/standalone-chrome-debug:3.141.59-20210913
+ # ports:
+ # - $SELENIUM_PORT_1:4444
+ # - $SELENIUM_PORT_2:5900
+ # shm_size: 2gb
+
+ smtp:
+ image: schickling/mailcatcher
+ ports:
+ - $MAILCATCHER_PORT:1080
diff --git a/.devcontainer/files/.vscode/launch.json b/.devcontainer/files/.vscode/launch.json
new file mode 100644
index 0000000000..95285ae0cd
--- /dev/null
+++ b/.devcontainer/files/.vscode/launch.json
@@ -0,0 +1,17 @@
+{
+ "version": "0.2.0",
+ "configurations": [
+ {
+ "name": "Rails server",
+ "type": "Ruby",
+ "request": "launch",
+ "cwd": "${workspaceRoot}",
+ "program": "${workspaceRoot}/bin/rails",
+ "args": [
+ "server",
+ "-b",
+ "0"
+ ]
+ }
+ ]
+}
diff --git a/.devcontainer/files/Gemfile.local b/.devcontainer/files/Gemfile.local
new file mode 100644
index 0000000000..ddfc5cca2b
--- /dev/null
+++ b/.devcontainer/files/Gemfile.local
@@ -0,0 +1,16 @@
+gem 'pry-rails'
+gem 'pry-byebug'
+gem 'binding_of_caller'
+gem 'better_errors'
+gem 'view_source_map'
+gem 'parallel_tests'
+gem 'benchmark-ips'
+gem 'activeresource'
+gem 'timecop'
+if Gem.ruby_version < Gem::Version.new('3.1.0')
+ gem 'ruby-debug-ide'
+ gem 'debase', '~> 0.2.5beta2'
+end
+if Gem.ruby_version >= Gem::Version.new('2.7.0')
+ gem 'debug'
+end
diff --git a/.devcontainer/files/additional_environment.rb b/.devcontainer/files/additional_environment.rb
new file mode 100644
index 0000000000..cb4d7a099e
--- /dev/null
+++ b/.devcontainer/files/additional_environment.rb
@@ -0,0 +1,4 @@
+# redmine-dev-mirror用ファイル
+
+# ログの保存箇所をvolumesの対象外にして同期による負かを軽くする
+config.logger = Logger.new('/logs/redmine.log', 2, 1000000)
diff --git a/.devcontainer/files/configuration.yml b/.devcontainer/files/configuration.yml
new file mode 100644
index 0000000000..6053be2184
--- /dev/null
+++ b/.devcontainer/files/configuration.yml
@@ -0,0 +1,10 @@
+# redmine-dev-mirror
+
+development:
+ email_delivery:
+ delivery_method: :smtp
+ smtp_settings:
+ address: 'smtp'
+ port: 1025
+test:
+production:
diff --git a/.devcontainer/files/database.yml b/.devcontainer/files/database.yml
new file mode 100644
index 0000000000..929f9f4d0b
--- /dev/null
+++ b/.devcontainer/files/database.yml
@@ -0,0 +1,23 @@
+# redmine-dev-mirror
+
+production:
+ adapter: <%= ENV['RAILS_DB_ADAPTER'] %>
+ database: <%= ENV['RAILS_DB'] %>
+ username: <%= ENV['RAILS_DB_USERNAME'] %>
+ password: <%= ENV['RAILS_DB_PASSWORD'] %>
+ host: <%= ENV['RAILS_DB_HOST'] %>
+ encoding: <%= ENV['RAILS_DB_ENCODING'] %>
+development:
+ adapter: <%= ENV['RAILS_DB_ADAPTER'] %>
+ database: <%= ENV['RAILS_DB'] %>_development
+ username: <%= ENV['RAILS_DB_USERNAME'] %>
+ password: <%= ENV['RAILS_DB_PASSWORD'] %>
+ host: <%= ENV['RAILS_DB_HOST'] %>
+ encoding: <%= ENV['RAILS_DB_ENCODING'] %>
+test:
+ adapter: <%= ENV['RAILS_DB_ADAPTER'] %>
+ database: <%= ENV['RAILS_DB'] %>_test
+ username: <%= ENV['RAILS_DB_USERNAME'] %>
+ password: <%= ENV['RAILS_DB_PASSWORD'] %>
+ host: <%= ENV['RAILS_DB_HOST'] %>
+ encoding: <%= ENV['RAILS_DB_ENCODING'] %>
\ No newline at end of file
diff --git a/.devcontainer/scripts/postCreateCommand.sh b/.devcontainer/scripts/postCreateCommand.sh
new file mode 100644
index 0000000000..391fa1ecf5
--- /dev/null
+++ b/.devcontainer/scripts/postCreateCommand.sh
@@ -0,0 +1,15 @@
+#!/bin/bash
+
+cp .devcontainer/files/Gemfile.local Gemfile.local
+cp .devcontainer/files/database.yml config/database.yml
+cp .devcontainer/files/configuration.yml config/configuration.yml
+cp .devcontainer/files/additional_environment.rb config/additional_environment.rb
+cp -r .devcontainer/files/.vscode .vscode
+
+sudo mkdir /logs
+sudo touch /logs/redmine.log
+sudo chown -R vscode /logs
+
+bundle install
+
+rake db:create
diff --git a/.devcontainer/scripts/postStartCommand.sh b/.devcontainer/scripts/postStartCommand.sh
new file mode 100644
index 0000000000..53b70d08ac
--- /dev/null
+++ b/.devcontainer/scripts/postStartCommand.sh
@@ -0,0 +1,9 @@
+#!/bin/bash
+
+bundle update
+rake generate_secret_token
+
+rake db:migrate
+rake redmine:plugins:migrate
+
+rake log:clear
diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
index b501ea9a58..d08f0d19f3 100644
--- a/.github/PULL_REQUEST_TEMPLATE.md
+++ b/.github/PULL_REQUEST_TEMPLATE.md
@@ -1,13 +1,5 @@
+redmine.orgのチケットURL: https://www.redmine.org/issues/xxxx
-____________________________________________________________________
-
-Your contributions to Redmine are welcome!
-
-Please **open an issue on the [official website]** instead of sending pull requests.
-
-Since the development of Redmine is not conducted on GitHub but on the [official website] and core developers are not monitoring the GitHub repo, pull requests might not get reviewed.
-
-For more detail about how to contribute, please see the wiki page [Contribute] on the [official website].
-
-[official website]: https://www.redmine.org/
-[Contribute]: https://www.redmine.org/projects/redmine/wiki/Contribute
+TODO:
+- [ ] 単体テストかく
+- [ ] ...
diff --git a/.github/actions/comment_patch_url.rb b/.github/actions/comment_patch_url.rb
new file mode 100755
index 0000000000..dd4f72dbfb
--- /dev/null
+++ b/.github/actions/comment_patch_url.rb
@@ -0,0 +1,76 @@
+#!/usr/bin/env ruby
+
+require 'json'
+
+require 'faraday'
+
+REPO = 'agileware-jp/redmine-dev-mirror'
+
+WORKFLOW_RUN = JSON.parse ENV['WORKFLOW_RUN_JSON']
+
+CONNECTION = Faraday.new('https://api.github.com/') do |conn|
+ conn.response :raise_error
+ conn.adapter Faraday.default_adapter
+end
+
+def repo_resource(resource)
+ "repos/#{REPO}/#{resource}"
+end
+
+def get_repo_resource(resource)
+ response = CONNECTION.get repo_resource(resource)
+ JSON.parse response.body
+end
+
+def post_to_repo_resource(resource, body)
+ response = CONNECTION.post repo_resource(resource),
+ body.to_json,
+ "Content-Type" => "application/json",
+ "Authorization" => "token #{ENV['GITHUB_TOKEN']}"
+ JSON.parse response.body
+end
+
+def patch_artifact_id
+ response = JSON.parse CONNECTION.get(WORKFLOW_RUN['artifacts_url']).body
+ patch_artifact = response['artifacts'].find { |artifact| artifact['name'] == 'patch' }
+ patch_artifact['id']
+end
+
+def get_suite_id
+ suite_url = WORKFLOW_RUN['check_suite_url']
+ id_start_index = suite_url.rindex('/') + 1
+ suite_url[id_start_index..-1]
+end
+
+def patch_artifact_download_url
+ "https://github.com/#{REPO}/suites/#{get_suite_id}/artifacts/#{patch_artifact_id}"
+end
+
+def pull_request_number
+ WORKFLOW_RUN.dig('pull_requests', 0, 'number')
+end
+
+def post_pr_comment(pr_number, comment)
+ post_to_repo_resource "issues/#{pr_number}/comments", { body: comment }
+end
+
+def find_previous_comment_id(pr_number)
+ comments = get_repo_resource "issues/#{pr_number}/comments"
+ previous_comment = comments.find { |comment|
+ comment['body'].include?('Patch can be downloaded [here]') && comment['user']['login'].include?('github-actions')
+ }
+ previous_comment['id'] if previous_comment
+end
+
+def delete_comment(comment_id)
+ CONNECTION.delete repo_resource("issues/comments/#{comment_id}"), nil, "Authorization" => "token #{ENV['GITHUB_TOKEN']}"
+end
+
+def main
+ existing_comment_id = find_previous_comment_id(pull_request_number)
+ delete_comment(existing_comment_id) if existing_comment_id
+
+ post_pr_comment pull_request_number, "Patch can be downloaded [here](#{patch_artifact_download_url})" if pull_request_number
+end
+
+main if __FILE__ == $0
diff --git a/.github/actions/test-with-db.sh b/.github/actions/test-with-db.sh
new file mode 100755
index 0000000000..2aac7b33a7
--- /dev/null
+++ b/.github/actions/test-with-db.sh
@@ -0,0 +1,11 @@
+#!/bin/bash
+
+set -x
+
+database=$1
+
+cp ./config/database.$database.yml ./config/database.yml
+bundle install --path vendor/bundle --without minimagick
+bundle update
+bundle exec rake db:create db:migrate
+bundle exec rake test
diff --git a/.github/workflows/comment-patch.yml b/.github/workflows/comment-patch.yml
new file mode 100644
index 0000000000..0bdcb1d602
--- /dev/null
+++ b/.github/workflows/comment-patch.yml
@@ -0,0 +1,24 @@
+name: Comment Patch
+
+on:
+ workflow_run:
+ workflows:
+ - Create Patch
+ types:
+ - completed
+ branches-ignore:
+ - master
+ - develop
+
+jobs:
+ create-patch:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Install gems
+ run: sudo gem install faraday
+ - uses: actions/checkout@v2
+ - name: Comment Patch URL
+ run: ./.github/actions/comment_patch_url.rb
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ WORKFLOW_RUN_JSON: ${{ toJSON(github.event.workflow_run) }}
diff --git a/.github/workflows/create-patch.yml b/.github/workflows/create-patch.yml
new file mode 100644
index 0000000000..87acdd8e8c
--- /dev/null
+++ b/.github/workflows/create-patch.yml
@@ -0,0 +1,35 @@
+name: Create Patch
+
+on:
+ push:
+ branches-ignore:
+ - master
+ - develop
+
+jobs:
+ create-patch:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v2
+ with:
+ fetch-depth: 0
+ - name: Create Patch
+ run: |
+ git config user.email "$AUTHOR_EMAIL"
+ git config user.name "$AUTHOR_NAME"
+ git rev-parse --abbrev-ref HEAD > .branch-name
+ git checkout develop
+ git checkout -b patch
+ git merge --squash `cat .branch-name`
+ git commit -m "Patch for `cat .branch-name`"
+ PATCH_FILE=`cat .branch-name | sed 's/\//_/g'`.patch # Replace forward slash in branch name with _
+ git format-patch develop..HEAD --stdout -k > $PATCH_FILE
+ echo "::set-output name=PATCH_FILE::$PATCH_FILE"
+ id: patch-creator
+ env:
+ AUTHOR_EMAIL: ${{ github.event.head_commit.author.email }}
+ AUTHOR_NAME: ${{ github.event.head_commit.author.name }}
+ - uses: actions/upload-artifact@v2
+ with:
+ name: patch
+ path: ${{ steps.patch-creator.outputs.PATCH_FILE }}
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
new file mode 100644
index 0000000000..a2c8c70972
--- /dev/null
+++ b/.github/workflows/test.yml
@@ -0,0 +1,92 @@
+name: Test
+
+on:
+ push:
+ branches-ignore:
+ - master
+
+jobs:
+ test-with-mysql:
+ strategy:
+ fail-fast: false
+ matrix:
+ ruby: ['2.7', '3.0', '3.1', '3.2']
+ db_version: [5.7]
+ runs-on: ubuntu-latest
+ container:
+ image: ruby:${{ matrix.ruby }}
+ services:
+ db:
+ image: mysql:${{ matrix.db_version }}
+ env:
+ MYSQL_ROOT_PASSWORD: password
+ ports:
+ - 3306:3306
+ steps:
+ - uses: actions/checkout@v2
+ - name: Cache gems
+ uses: actions/cache@v2
+ with:
+ path: vendor/bundle
+ key: ${{ matrix.ruby }}-mysql-${{ hashFiles('**/Gemfile') }}
+ restore-keys: |
+ ${{ matrix.ruby }}-mysql-
+ ${{ matrix.ruby }}-
+ - name: Install & run tests
+ run: ./.github/actions/test-with-db.sh mysql
+ env:
+ DB_HOST: db
+ test-with-postgres:
+ strategy:
+ fail-fast: false
+ matrix:
+ ruby: ['2.7', '3.0', '3.1', '3.2']
+ db_version: [10]
+ runs-on: ubuntu-latest
+ container:
+ image: ruby:${{ matrix.ruby }}
+ services:
+ db:
+ image: postgres:${{ matrix.db_version }}
+ env:
+ LANG: C.UTF-8
+ POSTGRES_INITDB_ARGS: --locale=C.UTF-8
+ POSTGRES_PASSWORD: postgres
+ ports:
+ - 5432:5432
+ # needed because the postgres container does not provide a healthcheck
+ options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5
+ steps:
+ - uses: actions/checkout@v2
+ - name: Cache gems
+ uses: actions/cache@v2
+ with:
+ path: vendor/bundle
+ key: ${{ matrix.ruby }}-postgres-${{ hashFiles('**/Gemfile') }}
+ restore-keys: |
+ ${{ matrix.ruby }}-postgres-
+ ${{ matrix.ruby }}-
+ - name: Install & run tests
+ run: ./.github/actions/test-with-db.sh postgres
+ env:
+ DB_HOST: db
+ test-with-sqlite:
+ strategy:
+ fail-fast: false
+ matrix:
+ ruby: ['2.7', '3.0', '3.1', '3.2']
+ runs-on: ubuntu-latest
+ container:
+ image: ruby:${{ matrix.ruby }}
+ steps:
+ - uses: actions/checkout@v2
+ - name: Cache gems
+ uses: actions/cache@v2
+ with:
+ path: vendor/bundle
+ key: ${{ matrix.ruby }}-sqlite-${{ hashFiles('**/Gemfile') }}
+ restore-keys: |
+ ${{ matrix.ruby }}-sqlite-
+ ${{ matrix.ruby }}-
+ - name: Install & run tests
+ run: ./.github/actions/test-with-db.sh sqlite
diff --git a/.gitignore b/.gitignore
index ebc25cbd86..f3e4ea2546 100644
--- a/.gitignore
+++ b/.gitignore
@@ -45,3 +45,7 @@
/node_modules
yarn-error.log
+
+/docker-compose.yml
+
+/.vscode
\ No newline at end of file
diff --git a/Gemfile b/Gemfile
index 9acac00fb2..c02bcf2424 100644
--- a/Gemfile
+++ b/Gemfile
@@ -90,6 +90,10 @@ end
group :development do
gem 'listen', '~> 3.3'
gem "yard"
+ gem "guard"
+ gem "guard-minitest"
+ gem "pry", "<= 0.12.2" if RUBY_VERSION < '2.4'
+ gem "pry-byebug"
end
group :test do
diff --git a/Guardfile b/Guardfile
new file mode 100644
index 0000000000..2ee21bd185
--- /dev/null
+++ b/Guardfile
@@ -0,0 +1,3 @@
+guard :minitest, all_on_start: false do
+ watch(%r{^test/(.*)test(.*)\.rb$})
+end
diff --git a/README.md b/README.md
new file mode 100644
index 0000000000..139671f68c
--- /dev/null
+++ b/README.md
@@ -0,0 +1,167 @@
+# Agileware Redmine Mirror
+
+## このリポジトリ
+
+Redmineパッチ会の[redmine-dev-mirror](https://github.com/redmine-patch-meetup/redmine-dev-mirror)のフォークリポジトリです。
+
+このリポジトリでRedmineのバグ修正や機能改善を行い、Redmine本体に取り込んでもらうことでRedmineをより良くしていけるよう活動しています。
+
+----
+
+以降はRedmineパッチ会の情報です。最新の情報は[redmine-dev-mirror](https://github.com/redmine-patch-meetup/redmine-dev-mirror)をご覧ください。
+
+----
+
+## Redmineパッチ会に参加したい
+
+Redmineの改善に興味ある方であればどなたでも。
+プログラミングせずに画面の文言変更でもパッチは送れます。
+一緒に仕様を考えて、本家にチケットを作成するだけでもやれることはあります。 Ruby・Railsのプログラミング経験があると更に幅は広がります。
+
+初参加の場合、見学からでもお気軽にどうぞ(^^
+
+### 1. Connpassでイベントを公開しているので、参加申し込みをしてみましょう!
+
+https://redmine-patch.connpass.com/
+
+### 2. 参加登録をしたら、オンラインのやりとり・当日の会場として利用しているDiscordに参加しよう!
+
+イベントに参加登録をした方にのみ参加用URLが確認可能です。
+参加の上で不安な点、わからない点があったらテキストチャンネルで気軽に相談してください👍
+
+### 3. チーム開発に参加できる環境を整えよう!(プログラミング以外での参加の場合は不要)
+
+主に通話にDiscord、複数人でのコーディングにVisual Studio CodeのLive Share拡張を利用しています。
+**VSCodeのLive Shareでモブプロのように参加できるため、Redmineが動く開発環境がなくても参加できます。**
+
+* [Visual Studio Code](https://code.visualstudio.com/)をインストール
+* Visual Studio Codeを開いて、拡張機能 [Live Share](https://marketplace.visualstudio.com/items?itemName=MS-vsliveshare.vsliveshare)をインストール
+* (ない人は)Githubのアカウントを作成
+
+### 4. イベントの時間になったらDiscordを開いて、ボイスチャンネルに参加しよう!
+
+(時間になったら他の参加者も参加しているはず)
+
+## VSCode Remote ContainerによるRedmineの開発環境の作り方 / 機能
+
+Redmineの開発環境を作るやり方のうちの一つです。開発環境がすでにある人はこの手順を使わなくても大丈夫です。
+
+### 前提条件
+
+* Docker Desktopを起動している
+* Visual Studio Codeが利用できる
+
+### 利用手順
+
+* このリポジトリを手元にClone
+
+```bash session
+git clone --config=core.autocrlf=input https://github.com/redmine-patch-meetup/redmine-dev-mirror.git
+cd ./redmine-dev-mirror
+```
+
+* 必要に応じて.devcontainer/.envを書き換える(portの衝突がなければデフォルトでも動きます)
+
+```bash
+# 開発中のRedmineに http://localhost:8000 でアクセス出来るようになる。8000を既に使っている場合は変える
+APP_PORT=8000
+# Seleniumのテストを実行するときに利用するポート。4444, 5900を既に使っている場合は変える
+SELENIUM_PORT_1=4444
+SELENIUM_PORT_2=5900
+# Redmineから送信したメールを http://localhost:1080 で確認出来るようになる。1080を既に使っている場合は変える
+MAILCATCHER_PORT=1080
+# mysqlやsqlite3に変えても良い。mysqlの場合、.devcontainer/docker-compose.ymlのMySQL関連のコメントアウトを外す
+RAILS_DB_ADAPTER=postgresql
+# postgres、mysqlのホスト側への公開ポート。ホスト側で既に使っている場合は変える
+POSTGRES_PORT=5433
+MYSQL_PORT=3307
+```
+
+* VScodeに拡張機能[Remote-Containers](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers)をインストール
+
+* VScodeで/your/path/redmine-dev-mirror を開く
+
+
+
+* 右下に出てくるポップアップのReopen in Containerを選択(出てこなかったらVSCodeのコマンドパレットからRemote Containers: Rebuild and Reopen in Containerを選択) => ビルドが始まるはず
+
+
+
+* VSCodeの左側のバーが赤くなり、左側のファイルツリーも表示されたらコンテナ内に入れている状態
+
+画面下のターミナルに"Press any key"と表示されるため、「キー入力を行い(ターミナルが閉じる)、メニューからターミナルを開く」か 「"Press any key"を放置したままターミナル右上のプラスを押す」 という流れでコマンドを入力できるようにする。
+
+
+↓
+
+
+* 画面下のターミナル内で
+```bash
+rails s -b 0.0.0.0
+```
+* 少し待つと、ブラウザから http://localhost:[.devcontainer/.envで指定したAPP_PORT] でRedmineにアクセスできるようになる。
+
+
+
+* テストの実行
+```bash
+bundle exec rake test RAILS_ENV=test
+```
+
+### おまけ
+
+#### 1. VSCodeの拡張機能を増やしたい
+
+.devcontainer/devcontainer.jsonのextensionsに拡張機能を追加し、VSCodeのコマンドパレットからRebuild and Reopen container
+
+#### 2. Redmineから送信されるメールの内容をチェック
+
+http://localhost:[.devcontainer/.envで指定したMAILCATCHER_PORT] でにアクセスするとメールキャッチャーを開ける
+
+#### 3. Ruby3.0系以外のバージョンで動作検証やテストをしたい
+
+.devcontainer/docker-compose.yml ファイルの `VARIANT: "3.0-bullseye"` の3.0-bulleseye 部分を利用したいバージョンに書き換えて、VSCodeのコマンドパレットからRebuild and Reopen container
+
+#### 4. test/systemのテストを実行する場合
+
+.devcontainer/docker-compose.yml内のchrome:の塊のコメントアウトを外し、VSCodeのコマンドパレットからRebuild and Reopen container
+
+ selenium/standalone-chrome-debugイメージから持ってきたchromeを動かすためにCapybara周りで下のように設定を追加する。
+ app == docker-composeでrailsアプリケーションが動いているところのサービス名
+ chrome:4444 == docker-compose selenium/standalone-chrome-debugイメージのサービス名 + port
+
+```diff
+diff --git a/test/application_system_test_case.rb b/test/application_system_test_case.rb
+index 1a1e0cb4a..fedbe7d15 100644
+--- a/test/application_system_test_case.rb
++++ b/test/application_system_test_case.rb
+@@ -43,13 +43,17 @@ class ApplicationSystemTestCase < ActionDispatch::SystemTestCase
+ }
+ }
+ )
+-
++ options[:browser] = :remote
++ Capybara.server_host = 'app'
++ Capybara.server_port = <.devcontainer/.envのAPP_PORT(デフォルト8000)に入れた値に書き換える>
+ driven_by(
+ :selenium, using: :chrome, screen_size: [1024, 900],
+ options: options
+ )
+
+ setup do
++ Capybara.app_host = "http://#{Capybara.server_host}:#{Capybara.server_port}"
+ # Allow defining a custom app host (useful when using a remote Selenium hub)
+ if ENV['CAPYBARA_APP_HOST']
+ Capybara.configure do |config|
+
+```
+
+```
+ bundle exec rake test TEST=test/system RAILS_ENV=test
+```
+
+そのときホスト側で
+```
+open vnc://localhost:5900
+```
+を実行すると実際に動いているChromeの画面を見ることができる。 (パスワードを要求されたら `secret` と入れる)
diff --git a/README.rdoc b/README.rdoc
deleted file mode 100644
index 4132fb86e7..0000000000
--- a/README.rdoc
+++ /dev/null
@@ -1,5 +0,0 @@
-= Redmine
-
-Redmine is a flexible project management web application written using Ruby on Rails framework.
-
-More details can be found in the doc directory or on the official website http://www.redmine.org
diff --git a/config/database.mysql.yml b/config/database.mysql.yml
new file mode 100644
index 0000000000..3a9ec22916
--- /dev/null
+++ b/config/database.mysql.yml
@@ -0,0 +1,18 @@
+default: &default
+ adapter: mysql2
+ host: <%= ENV.fetch('DB_HOST', '127.0.0.1') %>
+ port: <%= ENV.fetch('DB_PORT', '3306') %>
+ username: root
+ password: password
+
+production:
+ <<: *default
+ database: redmine_production
+
+development:
+ <<: *default
+ database: redmine_development
+
+test:
+ <<: *default
+ database: redmine_test
diff --git a/config/database.postgres.yml b/config/database.postgres.yml
new file mode 100644
index 0000000000..20d7dd38e0
--- /dev/null
+++ b/config/database.postgres.yml
@@ -0,0 +1,19 @@
+default: &default
+ adapter: postgresql
+ encoding: utf8
+ host: <%= ENV.fetch('DB_HOST', 'localhost') %>
+ port: <%= ENV.fetch('DB_PORT', '5432') %>
+ username: postgres
+ password: postgres
+
+production:
+ <<: *default
+ database: redmine_production
+
+development:
+ <<: *default
+ database: redmine_development
+
+test:
+ <<: *default
+ database: redmine_test
diff --git a/config/database.sqlite.yml b/config/database.sqlite.yml
new file mode 100644
index 0000000000..0d72b884a5
--- /dev/null
+++ b/config/database.sqlite.yml
@@ -0,0 +1,18 @@
+# Default setup is given for MySQL 5.7.7 or later.
+# Examples for PostgreSQL, SQLite3 and SQL Server can be found at the end.
+# Line indentation must be 2 spaces (no tabs).
+
+default: &default
+ adapter: sqlite3
+
+production:
+ <<: *default
+ database: db/redmine_production.sqlite3
+
+development:
+ <<: *default
+ database: db/redmine_development.sqlite3
+
+test:
+ <<: *default
+ database: db/redmine_test.sqlite3
diff --git a/docker-compose.mysql.yml b/docker-compose.mysql.yml
new file mode 100644
index 0000000000..d6033fe553
--- /dev/null
+++ b/docker-compose.mysql.yml
@@ -0,0 +1,14 @@
+version: '3.4'
+services:
+ db:
+ image: mysql:${DB_VERSION:-latest}
+ environment:
+ MYSQL_ROOT_PASSWORD: password
+ volumes:
+ - mysql_data:/var/lib/mysql
+ ports:
+ - "3306:3306"
+
+
+volumes:
+ mysql_data:
diff --git a/docker-compose.postgres.yml b/docker-compose.postgres.yml
new file mode 100644
index 0000000000..ad21b712e7
--- /dev/null
+++ b/docker-compose.postgres.yml
@@ -0,0 +1,15 @@
+version: '3.4'
+services:
+ db:
+ image: postgres:${DB_VERSION:-latest}
+ volumes:
+ - postgres_data:/var/lib/postgresql
+ ports:
+ - "5432:5432"
+ environment:
+ LANG: C.UTF-8
+ POSTGRES_INITDB_ARGS: --locale=C.UTF-8
+ POSTGRES_PASSWORD: postgres
+
+volumes:
+ postgres_data:
diff --git a/lib/generators/redmine_plugin_model/redmine_plugin_model_generator.rb b/lib/generators/redmine_plugin_model/redmine_plugin_model_generator.rb
index 2715a7bbe6..715e859a2d 100644
--- a/lib/generators/redmine_plugin_model/redmine_plugin_model_generator.rb
+++ b/lib/generators/redmine_plugin_model/redmine_plugin_model_generator.rb
@@ -24,7 +24,6 @@ class RedminePluginModelGenerator < Rails::Generators::NamedBase
class_option :migration, :type => :boolean, :default => true
class_option :timestamps, :type => :boolean
class_option :parent, :type => :string, :desc => "The parent class for the generated model"
- class_option :indexes, :type => :boolean, :default => true, :desc => "Add indexes for references and belongs_to columns"
attr_reader :plugin_path, :plugin_name, :plugin_pretty_name
@@ -45,13 +44,13 @@ def copy_templates
return unless options[:migration]
migration_filename = "%.14d_#{@migration_filename}.rb" % migration_number
- template "migration.rb", "#{plugin_path}/db/migrate/#{migration_filename}"
+ template "migration.rb.erb", "#{plugin_path}/db/migrate/#{migration_filename}"
end
private
def attributes_with_index
- attributes.select {|a| a.has_index? || (a.reference? && options[:indexes])}
+ attributes.select {|a| a.has_index?}
end
def migration_number
diff --git a/lib/generators/redmine_plugin_model/templates/migration.rb b/lib/generators/redmine_plugin_model/templates/migration.rb.erb
similarity index 100%
rename from lib/generators/redmine_plugin_model/templates/migration.rb
rename to lib/generators/redmine_plugin_model/templates/migration.rb.erb
diff --git a/test/generators/model_generator_test.rb b/test/generators/model_generator_test.rb
new file mode 100644
index 0000000000..42683eade5
--- /dev/null
+++ b/test/generators/model_generator_test.rb
@@ -0,0 +1,56 @@
+# frozen_string_literal: true
+
+# Redmine - project management software
+# Copyright (C) 2006-2023 Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+require_relative '../test_helper'
+require_relative '../../lib/generators/redmine_plugin_model/redmine_plugin_model_generator'
+
+class ModelGeneratorTest < Rails::Generators::TestCase
+ TMP_DIR = Rails.root / 'tmp/test/generators'
+
+ tests RedminePluginModelGenerator
+ destination TMP_DIR
+ setup :prepare_destination
+
+ setup do
+ @plugin_directory = Redmine::Plugin.directory
+ Redmine::Plugin.directory = TMP_DIR
+ end
+
+ teardown do
+ Redmine::Plugin.directory = @plugin_directory
+ end
+
+ def test_no_add_index_with_references
+ g = generator ['ModelDemo', 'SandboxModel', 'issue:references', 'project:belongs_to']
+
+ capture(:stdout) do
+ g.invoke_all
+ end
+
+ path_names = (Redmine::Plugin.directory / 'model_demo/db/migrate')
+ .glob('*_create_sandbox_models.rb')
+ assert_equal 1, path_names.count
+
+ migration = path_names.first.read
+
+ assert_match %r{t\.references :issue, foreign_key: true}, migration
+ assert_match %r{t\.belongs_to :project, foreign_key: true}, migration
+ assert_no_match %r{add_index}, path_names.first.read
+ end
+end