diff --git a/.github/workflows/labeler.yml b/.github/workflows/labeler.yml index ccadfb89777..0b3e2515d7d 100644 --- a/.github/workflows/labeler.yml +++ b/.github/workflows/labeler.yml @@ -10,7 +10,7 @@ permissions: jobs: triage: if: github.actor != 'discourse-translator-bot' - runs-on: debian-12 + runs-on: ubuntu-latest steps: - uses: actions/labeler@v5 diff --git a/.github/workflows/licenses.yml b/.github/workflows/licenses.yml index 9e7a6384beb..1b8252cb174 100644 --- a/.github/workflows/licenses.yml +++ b/.github/workflows/licenses.yml @@ -17,7 +17,7 @@ jobs: build: if: github.event_name == 'pull_request' || github.repository != 'discourse/discourse-private-mirror' name: run - runs-on: debian-12 + runs-on: ${{ (github.repository != 'discourse/discourse' && 'ubuntu-latest') || 'debian-12' }} container: discourse/discourse_test:slim timeout-minutes: 10 diff --git a/.github/workflows/linting.yml b/.github/workflows/linting.yml index 13990395090..d016f50cd4a 100644 --- a/.github/workflows/linting.yml +++ b/.github/workflows/linting.yml @@ -17,7 +17,7 @@ jobs: build: if: github.event_name == 'pull_request' || github.repository != 'discourse/discourse-private-mirror' name: run - runs-on: debian-12 + runs-on: ${{ (github.repository != 'discourse/discourse' && 'ubuntu-latest') || 'debian-12' }} container: discourse/discourse_test:slim timeout-minutes: 30 diff --git a/.github/workflows/migration-tests.yml b/.github/workflows/migration-tests.yml index f39602de7eb..a1f4e119f8c 100644 --- a/.github/workflows/migration-tests.yml +++ b/.github/workflows/migration-tests.yml @@ -24,7 +24,7 @@ jobs: tests: if: github.event_name == 'pull_request' || github.repository != 'discourse/discourse-private-mirror' name: Tests with Ruby ${{ matrix.ruby }} - runs-on: debian-12 + runs-on: ${{ (github.repository != 'discourse/discourse' && 'ubuntu-latest') || 'debian-12' }} container: discourse/discourse_test:slim timeout-minutes: 20 @@ -126,11 +126,11 @@ jobs: if: steps.app-cache.outputs.cache-hit != 'true' run: rm -rf tmp/app-cache/uploads && cp -r public/uploads tmp/app-cache/uploads -# - name: Check core database drift -# run: | -# mkdir /tmp/intermediate_db -# ./migrations/scripts/schema_generator /tmp/intermediate_db/base_migration.sql -# diff -u migrations/common/intermediate_db_schema/000_base_schema.sql /tmp/intermediate_db/base_migration.sql + # - name: Check core database drift + # run: | + # mkdir /tmp/intermediate_db + # ./migrations/scripts/schema_generator /tmp/intermediate_db/base_migration.sql + # diff -u migrations/common/intermediate_db_schema/000_base_schema.sql /tmp/intermediate_db/base_migration.sql - name: RSpec run: bin/rspec --default-path migrations/spec diff --git a/.github/workflows/release-notes.yml b/.github/workflows/release-notes.yml index 2d2fcf65a60..eb0a35d45a8 100644 --- a/.github/workflows/release-notes.yml +++ b/.github/workflows/release-notes.yml @@ -4,14 +4,14 @@ on: workflow_dispatch: inputs: from: - description: 'Starting ref (exclusive). Can be a tag, branch or commit ref. `latest-release` refers to the last beta version bump.' + description: "Starting ref (exclusive). Can be a tag, branch or commit ref. `latest-release` refers to the last beta version bump." required: true - default: 'latest-release' + default: "latest-release" type: string to: - description: 'Ending ref (inclusive). Can be a tag, branch or commit ref. `HEAD` refers to the most recent commit.' + description: "Ending ref (inclusive). Can be a tag, branch or commit ref. `HEAD` refers to the most recent commit." required: true - default: 'HEAD' + default: "HEAD" type: string permissions: @@ -20,7 +20,7 @@ permissions: jobs: build: name: run - runs-on: debian-12 + runs-on: ${{ (github.repository != 'discourse/discourse' && 'ubuntu-latest') || 'debian-12' }} container: discourse/discourse_test:slim timeout-minutes: 10 env: @@ -87,7 +87,7 @@ jobs: echo "From: $from_ref - $(git rev-parse --short $from_ref) - ${{ steps.dates.outputs.from }}" >> $GITHUB_STEP_SUMMARY echo "To: $to_ref - $(git rev-parse --short $to_ref) - ${{ steps.dates.outputs.to }}" >> $GITHUB_STEP_SUMMARY - + echo "" >> $GITHUB_STEP_SUMMARY echo "---" >> $GITHUB_STEP_SUMMARY echo "" >> $GITHUB_STEP_SUMMARY diff --git a/.github/workflows/stale-pr-closer.yml b/.github/workflows/stale-pr-closer.yml index b0469f4f9ad..de7299191d9 100644 --- a/.github/workflows/stale-pr-closer.yml +++ b/.github/workflows/stale-pr-closer.yml @@ -1,7 +1,7 @@ -name: 'Close stale PRs' +name: "Close stale PRs" on: schedule: - - cron: '30 1 * * *' + - cron: "30 1 * * *" workflow_dispatch: permissions: @@ -9,11 +9,11 @@ permissions: jobs: stale: - runs-on: debian-12 + runs-on: ${{ (github.repository != 'discourse/discourse' && 'ubuntu-latest') || 'debian-12' }} steps: - uses: actions/stale@v9 with: days-before-stale: 60 days-before-close: 14 - stale-pr-message: 'This pull request has been automatically marked as stale because it has been open for 60 days with no activity. To keep it open, remove the stale tag, push code, or add a comment. Otherwise, it will be closed in 14 days.' + stale-pr-message: "This pull request has been automatically marked as stale because it has been open for 60 days with no activity. To keep it open, remove the stale tag, push code, or add a comment. Otherwise, it will be closed in 14 days." exempt-pr-labels: dependencies diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 80c4851c960..89737d8a00d 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -29,7 +29,7 @@ jobs: build: if: github.event_name == 'pull_request' || github.repository != 'discourse/discourse-private-mirror' name: ${{ matrix.target }} ${{ matrix.build_type }} # Update fetch-job-id step if changing this - runs-on: ${{ ((github.ref == 'refs/heads/main') && 'debian-12') || 'ubuntu-22.04-8core' }} + runs-on: ${{ (github.repository != 'discourse/discourse' && 'ubuntu-22.04-8core') || 'debian-12' }} container: discourse/discourse_test:slim${{ (matrix.build_type == 'frontend' || matrix.build_type == 'system') && '-browsers' || '' }} timeout-minutes: 20 @@ -44,6 +44,7 @@ jobs: DISCOURSE_TURBO_RSPEC_RETRY_AND_LOG_FLAKY_TESTS: ${{ (matrix.build_type == 'system' || matrix.build_type == 'backend') && github.ref == 'refs/heads/main' && '1' }} CHEAP_SOURCE_MAPS: "1" TESTEM_DEFAULT_BROWSER: Chrome + MINIO_RUNNER_INSTALL_DIR: /home/discourse/.minio_runner strategy: fail-fast: false @@ -255,6 +256,13 @@ jobs: if: matrix.build_type == 'system' run: bin/ember-cli --build + - name: Minio cache + if: matrix.build_type == 'system' && matrix.target == 'core' + uses: actions/cache@v4 + with: + path: ${{ env.MINIO_RUNNER_INSTALL_DIR }} + key: ${{ runner.os }}-${{ steps.container-envs.outputs.ruby_version }}-${{ steps.container-envs.outputs.debian_release }}-gem-${{ hashFiles('**/Gemfile.lock') }} + - name: Ensure latest minio binary installed for Core System Tests if: matrix.build_type == 'system' && matrix.target == 'core' run: bundle exec ruby script/install_minio_binaries.rb @@ -358,7 +366,7 @@ jobs: core_frontend_tests: if: github.event_name == 'pull_request' || github.repository != 'discourse/discourse-private-mirror' name: core frontend (${{ matrix.browser }}) - runs-on: ${{ ((github.ref == 'refs/heads/main') && 'debian-12') || 'ubuntu-22.04-8core' }} + runs-on: ${{ (github.repository != 'discourse/discourse' && 'ubuntu-22.04-8core') || 'debian-12' }} container: image: discourse/discourse_test:slim-browsers options: --user discourse @@ -397,7 +405,7 @@ jobs: - name: Core QUnit working-directory: ./app/assets/javascripts/discourse run: | - pnpm ember exam --path /tmp/emberbuild --load-balance --parallel=$(($(nproc) / 2 + 1)) --launch "${{ env.TESTEM_BROWSER }}" --write-execution-file --random + pnpm ember exam --path /tmp/emberbuild --load-balance --parallel=$(($(nproc) / 2)) --launch "${{ env.TESTEM_BROWSER }}" --write-execution-file --random timeout-minutes: 15 - uses: actions/upload-artifact@v4 diff --git a/.licensed.yml b/.licensed.yml index cbd3d6472ab..1de021fc63f 100644 --- a/.licensed.yml +++ b/.licensed.yml @@ -45,6 +45,7 @@ reviewed: - concurrent-ruby # MIT - css_parser # MIT - drb # BSD-2-Clause + - dry-initializer # MIT - excon # MIT - faraday-em_http # MIT - faraday-em_synchrony # MIT diff --git a/Gemfile b/Gemfile index 81db1d4e4ae..0ebcced79e1 100644 --- a/Gemfile +++ b/Gemfile @@ -287,3 +287,5 @@ group :migrations, optional: true do # CLI gem "ruby-progressbar" end + +gem "dry-initializer", "~> 3.1" diff --git a/Gemfile.lock b/Gemfile.lock index 39988ad5f5a..4686a89a326 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -132,9 +132,10 @@ GEM literate_randomizer docile (1.4.1) drb (2.2.1) + dry-initializer (3.1.1) email_reply_trimmer (0.1.13) erubi (1.13.0) - excon (0.111.0) + excon (0.112.0) execjs (2.9.1) exifr (1.4.0) extralite-bundle (2.8.2) @@ -142,8 +143,9 @@ GEM faker (2.23.0) i18n (>= 1.8.11, < 2) fakeweb (1.3.0) - faraday (2.11.0) + faraday (2.12.0) faraday-net_http (>= 2.0, < 3.4) + json logger faraday-net_http (3.3.0) net-http @@ -158,16 +160,16 @@ GEM fspath (3.1.2) globalid (1.2.1) activesupport (>= 6.1) - google-protobuf (4.28.1-aarch64-linux) + google-protobuf (4.28.2-aarch64-linux) bigdecimal rake (>= 13) - google-protobuf (4.28.1-arm64-darwin) + google-protobuf (4.28.2-arm64-darwin) bigdecimal rake (>= 13) - google-protobuf (4.28.1-x86_64-darwin) + google-protobuf (4.28.2-x86_64-darwin) bigdecimal rake (>= 13) - google-protobuf (4.28.1-x86_64-linux) + google-protobuf (4.28.2-x86_64-linux) bigdecimal rake (>= 13) guess_html_encoding (0.0.11) @@ -178,7 +180,7 @@ GEM reline htmlentities (4.3.4) http_accept_language (2.1.1) - i18n (1.14.5) + i18n (1.14.6) concurrent-ruby (~> 1.0) image_optim (0.31.3) exifr (~> 1.2, >= 1.2.2) @@ -189,7 +191,7 @@ GEM image_size (3.4.0) in_threads (1.6.0) io-console (0.7.2) - irb (1.14.0) + irb (1.14.1) rdoc (>= 4.0.0) reline (>= 0.4.2) iso8601 (0.13.0) @@ -234,7 +236,7 @@ GEM net-smtp matrix (0.4.2) maxminddb (0.1.22) - memory_profiler (1.0.2) + memory_profiler (1.1.0) message_bus (4.3.8) rack (>= 1.1.3) messageformat-wrapper (1.1.0) @@ -344,7 +346,7 @@ GEM psych (5.1.2) stringio public_suffix (6.0.1) - puma (6.4.2) + puma (6.4.3) nio4r (~> 2.0) racc (1.8.1) rack (2.2.9) @@ -404,10 +406,10 @@ GEM io-console (~> 0.5) request_store (1.7.0) rack (>= 1.4) - rexml (3.3.7) + rexml (3.3.8) rinku (2.0.6) rotp (6.3.0) - rouge (4.3.0) + rouge (4.4.0) rqrcode (2.2.0) chunky_png (~> 1.0) rqrcode_core (~> 1.0) @@ -426,7 +428,7 @@ GEM rspec-html-matchers (0.10.0) nokogiri (~> 1) rspec (>= 3.0.0.a) - rspec-mocks (3.13.1) + rspec-mocks (3.13.2) diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.13.0) rspec-multi-mock (0.3.1) @@ -473,12 +475,12 @@ GEM rubocop-rspec_rails (>= 2.30.0) rubocop-factory_bot (2.26.1) rubocop (~> 1.61) - rubocop-rails (2.26.1) + rubocop-rails (2.26.2) activesupport (>= 4.2.0) rack (>= 1.1) rubocop (>= 1.52.0, < 2.0) rubocop-ast (>= 1.31.1, < 2.0) - rubocop-rspec (3.0.5) + rubocop-rspec (3.1.0) rubocop (~> 1.61) rubocop-rspec_rails (2.30.0) rubocop (~> 1.61) @@ -503,9 +505,9 @@ GEM google-protobuf (>= 3.25, < 5.0) sassc-embedded (1.77.7) sass-embedded (~> 1.77) - selenium-devtools (0.128.0) + selenium-devtools (0.129.0) selenium-webdriver (~> 4.2) - selenium-webdriver (4.24.0) + selenium-webdriver (4.25.0) base64 (~> 0.2) logger (~> 1.4) rexml (~> 3.2, >= 3.2.5) @@ -527,7 +529,7 @@ GEM snaky_hash (2.0.1) hashie version_gem (~> 1.1, >= 1.1.1) - sprockets (3.7.4) + sprockets (3.7.5) base64 concurrent-ruby (~> 1.0) rack (> 1, < 3) @@ -535,10 +537,10 @@ GEM actionpack (>= 6.1) activesupport (>= 6.1) sprockets (>= 3.0.0) - sqlite3 (2.0.4-aarch64-linux-gnu) - sqlite3 (2.0.4-arm64-darwin) - sqlite3 (2.0.4-x86_64-darwin) - sqlite3 (2.0.4-x86_64-linux-gnu) + sqlite3 (2.1.0-aarch64-linux-gnu) + sqlite3 (2.1.0-arm64-darwin) + sqlite3 (2.1.0-x86_64-darwin) + sqlite3 (2.1.0-x86_64-linux-gnu) sshkey (3.0.0) stackprof (0.2.26) stringio (3.1.1) @@ -553,10 +555,10 @@ GEM concurrent-ruby (~> 1.0) tzinfo-data (1.2024.2) tzinfo (>= 1.0.0) - uglifier (4.2.0) + uglifier (4.2.1) execjs (>= 0.3.0, < 3) unf (0.2.0) - unicode-display_width (2.5.0) + unicode-display_width (2.6.0) unicorn (6.1.0) kgio (~> 2.6) raindrops (~> 0.7) @@ -566,7 +568,7 @@ GEM web-push (3.0.1) jwt (~> 2.0) openssl (~> 3.0) - webmock (3.23.1) + webmock (3.24.0) addressable (>= 2.8.0) crack (>= 0.3.2) hashdiff (>= 0.4.0, < 2.0.0) @@ -623,6 +625,7 @@ DEPENDENCIES discourse-fonts discourse-seed-fu discourse_dev_assets + dry-initializer (~> 3.1) email_reply_trimmer excon execjs diff --git a/app/assets/javascripts/admin/addon/components/admin-config-area-cards/about/contact-information.gjs b/app/assets/javascripts/admin/addon/components/admin-config-area-cards/about/contact-information.gjs index db75ec52aa7..e0bf32ec63c 100644 --- a/app/assets/javascripts/admin/addon/components/admin-config-area-cards/about/contact-information.gjs +++ b/app/assets/javascripts/admin/addon/components/admin-config-area-cards/about/contact-information.gjs @@ -82,7 +82,7 @@ export default class AdminConfigAreasAboutContactInformation extends Component {
{{this.description}}
+
+
-
{{this.code}}
\ No newline at end of file
diff --git a/app/assets/javascripts/admin/addon/components/highlighted-code.js b/app/assets/javascripts/admin/addon/components/highlighted-code.js
deleted file mode 100644
index 65208dc6eff..00000000000
--- a/app/assets/javascripts/admin/addon/components/highlighted-code.js
+++ /dev/null
@@ -1,11 +0,0 @@
-import Component from "@ember/component";
-import { observes, on } from "@ember-decorators/object";
-import highlightSyntax from "discourse/lib/highlight-syntax";
-
-export default class HighlightedCode extends Component {
- @on("didInsertElement")
- @observes("code")
- _refresh() {
- highlightSyntax(this.element, this.siteSettings, this.session);
- }
-}
diff --git a/app/assets/javascripts/admin/addon/controllers/admin-dashboard.js b/app/assets/javascripts/admin/addon/controllers/admin-dashboard.js
index 89a6a52ad19..8f60607eba4 100644
--- a/app/assets/javascripts/admin/addon/controllers/admin-dashboard.js
+++ b/app/assets/javascripts/admin/addon/controllers/admin-dashboard.js
@@ -18,16 +18,6 @@ export default class AdminDashboardController extends Controller {
@setting("version_checks") showVersionChecks;
- @discourseComputed(
- "lowPriorityProblems.length",
- "highPriorityProblems.length"
- )
- foundProblems(lowPriorityProblemsLength, highPriorityProblemsLength) {
- const problemsLength =
- lowPriorityProblemsLength + highPriorityProblemsLength;
- return this.currentUser.admin && problemsLength > 0;
- }
-
@computed("siteSettings.dashboard_visible_tabs")
get visibleTabs() {
return (this.siteSettings.dashboard_visible_tabs || "")
@@ -106,16 +96,7 @@ export default class AdminDashboardController extends Controller {
});
AdminDashboard.fetchProblems()
- .then((model) => {
- this.set(
- "highPriorityProblems",
- model.problems.filterBy("priority", "high")
- );
- this.set(
- "lowPriorityProblems",
- model.problems.filterBy("priority", "low")
- );
- })
+ .then((model) => this.set("problems", model.problems))
.finally(() => this.set("loadingProblems", false));
}
diff --git a/app/assets/javascripts/admin/addon/controllers/admin-user-index.js b/app/assets/javascripts/admin/addon/controllers/admin-user-index.js
index b3133a9f053..d1fac2a80d3 100644
--- a/app/assets/javascripts/admin/addon/controllers/admin-user-index.js
+++ b/app/assets/javascripts/admin/addon/controllers/admin-user-index.js
@@ -78,8 +78,8 @@ export default class AdminUserIndexController extends Controller.extend(
@discourseComputed("model.associated_accounts")
associatedAccounts(associatedAccounts) {
return associatedAccounts
- .map((provider) => `${provider.name} (${provider.description})`)
- .join(", ");
+ ?.map((provider) => `${provider.name} (${provider.description})`)
+ ?.join(", ");
}
@discourseComputed("model.user_fields.[]")
@@ -319,6 +319,16 @@ export default class AdminUserIndexController extends Controller.extend(
return this.model.silence();
}
+ @action
+ deleteAssociatedAccounts() {
+ this.dialog.yesNoConfirm({
+ message: I18n.t("admin.user.delete_associated_accounts_confirm"),
+ didConfirm: () => {
+ this.model.deleteAssociatedAccounts().catch(popupAjaxError);
+ },
+ });
+ }
+
@action
anonymize() {
const user = this.model;
diff --git a/app/assets/javascripts/admin/addon/models/admin-plugin.js b/app/assets/javascripts/admin/addon/models/admin-plugin.js
index 33730888da8..02d940d9470 100644
--- a/app/assets/javascripts/admin/addon/models/admin-plugin.js
+++ b/app/assets/javascripts/admin/addon/models/admin-plugin.js
@@ -24,6 +24,10 @@ export default class AdminPlugin {
return this.name.replaceAll("-", "_");
}
+ get kebabCaseName() {
+ return this.name.replaceAll(" ", "-").replaceAll("_", "-");
+ }
+
get translatedCategoryName() {
// We do this because the site setting list is grouped by category,
// with plugins that have their root site setting key defined as `plugins:`
diff --git a/app/assets/javascripts/admin/addon/models/admin-user.js b/app/assets/javascripts/admin/addon/models/admin-user.js
index 79489398db6..0449fd5056c 100644
--- a/app/assets/javascripts/admin/addon/models/admin-user.js
+++ b/app/assets/javascripts/admin/addon/models/admin-user.js
@@ -287,6 +287,17 @@ export default class AdminUser extends User {
});
}
+ deleteAssociatedAccounts() {
+ return ajax(`/admin/users/${this.id}/delete_associated_accounts`, {
+ type: "PUT",
+ data: {
+ context: window.location.pathname,
+ },
+ }).then(() => {
+ this.set("associated_accounts", []);
+ });
+ }
+
destroy(formData) {
return ajax(`/admin/users/${this.id}.json`, {
type: "DELETE",
diff --git a/app/assets/javascripts/admin/addon/routes/admin-route-map.js b/app/assets/javascripts/admin/addon/routes/admin-route-map.js
index c0adae5c180..facec60a4f4 100644
--- a/app/assets/javascripts/admin/addon/routes/admin-route-map.js
+++ b/app/assets/javascripts/admin/addon/routes/admin-route-map.js
@@ -239,5 +239,13 @@ export default function () {
path: "/whats-new",
resetNamespace: true,
});
+
+ this.route(
+ "adminSection",
+ { path: "/section", resetNamespace: true },
+ function () {
+ this.route("account");
+ }
+ );
});
}
diff --git a/app/assets/javascripts/admin/addon/templates/dashboard.hbs b/app/assets/javascripts/admin/addon/templates/dashboard.hbs
index 2d0e81ff674..f5a07025ee1 100644
--- a/app/assets/javascripts/admin/addon/templates/dashboard.hbs
+++ b/app/assets/javascripts/admin/addon/templates/dashboard.hbs
@@ -18,9 +18,7 @@
{{i18n "categories.category"}} | {{i18n "categories.topics"}} | {{#if this.showTopics}} @@ -51,19 +18,61 @@ {{/if}}
---|
{{i18n "categories.category"}} | +{{i18n "categories.topics"}} | + {{#if this.showTopics}} +{{i18n "categories.latest"}} | + {{/if}} +
---|
- {{i18n - "badges.favorite_count" - count=this.favoriteBadges.length - max=this.siteSettings.max_favorite_badges - }} -
- {{/if}} ++ {{i18n + "badges.favorite_count" + count=this.favoriteBadges.length + max=this.siteSettings.max_favorite_badges + }} +
+ {{/if}} -