Compare commits

..

1 Commits

Author SHA1 Message Date
David Taylor
e1b0bb042a
Proof of concept: hinted associations 2020-11-16 12:38:33 +00:00
26366 changed files with 378468 additions and 842869 deletions

View File

@ -1,16 +0,0 @@
{
"name": "Discourse",
"image": "discourse/discourse_dev:release",
"workspaceMount": "source=${localWorkspaceFolder}/../..,target=/var/www/discourse,type=bind",
"workspaceFolder": "/var/www/discourse",
"settings": {
"search.followSymlinks": false
},
"postStartCommand": "sudo /sbin/boot",
"extensions": ["rebornix.Ruby"],
"forwardPorts": [9292],
"remoteUser": "discourse",
"remoteEnv": {
"DISCOURSE_DEV_HOSTS": ".githubpreview.dev"
}
}

View File

@ -12,6 +12,3 @@ indent_size = 2
[*.md]
trim_trailing_whitespace = false
[*.hbs]
insert_final_newline = false

View File

@ -1,15 +1,16 @@
app/assets/javascripts/env.js
app/assets/javascripts/main_include_admin.js
app/assets/javascripts/vendor.js
app/assets/javascripts/locales/i18n.js
app/assets/javascripts/ember-addons/
app/assets/javascripts/discourse/lib/autosize.js
lib/javascripts/locale/
lib/javascripts/messageformat.js
lib/javascripts/messageformat-lookup.js
lib/pretty_text/
lib/highlight_js/
plugins/**/lib/javascripts/locale
public/
vendor/
app/assets/javascripts/discourse/tests/test_helper.js
app/assets/javascripts/discourse/tests/fixtures
node_modules/
spec/
dist/
tmp/
documentation/

View File

@ -1,48 +1,17 @@
{
"extends": "eslint-config-discourse",
"rules": {
"discourse-ember/global-ember": 2,
"eol-last": 2,
"no-restricted-globals": 0
"discourse-ember/global-ember": 2
},
"globals": {
"_": "off",
"acceptance": "off",
"asyncRender": "off",
"bootbox": "off",
"click": "off",
"count": "off",
"currentPath": "off",
"currentRouteName": "off",
"currentURL": "off",
"currentUser": "off",
"Discourse": "off",
"Ember": "off",
"exists": "off",
"fillIn": "off",
"find": "off",
"getSettledState": "off",
"globalThis": "readonly",
"hasModule": "off",
"invisible": "off",
"jQuery": "off",
"keyboardHelper": "off",
"keyEvent": "off",
"moduleFor": "off",
"moduleForComponent": "off",
"pauseTest": "off",
"Pretender": "off",
"query": "off",
"queryAll": "off",
"QUnit": "off",
"sandbox": "off",
"sinon": "off",
"test": "off",
"testDone": "off",
"testStart": "off",
"triggerEvent": "off",
"testDone": "off",
"sinon": "off",
"currentURL": "off",
"invisible": "off",
"visible": "off",
"visit": "off",
"waitUntil": "off"
"count": "off",
}
}

View File

@ -45,29 +45,7 @@ bf88410126f73aab47b7e694e3c5b46453cec1b6
ce3fe2f4c4ddf166949ee3cec3d9ecbf9108ab52
# REFACTOR: Move qunit tests to a different directory structure
445d6ba45fe954fb7de11ce7b1392232160e2b63
bc97c79a35d8acd283d4d8b79aa079bce9d127c6
# REFACTOR: Move javascript tests inside discourse app
23f24bfb510edb25b18b6a0d5485270c88df9b24
# DEV: Tidy up imports. (#11364)
1c2358ba162eb9f9ba9095c9afe30cf51dd85e04
# DEV: Sort imports alphabetically (#11382)
bbe5d8d5cf1220165842985c0e2cd4c454d501cd
# DEV: Template colocation for sidebar files
95c7cdab941a56686ac5831d2a5c5eca38d780c5
# DEV: Apply prettier to hbs files
c8e2e37fa77d3c3c69c7572866017e9bb92befa3
# DEV: Apply syntax_tree to...
5a003715d366e1d871f9fcb0656dc9e23e9c2259
64171730827c58df26a7ad75f0e58f17c2add118
b0fda61a8e75c81e3458c8af9d2afe9d32183457
cb932d6ee1b3b3571e4d4d9118635e2dbf58f0ef
0cf6421716d0908da57ad7743a2decb08588b48a
7c77cc6a580d7cb49f8c19ceee8cfdd08862259d
436b3b392b9c917510d4ff0d73a5167cd3eb936c
055310cea496519a996b9c3bf4dc7e716cfe62ba

View File

@ -1,50 +1,38 @@
version: 2
updates:
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"
- package-ecosystem: bundler
directory: "/"
schedule:
interval: daily
time: "08:00"
timezone: Australia/Sydney
open-pull-requests-limit: 20
versioning-strategy: lockfile-only
allow:
- dependency-type: direct
- dependency-type: indirect
ignore:
- dependency-name: aws-partitions
versions:
- "> 1.329.0"
- "< 2"
- dependency-name: aws-sdk-core
versions:
- "> 3.99.1"
- "< 4"
- dependency-name: aws-sdk-kms
versions:
- "> 1.31.0"
- "< 2"
- dependency-name: aws-sdk-s3
versions:
- "> 1.66.0"
- "< 2"
- dependency-name: aws-sdk-sns
versions:
- "> 1.25.1"
- "< 2"
- dependency-name: aws-sigv4
versions:
- "> 1.2.0"
- "< 2"
- package-ecosystem: "npm"
directory: "/app/assets/javascripts/"
schedule:
interval: daily
time: "08:00"
timezone: Australia/Sydney
open-pull-requests-limit: 20
versioning-strategy: increase
- package-ecosystem: bundler
directory: "/"
schedule:
interval: daily
time: "08:00"
timezone: Australia/Sydney
open-pull-requests-limit: 10
versioning-strategy: lockfile-only
allow:
- dependency-type: direct
- dependency-type: indirect
ignore:
- dependency-name: aws-partitions
versions:
- "> 1.329.0"
- "< 2"
- dependency-name: aws-sdk-core
versions:
- "> 3.99.1"
- "< 4"
- dependency-name: aws-sdk-kms
versions:
- "> 1.31.0"
- "< 2"
- dependency-name: aws-sdk-s3
versions:
- "> 1.66.0"
- "< 2"
- dependency-name: aws-sdk-sns
versions:
- "> 1.25.1"
- "< 2"
- dependency-name: aws-sigv4
versions:
- "> 1.2.0"
- "< 2"

2
.github/labeler.yml vendored
View File

@ -1,2 +0,0 @@
chat:
- plugins/chat/**/*

View File

@ -1 +1 @@
<!-- NOTE: All pull requests should have tests (rspec in Ruby, qunit in JavaScript). If your code does not include test coverage, please include an explanation of why it was omitted. -->
<!-- NOTE: All pull requests should have tests (rspec in Ruby, qunit in Javascript). If your code does not include test coverage, please include an explanation of why it was omitted. -->

222
.github/workflows/ci.yml vendored Normal file
View File

@ -0,0 +1,222 @@
name: CI
on:
push:
branches:
- master
pull_request:
branches-ignore:
- "tests-passed"
jobs:
build:
name: "${{ matrix.target }}-${{ matrix.build_types }}"
runs-on: ${{ matrix.os }}
timeout-minutes: 60
env:
DISCOURSE_HOSTNAME: www.example.com
RUBY_GLOBAL_METHOD_CACHE_SIZE: 131072
BUILD_TYPE: ${{ matrix.build_types }}
TARGET: ${{ matrix.target }}
RAILS_ENV: test
PGHOST: localhost
PGUSER: discourse
PGPASSWORD: discourse
strategy:
fail-fast: false
matrix:
build_types: ["BACKEND", "FRONTEND", "LINT"]
target: ["PLUGINS", "CORE"]
os: [ubuntu-latest]
ruby: ["2.6"]
postgres: ["12"]
redis: ["4.x"]
services:
postgres:
image: postgres:${{ matrix.postgres }}
ports:
- 5432:5432
env:
POSTGRES_USER: discourse
POSTGRES_PASSWORD: discourse
POSTGRES_DB: discourse_test
options: >-
--mount type=tmpfs,destination=/var/lib/postgresql/data
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
steps:
- uses: actions/checkout@master
with:
fetch-depth: 1
- name: Setup Git
run: |
git config --global user.email "ci@ci.invalid"
git config --global user.name "Discourse CI"
- name: Setup packages
if: env.BUILD_TYPE != 'LINT'
run: |
sudo apt-get update
sudo apt-get -yqq install postgresql-client libpq-dev jpegoptim optipng jhead
wget -qO- https://raw.githubusercontent.com/discourse/discourse_docker/master/image/base/install-pngquant | sudo sh
- name: Update imagemagick
if: env.BUILD_TYPE == 'BACKEND'
run: |
wget https://raw.githubusercontent.com/discourse/discourse_docker/master/image/base/install-imagemagick
chmod +x install-imagemagick
sudo ./install-imagemagick
- name: Setup redis
uses: shogo82148/actions-setup-redis@v1
if: env.BUILD_TYPE != 'LINT'
with:
redis-version: ${{ matrix.redis }}
- name: Setup ruby
uses: actions/setup-ruby@v1
with:
ruby-version: ${{ matrix.ruby }}
- name: Setup bundler
run: |
gem install bundler -v 2.1.4 --no-doc
bundle config deployment 'true'
bundle config without 'development'
bundle config path vendor/bundle
- name: Bundler cache
uses: actions/cache@v2
id: bundler-cache
with:
path: vendor/bundle
key: ${{ runner.os }}-gem-${{ hashFiles('**/Gemfile.lock') }}
restore-keys: |
${{ runner.os }}-gem-
- name: Setup gems
run: bundle install --jobs 4
- name: Get yarn cache directory
id: yarn-cache-dir
run: echo "::set-output name=dir::$(yarn cache dir)"
- name: Yarn cache
uses: actions/cache@v2
id: yarn-cache
with:
path: ${{ steps.yarn-cache-dir.outputs.dir }}
key: ${{ runner.os }}-${{ matrix.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
restore-keys: |
${{ runner.os }}-${{ matrix.os }}-yarn-
- name: Yarn install
run: yarn install --dev
- name: "Checkout official plugins"
if: env.TARGET == 'PLUGINS'
run: bin/rake plugin:install_all_official
- name: Create database
if: env.BUILD_TYPE != 'LINT'
run: |
bin/rake db:create
bin/rake db:migrate
- name: Create parallel databases
if: env.BUILD_TYPE == 'BACKEND' && env.TARGET == 'CORE'
run: |
bin/rake parallel:create
bin/rake parallel:migrate
- name: Rubocop (core and core plugins)
if: env.BUILD_TYPE == 'LINT' && env.TARGET == 'CORE'
run: bundle exec rubocop .
- name: Rubocop (all plugins)
if: env.BUILD_TYPE == 'LINT' && env.TARGET == 'PLUGINS'
run: bundle exec rubocop plugins
- name: ESLint (core)
if: env.BUILD_TYPE == 'LINT' && env.TARGET == 'CORE'
run: yarn eslint --ext .js,.js.es6 --no-error-on-unmatched-pattern app/assets/javascripts
- name: ESLint (core plugins)
if: env.BUILD_TYPE == 'LINT' && env.TARGET == 'CORE'
run: yarn eslint --ext .js,.js.es6 --no-error-on-unmatched-pattern plugins/**/{test,assets}/javascripts
- name: ESLint (all plugins)
if: env.BUILD_TYPE == 'LINT' && env.TARGET == 'PLUGINS'
run: yarn eslint --ext .js,.js.es6 --no-error-on-unmatched-pattern plugins/**/{test,assets}/javascripts
- name: Prettier (core and core plugins)
if: env.BUILD_TYPE == 'LINT' && env.TARGET == 'CORE'
run: |
yarn prettier -v
yarn prettier --list-different \
"app/assets/stylesheets/**/*.scss" \
"app/assets/javascripts/**/*.{js,es6}" \
"plugins/**/assets/stylesheets/**/*.scss" \
"plugins/**/assets/javascripts/**/*.{js,es6}"
- name: Prettier (all plugins)
if: env.BUILD_TYPE == 'LINT' && env.TARGET == 'PLUGINS'
run: |
yarn prettier -v
yarn prettier --list-different \
"plugins/**/assets/stylesheets/**/*.scss" \
"plugins/**/assets/javascripts/**/*.{js,es6}"
- name: Ember template lint (core and core plugins)
if: env.BUILD_TYPE == 'LINT' && env.TARGET == 'CORE'
run: |
yarn ember-template-lint \
app/assets/javascripts \
plugins/**/assets/javascripts
- name: Ember template lint (all plugins)
if: env.BUILD_TYPE == 'LINT' && env.TARGET == 'PLUGINS'
run: |
yarn ember-template-lint \
plugins/**/assets/javascripts
- name: Core English locale
if: env.BUILD_TYPE == 'LINT' && env.TARGET == 'CORE'
run: bundle exec ruby script/i18n_lint.rb "config/**/locales/{client,server}.en.yml"
- name: Plugin English locale
if: env.BUILD_TYPE == 'LINT' && env.TARGET == 'PLUGINS'
run: bundle exec ruby script/i18n_lint.rb "plugins/**/locales/{client,server}.en.yml"
- name: Core RSpec
if: env.BUILD_TYPE == 'BACKEND' && env.TARGET == 'CORE'
run: |
bin/turbo_rspec
bin/rake plugin:spec
- name: Plugin RSpec
if: env.BUILD_TYPE == 'BACKEND' && env.TARGET == 'PLUGINS'
run: bin/rake plugin:spec
- name: Core QUnit
if: env.BUILD_TYPE == 'FRONTEND' && env.TARGET == 'CORE'
run: bundle exec rake qunit:test['1200000']
timeout-minutes: 30
- name: Wizard QUnit
if: env.BUILD_TYPE == 'FRONTEND' && env.TARGET == 'CORE'
run: bundle exec rake qunit:test['1200000','/wizard/qunit']
timeout-minutes: 30
- name: Plugin QUnit # Tests core plugins in TARGET=CORE, and all plugins in TARGET=PLUGINS
if: env.BUILD_TYPE == 'FRONTEND'
run: bundle exec rake plugin:qunit['*','1200000']
timeout-minutes: 30

View File

@ -1,14 +0,0 @@
name: "Pull Request Labeler"
on:
- pull_request_target
jobs:
triage:
permissions:
contents: read
pull-requests: write
runs-on: ubuntu-latest
steps:
- uses: actions/labeler@v4
with:
repo-token: "${{ secrets.GITHUB_TOKEN }}"

View File

@ -1,87 +0,0 @@
name: Licenses
on:
pull_request:
push:
branches:
- main
concurrency:
group: licenses-${{ format('{0}-{1}', github.head_ref || github.run_number, github.job) }}
cancel-in-progress: true
permissions:
contents: read
jobs:
build:
if: "!(github.event_name == 'push' && github.repository == 'discourse/discourse-private-mirror')"
name: run
runs-on: ubuntu-latest
container: discourse/discourse_test:slim
timeout-minutes: 10
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 1
- name: Setup Git
run: |
git config --global user.email "ci@ci.invalid"
git config --global user.name "Discourse CI"
- name: Bundler cache
uses: actions/cache@v3
with:
path: vendor/bundle
key: ${{ runner.os }}-gem-${{ hashFiles('**/Gemfile.lock') }}
restore-keys: |
${{ runner.os }}-gem-
- name: Setup gems
run: |
bundle config --local path vendor/bundle
bundle config --local deployment true
bundle config --local without development
bundle install --jobs 4
bundle clean
- name: Setup licensed
run: |
gem install licensed
- name: Get yarn cache directory
id: yarn-cache-dir
run: echo "dir=$(yarn cache dir)" >> $GITHUB_OUTPUT
- name: Yarn cache
uses: actions/cache@v3
id: yarn-cache
with:
path: ${{ steps.yarn-cache-dir.outputs.dir }}
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
restore-keys: |
${{ runner.os }}-yarn-
- name: Check RubyGems Licenses
if: ${{ !cancelled() }}
run: |
licensed cache
licensed status
- name: Yarn install
run: yarn install
- name: Check Yarn Licenses
if: ${{ !cancelled() }}
run: |
yarn global add licensee
yarn global upgrade licensee
licensee --errors-only
- name: Check Ember CLI Workspace Licenses
if: ${{ !cancelled() }}
working-directory: ./app/assets/javascripts
run: |
licensee --errors-only

View File

@ -1,114 +0,0 @@
name: Linting
on:
pull_request:
push:
branches:
- main
concurrency:
group: linting-${{ format('{0}-{1}', github.head_ref || github.run_number, github.job) }}
cancel-in-progress: true
permissions:
contents: read
jobs:
build:
if: "!(github.event_name == 'push' && github.repository == 'discourse/discourse-private-mirror')"
name: run
runs-on: ubuntu-latest
container: discourse/discourse_test:slim
timeout-minutes: 30
steps:
- name: Set working directory owner
run: chown root:root .
- uses: actions/checkout@v3
with:
fetch-depth: 1
- name: Setup Git
run: |
git config --global user.email "ci@ci.invalid"
git config --global user.name "Discourse CI"
- name: Bundler cache
uses: actions/cache@v3
with:
path: vendor/bundle
key: ${{ runner.os }}-gem-${{ hashFiles('**/Gemfile.lock') }}
restore-keys: |
${{ runner.os }}-gem-
- name: Setup gems
run: |
gem install bundler --conservative -v $(awk '/BUNDLED WITH/ { getline; gsub(/ /,""); print $0 }' Gemfile.lock)
bundle config --local path vendor/bundle
bundle config --local deployment true
bundle config --local without development
bundle install --jobs 4
bundle clean
- name: Get yarn cache directory
id: yarn-cache-dir
run: echo "dir=$(yarn cache dir)" >> $GITHUB_OUTPUT
- name: Yarn cache
uses: actions/cache@v3
id: yarn-cache
with:
path: ${{ steps.yarn-cache-dir.outputs.dir }}
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
restore-keys: |
${{ runner.os }}-yarn-
- name: Yarn install
run: yarn install
- name: Rubocop
if: ${{ !cancelled() }}
run: bundle exec rubocop --parallel .
- name: syntax_tree
if: ${{ !cancelled() }}
run: |
set -E
bundle exec stree check Gemfile $(git ls-files '*.rb') $(git ls-files '*.rake')
- name: ESLint (core)
if: ${{ !cancelled() }}
run: yarn eslint app/assets/javascripts
- name: ESLint (core plugins)
if: ${{ !cancelled() }}
run: yarn eslint plugins
- name: Prettier
if: ${{ !cancelled() }}
run: |
yarn prettier -v
yarn pprettier --list-different \
"app/assets/stylesheets/**/*.scss" \
"app/assets/javascripts/**/*.js" \
"app/assets/javascripts/**/*.hbs" \
"plugins/**/assets/stylesheets/**/*.scss" \
"plugins/**/assets/javascripts/**/*.js" \
"plugins/**/assets/javascripts/**/*.hbs" \
- name: Ember template lint
if: ${{ !cancelled() }}
run: |
yarn ember-template-lint \
--no-error-on-unmatched-pattern \
"app/assets/javascripts/**/*.hbs" \
"plugins/**/assets/javascripts/**/*.hbs"
- name: English locale lint (core)
if: ${{ !cancelled() }}
run: bundle exec ruby script/i18n_lint.rb "config/**/locales/{client,server}.en.yml"
- name: English locale lint (core plugins)
if: ${{ !cancelled() }}
run: bundle exec ruby script/i18n_lint.rb "plugins/**/locales/{client,server}.en.yml"

View File

@ -1,292 +0,0 @@
name: Tests
on:
pull_request:
push:
branches:
- main
- beta
- stable
concurrency:
group: tests-${{ format('{0}-{1}', github.head_ref || github.run_number, github.job) }}
cancel-in-progress: true
permissions:
contents: read
jobs:
build:
if: "!(github.event_name == 'push' && github.repository == 'discourse/discourse-private-mirror')"
name: ${{ matrix.target }} ${{ matrix.build_type }} ${{ matrix.ruby }}
runs-on: ${{ (matrix.build_type == 'annotations') && 'ubuntu-latest' || 'ubuntu-20.04-8core' }}
container: discourse/discourse_test:slim${{ (matrix.build_type == 'frontend' || matrix.build_type == 'system') && '-browsers' || '' }}${{ (matrix.ruby == '3.1') && '-ruby-3.1.0' || '' }}
timeout-minutes: 20
env:
DISCOURSE_HOSTNAME: www.example.com
RUBY_GLOBAL_METHOD_CACHE_SIZE: 131072
RAILS_ENV: test
PGUSER: discourse
PGPASSWORD: discourse
USES_PARALLEL_DATABASES: ${{ matrix.build_type == 'backend' || matrix.build_type == 'system' }}
CAPBYARA_DEFAULT_MAX_WAIT_TIME: 4
strategy:
fail-fast: false
matrix:
build_type: [backend, frontend, system, annotations]
target: [core, plugins]
ruby: ['3.2']
exclude:
- build_type: annotations
target: plugins
- build_type: frontend
target: core # Handled by core_frontend_tests job (below)
steps:
- name: Set working directory owner
run: chown root:root .
- uses: actions/checkout@v3
with:
fetch-depth: 1
- name: Setup Git
run: |
git config --global user.email "ci@ci.invalid"
git config --global user.name "Discourse CI"
- name: Start redis
run: |
redis-server /etc/redis/redis.conf &
- name: Start Postgres
run: |
chown -R postgres /var/run/postgresql
sudo -E -u postgres script/start_test_db.rb
sudo -u postgres psql -c "CREATE ROLE $PGUSER LOGIN SUPERUSER PASSWORD '$PGPASSWORD';"
- name: Bundler cache
uses: actions/cache@v3
with:
path: vendor/bundle
key: ${{ runner.os }}-${{ matrix.ruby }}-gem-${{ hashFiles('**/Gemfile.lock') }}
restore-keys: |
${{ runner.os }}-${{ matrix.ruby }}-gem-
- name: Setup gems
run: |
gem install bundler --conservative -v $(awk '/BUNDLED WITH/ { getline; gsub(/ /,""); print $0 }' Gemfile.lock)
bundle config --local path vendor/bundle
bundle config --local deployment true
bundle config --local without development
bundle install --jobs 4
bundle clean
- name: Get yarn cache directory
id: yarn-cache-dir
run: echo "dir=$(yarn cache dir)" >> $GITHUB_OUTPUT
- name: Yarn cache
uses: actions/cache@v3
id: yarn-cache
with:
path: ${{ steps.yarn-cache-dir.outputs.dir }}
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
restore-keys: |
${{ runner.os }}-yarn-
- name: Yarn install
run: yarn install
- name: Checkout official plugins
if: matrix.target == 'plugins'
run: bin/rake plugin:install_all_official
- name: Pull compatible versions of plugins
if: matrix.target == 'plugins'
run: bin/rake plugin:pull_compatible_all
- name: Fetch app state cache
uses: actions/cache@v3
id: app-cache
with:
path: tmp/app-cache
key: >- # postgres version, hash of migrations, "parallel?"
${{ runner.os }}-
${{ hashFiles('.github/workflows/tests.yml') }}-
${{ matrix.postgres }}-
${{ hashFiles('db/**/*', 'plugins/**/db/**/*') }}-
${{ env.USES_PARALLEL_DATABASES }}
- name: Restore database from cache
if: steps.app-cache.outputs.cache-hit == 'true'
run: psql -f tmp/app-cache/cache.sql postgres
- name: Restore uploads from cache
if: steps.app-cache.outputs.cache-hit == 'true'
run: rm -rf public/uploads && cp -r tmp/app-cache/uploads public/uploads
- name: Create and migrate database
if: steps.app-cache.outputs.cache-hit != 'true'
run: |
bin/rake db:create
bin/rake db:migrate
- name: Create and migrate parallel databases
if: >-
env.USES_PARALLEL_DATABASES == 'true' &&
steps.app-cache.outputs.cache-hit != 'true'
run: |
bin/rake parallel:create
bin/rake parallel:migrate
- name: Dump database for cache
if: steps.app-cache.outputs.cache-hit != 'true'
run: mkdir -p tmp/app-cache && pg_dumpall > tmp/app-cache/cache.sql
- name: Dump uploads for cache
if: steps.app-cache.outputs.cache-hit != 'true'
run: rm -rf tmp/app-cache/uploads && cp -r public/uploads tmp/app-cache/uploads
- name: Fetch turbo_rspec_runtime.log cache
uses: actions/cache@v3
id: test-runtime-cache
if: matrix.build_type == 'backend' && matrix.target == 'core'
with:
path: tmp/turbo_rspec_runtime.log
key: rspec-runtime-backend-core
- name: Run Zeitwerk check
if: matrix.build_type == 'backend'
env:
LOAD_PLUGINS: ${{ (matrix.target == 'plugins') && '1' || '0' }}
run: |
if ! bin/rails zeitwerk:check --trace; then
echo
echo "---------------------------------------------"
echo
echo "::error::'bin/rails zeitwerk:check' failed - the app will fail to boot with 'eager_load=true' (e.g. in production)."
echo "To reproduce locally, run 'bin/rails zeitwerk:check'."
echo "Alternatively, you can run your local server/tests with the 'DISCOURSE_ZEITWERK_EAGER_LOAD=1' environment variable."
echo
exit 1
fi
- name: Core RSpec
if: matrix.build_type == 'backend' && matrix.target == 'core'
run: bin/turbo_rspec --verbose
- name: Plugin RSpec
if: matrix.build_type == 'backend' && matrix.target == 'plugins'
run: bin/rake plugin:turbo_spec
- name: Plugin QUnit
if: matrix.build_type == 'frontend' && matrix.target == 'plugins'
run: QUNIT_PARALLEL=3 bin/rake plugin:qunit['*','1200000']
timeout-minutes: 30
- name: Ember Build for System Tests
if: matrix.build_type == 'system'
run: bin/ember-cli --build
- name: Setup Webdriver
if: matrix.build_type == 'system'
run: bin/rails runner "require 'webdrivers'; Webdrivers::Chromedriver.update"
- name: Core System Tests
if: matrix.build_type == 'system' && matrix.target == 'core'
run: bin/rspec spec/system
- name: Plugin System Tests
if: matrix.build_type == 'system' && matrix.target == 'plugins'
run: LOAD_PLUGINS=1 bin/rspec plugins/*/spec/system
- name: Upload failed system test screenshots
uses: actions/upload-artifact@v3
if: matrix.build_type == 'system' && failure()
with:
name: failed-system-test-screenshots
path: tmp/capybara/*.png
- name: Check Annotations
if: matrix.build_type == 'annotations'
run: |
bin/rake annotate:ensure_all_indexes
bin/annotate --models --model-dir app/models
if [ ! -z "$(git status --porcelain app/models/)" ]; then
echo "Core annotations are not up to date. To resolve, run:"
echo " bin/rake annotate:clean"
echo
echo "Or manually apply the diff printed below:"
echo "---------------------------------------------"
git -c color.ui=always diff app/models/
exit 1
fi
timeout-minutes: 30
core_frontend_tests:
if: "!(github.event_name == 'push' && github.repository == 'discourse/discourse-private-mirror')"
name: core frontend (${{ matrix.browser }})
runs-on: ubuntu-20.04-8core
container:
image: discourse/discourse_test:slim-browsers
options: --user discourse
timeout-minutes: 35
strategy:
fail-fast: false
matrix:
browser: ["Chrome", "Firefox ESR", "Firefox Evergreen"]
env:
TESTEM_BROWSER: ${{ (startsWith(matrix.browser, 'Firefox') && 'Firefox') || matrix.browser }}
TESTEM_FIREFOX_PATH: ${{ (matrix.browser == 'Firefox Evergreen') && '/opt/firefox-evergreen/firefox' }}
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 1
- name: Setup Git
run: |
git config --global user.email "ci@ci.invalid"
git config --global user.name "Discourse CI"
- name: Get yarn cache directory
id: yarn-cache-dir
run: echo "dir=$(yarn cache dir)" >> $GITHUB_OUTPUT
- name: Yarn cache
uses: actions/cache@v3
id: yarn-cache
with:
path: ${{ steps.yarn-cache-dir.outputs.dir }}
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
restore-keys: |
${{ runner.os }}-yarn-
- name: Yarn install
working-directory: ./app/assets/javascripts/discourse
run: yarn install
- name: Ember Build
working-directory: ./app/assets/javascripts/discourse
run: |
mkdir /tmp/emberbuild
yarn ember build --environment=test -o /tmp/emberbuild
- name: Core QUnit
working-directory: ./app/assets/javascripts/discourse
run: yarn ember exam --path /tmp/emberbuild --load-balance --parallel=5 --launch "${{ env.TESTEM_BROWSER }}" --write-execution-file --random
timeout-minutes: 15
- uses: actions/upload-artifact@v3
if: ${{ always() }}
with:
name: ember-exam-execution-${{matrix.browser}}
path: ./app/assets/javascripts/discourse/test-execution-*.json

158
.gitignore vendored
View File

@ -1,27 +1,33 @@
/copyright
/coverage
/data
/log
/tmp
# See http://help.github.com/ignore-files/ for more about ignoring files.
#
# If you find yourself ignoring temporary files generated by your text editor
# or operating system, you probably want to add a global ignore instead:
# git config --global core.excludesfile ~/.gitignore_global
.DS_Store
._.DS_Store
dump.rdb
bin/*
data/
.sass-cache/*
public/csv/*
public/plugins/*
public/tombstone/*
# Ignore bundler config
/.bundle
/.env
/.procfile
/dump.rdb
/cache
/coverage/*
/config/discourse.conf
/config/discourse.pill
/config/multisite.yml
# `discourse_dev` gem
/config/dev.yml
/public/assets/*
/public/tombstone/*
/bundle/*
/public/assets
/public/backups
/public/csv
/public/fonts
/public/plugins
/public/tombstone
/public/uploads
config/discourse.pill
config/discourse.conf
# Ignore the default SQLite database and db dumps
*.sql
@ -30,39 +36,117 @@
/db/*.sqlite3
/db/structure.sql
/db/schema.rb
/db/schema_cache.yml
# Plugins except for the bundled ones
# Ignore all logfiles and tempfiles.
/log/*.log
/tmp
/logfile
log/
bootsnap-load-path-cache
bootsnap-compile-cache/
# Ignore plugins except for the bundled ones.
/plugins/*
!/plugins/lazy-yt/
!/plugins/poll/
!/plugins/discourse-details/
!/plugins/discourse-local-dates
!/plugins/discourse-nginx-performance-report
!/plugins/discourse-narrative-bot
!/plugins/discourse-presence
!/plugins/lazy-yt/
!/plugins/chat/
!/plugins/poll/
!/plugins/styleguide
!/plugins/discourse-local-dates
/plugins/*/auto_generated/
/spec/fixtures/plugins/my_plugin/auto_generated
/vendor/bundle/*
/vendor/data/GeoLite2-City.mmdb
/vendor/data/GeoLite2-ASN.mmdb
# Ignore Eclipse .project file
/.project
# We provide a .sample but people can use newer versions if they want to
# Ignore Eclipse .buildpath file
/.buildpath
# Ignore byebug history
/.byebug_history
# Ignore RubyMine settings
/.idea
# Ignore gem that is copied in
MiniProfiler/Ruby/rack-mini-profiler-2.0.1a.gem
discourse.sublime-workspace
# Vim temp files
*~
*.swp
*.swo
*.swm
# don't check in multisite config
config/multisite.yml
# don't check in my renamed multisite config as well :)
config/multisite1.yml
config/fog_credentials.yml
/public/fonts
/public/uploads
/public/backups
/public/stylesheet-cache/*
# Scripts used for downloading/refreshing db
script/download_db
script/refresh_db
# .procfile
.procfile
# .env, local environment variables for use with foreman
.env
# exclude our git version file for now
config/version.rb
# ignore the Ruby Version manager (rvm)
.rvmrc
.ruby-version
.ruby-gemset
.rbenv
bundler_stubs/*
# Front-end
dist
vendor/bundle/*
*.db
# ignore jetbrains ide file
*.iml
# vim swap
*.swn
# ignore nodejs files
node_modules
yarn-error.log
/package-lock.json
# Auto-generated plugin JS assets
/vendor/data/GeoLite2-City.mmdb
# Vagrant
.vagrant
# ignore auto-generated plugin js assets
/app/assets/javascripts/plugins/*
# Generated API documentation files
# ignore generated api documentation files
openapi/*
# Cached License Data Files
/.licenses
# ignore VSCode config files
.vscode
# ignore direnv
.envrc
# ember-cli generated
dist
# Copyright Deposits
copyright
yarn-error.log

21
.jsdoc
View File

@ -1,21 +0,0 @@
// jsdoc doesn't accept paths starting with _ (which is the case on github runners)
// so we need to alter the default config
{
"source": {
"excludePattern": ""
},
"templates": {
"default": {
"includeDate": false
}
},
"opts": {
"template": "./node_modules/tidy-jsdoc",
"prism-theme": "prism-custom",
"encoding": "utf8",
"recurse": true
},
"metadata": {
"title": "Discourse"
}
}

View File

@ -1,62 +1,12 @@
sources:
yarn: true
bundler: true
allowed:
- 0bsd
- mit
- apache-2.0
- bsd-2-clause
- bsd-3-clause
- cc0-1.0
- isc
- mit
- ruby
ignored:
bundler:
- cgi # Ruby (default gem)
- date # Ruby (default gem)
- digest # Ruby (default gem)
- io-wait # Ruby (default gem)
- json # Ruby (default gem)
- net-http # Ruby (default gem)
- net-protocol # Ruby (default gem)
- openssl # Ruby (default gem)
- racc # Ruby (default gem)
- rchardet # LGPL
- ruby2_keywords # Ruby (default gem)
- strscan # Ruby (default gem)
- timeout # Ruby (default gem)
- uri # Ruby (default gem)
reviewed:
bundler:
- activerecord # MIT
- coderay # MIT
- concurrent-ruby # MIT
- css_parser # MIT
- excon # MIT
- faraday-em_http # MIT
- faraday-em_synchrony # MIT
- faraday-excon # MIT
- faraday-httpclient # MIT
- faraday-net_http # MIT
- faraday-patron # MIT
- faraday-rack # MIT
- highline # Ruby or GPL-2.0
- htmlentities # MIT
- image_size # MIT
- jwt # MIT
- kgio # LGPL-2.1+
- logstash-event # Apache-2.0
- net-imap # Ruby (bundled gem)
- net-pop # Ruby (bundled gem)
- net-smtp # Ruby (bundled gem)
- omniauth # MIT
- pg # Ruby
- r2 # Apache-2.0 (Twitter)
- raindrops # LGPL-2.1+
- rubyzip # Ruby
- sidekiq # LGPL (Sidekiq)
- tilt # MIT
- unf # BSD-2-Clause
- unicorn # Ruby or GPLv2/GPLv3
- other
- none

View File

@ -1,18 +0,0 @@
{
"licenses": {
"blueOak": "bronze",
"spdx": [
"CC0-1.0",
"CC-BY-3.0",
"CC-BY-4.0",
"Apache-2.0 WITH LLVM-exception"
]
},
"packages": {
"@fortawesome/fontawesome-free": "*",
"ember-template-lint-plugin-discourse": "*",
"squoosh": "2.0.0",
"taffydb": "2.6.2"
},
"corrections": true
}

1
.npmrc
View File

@ -1 +0,0 @@
engine-strict = true

View File

@ -1,15 +1,14 @@
app/assets/stylesheets/vendor/
plugins/**/assets/stylesheets/vendor/
plugins/**/assets/javascripts/vendor/
plugins/**/config/locales/**/*.yml
plugins/**/config/*.yml
documentation/
package.json
config/locales/**/*.yml
!config/locales/**/*.en*.yml
script/import_scripts/**/*.yml
app/assets/javascripts/browser-update.js
app/assets/javascripts/env.js
app/assets/javascripts/main_include_admin.js
app/assets/javascripts/vendor.js
app/assets/javascripts/locales/i18n.js
app/assets/javascripts/ember-addons/
app/assets/javascripts/discourse/lib/autosize.js
@ -18,15 +17,9 @@ lib/javascripts/messageformat.js
lib/highlight_js/
plugins/**/lib/javascripts/locale
public/
!/app/assets/javascripts/discourse/public
vendor/
app/assets/javascripts/discourse/tests/test_helper.js
app/assets/javascripts/discourse/tests/fixtures
spec/
node_modules/
dist/
tmp/
**/*.rb
**/*.html
**/*.json
**/*.md

2
.rspec
View File

@ -1 +1 @@
--require 'rails_helper'
--colour

View File

@ -1,5 +1,5 @@
inherit_gem:
rubocop-discourse: stree-compat.yml
rubocop-discourse: default.yml
# Still work to do in ensuring we don't link old files
Discourse/NoAddReferenceOrAliasesActiveRecordMigration:
@ -7,7 +7,3 @@ Discourse/NoAddReferenceOrAliasesActiveRecordMigration:
Discourse/NoResetColumnInformationInMigrations:
Enabled: true
Lint/Debugger:
Exclude:
- script/**/*

View File

@ -1 +1 @@
3.2.1
2.6.5

View File

@ -1,2 +0,0 @@
--print-width=100
--plugins=plugin/trailing_comma,disable_ternary

View File

@ -1,31 +1,55 @@
module.exports = {
plugins: ["ember-template-lint-plugin-discourse"],
extends: "discourse:recommended",
extends: "recommended",
ignore: ["**/*.raw"],
// Pending:
// "eol-last": "always",
rules: {
"no-action-modifiers": true,
"block-indentation": true,
"deprecated-render-helper": true,
"linebreak-style": true,
"link-rel-noopener": "strict",
"no-abstract-roles": true,
"no-args-paths": true,
"no-attrs-in-components": true,
"no-capital-arguments": false, // TODO: we extensively use `args` argument name
"no-curly-component-invocation": {
allow: [
// These are helpers, not components
"directory-item-header-title",
"directory-item-user-field-value",
"directory-item-value",
"directory-table-header-title",
"loading-spinner",
"directory-item-label",
],
},
"no-implicit-this": {
allow: ["loading-spinner"],
},
// Begin prettier compatibility
"eol-last": false,
"self-closing-void-elements": false,
"block-indentation": false,
quotes: false,
// End prettier compatibility
"no-debugger": true,
"no-duplicate-attributes": true,
"no-extra-mut-helper-argument": true,
"no-html-comments": true,
"no-index-component-invocation": true,
"no-inline-styles": false,
"no-input-block": true,
"no-input-tagname": true,
"no-implicit-this": false,
"no-invalid-interactive": true,
"no-invalid-link-text": true,
"no-invalid-meta": true,
"no-invalid-role": true,
"no-log": true,
"no-negated-condition": true,
"no-nested-interactive": true,
"no-multiple-empty-lines": true,
"no-obsolete-elements": true,
"no-outlet-outside-routes": true,
"no-partial": true,
"no-positive-tabindex": false,
"no-quoteless-attributes": true,
"no-shadowed-elements": true,
"no-trailing-spaces": true,
"no-triple-curlies": true,
"no-unbound": true,
"no-unnecessary-concat": true,
"no-unnecessary-component-helper": true,
"no-unused-block-params": true,
quotes: "double",
"require-button-type": true,
"require-iframe-title": true,
"require-valid-alt-text": false,
"self-closing-void-elements": true,
"simple-unless": true,
"style-concatenation": true,
"table-groups": true,
"link-href-attributes": false,
},
};

View File

@ -1,19 +0,0 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Discourse",
"type": "Ruby",
"request": "launch",
"cwd": "/home/discourse/workspace/discourse",
// run bundle install before rails server
"preLaunchTask": "Prepare discourse",
"env": { "DISCOURSE_DEV_HOSTS": "${env:CLOUDENV_ENVIRONMENT_ID}-9292.apps.codespaces.githubusercontent.com", "UNICORN_BIND_ALL": "1", "UNICORN_WORKERS": "4", "DISCOURSE_DEV_ALLOW_ANON_TO_IMPERSONATE": "1" },
"program": "bin/unicorn",
"args": ["-x"],
}
]
}

View File

@ -1,12 +0,0 @@
{
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "2.0.0",
"tasks": [
{
"label": "Prepare discourse",
"type": "shell",
"command": "cd /home/discourse/workspace/discourse && bundle install && yarn && bin/rake db:migrate"
},
],
}

View File

@ -1,59 +0,0 @@
# Legal notice
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 as the file LICENSE.txt; if not, please see
http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
## Trademark
Discourse is a registered trademark of Civilized Discourse Construction Kit.
## Other copyright notices
Discourse includes works under other copyright notices and distributed
according to the terms of the GNU General Public License or a compatible
license (where indicated), including:
- Ember.js - Copyright (c) 2020 Yehuda Katz, Tom Dale and Ember.js contributors
MIT License
- jQuery - Copyright OpenJS Foundation and other contributors, https://openjsf.org/
MIT License
- Rails - Copyright (c) 2005-2021 David Heinemeier Hansson
MIT License
- Onebox - Copyright (c) 2013 jzeta
MIT License
MIT License:
```
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
```

31
COPYRIGHT.txt Normal file
View File

@ -0,0 +1,31 @@
All Discourse code is Copyright 2013 by Civilized Discourse Construction Kit, Inc.
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 as the file LICENSE.txt; if not, please see
http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
Discourse is a registered trademark of Civilized Discourse Construction Kit.
Discourse includes works under other copyright notices and distributed
according to the terms of the GNU General Public License or a compatible
license (where indicated), including:
Javascript
Ember.js - Copyright (c) 2012-2013 Yehuda Katz, Tom Dale, Charles Jolley and Ember.js contributors
jQuery - Copyright (c) 2010-2013 John Resig
Ruby
Rails - Copyright (c) 2005-2013 David Heinemeier Hansson, Rails Core Team contributors (MIT)

73
Dangerfile Normal file
View File

@ -0,0 +1,73 @@
# frozen_string_literal: true
if github.pr_json && (github.pr_json["additions"] || 0) > 250 || (github.pr_json["deletions"] || 0) > 250
warn("This pull request is big! We prefer smaller PRs whenever possible, as they are easier to review. Can this be split into a few smaller PRs?")
end
prettier_offenses = `yarn --silent prettier --list-different "app/assets/stylesheets/**/*.scss" "app/assets/javascripts/**/*.js" "app/assets/javascripts/**/*.es6" "test/javascripts/**/*.es6"`.split("\n")
unless prettier_offenses.empty?
fail(%{
This PR doesn't match our required code formatting standards, as enforced by prettier.io. <a href='https://meta.discourse.org/t/prettier-code-formatting-tool/93212'>Here's how to set up prettier in your code editor.</a>\n
#{prettier_offenses.map { |o| github.html_link(o) }.join("\n")}
})
end
locales_changes = git.modified_files.grep(%r{config/locales})
has_non_en_locales_changes = locales_changes.grep_v(%r{config/locales/(?:client|server)\.(?:en|en_US)\.yml}).any?
if locales_changes.any? && has_non_en_locales_changes
fail("Please submit your non-English translation updates via [Crowdin](https://translate.discourse.org/). You can read more on how to contribute translations [here](https://meta.discourse.org/t/contribute-a-translation-to-discourse/14882).")
end
files = (git.added_files + git.modified_files)
.select { |path| !path.start_with?("plugins/") }
.select { |path| path.end_with?("es6") || path.end_with?("js") || path.end_with?("rb") }
js_files = files.select { |path| path.end_with?(".js.es6") || path.end_with?(".js") }
js_test_files = js_files.select { |path| path.end_with?("-test.js.es6") }
super_offenses = []
self_offenses = []
js_files.each do |path|
diff = git.diff_for_file(path)
next if !diff
diff.patch.lines.grep(/^\+\s\s/).each do |added_line|
super_offenses << path if added_line['this._super()']
self_offenses << path if added_line[/(?:(^|\W)self\.?)/]
end
end
jquery_find_offenses = []
js_test_files.each do |path|
diff = git.diff_for_file(path)
next if !diff
diff.patch.lines.grep(/^\+\s\s/).each do |added_line|
jquery_find_offenses << path if added_line['this.$(']
end
end
if !self_offenses.empty?
warn(%{
Use fat arrow instead of self pattern.\n
#{self_offenses.uniq.map { |o| github.html_link(o) }.join("\n")}
})
end
if !super_offenses.empty?
warn(%{
When possible use `this._super(...arguments)` instead of `this._super()`\n
#{super_offenses.uniq.map { |o| github.html_link(o) }.join("\n")}
})
end
if !jquery_find_offenses.empty?
warn(%{
Use `find()` instead of `this.$` in js tests`\n
#{jquery_find_offenses.uniq.map { |o| github.html_link(o) }.join("\n")}
})
end

313
Gemfile
View File

@ -1,51 +1,50 @@
# frozen_string_literal: true
source "https://rubygems.org"
source 'https://rubygems.org'
# if there is a super emergency and rubygems is playing up, try
#source 'http://production.cf.rubygems.org'
gem "bootsnap", require: false, platform: :mri
gem 'bootsnap', require: false, platform: :mri
def rails_master?
ENV["RAILS_MASTER"] == "1"
ENV["RAILS_MASTER"] == '1'
end
if rails_master?
gem "arel", git: "https://github.com/rails/arel.git"
gem "rails", git: "https://github.com/rails/rails.git"
gem 'arel', git: 'https://github.com/rails/arel.git'
gem 'rails', git: 'https://github.com/rails/rails.git'
else
# NOTE: Until rubygems gives us optional dependencies we are stuck with this needing to be explicit
# this allows us to include the bits of rails we use without pieces we do not.
#
# To issue a rails update bump the version number here
rails_version = "7.0.4.3"
gem "actionmailer", rails_version
gem "actionpack", rails_version
gem "actionview", rails_version
gem "activemodel", rails_version
gem "activerecord", rails_version
gem "activesupport", rails_version
gem "railties", rails_version
gem "sprockets-rails"
gem 'actionmailer', '6.0.3.3'
gem 'actionpack', '6.0.3.3'
gem 'actionview', '6.0.3.3'
gem 'activemodel', '6.0.3.3'
gem 'activerecord', '6.0.3.3'
gem 'activesupport', '6.0.3.3'
gem 'railties', '6.0.3.3'
gem 'sprockets-rails'
end
gem "json"
gem 'json'
# TODO: At the moment Discourse does not work with Sprockets 4, we would need to correct internals
# We intend to drop sprockets rather than upgrade to 4.x
gem "sprockets", git: "https://github.com/rails/sprockets", branch: "3.x"
# This is a desired upgrade we should get to.
gem 'sprockets', '3.7.2'
# this will eventually be added to rails,
# allows us to precompile all our templates in the unicorn master
gem "actionview_precompiler", require: false
gem 'actionview_precompiler', require: false
gem "discourse-seed-fu"
gem 'seed-fu'
gem "mail", git: "https://github.com/discourse/mail.git"
gem "mini_mime"
gem "mini_suffix"
gem 'mail', require: false
gem 'mini_mime'
gem 'mini_suffix'
gem "redis"
gem 'redis'
# This is explicitly used by Sidekiq and is an optional dependency.
# We tell Sidekiq to use the namespace "sidekiq" which triggers this
@ -53,231 +52,197 @@ gem "redis"
# redis namespace support is optional
# We already namespace stuff in DiscourseRedis, so we should consider
# just using a single implementation in core vs having 2 namespace implementations
gem "redis-namespace"
gem 'redis-namespace'
# NOTE: AM serializer gets a lot slower with recent updates
# we used an old branch which is the fastest one out there
# are long term goal here is to fork this gem so we have a
# better maintained living fork
gem "active_model_serializers", "~> 0.8.3"
gem 'active_model_serializers', '~> 0.8.3'
gem "http_accept_language", require: false
gem 'onebox'
gem "discourse-fonts", require: "discourse_fonts"
gem 'http_accept_language', require: false
gem "message_bus"
# Ember related gems need to be pinned cause they control client side
# behavior, we will push these versions up when upgrading ember
gem 'discourse-ember-rails', '0.18.6', require: 'ember-rails'
gem 'discourse-ember-source', '~> 3.12.2'
gem 'ember-handlebars-template', '0.8.0'
gem 'discourse-fonts'
gem "rails_multisite"
gem 'barber'
gem "fast_xs", platform: :ruby
gem 'message_bus'
gem "xorcist"
gem 'rails_multisite'
gem "fastimage"
gem 'fast_xs', platform: :ruby
gem "aws-sdk-s3", require: false
gem "aws-sdk-sns", require: false
gem "excon", require: false
gem "unf", require: false
gem 'xorcist'
gem "email_reply_trimmer"
gem 'fastimage'
gem "image_optim"
gem "multi_json"
gem "mustache"
gem "nokogiri"
gem "loofah"
gem "css_parser", require: false
gem 'aws-sdk-s3', require: false
gem 'aws-sdk-sns', require: false
gem 'excon', require: false
gem 'unf', require: false
gem "omniauth"
gem "omniauth-facebook"
gem "omniauth-twitter"
gem "omniauth-github"
gem 'email_reply_trimmer'
gem "omniauth-oauth2", require: false
# Forked until https://github.com/toy/image_optim/pull/162 is merged
# https://github.com/discourse/image_optim
gem 'discourse_image_optim', require: 'image_optim'
gem 'multi_json'
gem 'mustache'
gem 'nokogiri'
gem 'css_parser', require: false
gem "omniauth-google-oauth2"
gem 'omniauth'
gem 'omniauth-facebook'
gem 'omniauth-twitter'
gem 'omniauth-github'
# pending: https://github.com/ohler55/oj/issues/789
gem "oj", "3.13.14"
gem 'omniauth-oauth2', require: false
gem "pg"
gem "mini_sql"
gem "pry-rails", require: false
gem "pry-byebug", require: false
gem "rtlcss", require: false
gem "rake"
gem 'omniauth-google-oauth2'
gem "thor", require: false
gem "diffy", require: false
gem "rinku"
gem "sidekiq"
gem "mini_scheduler"
gem 'oj'
gem 'pg'
gem 'mini_sql'
gem 'pry-rails', require: false
gem 'pry-byebug', require: false
gem 'r2', require: false
gem 'rake'
gem "execjs", require: false
gem "mini_racer"
gem 'thor', require: false
gem 'diffy', require: false
gem 'rinku'
gem 'sidekiq'
gem 'mini_scheduler'
gem "highline", require: false
gem 'execjs', require: false
gem 'mini_racer'
gem "rack"
gem 'highline', require: false
gem "rack-protection" # security
gem "cbor", require: false
gem "cose", require: false
gem "addressable"
gem "json_schemer"
gem 'rack'
gem "net-smtp", require: false
gem "net-imap", require: false
gem "net-pop", require: false
gem "digest", require: false
gem 'rack-protection' # security
gem 'cbor', require: false
gem 'cose', require: false
gem 'addressable'
# Gems used only for assets and not required in production environments by default.
# Allow everywhere for now cause we are allowing asset debugging in production
group :assets do
gem "uglifier"
gem 'uglifier'
gem 'rtlit', require: false # for css rtling
end
group :test do
gem "capybara", require: false
gem "webmock", require: false
gem "fakeweb", require: false
gem "minitest", require: false
gem "simplecov", require: false
gem "selenium-webdriver", require: false
gem 'webmock', require: false
gem 'fakeweb', require: false
gem 'minitest', require: false
gem 'simplecov', require: false
gem "test-prof"
gem "webdrivers", require: false
end
group :test, :development do
gem "rspec"
gem "listen", require: false
gem "certified", require: false
gem "fabrication", require: false
gem "mocha", require: false
gem 'rspec'
gem 'mock_redis'
gem 'listen', require: false
gem 'certified', require: false
gem 'fabrication', require: false
gem 'mocha', require: false
gem "rb-fsevent", require: RUBY_PLATFORM =~ /darwin/i ? "rb-fsevent" : false
gem 'rb-fsevent', require: RUBY_PLATFORM =~ /darwin/i ? 'rb-fsevent' : false
gem "rspec-rails"
gem 'rspec-rails'
gem "shoulda-matchers", require: false
gem "rspec-html-matchers"
gem "byebug", require: ENV["RM_INFO"].nil?, platform: :mri
gem 'shoulda-matchers', require: false
gem 'rspec-html-matchers'
gem 'byebug', require: ENV['RM_INFO'].nil?, platform: :mri
gem "rubocop-discourse", require: false
gem "parallel_tests"
gem 'parallel_tests'
gem "rswag-specs"
gem "annotate"
gem "syntax_tree"
gem "syntax_tree-disable_ternary"
gem 'rswag-specs'
end
group :development do
gem "ruby-prof", require: false, platform: :mri
gem "bullet", require: !!ENV["BULLET"]
gem "better_errors", platform: :mri, require: !!ENV["BETTER_ERRORS"]
gem "binding_of_caller"
gem "yaml-lint"
gem "yard"
end
if ENV["ALLOW_DEV_POPULATE"] == "1"
gem "discourse_dev_assets"
gem "faker", "~> 2.16"
else
group :development, :test do
gem "discourse_dev_assets"
gem "faker", "~> 2.16"
end
gem 'ruby-prof', require: false, platform: :mri
gem 'bullet', require: !!ENV['BULLET']
gem 'better_errors', platform: :mri, require: !!ENV['BETTER_ERRORS']
gem 'binding_of_caller'
gem 'yaml-lint'
gem 'annotate'
end
# this is an optional gem, it provides a high performance replacement
# to String#blank? a method that is called quite frequently in current
# ActiveRecord, this may change in the future
gem "fast_blank", platform: :ruby
gem 'fast_blank', platform: :ruby
# this provides a very efficient lru cache
gem "lru_redux"
gem 'lru_redux'
gem "htmlentities", require: false
gem 'htmlentities', require: false
# IMPORTANT: mini profiler monkey patches, so it better be required last
# If you want to amend mini profiler to do the monkey patches in the railties
# we are open to it. by deferring require to the initializer we can configure discourse installs without it
gem "rack-mini-profiler", require: ["enable_rails_patches"]
gem 'flamegraph', require: false
gem 'rack-mini-profiler', require: ['enable_rails_patches']
gem "unicorn", require: false, platform: :ruby
gem "puma", require: false
gem "rbtrace", require: false, platform: :mri
gem "gc_tracer", require: false, platform: :mri
gem 'unicorn', require: false, platform: :ruby
gem 'puma', require: false
gem 'rbtrace', require: false, platform: :mri
gem 'gc_tracer', require: false, platform: :mri
# required for feed importing and embedding
gem "ruby-readability", require: false
gem 'ruby-readability', require: false
# rss gem is a bundled gem from Ruby 3 onwards
gem "rss", require: false
gem 'stackprof', require: false, platform: :mri
gem 'memory_profiler', require: false, platform: :mri
gem "stackprof", require: false, platform: :mri
gem "memory_profiler", require: false, platform: :mri
gem 'cppjieba_rb', require: false
gem "cppjieba_rb", require: false
gem 'lograge', require: false
gem 'logstash-event', require: false
gem 'logstash-logger', require: false
gem 'logster'
gem "lograge", require: false
gem "logstash-event", require: false
gem "logstash-logger", require: false
gem "logster"
# NOTE: later versions of sassc are causing a segfault, possibly dependent on processer architecture
# and until resolved should be locked at 2.0.1
gem 'sassc', '2.0.1', require: false
gem "sassc-rails"
# These are forks of sassc and sassc-rails with dart-sass support
gem "dartsass-ruby"
gem "dartsass-sprockets"
gem 'rotp', require: false
gem "rotp", require: false
gem 'rqrcode'
gem "rqrcode"
gem 'rubyzip', require: false
gem "rubyzip", require: false
gem 'sshkey', require: false
gem "sshkey", require: false
gem "rchardet", require: false
gem "lz4-ruby", require: false, platform: :ruby
gem "sanitize"
gem 'rchardet', require: false
gem 'lz4-ruby', require: false, platform: :ruby
if ENV["IMPORT"] == "1"
gem "mysql2"
gem "redcarpet"
gem 'mysql2'
gem 'redcarpet'
# NOTE: in import mode the version of sqlite can matter a lot, so we stick it to a specific one
gem "sqlite3", "~> 1.3", ">= 1.3.13"
gem "ruby-bbcode-to-md", git: "https://github.com/nlalonde/ruby-bbcode-to-md"
gem "reverse_markdown"
gem "tiny_tds"
gem "csv"
gem "parallel", require: false
gem 'sqlite3', '~> 1.3', '>= 1.3.13'
gem 'ruby-bbcode-to-md', git: 'https://github.com/nlalonde/ruby-bbcode-to-md'
gem 'reverse_markdown'
gem 'tiny_tds'
gem 'csv'
end
gem "web-push"
gem "colored2", require: false
gem "maxminddb"
gem 'webpush', require: false
gem 'colored2', require: false
gem 'maxminddb'
gem "rails_failover", require: false
gem "faraday"
gem "faraday-retry"
# workaround for faraday-net_http, see
# https://github.com/ruby/net-imap/issues/16#issuecomment-803086765
gem "net-http"
# workaround for prometheus-client
gem "webrick", require: false
# Workaround until Ruby ships with cgi version 0.3.6 or higher.
gem "cgi", ">= 0.3.6", require: false
gem "tzinfo-data"
gem 'rails_failover', require: false

View File

@ -1,41 +1,21 @@
GIT
remote: https://github.com/discourse/mail.git
revision: 5b700fc95ee66378e0cf2559abc73c8bc3062a4b
specs:
mail (2.8.0.edge)
mini_mime (>= 0.1.1)
GIT
remote: https://github.com/rails/sprockets
revision: f4d3dae71ef29c44b75a49cfbf8032cce07b423a
branch: 3.x
specs:
sprockets (3.7.2)
concurrent-ruby (~> 1.0)
rack (> 1, < 3)
GEM
remote: https://rubygems.org/
specs:
actionmailer (7.0.4.3)
actionpack (= 7.0.4.3)
actionview (= 7.0.4.3)
activejob (= 7.0.4.3)
activesupport (= 7.0.4.3)
actionmailer (6.0.3.3)
actionpack (= 6.0.3.3)
actionview (= 6.0.3.3)
activejob (= 6.0.3.3)
mail (~> 2.5, >= 2.5.4)
net-imap
net-pop
net-smtp
rails-dom-testing (~> 2.0)
actionpack (7.0.4.3)
actionview (= 7.0.4.3)
activesupport (= 7.0.4.3)
rack (~> 2.0, >= 2.2.0)
actionpack (6.0.3.3)
actionview (= 6.0.3.3)
activesupport (= 6.0.3.3)
rack (~> 2.0, >= 2.0.8)
rack-test (>= 0.6.3)
rails-dom-testing (~> 2.0)
rails-html-sanitizer (~> 1.0, >= 1.2.0)
actionview (7.0.4.3)
activesupport (= 7.0.4.3)
actionview (6.0.3.3)
activesupport (= 6.0.3.3)
builder (~> 3.1)
erubi (~> 1.4)
rails-dom-testing (~> 2.0)
@ -44,174 +24,146 @@ GEM
actionview (>= 6.0.a)
active_model_serializers (0.8.4)
activemodel (>= 3.0)
activejob (7.0.4.3)
activesupport (= 7.0.4.3)
activejob (6.0.3.3)
activesupport (= 6.0.3.3)
globalid (>= 0.3.6)
activemodel (7.0.4.3)
activesupport (= 7.0.4.3)
activerecord (7.0.4.3)
activemodel (= 7.0.4.3)
activesupport (= 7.0.4.3)
activesupport (7.0.4.3)
activemodel (6.0.3.3)
activesupport (= 6.0.3.3)
activerecord (6.0.3.3)
activemodel (= 6.0.3.3)
activesupport (= 6.0.3.3)
activesupport (6.0.3.3)
concurrent-ruby (~> 1.0, >= 1.0.2)
i18n (>= 1.6, < 2)
minitest (>= 5.1)
tzinfo (~> 2.0)
addressable (2.8.1)
public_suffix (>= 2.0.2, < 6.0)
annotate (3.2.0)
activerecord (>= 3.2, < 8.0)
i18n (>= 0.7, < 2)
minitest (~> 5.1)
tzinfo (~> 1.1)
zeitwerk (~> 2.2, >= 2.2.2)
addressable (2.7.0)
public_suffix (>= 2.0.2, < 5.0)
annotate (3.1.1)
activerecord (>= 3.2, < 7.0)
rake (>= 10.4, < 14.0)
ast (2.4.2)
aws-eventstream (1.2.0)
aws-partitions (1.583.0)
aws-sdk-core (3.130.2)
ast (2.4.1)
aws-eventstream (1.1.0)
aws-partitions (1.390.0)
aws-sdk-core (3.109.2)
aws-eventstream (~> 1, >= 1.0.2)
aws-partitions (~> 1, >= 1.525.0)
aws-partitions (~> 1, >= 1.239.0)
aws-sigv4 (~> 1.1)
jmespath (~> 1.0)
aws-sdk-kms (1.56.0)
aws-sdk-core (~> 3, >= 3.127.0)
aws-sdk-kms (1.39.0)
aws-sdk-core (~> 3, >= 3.109.0)
aws-sigv4 (~> 1.1)
aws-sdk-s3 (1.114.0)
aws-sdk-core (~> 3, >= 3.127.0)
aws-sdk-s3 (1.83.2)
aws-sdk-core (~> 3, >= 3.109.0)
aws-sdk-kms (~> 1)
aws-sigv4 (~> 1.4)
aws-sdk-sns (1.53.0)
aws-sdk-core (~> 3, >= 3.127.0)
aws-sigv4 (~> 1.1)
aws-sigv4 (1.5.0)
aws-sdk-sns (1.35.0)
aws-sdk-core (~> 3, >= 3.109.0)
aws-sigv4 (~> 1.1)
aws-sigv4 (1.2.2)
aws-eventstream (~> 1, >= 1.0.2)
barber (0.12.2)
ember-source (>= 1.0, < 3.1)
execjs (>= 1.2, < 3)
better_errors (2.9.1)
coderay (>= 1.0.0)
erubi (>= 1.0.0)
rack (>= 0.9.0)
binding_of_caller (1.0.0)
binding_of_caller (0.8.0)
debug_inspector (>= 0.0.1)
bootsnap (1.16.0)
msgpack (~> 1.2)
bootsnap (1.5.1)
msgpack (~> 1.0)
builder (3.2.4)
bullet (7.0.7)
bullet (6.1.0)
activesupport (>= 3.0.0)
uniform_notifier (~> 1.11)
byebug (11.1.3)
capybara (3.38.0)
addressable
matrix
mini_mime (>= 0.1.3)
nokogiri (~> 1.8)
rack (>= 1.6.0)
rack-test (>= 0.6.3)
regexp_parser (>= 1.5, < 3.0)
xpath (~> 3.2)
cbor (0.5.9.6)
certified (1.0.0)
cgi (0.3.6)
chunky_png (1.4.0)
chunky_png (1.3.14)
coderay (1.1.3)
colored2 (3.1.2)
concurrent-ruby (1.2.2)
connection_pool (2.3.0)
cose (1.3.0)
concurrent-ruby (1.1.7)
connection_pool (2.2.3)
cose (1.2.0)
cbor (~> 0.5.9)
openssl-signature_algorithm (~> 1.0)
cppjieba_rb (0.4.2)
crack (0.4.5)
rexml
cppjieba_rb (0.3.3)
crack (0.4.4)
crass (1.0.6)
css_parser (1.14.0)
css_parser (1.7.1)
addressable
dartsass-ruby (3.0.1)
sass-embedded (~> 1.54)
dartsass-sprockets (3.0.0)
dartsass-ruby (~> 3.0)
railties (>= 4.0.0)
sprockets (> 3.0)
sprockets-rails
tilt
date (3.3.3)
debug_inspector (1.1.0)
diff-lcs (1.5.0)
diffy (3.4.2)
digest (3.1.1)
discourse-fonts (0.0.9)
discourse-seed-fu (2.3.12)
activerecord (>= 3.1)
activesupport (>= 3.1)
discourse_dev_assets (0.0.4)
faker (~> 2.16)
literate_randomizer
docile (1.4.0)
ecma-re-validator (0.4.0)
regexp_parser (~> 2.2)
email_reply_trimmer (0.1.13)
erubi (1.12.0)
excon (0.99.0)
execjs (2.8.1)
exifr (1.3.10)
fabrication (2.30.0)
faker (2.23.0)
i18n (>= 1.8.11, < 2)
fakeweb (1.3.0)
faraday (2.7.4)
faraday-net_http (>= 2.0, < 3.1)
ruby2_keywords (>= 0.0.4)
faraday-net_http (3.0.2)
faraday-retry (2.1.0)
faraday (~> 2.0)
fast_blank (1.0.1)
fast_xs (0.8.0)
fastimage (2.2.6)
ffi (1.15.5)
fspath (3.1.2)
gc_tracer (1.5.1)
globalid (1.1.0)
activesupport (>= 5.0)
google-protobuf (3.22.2)
google-protobuf (3.22.2-aarch64-linux)
google-protobuf (3.22.2-arm64-darwin)
google-protobuf (3.22.2-x86_64-darwin)
google-protobuf (3.22.2-x86_64-linux)
guess_html_encoding (0.0.11)
hana (1.3.7)
hashdiff (1.0.1)
hashie (5.0.0)
highline (2.1.0)
hkdf (1.0.0)
htmlentities (4.3.4)
http_accept_language (2.1.1)
i18n (1.12.0)
concurrent-ruby (~> 1.0)
image_optim (0.31.3)
debug_inspector (0.0.3)
diff-lcs (1.4.4)
diffy (3.4.0)
discourse-ember-rails (0.18.6)
active_model_serializers
ember-data-source (>= 1.0.0.beta.5)
ember-handlebars-template (>= 0.1.1, < 1.0)
ember-source (>= 1.1.0)
jquery-rails (>= 1.0.17)
railties (>= 3.1)
discourse-ember-source (3.12.2.2)
discourse-fonts (0.0.5)
discourse_image_optim (0.26.2)
exifr (~> 1.2, >= 1.2.2)
fspath (~> 3.0)
image_size (>= 1.5, < 4)
image_size (~> 1.5)
in_threads (~> 1.3)
progress (~> 3.0, >= 3.0.1)
image_size (3.2.0)
in_threads (1.6.0)
jmespath (1.6.2)
json (2.6.3)
json-schema (3.0.0)
addressable (>= 2.8)
json_schemer (0.2.23)
ecma-re-validator (~> 0.3)
hana (~> 1.3)
regexp_parser (~> 2.0)
uri_template (~> 0.7)
jwt (2.7.0)
kgio (2.11.4)
libv8-node (16.10.0.0)
libv8-node (16.10.0.0-aarch64-linux)
libv8-node (16.10.0.0-arm64-darwin)
libv8-node (16.10.0.0-x86_64-darwin)
libv8-node (16.10.0.0-x86_64-darwin-19)
libv8-node (16.10.0.0-x86_64-linux)
listen (3.8.0)
docile (1.3.2)
email_reply_trimmer (0.1.13)
ember-data-source (3.0.2)
ember-source (>= 2, < 3.0)
ember-handlebars-template (0.8.0)
barber (>= 0.11.0)
sprockets (>= 3.3, < 4.1)
ember-source (2.18.2)
erubi (1.9.0)
excon (0.78.0)
execjs (2.7.0)
exifr (1.3.9)
fabrication (2.21.1)
fakeweb (1.3.0)
faraday (1.1.0)
multipart-post (>= 1.2, < 3)
ruby2_keywords
fast_blank (1.0.0)
fast_xs (0.8.0)
fastimage (2.2.0)
ffi (1.13.1)
flamegraph (0.9.5)
fspath (3.1.2)
gc_tracer (1.5.1)
globalid (0.4.2)
activesupport (>= 4.2.0)
guess_html_encoding (0.0.11)
hashdiff (1.0.1)
hashie (4.1.0)
highline (2.0.3)
hkdf (0.3.0)
htmlentities (4.3.4)
http_accept_language (2.1.1)
i18n (1.8.5)
concurrent-ruby (~> 1.0)
image_size (1.5.0)
in_threads (1.5.4)
jmespath (1.4.0)
jquery-rails (4.4.0)
rails-dom-testing (>= 1, < 3)
railties (>= 4.2.0)
thor (>= 0.14, < 2.0)
json (2.3.1)
json-schema (2.8.1)
addressable (>= 2.4)
jwt (2.2.2)
kgio (2.11.3)
libv8 (8.4.255.0)
listen (3.3.0)
rb-fsevent (~> 0.10, >= 0.10.3)
rb-inotify (~> 0.9, >= 0.9.10)
literate_randomizer (0.4.0)
lograge (0.12.0)
lograge (0.11.2)
actionpack (>= 4)
activesupport (>= 4)
railties (>= 4)
@ -219,146 +171,126 @@ GEM
logstash-event (1.2.02)
logstash-logger (0.26.1)
logstash-event (~> 1.2)
logster (2.12.2)
loofah (2.19.1)
logster (2.9.4)
loofah (2.7.0)
crass (~> 1.0.2)
nokogiri (>= 1.5.9)
lru_redux (1.1.0)
lz4-ruby (0.3.3)
matrix (0.4.2)
mail (2.7.1)
mini_mime (>= 0.1.1)
maxminddb (0.1.22)
memory_profiler (1.0.1)
message_bus (4.3.2)
memory_profiler (0.9.14)
message_bus (3.3.4)
rack (>= 1.1.3)
method_source (1.0.0)
mini_mime (1.1.2)
mini_portile2 (2.8.1)
mini_racer (0.6.3)
libv8-node (~> 16.10.0.0)
mini_scheduler (0.15.0)
sidekiq (>= 4.2.3, < 7.0)
mini_sql (1.4.0)
mini_suffix (0.3.3)
mini_mime (1.0.2)
mini_portile2 (2.4.0)
mini_racer (0.3.1)
libv8 (~> 8.4.255)
mini_scheduler (0.12.3)
sidekiq
mini_sql (0.3)
mini_suffix (0.3.0)
ffi (~> 1.9)
minitest (5.18.0)
mocha (2.0.2)
ruby2_keywords (>= 0.0.5)
msgpack (1.6.1)
minitest (5.14.2)
mocha (1.11.2)
mock_redis (0.26.0)
msgpack (1.3.3)
multi_json (1.15.0)
multi_xml (0.6.0)
multipart-post (2.1.1)
mustache (1.1.1)
net-http (0.3.2)
uri
net-imap (0.3.4)
date
net-protocol
net-pop (0.1.2)
net-protocol
net-protocol (0.2.1)
timeout
net-smtp (0.3.3)
net-protocol
nio4r (2.5.8)
nokogiri (1.14.2)
mini_portile2 (~> 2.8.0)
racc (~> 1.4)
nokogiri (1.14.2-aarch64-linux)
racc (~> 1.4)
nokogiri (1.14.2-arm64-darwin)
racc (~> 1.4)
nokogiri (1.14.2-x86_64-darwin)
racc (~> 1.4)
nokogiri (1.14.2-x86_64-linux)
racc (~> 1.4)
oauth (1.1.0)
oauth-tty (~> 1.0, >= 1.0.1)
snaky_hash (~> 2.0)
version_gem (~> 1.1)
oauth-tty (1.0.5)
version_gem (~> 1.1, >= 1.1.1)
oauth2 (1.4.11)
faraday (>= 0.17.3, < 3.0)
nio4r (2.5.4)
nokogiri (1.10.10)
mini_portile2 (~> 2.4.0)
nokogumbo (2.0.2)
nokogiri (~> 1.8, >= 1.8.4)
oauth (0.5.4)
oauth2 (1.4.4)
faraday (>= 0.8, < 2.0)
jwt (>= 1.0, < 3.0)
multi_json (~> 1.3)
multi_xml (~> 0.5)
rack (>= 1.2, < 4)
oj (3.13.14)
omniauth (1.9.2)
rack (>= 1.2, < 3)
oj (3.10.16)
omniauth (1.9.1)
hashie (>= 3.4.6)
rack (>= 1.6.2, < 3)
omniauth-facebook (9.0.0)
omniauth-facebook (8.0.0)
omniauth-oauth2 (~> 1.2)
omniauth-github (1.4.0)
omniauth (~> 1.5)
omniauth-oauth2 (>= 1.4.0, < 2.0)
omniauth-google-oauth2 (0.8.2)
omniauth-google-oauth2 (0.8.0)
jwt (>= 2.0)
oauth2 (~> 1.1)
omniauth (~> 1.1)
omniauth (>= 1.1.1)
omniauth-oauth2 (>= 1.6)
omniauth-oauth (1.2.0)
omniauth-oauth (1.1.0)
oauth
omniauth (>= 1.0, < 3)
omniauth-oauth2 (1.7.3)
oauth2 (>= 1.4, < 3)
omniauth (>= 1.9, < 3)
omniauth (~> 1.0)
omniauth-oauth2 (1.7.0)
oauth2 (~> 1.4)
omniauth (~> 1.9)
omniauth-twitter (1.4.0)
omniauth-oauth (~> 1.1)
rack
openssl (3.1.0)
openssl-signature_algorithm (1.3.0)
openssl (> 2.0)
onebox (2.1.5)
addressable (~> 2.7.0)
htmlentities (~> 4.3)
multi_json (~> 1.11)
mustache
nokogiri (~> 1.7)
sanitize
openssl-signature_algorithm (1.0.0)
optimist (3.0.1)
parallel (1.22.1)
parallel_tests (4.2.0)
parallel (1.20.0)
parallel_tests (3.3.0)
parallel
parser (3.2.1.1)
parser (2.7.2.0)
ast (~> 2.4.1)
pg (1.4.6)
prettier_print (1.2.1)
progress (3.6.0)
pry (0.14.2)
pg (1.2.3)
progress (3.5.2)
pry (0.13.1)
coderay (~> 1.1)
method_source (~> 1.0)
pry-byebug (3.10.1)
pry-byebug (3.9.0)
byebug (~> 11.0)
pry (>= 0.13, < 0.15)
pry (~> 0.13.0)
pry-rails (0.3.9)
pry (>= 0.10.4)
public_suffix (5.0.1)
puma (6.1.1)
public_suffix (4.0.6)
puma (5.0.4)
nio4r (~> 2.0)
racc (1.6.2)
rack (2.2.6.4)
rack-mini-profiler (3.0.0)
r2 (0.2.7)
rack (2.2.3)
rack-mini-profiler (2.2.0)
rack (>= 1.2.0)
rack-protection (3.0.5)
rack-protection (2.1.0)
rack
rack-test (2.1.0)
rack (>= 1.3)
rack-test (1.1.0)
rack (>= 1.0, < 3)
rails-dom-testing (2.0.3)
activesupport (>= 4.2.0)
nokogiri (>= 1.6)
rails-html-sanitizer (1.5.0)
loofah (~> 2.19, >= 2.19.1)
rails_failover (0.8.1)
activerecord (> 6.0, < 7.1)
concurrent-ruby
railties (> 6.0, < 7.1)
rails_multisite (4.0.1)
activerecord (> 5.0, < 7.1)
railties (> 5.0, < 7.1)
railties (7.0.4.3)
actionpack (= 7.0.4.3)
activesupport (= 7.0.4.3)
rails-html-sanitizer (1.3.0)
loofah (~> 2.3)
rails_failover (0.6.0)
activerecord (~> 6.0)
railties (~> 6.0)
rails_multisite (2.5.0)
activerecord (> 5.0, < 7)
railties (> 5.0, < 7)
railties (6.0.3.3)
actionpack (= 6.0.3.3)
activesupport (= 6.0.3.3)
method_source
rake (>= 12.2)
thor (~> 1.0)
zeitwerk (~> 2.5)
rainbow (3.1.1)
raindrops (0.20.1)
rake (13.0.6)
rb-fsevent (0.11.2)
rake (>= 0.8.7)
thor (>= 0.20.3, < 2.0)
rainbow (3.0.0)
raindrops (0.19.1)
rake (13.0.1)
rb-fsevent (0.10.4)
rb-inotify (0.10.1)
ffi (~> 1.0)
rbtrace (0.4.14)
@ -366,233 +298,190 @@ GEM
msgpack (>= 0.4.3)
optimist (>= 3.0.0)
rchardet (1.8.0)
redis (4.8.1)
redis-namespace (1.10.0)
redis (>= 4)
regexp_parser (2.7.0)
request_store (1.5.1)
redis (4.2.2)
redis-namespace (1.8.0)
redis (>= 3.0.4)
regexp_parser (1.8.2)
request_store (1.5.0)
rack (>= 1.4)
rexml (3.2.5)
rexml (3.2.4)
rinku (2.0.6)
rotp (6.2.2)
rqrcode (2.1.2)
rotp (6.2.0)
rqrcode (1.1.2)
chunky_png (~> 1.0)
rqrcode_core (~> 1.0)
rqrcode_core (1.2.0)
rspec (3.12.0)
rspec-core (~> 3.12.0)
rspec-expectations (~> 3.12.0)
rspec-mocks (~> 3.12.0)
rspec-core (3.12.1)
rspec-support (~> 3.12.0)
rspec-expectations (3.12.2)
rqrcode_core (~> 0.1)
rqrcode_core (0.1.2)
rspec (3.10.0)
rspec-core (~> 3.10.0)
rspec-expectations (~> 3.10.0)
rspec-mocks (~> 3.10.0)
rspec-core (3.10.0)
rspec-support (~> 3.10.0)
rspec-expectations (3.10.0)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.12.0)
rspec-html-matchers (0.10.0)
rspec-support (~> 3.10.0)
rspec-html-matchers (0.9.4)
nokogiri (~> 1)
rspec (>= 3.0.0.a)
rspec-mocks (3.12.4)
rspec (>= 3.0.0.a, < 4)
rspec-mocks (3.10.0)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.12.0)
rspec-rails (6.0.1)
actionpack (>= 6.1)
activesupport (>= 6.1)
railties (>= 6.1)
rspec-core (~> 3.11)
rspec-expectations (~> 3.11)
rspec-mocks (~> 3.11)
rspec-support (~> 3.11)
rspec-support (3.12.0)
rss (0.2.9)
rexml
rswag-specs (2.8.0)
activesupport (>= 3.1, < 7.1)
json-schema (>= 2.2, < 4.0)
railties (>= 3.1, < 7.1)
rspec-core (>= 2.14)
rtlcss (0.2.0)
mini_racer (~> 0.6.3)
rubocop (1.48.1)
json (~> 2.3)
rspec-support (~> 3.10.0)
rspec-rails (4.0.1)
actionpack (>= 4.2)
activesupport (>= 4.2)
railties (>= 4.2)
rspec-core (~> 3.9)
rspec-expectations (~> 3.9)
rspec-mocks (~> 3.9)
rspec-support (~> 3.9)
rspec-support (3.10.0)
rswag-specs (2.3.1)
activesupport (>= 3.1, < 7.0)
json-schema (~> 2.2)
railties (>= 3.1, < 7.0)
rtlit (0.0.5)
rubocop (1.3.0)
parallel (~> 1.10)
parser (>= 3.2.0.0)
parser (>= 2.7.1.5)
rainbow (>= 2.2.2, < 4.0)
regexp_parser (>= 1.8, < 3.0)
rexml (>= 3.2.5, < 4.0)
rubocop-ast (>= 1.26.0, < 2.0)
regexp_parser (>= 1.8)
rexml
rubocop-ast (>= 1.1.1)
ruby-progressbar (~> 1.7)
unicode-display_width (>= 2.4.0, < 3.0)
rubocop-ast (1.27.0)
parser (>= 3.2.1.0)
rubocop-capybara (2.17.1)
rubocop (~> 1.41)
rubocop-discourse (3.2.0)
unicode-display_width (>= 1.4.0, < 2.0)
rubocop-ast (1.1.1)
parser (>= 2.7.1.5)
rubocop-discourse (2.4.1)
rubocop (>= 1.1.0)
rubocop-rspec (>= 2.0.0)
rubocop-rspec (2.19.0)
rubocop (~> 1.33)
rubocop-capybara (~> 2.17)
ruby-prof (1.6.1)
ruby-progressbar (1.13.0)
rubocop-rspec (2.0.0)
rubocop (~> 1.0)
rubocop-ast (>= 1.1.0)
ruby-prof (1.4.2)
ruby-progressbar (1.10.1)
ruby-readability (0.7.0)
guess_html_encoding (>= 0.0.4)
nokogiri (>= 1.6.0)
ruby2_keywords (0.0.5)
rubyzip (2.3.2)
sanitize (6.0.1)
ruby2_keywords (0.0.2)
rubyzip (2.3.0)
sanitize (5.2.1)
crass (~> 1.0.2)
nokogiri (>= 1.12.0)
sass-embedded (1.59.2)
google-protobuf (~> 3.21)
rake (>= 10.0.0)
sass-embedded (1.59.2-aarch64-linux-gnu)
google-protobuf (~> 3.21)
sass-embedded (1.59.2-arm64-darwin)
google-protobuf (~> 3.21)
sass-embedded (1.59.2-x86_64-darwin)
google-protobuf (~> 3.21)
sass-embedded (1.59.2-x86_64-linux-gnu)
google-protobuf (~> 3.21)
selenium-webdriver (4.8.1)
rexml (~> 3.2, >= 3.2.5)
rubyzip (>= 1.2.2, < 3.0)
websocket (~> 1.0)
shoulda-matchers (5.3.0)
activesupport (>= 5.2.0)
sidekiq (6.5.8)
connection_pool (>= 2.2.5, < 3)
nokogiri (>= 1.8.0)
nokogumbo (~> 2.0)
sassc (2.0.1)
ffi (~> 1.9)
rake
sassc-rails (2.1.2)
railties (>= 4.0.0)
sassc (>= 2.0)
sprockets (> 3.0)
sprockets-rails
tilt
seed-fu (2.3.9)
activerecord (>= 3.1)
activesupport (>= 3.1)
shoulda-matchers (4.4.1)
activesupport (>= 4.2.0)
sidekiq (6.1.2)
connection_pool (>= 2.2.2)
rack (~> 2.0)
redis (>= 4.5.0, < 5)
simplecov (0.22.0)
redis (>= 4.2.0)
simplecov (0.19.1)
docile (~> 1.1)
simplecov-html (~> 0.11)
simplecov_json_formatter (~> 0.1)
simplecov-html (0.12.3)
simplecov_json_formatter (0.1.4)
snaky_hash (2.0.1)
hashie
version_gem (~> 1.1, >= 1.1.1)
sprockets-rails (3.4.2)
actionpack (>= 5.2)
activesupport (>= 5.2)
sprockets (3.7.2)
concurrent-ruby (~> 1.0)
rack (> 1, < 3)
sprockets-rails (3.2.2)
actionpack (>= 4.0)
activesupport (>= 4.0)
sprockets (>= 3.0.0)
sshkey (2.0.0)
stackprof (0.2.23)
syntax_tree (6.0.2)
prettier_print (>= 1.2.0)
syntax_tree-disable_ternary (1.0.0)
test-prof (1.2.0)
thor (1.2.1)
tilt (2.1.0)
timeout (0.3.2)
tzinfo (2.0.6)
concurrent-ruby (~> 1.0)
tzinfo-data (1.2022.7)
tzinfo (>= 1.0.0)
stackprof (0.2.16)
test-prof (0.12.2)
thor (1.0.1)
thread_safe (0.3.6)
tilt (2.0.10)
tzinfo (1.2.8)
thread_safe (~> 0.1)
uglifier (4.2.0)
execjs (>= 0.3.0, < 3)
unf (0.1.4)
unf_ext
unf_ext (0.0.8.2)
unicode-display_width (2.4.2)
unicorn (6.1.0)
unf_ext (0.0.7.7)
unicode-display_width (1.7.0)
unicorn (5.7.0)
kgio (~> 2.6)
raindrops (~> 0.7)
uniform_notifier (1.16.0)
uri (0.12.0)
uri_template (0.7.0)
version_gem (1.1.1)
web-push (3.0.0)
hkdf (~> 1.0)
jwt (~> 2.0)
openssl (~> 3.0)
webdrivers (5.2.0)
nokogiri (~> 1.6)
rubyzip (>= 1.3.0)
selenium-webdriver (~> 4.0)
webmock (3.18.1)
addressable (>= 2.8.0)
uniform_notifier (1.13.0)
webmock (3.10.0)
addressable (>= 2.3.6)
crack (>= 0.3.2)
hashdiff (>= 0.4.0, < 2.0.0)
webrick (1.7.0)
websocket (1.2.9)
xorcist (1.1.3)
xpath (3.2.0)
nokogiri (~> 1.8)
yaml-lint (0.1.2)
yard (0.9.28)
webrick (~> 1.7.0)
zeitwerk (2.6.7)
webpush (1.0.0)
hkdf (~> 0.2)
jwt (~> 2.0)
xorcist (1.1.2)
yaml-lint (0.0.10)
zeitwerk (2.4.1)
PLATFORMS
aarch64-linux
arm64-darwin-20
ruby
x86_64-darwin-18
x86_64-darwin-19
x86_64-darwin-20
x86_64-linux
DEPENDENCIES
actionmailer (= 7.0.4.3)
actionpack (= 7.0.4.3)
actionview (= 7.0.4.3)
actionmailer (= 6.0.3.3)
actionpack (= 6.0.3.3)
actionview (= 6.0.3.3)
actionview_precompiler
active_model_serializers (~> 0.8.3)
activemodel (= 7.0.4.3)
activerecord (= 7.0.4.3)
activesupport (= 7.0.4.3)
activemodel (= 6.0.3.3)
activerecord (= 6.0.3.3)
activesupport (= 6.0.3.3)
addressable
annotate
aws-sdk-s3
aws-sdk-sns
barber
better_errors
binding_of_caller
bootsnap
bullet
byebug
capybara
cbor
certified
cgi (>= 0.3.6)
colored2
cose
cppjieba_rb
css_parser
dartsass-ruby
dartsass-sprockets
diffy
digest
discourse-ember-rails (= 0.18.6)
discourse-ember-source (~> 3.12.2)
discourse-fonts
discourse-seed-fu
discourse_dev_assets
discourse_image_optim
email_reply_trimmer
ember-handlebars-template (= 0.8.0)
excon
execjs
fabrication
faker (~> 2.16)
fakeweb
faraday
faraday-retry
fast_blank
fast_xs
fastimage
flamegraph
gc_tracer
highline
htmlentities
http_accept_language
image_optim
json
json_schemer
listen
lograge
logstash-event
logstash-logger
logster
loofah
lru_redux
lz4-ruby
mail!
mail
maxminddb
memory_profiler
message_bus
@ -603,31 +492,30 @@ DEPENDENCIES
mini_suffix
minitest
mocha
mock_redis
multi_json
mustache
net-http
net-imap
net-pop
net-smtp
nokogiri
oj (= 3.13.14)
oj
omniauth
omniauth-facebook
omniauth-github
omniauth-google-oauth2
omniauth-oauth2
omniauth-twitter
onebox
parallel_tests
pg
pry-byebug
pry-rails
puma
r2
rack
rack-mini-profiler
rack-protection
rails_failover
rails_multisite
railties (= 7.0.4.3)
railties (= 6.0.3.3)
rake
rb-fsevent
rbtrace
@ -640,37 +528,31 @@ DEPENDENCIES
rspec
rspec-html-matchers
rspec-rails
rss
rswag-specs
rtlcss
rtlit
rubocop-discourse
ruby-prof
ruby-readability
rubyzip
sanitize
selenium-webdriver
sassc (= 2.0.1)
sassc-rails
seed-fu
shoulda-matchers
sidekiq
simplecov
sprockets!
sprockets (= 3.7.2)
sprockets-rails
sshkey
stackprof
syntax_tree
syntax_tree-disable_ternary
test-prof
thor
tzinfo-data
uglifier
unf
unicorn
web-push
webdrivers
webmock
webrick
webpush
xorcist
yaml-lint
yard
BUNDLED WITH
2.4.4
2.1.4

View File

@ -1,12 +1,12 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
@ -56,7 +56,7 @@ patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
@ -255,7 +255,7 @@ make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
@ -277,9 +277,9 @@ YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it

View File

@ -1,6 +1,8 @@
<a href="https://www.discourse.org/">
<img src="images/discourse-readme-logo.png" width="300px">
</a>
<a href="https://www.discourse.org/"><img src=
"https://user-images.githubusercontent.com/1681963/52239617-e2683480-289c-11e9-922b-5da55472e5b4.png"
width="300px"></a>
Discourse is the 100% open source discussion platform built for the next decade of the Internet. Use it as a:
@ -15,6 +17,9 @@ To learn more about the philosophy and goals of the project, [visit **discourse.
<a href="https://bbs.boingboing.net"><img alt="Boing Boing" src="https://user-images.githubusercontent.com/1681963/52239245-04ad8280-289c-11e9-9c88-8c173d4a0422.png" width="720px"></a>
<a href="https://twittercommunity.com/"><img src="https://user-images.githubusercontent.com/1681963/52239250-04ad8280-289c-11e9-9e42-574f6eaab9d7.png" width="720px"></a>
<a href="https://discuss.atom.io/"><img src="https://user-images.githubusercontent.com/1681963/89088039-6735f080-d364-11ea-93a6-5629ea8738fe.png" width="720px"></a>
<a href="https://forums.gearboxsoftware.com/"><img src="https://user-images.githubusercontent.com/1681963/89088042-68ffb400-d364-11ea-93be-161ea04d8b29.png" width="720px"></a>
<img src="https://user-images.githubusercontent.com/1681963/52239118-b304f800-289b-11e9-9904-16450680d9ec.jpg" alt="Mobile" width="414">
@ -30,7 +35,7 @@ To get your environment setup, follow the community setup guide for your operati
If you're familiar with how Rails works and are comfortable setting up your own environment, you can also try out the [**Discourse Advanced Developer Guide**](docs/DEVELOPER-ADVANCED.md), which is aimed primarily at Ubuntu and macOS environments.
Before you get started, ensure you have the following minimum versions: [Ruby 3.2+](https://www.ruby-lang.org/en/downloads/), [PostgreSQL 13](https://www.postgresql.org/download/), [Redis 7](https://redis.io/download). If you're having trouble, please see our [**TROUBLESHOOTING GUIDE**](docs/TROUBLESHOOTING.md) first!
Before you get started, ensure you have the following minimum versions: [Ruby 2.6+](https://www.ruby-lang.org/en/downloads/), [PostgreSQL 10+](https://www.postgresql.org/download/), [Redis 4.0+](https://redis.io/download). If you're having trouble, please see our [**TROUBLESHOOTING GUIDE**](docs/TROUBLESHOOTING.md) first!
## Setting up Discourse
@ -51,8 +56,6 @@ Discourse supports the **latest, stable releases** of all major browsers and pla
| Microsoft Edge | | |
| Mozilla Firefox | | |
Additionally, we aim to support Safari on iOS 15.7+.
## Built With
- [Ruby on Rails](https://github.com/rails/rails) &mdash; Our back end API is a Rails app. It responds to requests RESTfully in JSON.
@ -61,11 +64,11 @@ Additionally, we aim to support Safari on iOS 15.7+.
- [Redis](https://redis.io/) &mdash; We use Redis as a cache and for transient data.
- [BrowserStack](https://www.browserstack.com/) &mdash; We use BrowserStack to test on real devices and browsers.
Plus *lots* of Ruby Gems, a complete list of which is at [/main/Gemfile](https://github.com/discourse/discourse/blob/main/Gemfile).
Plus *lots* of Ruby Gems, a complete list of which is at [/master/Gemfile](https://github.com/discourse/discourse/blob/master/Gemfile).
## Contributing
[![Build Status](https://github.com/discourse/discourse/actions/workflows/tests.yml/badge.svg)](https://github.com/discourse/discourse/actions)
[![Build Status](https://github.com/discourse/discourse/workflows/CI/badge.svg)](https://github.com/discourse/discourse/actions)
Discourse is **100% free** and **open source**. We encourage and support an active, healthy community that
accepts contributions from the public &ndash; including you!
@ -75,7 +78,7 @@ Before contributing to Discourse:
1. Please read the complete mission statements on [**discourse.org**](https://www.discourse.org). Yes we actually believe this stuff; you should too.
2. Read and sign the [**Electronic Discourse Forums Contribution License Agreement**](https://www.discourse.org/cla).
3. Dig into [**CONTRIBUTING.MD**](CONTRIBUTING.md), which covers submitting bugs, requesting new features, preparing your code for a pull request, etc.
4. Always strive to collaborate [with mutual respect](https://github.com/discourse/discourse/blob/main/docs/code-of-conduct.md).
4. Always strive to collaborate [with mutual respect](https://github.com/discourse/discourse/blob/master/docs/code-of-conduct.md).
5. Not sure what to work on? [**We've got some ideas.**](https://meta.discourse.org/t/so-you-want-to-help-out-with-discourse/3823)
@ -83,7 +86,7 @@ We look forward to seeing your pull requests!
## Security
We take security very seriously at Discourse; all our code is 100% open source and peer reviewed. Please read [our security guide](https://github.com/discourse/discourse/blob/main/docs/SECURITY.md) for an overview of security measures in Discourse, or if you wish to report a security issue.
We take security very seriously at Discourse; all our code is 100% open source and peer reviewed. Please read [our security guide](https://github.com/discourse/discourse/blob/master/docs/SECURITY.md) for an overview of security measures in Discourse, or if you wish to report a security issue.
## The Discourse Team
@ -91,7 +94,7 @@ The original Discourse code contributors can be found in [**AUTHORS.MD**](docs/A
## Copyright / License
Copyright 2014 - 2023 Civilized Discourse Construction Kit, Inc.
Copyright 2014 - 2020 Civilized Discourse Construction Kit, Inc.
Licensed under the GNU General Public License Version 2.0 (or later);
you may not use this work except in compliance with the License.
@ -107,10 +110,6 @@ limitations under the License.
Discourse logo and “Discourse Forum” ®, Civilized Discourse Construction Kit, Inc.
## Accessibility
To guide our ongoing effort to build accessible software we follow the [W3Cs Web Content Accessibility Guidelines (WCAG)](https://www.w3.org/TR/WCAG21/). If you'd like to report an accessibility issue that makes it difficult for you to use Discourse, email accessibility@discourse.org. For more information visit [discourse.org/accessibility](https://discourse.org/accessibility).
## Dedication
Discourse is built with [love, Internet style.](https://www.youtube.com/watch?v=Xe1TZaElTAs)

View File

@ -7,3 +7,7 @@
require File.expand_path('../config/application', __FILE__)
Discourse::Application.load_tasks
# this prevents crashes when migrating a database in production in certain
# PostgreSQL configuations when trying to create structure.sql
Rake::Task["db:structure:dump"].clear if Rails.env.production?

1
adminjs Symbolic link
View File

@ -0,0 +1 @@
app/assets/javascripts/admin

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 882 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 984 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 895 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 KiB

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

After

Width:  |  Height:  |  Size: 2.8 KiB

View File

@ -1 +0,0 @@
Images created in https://fa2png.app/ using 150px size and #919191 color.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.1 KiB

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 613 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 845 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

View File

@ -1,32 +0,0 @@
{
"licenses": {
"blueOak": "bronze",
"spdx": [
"CC0-1.0",
"CC-BY-3.0",
"CC-BY-4.0",
"Apache-2.0 WITH LLVM-exception",
"ISC"
]
},
"packages": {
"component-bind": "1.0.0",
"component-inherit": "0.0.3",
"duplex": "1.0.0",
"glob": "3.1.21",
"indexof": "0.0.1",
"inherits": "1.0.2",
"jsonify": "0.0.0",
"messageformat": "0.1.5",
"line-stream": "0.0.0",
"regenerator-transform": "0.10.1",
"source-map": "0.1.43",
"sourcemap-validator": "1.1.1"
},
"corrections": true,
"ignore": [
{
"author": "Discourse"
}
]
}

View File

@ -1 +0,0 @@
engine-strict = true

View File

@ -0,0 +1,20 @@
// discourse-skip-module
(function () {
setTimeout(function () {
const $activateButton = $("#activate-account-button");
$activateButton.on("click", function () {
$activateButton.prop("disabled", true);
const hpPath = document.getElementById("data-activate-account").dataset
.path;
$.ajax(hpPath)
.then(function (hp) {
$("#password_confirmation").val(hp.value);
$("#challenge").val(hp.challenge.split("").reverse().join(""));
$("#activate-account-form").submit();
})
.fail(function () {
$activateButton.prop("disabled", false);
});
});
}, 50);
})();

View File

@ -0,0 +1,13 @@
<%
require_asset("main_include_admin.js")
DiscoursePluginRegistry.admin_javascripts.each { |js| require_asset(js) }
DiscoursePluginRegistry.each_globbed_asset(admin: true) do |f, ext|
if File.directory?(f)
depend_on(f)
elsif f.to_s.end_with?(".#{ext}")
require_asset(f)
end
end
%>

View File

@ -1 +0,0 @@
engine-strict = true

View File

@ -1,13 +1,13 @@
import RestAdapter from "discourse/adapters/rest";
import RESTAdapter from "discourse/adapters/rest";
export default class ApiKey extends RestAdapter {
jsonMode = true;
export default RESTAdapter.extend({
jsonMode: true,
basePath() {
return "/admin/api/";
}
},
apiNameFor() {
return "key";
}
}
},
});

View File

@ -1,11 +1,11 @@
import RestAdapter from "discourse/adapters/rest";
export default function buildPluginAdapter(pluginName) {
return class extends RestAdapter {
return RestAdapter.extend({
pathFor(store, type, findArgs) {
return (
"/admin/plugins/" + pluginName + super.pathFor(store, type, findArgs)
"/admin/plugins/" + pluginName + this._super(store, type, findArgs)
);
}
};
},
});
}

View File

@ -1,7 +1,7 @@
import RestAdapter from "discourse/adapters/rest";
export default class CustomizationBase extends RestAdapter {
export default RestAdapter.extend({
basePath() {
return "/admin/customize/";
}
}
},
});

View File

@ -1,7 +1,7 @@
import RestAdapter from "discourse/adapters/rest";
export default class EmailStyle extends RestAdapter {
export default RestAdapter.extend({
pathFor() {
return "/admin/customize/email_style";
}
}
},
});

View File

@ -1,7 +1,7 @@
import RestAdapter from "discourse/adapters/rest";
export default class Embedding extends RestAdapter {
export default RestAdapter.extend({
pathFor() {
return "/admin/customize/embedding";
}
}
},
});

View File

@ -1,7 +1,7 @@
import RestAdapter from "discourse/adapters/rest";
export default class StaffActionLog extends RestAdapter {
export default RestAdapter.extend({
basePath() {
return "/admin/logs/";
}
}
},
});

View File

@ -1,5 +1,5 @@
import RestAdapter from "discourse/adapters/rest";
export default class TagGroup extends RestAdapter {
jsonMode = true;
}
export default RestAdapter.extend({
jsonMode: true,
});

View File

@ -1,10 +1,9 @@
import RestAdapter from "discourse/adapters/rest";
export default class Theme extends RestAdapter {
jsonMode = true;
export default RestAdapter.extend({
basePath() {
return "/admin/";
}
},
afterFindAll(results) {
let map = {};
@ -21,5 +20,7 @@ export default class Theme extends RestAdapter {
theme.set("parentThemes", mappedParents);
});
return results;
}
}
},
jsonMode: true,
});

View File

@ -1,7 +1,7 @@
import RestAdapter from "discourse/adapters/rest";
import RESTAdapter from "discourse/adapters/rest";
export default class WebHookEvent extends RestAdapter {
export default RESTAdapter.extend({
basePath() {
return "/admin/api/";
}
}
},
});

View File

@ -1,7 +1,7 @@
import RestAdapter from "discourse/adapters/rest";
import RESTAdapter from "discourse/adapters/rest";
export default class WebHook extends RestAdapter {
export default RESTAdapter.extend({
basePath() {
return "/admin/api/";
}
}
},
});

View File

@ -1 +0,0 @@
<div class="ace">{{this.content}}</div>

View File

@ -1,33 +1,22 @@
import { action } from "@ember/object";
import { classNames } from "@ember-decorators/component";
import { observes, on } from "@ember-decorators/object";
import Component from "@ember/component";
import getURL from "discourse-common/lib/get-url";
import loadScript from "discourse/lib/load-script";
import I18n from "I18n";
import { bind } from "discourse-common/utils/decorators";
import getURL from "discourse-common/lib/get-url";
import { observes } from "discourse-common/utils/decorators";
import { on } from "@ember/object/evented";
const COLOR_VARS_REGEX =
/\$(primary|secondary|tertiary|quaternary|header_background|header_primary|highlight|danger|success|love)(\s|;|-(low|medium|high))/g;
@classNames("ace-wrapper")
export default class AceEditor extends Component {
mode = "css";
disabled = false;
htmlPlaceholder = false;
_editor = null;
_skipContentChangeEvent = null;
export default Component.extend({
mode: "css",
classNames: ["ace-wrapper"],
_editor: null,
_skipContentChangeEvent: null,
disabled: false,
@observes("editorId")
editorIdChanged() {
if (this.autofocus) {
this.send("focus");
}
}
didRender() {
this._skipContentChangeEvent = false;
}
},
@observes("content")
contentChanged() {
@ -35,14 +24,14 @@ export default class AceEditor extends Component {
if (this._editor && !this._skipContentChangeEvent) {
this._editor.getSession().setValue(content);
}
}
},
@observes("mode")
modeChanged() {
if (this._editor && !this._skipContentChangeEvent) {
this._editor.getSession().setMode("ace/mode/" + this.mode);
}
}
},
@observes("placeholder")
placeholderChanged() {
@ -51,12 +40,12 @@ export default class AceEditor extends Component {
placeholder: this.placeholder,
});
}
}
},
@observes("disabled")
disabledStateChanged() {
this.changeDisabledState();
}
},
changeDisabledState() {
const editor = this._editor;
@ -69,10 +58,9 @@ export default class AceEditor extends Component {
});
editor.container.parentNode.setAttribute("data-disabled", disabled);
}
}
},
@on("willDestroyElement")
_destroyEditor() {
_destroyEditor: on("willDestroyElement", function () {
if (this._editor) {
this._editor.destroy();
this._editor = null;
@ -83,58 +71,41 @@ export default class AceEditor extends Component {
}
$(window).off("ace:resize");
}
}),
resize() {
if (this._editor) {
this._editor.resize();
}
}
},
didInsertElement() {
super.didInsertElement(...arguments);
this._super(...arguments);
loadScript("/javascripts/ace/ace.js").then(() => {
window.ace.require(["ace/ace"], (loadedAce) => {
loadedAce.config.set("loadWorkerFromBlob", false);
loadedAce.config.set("workerPath", getURL("/javascripts/ace")); // Do not use CDN for workers
if (this.htmlPlaceholder) {
this._overridePlaceholder(loadedAce);
}
if (!this.element || this.isDestroying || this.isDestroyed) {
return;
}
const editor = loadedAce.edit(this.element.querySelector(".ace"));
editor.setTheme("ace/theme/chrome");
editor.setShowPrintMargin(false);
editor.setOptions({ fontSize: "14px", placeholder: this.placeholder });
editor.getSession().setMode("ace/mode/" + this.mode);
editor.on("change", () => {
this._skipContentChangeEvent = true;
this.set("content", editor.getSession().getValue());
this._skipContentChangeEvent = false;
});
if (this.attrs.save) {
editor.commands.addCommand({
name: "save",
exec: () => {
this.attrs.save();
},
bindKey: { mac: "cmd-s", win: "ctrl-s" },
});
}
editor.on("blur", () => {
this.warnSCSSDeprecations();
});
editor.$blockScrolling = Infinity;
editor.renderer.setScrollMargin(10, 10);
this.element.setAttribute("data-editor", editor);
this._editor = editor;
this.changeDisabledState();
this.warnSCSSDeprecations();
$(window)
.off("ace:resize")
@ -148,98 +119,16 @@ export default class AceEditor extends Component {
if (this.autofocus) {
this.send("focus");
}
this.setAceTheme();
this._darkModeListener = window.matchMedia(
"(prefers-color-scheme: dark)"
);
this._darkModeListener.addListener(this.setAceTheme);
});
});
}
},
willDestroyElement() {
if (this._darkModeListener) {
this._darkModeListener.removeListener(this.setAceTheme);
}
}
@bind
setAceTheme() {
const schemeType = getComputedStyle(document.body)
.getPropertyValue("--scheme-type")
.trim();
this._editor.setTheme(
`ace/theme/${schemeType === "dark" ? "chaos" : "chrome"}`
);
}
warnSCSSDeprecations() {
if (
this.mode !== "scss" ||
this.editorId.startsWith("color_definitions") ||
!this._editor
) {
return;
}
let warnings = this.content
.split("\n")
.map((line, row) => {
if (line.match(COLOR_VARS_REGEX)) {
return {
row,
column: 0,
text: I18n.t("admin.customize.theme.scss_warning_inline"),
type: "warning",
};
}
})
.filter(Boolean);
this._editor.getSession().setAnnotations(warnings);
this.setWarning?.(
warnings.length
? I18n.t("admin.customize.theme.scss_color_variables_warning")
: false
);
}
@action
focus() {
if (this._editor) {
this._editor.focus();
this._editor.navigateFileEnd();
}
}
_overridePlaceholder(loadedAce) {
const originalPlaceholderSetter =
loadedAce.config.$defaultOptions.editor.placeholder.set;
loadedAce.config.$defaultOptions.editor.placeholder.set = function () {
if (!this.$updatePlaceholder) {
const originalRendererOn = this.renderer.on;
this.renderer.on = function () {};
originalPlaceholderSetter.call(this, ...arguments);
this.renderer.on = originalRendererOn;
const originalUpdatePlaceholder = this.$updatePlaceholder;
this.$updatePlaceholder = function () {
originalUpdatePlaceholder.call(this, ...arguments);
if (this.renderer.placeholderNode) {
this.renderer.placeholderNode.innerHTML = this.$placeholder || "";
}
}.bind(this);
this.on("input", this.$updatePlaceholder);
actions: {
focus() {
if (this._editor) {
this._editor.focus();
this._editor.navigateFileEnd();
}
this.$updatePlaceholder();
};
}
}
},
},
});

View File

@ -1,8 +0,0 @@
{{#if this.hasFormattedLogs}}
<pre>{{this.formattedLogs}}</pre>
{{else}}
<p>{{this.noLogsMessage}}</p>
{{/if}}
{{#if this.showLoadingSpinner}}
<div class="spinner small"></div>
{{/if}}

View File

@ -1,26 +1,28 @@
import { classNames } from "@ember-decorators/component";
import { observes, on } from "@ember-decorators/object";
import Component from "@ember/component";
import I18n from "I18n";
import discourseDebounce from "discourse-common/lib/debounce";
import { scheduleOnce } from "@ember/runloop";
import Component from "@ember/component";
import discourseDebounce from "discourse/lib/debounce";
import { observes, on } from "discourse-common/utils/decorators";
@classNames("admin-backups-logs")
export default class AdminBackupsLogs extends Component {
showLoadingSpinner = false;
hasFormattedLogs = false;
noLogsMessage = I18n.t("admin.backups.logs.none");
formattedLogs = "";
index = 0;
export default Component.extend({
classNames: ["admin-backups-logs"],
showLoadingSpinner: false,
hasFormattedLogs: false,
noLogsMessage: I18n.t("admin.backups.logs.none"),
init() {
this._super(...arguments);
this._reset();
},
_reset() {
this.setProperties({ formattedLogs: "", index: 0 });
}
},
_scrollDown() {
const div = this.element;
div.scrollTop = div.scrollHeight;
}
},
@on("init")
@observes("logs.[]")
@ -29,9 +31,11 @@ export default class AdminBackupsLogs extends Component {
this._reset(); // reset the cached logs whenever the model is reset
this.renderLogs();
}
}
},
_updateFormattedLogsFunc() {
@on("init")
@observes("logs.[]")
_updateFormattedLogs: discourseDebounce(function () {
const logs = this.logs;
if (logs.length === 0) {
return;
@ -46,20 +50,14 @@ export default class AdminBackupsLogs extends Component {
}
// update the formatted logs & cache index
this.setProperties({
formattedLogs,
formattedLogs: formattedLogs,
index: logs.length,
});
// force rerender
this.renderLogs();
scheduleOnce("afterRender", this, this._scrollDown);
}
@on("init")
@observes("logs.[]")
_updateFormattedLogs() {
discourseDebounce(this, this._updateFormattedLogsFunc, 150);
}
}, 150),
renderLogs() {
const formattedLogs = this.formattedLogs;
@ -74,5 +72,5 @@ export default class AdminBackupsLogs extends Component {
} else {
this.set("showLoadingSpinner", false);
}
}
}
},
});

View File

@ -1,30 +0,0 @@
<div class="field">{{i18n this.name}}</div>
<div class="value">
{{#if this.editing}}
<TextField
@value={{this.buffer}}
@autofocus="autofocus"
@autocomplete="off"
/>
{{else}}
<a href {{on "click" this.edit}} class="inline-editable-field">
<span>{{this.value}}</span>
</a>
{{/if}}
</div>
<div class="controls">
{{#if this.editing}}
<DButton
@class="btn-default"
@action={{action "save"}}
@label="admin.user_fields.save"
/>
<a href {{on "click" this.edit}}>{{i18n "cancel"}}</a>
{{else}}
<DButton
@class="btn-default"
@action={{action "edit"}}
@icon="pencil-alt"
/>
{{/if}}
</div>

View File

@ -1,22 +1,24 @@
import { tagName } from "@ember-decorators/component";
import Component from "@ember/component";
import { action } from "@ember/object";
export default Component.extend({
tagName: "",
@tagName("")
export default class AdminEditableField extends Component {
buffer = "";
editing = false;
buffer: "",
editing: false,
@action
edit(event) {
event?.preventDefault();
this.set("buffer", this.value);
this.toggleProperty("editing");
}
init() {
this._super(...arguments);
this.set("editing", false);
},
@action
save() {
// Action has to toggle 'editing' property.
this.action(this.buffer);
}
}
actions: {
edit() {
this.set("buffer", this.value);
this.toggleProperty("editing");
},
save() {
// Action has to toggle 'editing' property.
this.action(this.buffer);
},
},
});

View File

@ -1,14 +0,0 @@
<div class="form-element label-area">
{{#if this.label}}
<label>{{i18n this.label}}</label>
{{else}}
&nbsp;
{{/if}}
</div>
<div class="form-element input-area">
{{#if this.wrapLabel}}
<label>{{yield}}</label>
{{else}}
{{yield}}
{{/if}}
</div>

View File

@ -1,5 +1,4 @@
import { classNames } from "@ember-decorators/component";
import Component from "@ember/component";
@classNames("row")
export default class AdminFormRow extends Component {}
export default Component.extend({
classNames: ["row"],
});

View File

@ -1,17 +1,16 @@
import { tagName } from "@ember-decorators/component";
import Component from "@ember/component";
import loadScript from "discourse/lib/load-script";
@tagName("canvas")
export default class AdminGraph extends Component {
type = "line";
export default Component.extend({
tagName: "canvas",
type: "line",
refreshChart() {
const ctx = this.element.getContext("2d");
const model = this.model;
const rawData = this.get("model.data");
let data = {
var data = {
labels: rawData.map((r) => r.x),
datasets: [
{
@ -25,19 +24,17 @@ export default class AdminGraph extends Component {
const config = {
type: this.type,
data,
data: data,
options: {
responsive: true,
plugins: {
tooltip: {
callbacks: {
title: (context) =>
moment(context[0].label, "YYYY-MM-DD").format("LL"),
},
tooltips: {
callbacks: {
title: (context) =>
moment(context[0].xLabel, "YYYY-MM-DD").format("LL"),
},
},
scales: {
y: [
yAxes: [
{
display: true,
ticks: {
@ -50,11 +47,11 @@ export default class AdminGraph extends Component {
};
this._chart = new window.Chart(ctx, config);
}
},
didInsertElement() {
loadScript("/javascripts/Chart.min.js").then(() =>
this.refreshChart.apply(this)
);
}
}
},
});

View File

@ -1,7 +0,0 @@
<div class="admin-controls">
<nav>
<ul class="nav nav-pills">
{{yield}}
</ul>
</nav>
</div>

View File

@ -1,5 +1,4 @@
import { tagName } from "@ember-decorators/component";
import Component from "@ember/component";
@tagName("")
export default class AdminNav extends Component {}
export default Component.extend({
tagName: "",
});

Some files were not shown because too many files have changed in this diff Show More