mirror of
https://github.com/mastodon/mastodon.git
synced 2024-12-22 18:45:41 +01:00
Merge branch 'main' into patch-7
This commit is contained in:
commit
6f019e013f
2348 changed files with 59815 additions and 32986 deletions
59
.annotaterb.yml
Normal file
59
.annotaterb.yml
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
---
|
||||||
|
:position: before
|
||||||
|
:position_in_additional_file_patterns: before
|
||||||
|
:position_in_class: before
|
||||||
|
:position_in_factory: before
|
||||||
|
:position_in_fixture: before
|
||||||
|
:position_in_routes: before
|
||||||
|
:position_in_serializer: before
|
||||||
|
:position_in_test: before
|
||||||
|
:classified_sort: true
|
||||||
|
:exclude_controllers: true
|
||||||
|
:exclude_factories: true
|
||||||
|
:exclude_fixtures: true
|
||||||
|
:exclude_helpers: true
|
||||||
|
:exclude_scaffolds: true
|
||||||
|
:exclude_serializers: true
|
||||||
|
:exclude_sti_subclasses: true
|
||||||
|
:exclude_tests: true
|
||||||
|
:force: false
|
||||||
|
:format_markdown: false
|
||||||
|
:format_rdoc: false
|
||||||
|
:format_yard: false
|
||||||
|
:frozen: false
|
||||||
|
:ignore_model_sub_dir: false
|
||||||
|
:ignore_unknown_models: false
|
||||||
|
:include_version: false
|
||||||
|
:show_complete_foreign_keys: false
|
||||||
|
:show_foreign_keys: false
|
||||||
|
:show_indexes: false
|
||||||
|
:simple_indexes: false
|
||||||
|
:sort: false
|
||||||
|
:timestamp: false
|
||||||
|
:trace: false
|
||||||
|
:with_comment: true
|
||||||
|
:with_column_comments: true
|
||||||
|
:with_table_comments: true
|
||||||
|
:active_admin: false
|
||||||
|
:command:
|
||||||
|
:debug: false
|
||||||
|
:hide_default_column_types: ''
|
||||||
|
:hide_limit_column_types: 'integer,boolean'
|
||||||
|
:ignore_columns:
|
||||||
|
:ignore_routes:
|
||||||
|
:models: true
|
||||||
|
:routes: false
|
||||||
|
:skip_on_db_migrate: false
|
||||||
|
:target_action: :do_annotations
|
||||||
|
:wrapper:
|
||||||
|
:wrapper_close:
|
||||||
|
:wrapper_open:
|
||||||
|
:classes_default_to_s: []
|
||||||
|
:additional_file_patterns: []
|
||||||
|
:model_dir:
|
||||||
|
- app/models
|
||||||
|
:require: []
|
||||||
|
:root_dir:
|
||||||
|
- ''
|
||||||
|
|
||||||
|
:show_check_constraints: false
|
|
@ -1,6 +1,7 @@
|
||||||
[production]
|
[production]
|
||||||
defaults
|
defaults
|
||||||
> 0.2%
|
> 0.2%
|
||||||
|
firefox >= 78
|
||||||
ios >= 15.6
|
ios >= 15.6
|
||||||
not dead
|
not dead
|
||||||
not OperaMini all
|
not OperaMini all
|
||||||
|
|
|
@ -1,6 +0,0 @@
|
||||||
---
|
|
||||||
ignore:
|
|
||||||
# devise-two-factor advisory about brute-forcing TOTP
|
|
||||||
# We have rate-limits on authentication endpoints in place (including second
|
|
||||||
# factor verification) since Mastodon v3.2.0
|
|
||||||
- CVE-2024-0227
|
|
|
@ -1,17 +1,18 @@
|
||||||
# For details, see https://github.com/devcontainers/images/tree/main/src/ruby
|
# For details, see https://github.com/devcontainers/images/tree/main/src/ruby
|
||||||
FROM mcr.microsoft.com/devcontainers/ruby:1-3.3-bookworm
|
FROM mcr.microsoft.com/devcontainers/ruby:1-3.3-bookworm
|
||||||
|
|
||||||
# Update existing node version, keep in sync with .nvmrc
|
# Install node version from .nvmrc
|
||||||
ARG NODE_VERSION="20"
|
WORKDIR /app
|
||||||
RUN . /usr/local/share/nvm/nvm.sh && nvm install ${NODE_VERSION} 2>&1
|
COPY .nvmrc .
|
||||||
|
RUN /bin/bash --login -i -c "nvm install"
|
||||||
|
|
||||||
# Install additional OS packages
|
# Install additional OS packages
|
||||||
RUN apt-get update && \
|
RUN apt-get update && \
|
||||||
export DEBIAN_FRONTEND=noninteractive && \
|
export DEBIAN_FRONTEND=noninteractive && \
|
||||||
apt-get -y install --no-install-recommends libicu-dev libidn11-dev ffmpeg imagemagick libvips42 libpam-dev
|
apt-get -y install --no-install-recommends libicu-dev libidn11-dev ffmpeg imagemagick libvips42 libpam-dev
|
||||||
|
|
||||||
# Install global node packages
|
# Disable download prompt for Corepack
|
||||||
RUN . /usr/local/share/nvm/nvm.sh && corepack enable 2>&1
|
ENV COREPACK_ENABLE_DOWNLOAD_PROMPT=0
|
||||||
|
|
||||||
# Move welcome message to where VS Code expects it
|
# Move welcome message to where VS Code expects it
|
||||||
COPY welcome-message.txt /usr/local/etc/vscode-dev-containers/first-run-notice.txt
|
COPY .devcontainer/welcome-message.txt /usr/local/etc/vscode-dev-containers/first-run-notice.txt
|
||||||
|
|
|
@ -2,8 +2,8 @@ services:
|
||||||
app:
|
app:
|
||||||
working_dir: /workspaces/mastodon/
|
working_dir: /workspaces/mastodon/
|
||||||
build:
|
build:
|
||||||
context: .
|
context: ..
|
||||||
dockerfile: Dockerfile
|
dockerfile: .devcontainer/Dockerfile
|
||||||
volumes:
|
volumes:
|
||||||
- ..:/workspaces/mastodon:cached
|
- ..:/workspaces/mastodon:cached
|
||||||
environment:
|
environment:
|
||||||
|
@ -69,7 +69,7 @@ services:
|
||||||
hard: -1
|
hard: -1
|
||||||
|
|
||||||
libretranslate:
|
libretranslate:
|
||||||
image: libretranslate/libretranslate:v1.5.7
|
image: libretranslate/libretranslate:v1.6.2
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
volumes:
|
volumes:
|
||||||
- lt-data:/home/libretranslate/.local
|
- lt-data:/home/libretranslate/.local
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# This is a sample configuration file. You can generate your configuration
|
# This is a sample configuration file. You can generate your configuration
|
||||||
# with the `rake mastodon:setup` interactive setup wizard, but to customize
|
# with the `bundle exec rails mastodon:setup` interactive setup wizard, but to customize
|
||||||
# your setup even further, you'll need to edit it manually. This sample does
|
# your setup even further, you'll need to edit it manually. This sample does
|
||||||
# not demonstrate all available configuration options. Please look at
|
# not demonstrate all available configuration options. Please look at
|
||||||
# https://docs.joinmastodon.org/admin/config/ for the full documentation.
|
# https://docs.joinmastodon.org/admin/config/ for the full documentation.
|
||||||
|
@ -40,14 +40,25 @@ ES_PASS=password
|
||||||
|
|
||||||
# Secrets
|
# Secrets
|
||||||
# -------
|
# -------
|
||||||
# Make sure to use `rake secret` to generate secrets
|
# Make sure to use `bundle exec rails secret` to generate secrets
|
||||||
# -------
|
# -------
|
||||||
SECRET_KEY_BASE=
|
SECRET_KEY_BASE=
|
||||||
OTP_SECRET=
|
OTP_SECRET=
|
||||||
|
|
||||||
|
# Encryption secrets
|
||||||
|
# ------------------
|
||||||
|
# Must be available (and set to same values) for all server processes
|
||||||
|
# These are private/secret values, do not share outside hosting environment
|
||||||
|
# Use `bin/rails db:encryption:init` to generate fresh secrets
|
||||||
|
# Do not change these secrets once in use, as this would cause data loss and other issues
|
||||||
|
# ------------------
|
||||||
|
# ACTIVE_RECORD_ENCRYPTION_DETERMINISTIC_KEY=
|
||||||
|
# ACTIVE_RECORD_ENCRYPTION_KEY_DERIVATION_SALT=
|
||||||
|
# ACTIVE_RECORD_ENCRYPTION_PRIMARY_KEY=
|
||||||
|
|
||||||
# Web Push
|
# Web Push
|
||||||
# --------
|
# --------
|
||||||
# Generate with `rake mastodon:webpush:generate_vapid_key`
|
# Generate with `bundle exec rails mastodon:webpush:generate_vapid_key`
|
||||||
# --------
|
# --------
|
||||||
VAPID_PRIVATE_KEY=
|
VAPID_PRIVATE_KEY=
|
||||||
VAPID_PUBLIC_KEY=
|
VAPID_PUBLIC_KEY=
|
||||||
|
|
33
.eslintrc.js
33
.eslintrc.js
|
@ -20,10 +20,6 @@ module.exports = defineConfig({
|
||||||
es6: true,
|
es6: true,
|
||||||
},
|
},
|
||||||
|
|
||||||
globals: {
|
|
||||||
ATTACHMENT_HOST: false,
|
|
||||||
},
|
|
||||||
|
|
||||||
parser: '@typescript-eslint/parser',
|
parser: '@typescript-eslint/parser',
|
||||||
|
|
||||||
plugins: [
|
plugins: [
|
||||||
|
@ -68,7 +64,6 @@ module.exports = defineConfig({
|
||||||
'indent': ['error', 2],
|
'indent': ['error', 2],
|
||||||
'jsx-quotes': ['error', 'prefer-single'],
|
'jsx-quotes': ['error', 'prefer-single'],
|
||||||
'semi': ['error', 'always'],
|
'semi': ['error', 'always'],
|
||||||
'no-case-declarations': 'off',
|
|
||||||
'no-catch-shadow': 'error',
|
'no-catch-shadow': 'error',
|
||||||
'no-console': [
|
'no-console': [
|
||||||
'warn',
|
'warn',
|
||||||
|
@ -79,7 +74,7 @@ module.exports = defineConfig({
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
'no-empty': 'off',
|
'no-empty': ['error', { "allowEmptyCatch": true }],
|
||||||
'no-restricted-properties': [
|
'no-restricted-properties': [
|
||||||
'error',
|
'error',
|
||||||
{ property: 'substring', message: 'Use .slice instead of .substring.' },
|
{ property: 'substring', message: 'Use .slice instead of .substring.' },
|
||||||
|
@ -94,7 +89,6 @@ module.exports = defineConfig({
|
||||||
message: "Use '·' (middle dot) instead of '•' (bullet)",
|
message: "Use '·' (middle dot) instead of '•' (bullet)",
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
'no-self-assign': 'off',
|
|
||||||
'no-unused-expressions': 'error',
|
'no-unused-expressions': 'error',
|
||||||
'no-unused-vars': 'off',
|
'no-unused-vars': 'off',
|
||||||
'@typescript-eslint/no-unused-vars': [
|
'@typescript-eslint/no-unused-vars': [
|
||||||
|
@ -119,12 +113,10 @@ module.exports = defineConfig({
|
||||||
'react/jsx-tag-spacing': 'error',
|
'react/jsx-tag-spacing': 'error',
|
||||||
'react/jsx-uses-react': 'off', // not needed with new JSX transform
|
'react/jsx-uses-react': 'off', // not needed with new JSX transform
|
||||||
'react/jsx-wrap-multilines': 'error',
|
'react/jsx-wrap-multilines': 'error',
|
||||||
'react/no-deprecated': 'off',
|
|
||||||
'react/react-in-jsx-scope': 'off', // not needed with new JSX transform
|
'react/react-in-jsx-scope': 'off', // not needed with new JSX transform
|
||||||
'react/self-closing-comp': 'error',
|
'react/self-closing-comp': 'error',
|
||||||
|
|
||||||
// recommended values found in https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/v6.8.0/src/index.js#L46
|
// recommended values found in https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/v6.8.0/src/index.js#L46
|
||||||
'jsx-a11y/accessible-emoji': 'warn',
|
|
||||||
'jsx-a11y/click-events-have-key-events': 'off',
|
'jsx-a11y/click-events-have-key-events': 'off',
|
||||||
'jsx-a11y/label-has-associated-control': 'off',
|
'jsx-a11y/label-has-associated-control': 'off',
|
||||||
'jsx-a11y/media-has-caption': 'off',
|
'jsx-a11y/media-has-caption': 'off',
|
||||||
|
@ -139,23 +131,6 @@ module.exports = defineConfig({
|
||||||
// ],
|
// ],
|
||||||
'jsx-a11y/no-interactive-element-to-noninteractive-role': 'off',
|
'jsx-a11y/no-interactive-element-to-noninteractive-role': 'off',
|
||||||
// recommended rule is:
|
// recommended rule is:
|
||||||
// 'jsx-a11y/no-noninteractive-element-interactions': [
|
|
||||||
// 'error',
|
|
||||||
// {
|
|
||||||
// body: ['onError', 'onLoad'],
|
|
||||||
// iframe: ['onError', 'onLoad'],
|
|
||||||
// img: ['onError', 'onLoad'],
|
|
||||||
// },
|
|
||||||
// ],
|
|
||||||
'jsx-a11y/no-noninteractive-element-interactions': [
|
|
||||||
'warn',
|
|
||||||
{
|
|
||||||
handlers: [
|
|
||||||
'onClick',
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
// recommended rule is:
|
|
||||||
// 'jsx-a11y/no-noninteractive-tabindex': [
|
// 'jsx-a11y/no-noninteractive-tabindex': [
|
||||||
// 'error',
|
// 'error',
|
||||||
// {
|
// {
|
||||||
|
@ -165,7 +140,6 @@ module.exports = defineConfig({
|
||||||
// },
|
// },
|
||||||
// ],
|
// ],
|
||||||
'jsx-a11y/no-noninteractive-tabindex': 'off',
|
'jsx-a11y/no-noninteractive-tabindex': 'off',
|
||||||
'jsx-a11y/no-onchange': 'off',
|
|
||||||
// recommended is full 'error'
|
// recommended is full 'error'
|
||||||
'jsx-a11y/no-static-element-interactions': [
|
'jsx-a11y/no-static-element-interactions': [
|
||||||
'warn',
|
'warn',
|
||||||
|
@ -341,7 +315,7 @@ module.exports = defineConfig({
|
||||||
],
|
],
|
||||||
|
|
||||||
parserOptions: {
|
parserOptions: {
|
||||||
project: true,
|
projectService: true,
|
||||||
tsconfigRootDir: __dirname,
|
tsconfigRootDir: __dirname,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -349,6 +323,9 @@ module.exports = defineConfig({
|
||||||
// Disable formatting rules that have been enabled in the base config
|
// Disable formatting rules that have been enabled in the base config
|
||||||
'indent': 'off',
|
'indent': 'off',
|
||||||
|
|
||||||
|
// This is not needed as we use noImplicitReturns, which handles this in addition to understanding types
|
||||||
|
'consistent-return': 'off',
|
||||||
|
|
||||||
'import/consistent-type-specifier-style': ['error', 'prefer-top-level'],
|
'import/consistent-type-specifier-style': ['error', 'prefer-top-level'],
|
||||||
|
|
||||||
'@typescript-eslint/consistent-type-definitions': ['warn', 'interface'],
|
'@typescript-eslint/consistent-type-definitions': ['warn', 'interface'],
|
||||||
|
|
13
.github/ISSUE_TEMPLATE/1.web_bug_report.yml
vendored
13
.github/ISSUE_TEMPLATE/1.web_bug_report.yml
vendored
|
@ -1,6 +1,7 @@
|
||||||
name: Bug Report (Web Interface)
|
name: Bug Report (Web Interface)
|
||||||
description: If you are using Mastodon's web interface and something is not working as expected
|
description: There is a problem using Mastodon's web interface.
|
||||||
labels: [bug, 'status/to triage', 'area/web interface']
|
labels: ['status/to triage', 'area/web interface']
|
||||||
|
type: Bug
|
||||||
body:
|
body:
|
||||||
- type: markdown
|
- type: markdown
|
||||||
attributes:
|
attributes:
|
||||||
|
@ -47,8 +48,8 @@ body:
|
||||||
attributes:
|
attributes:
|
||||||
label: Mastodon version
|
label: Mastodon version
|
||||||
description: |
|
description: |
|
||||||
This is displayed at the bottom of the About page, eg. `v4.1.2+nightly-20230627`
|
This is displayed at the bottom of the About page, eg. `v4.4.0-alpha.1`
|
||||||
placeholder: v4.1.2
|
placeholder: v4.3.0
|
||||||
validations:
|
validations:
|
||||||
required: true
|
required: true
|
||||||
- type: input
|
- type: input
|
||||||
|
@ -56,7 +57,7 @@ body:
|
||||||
label: Browser name and version
|
label: Browser name and version
|
||||||
description: |
|
description: |
|
||||||
What browser are you using when getting this bug? Please specify the version as well.
|
What browser are you using when getting this bug? Please specify the version as well.
|
||||||
placeholder: Firefox 105.0.3
|
placeholder: Firefox 131.0.0
|
||||||
validations:
|
validations:
|
||||||
required: true
|
required: true
|
||||||
- type: input
|
- type: input
|
||||||
|
@ -64,7 +65,7 @@ body:
|
||||||
label: Operating system
|
label: Operating system
|
||||||
description: |
|
description: |
|
||||||
What OS are you running? Please specify the version as well.
|
What OS are you running? Please specify the version as well.
|
||||||
placeholder: macOS 13.4.1
|
placeholder: macOS 15.0.1
|
||||||
validations:
|
validations:
|
||||||
required: true
|
required: true
|
||||||
- type: textarea
|
- type: textarea
|
||||||
|
|
13
.github/ISSUE_TEMPLATE/2.server_bug_report.yml
vendored
13
.github/ISSUE_TEMPLATE/2.server_bug_report.yml
vendored
|
@ -1,7 +1,8 @@
|
||||||
name: Bug Report (server / API)
|
name: Bug Report (server / API)
|
||||||
description: |
|
description: |
|
||||||
If something is not working as expected, but is not from using the web interface.
|
There is a problem with the HTTP server, REST API, ActivityPub interaction, etc.
|
||||||
labels: [bug, 'status/to triage']
|
labels: ['status/to triage']
|
||||||
|
type: 'Bug'
|
||||||
body:
|
body:
|
||||||
- type: markdown
|
- type: markdown
|
||||||
attributes:
|
attributes:
|
||||||
|
@ -48,8 +49,8 @@ body:
|
||||||
attributes:
|
attributes:
|
||||||
label: Mastodon version
|
label: Mastodon version
|
||||||
description: |
|
description: |
|
||||||
This is displayed at the bottom of the About page, eg. `v4.1.2+nightly-20230627`
|
This is displayed at the bottom of the About page, eg. `v4.4.0-alpha.1`
|
||||||
placeholder: v4.1.2
|
placeholder: v4.3.0
|
||||||
validations:
|
validations:
|
||||||
required: false
|
required: false
|
||||||
- type: textarea
|
- type: textarea
|
||||||
|
@ -59,7 +60,7 @@ body:
|
||||||
Any additional technical details you may have, like logs or error traces
|
Any additional technical details you may have, like logs or error traces
|
||||||
value: |
|
value: |
|
||||||
If this is happening on your own Mastodon server, please fill out those:
|
If this is happening on your own Mastodon server, please fill out those:
|
||||||
- Ruby version: (from `ruby --version`, eg. v3.1.2)
|
- Ruby version: (from `ruby --version`, eg. v3.3.5)
|
||||||
- Node.js version: (from `node --version`, eg. v18.16.0)
|
- Node.js version: (from `node --version`, eg. v20.18.0)
|
||||||
validations:
|
validations:
|
||||||
required: false
|
required: false
|
||||||
|
|
74
.github/ISSUE_TEMPLATE/3.troubleshooting.yml
vendored
Normal file
74
.github/ISSUE_TEMPLATE/3.troubleshooting.yml
vendored
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
name: Deployment troubleshooting
|
||||||
|
description: |
|
||||||
|
You are a server administrator and you are encountering a technical issue during installation, upgrade or operations of Mastodon.
|
||||||
|
labels: ['status/to triage']
|
||||||
|
type: 'Troubleshooting'
|
||||||
|
body:
|
||||||
|
- type: markdown
|
||||||
|
attributes:
|
||||||
|
value: |
|
||||||
|
Make sure that you are submitting a new bug that was not previously reported or already fixed.
|
||||||
|
|
||||||
|
Please use a concise and distinct title for the issue.
|
||||||
|
- type: textarea
|
||||||
|
attributes:
|
||||||
|
label: Steps to reproduce the problem
|
||||||
|
description: What were you trying to do?
|
||||||
|
value: |
|
||||||
|
1.
|
||||||
|
2.
|
||||||
|
3.
|
||||||
|
...
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: input
|
||||||
|
attributes:
|
||||||
|
label: Expected behaviour
|
||||||
|
description: What should have happened?
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: input
|
||||||
|
attributes:
|
||||||
|
label: Actual behaviour
|
||||||
|
description: What happened?
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: textarea
|
||||||
|
attributes:
|
||||||
|
label: Detailed description
|
||||||
|
validations:
|
||||||
|
required: false
|
||||||
|
- type: input
|
||||||
|
attributes:
|
||||||
|
label: Mastodon instance
|
||||||
|
description: The address of the Mastodon instance where you experienced the issue
|
||||||
|
placeholder: mastodon.social
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: input
|
||||||
|
attributes:
|
||||||
|
label: Mastodon version
|
||||||
|
description: |
|
||||||
|
This is displayed at the bottom of the About page, eg. `v4.4.0-alpha.1`
|
||||||
|
placeholder: v4.3.0
|
||||||
|
validations:
|
||||||
|
required: false
|
||||||
|
- type: textarea
|
||||||
|
attributes:
|
||||||
|
label: Environment
|
||||||
|
description: |
|
||||||
|
Details about your environment, like how Mastodon is deployed, if containers are used, version numbers, etc.
|
||||||
|
value: |
|
||||||
|
Please at least include those informations:
|
||||||
|
- Operating system: (eg. Ubuntu 22.04)
|
||||||
|
- Ruby version: (from `ruby --version`, eg. v3.3.5)
|
||||||
|
- Node.js version: (from `node --version`, eg. v20.18.0)
|
||||||
|
validations:
|
||||||
|
required: false
|
||||||
|
- type: textarea
|
||||||
|
attributes:
|
||||||
|
label: Technical details
|
||||||
|
description: |
|
||||||
|
Any additional technical details you may have, like logs or error traces
|
||||||
|
validations:
|
||||||
|
required: false
|
|
@ -1,6 +1,6 @@
|
||||||
name: Feature Request
|
name: Feature Request
|
||||||
description: I have a suggestion
|
description: I have a suggestion
|
||||||
labels: [suggestion]
|
type: Suggestion
|
||||||
body:
|
body:
|
||||||
- type: markdown
|
- type: markdown
|
||||||
attributes:
|
attributes:
|
6
.github/codecov.yml
vendored
6
.github/codecov.yml
vendored
|
@ -3,9 +3,11 @@ coverage:
|
||||||
status:
|
status:
|
||||||
project:
|
project:
|
||||||
default:
|
default:
|
||||||
# Github status check is not blocking
|
# GitHub status check is not blocking
|
||||||
informational: true
|
informational: true
|
||||||
patch:
|
patch:
|
||||||
default:
|
default:
|
||||||
# Github status check is not blocking
|
# GitHub status check is not blocking
|
||||||
informational: true
|
informational: true
|
||||||
|
github_checks:
|
||||||
|
annotations: false
|
||||||
|
|
19
.github/renovate.json5
vendored
19
.github/renovate.json5
vendored
|
@ -2,10 +2,12 @@
|
||||||
$schema: 'https://docs.renovatebot.com/renovate-schema.json',
|
$schema: 'https://docs.renovatebot.com/renovate-schema.json',
|
||||||
extends: [
|
extends: [
|
||||||
'config:recommended',
|
'config:recommended',
|
||||||
|
'customManagers:dockerfileVersions',
|
||||||
':labels(dependencies)',
|
':labels(dependencies)',
|
||||||
':prConcurrentLimitNone', // Remove limit for open PRs at any time.
|
':prConcurrentLimitNone', // Remove limit for open PRs at any time.
|
||||||
':prHourlyLimit2', // Rate limit PR creation to a maximum of two per hour.
|
':prHourlyLimit2', // Rate limit PR creation to a maximum of two per hour.
|
||||||
],
|
],
|
||||||
|
rebaseWhen: 'conflicted',
|
||||||
minimumReleaseAge: '3', // Wait 3 days after the package has been published before upgrading it
|
minimumReleaseAge: '3', // Wait 3 days after the package has been published before upgrading it
|
||||||
// packageRules order is important, they are applied from top to bottom and are merged,
|
// packageRules order is important, they are applied from top to bottom and are merged,
|
||||||
// meaning the most important ones must be at the bottom, for example grouping rules
|
// meaning the most important ones must be at the bottom, for example grouping rules
|
||||||
|
@ -59,7 +61,7 @@
|
||||||
dependencyDashboardApproval: true,
|
dependencyDashboardApproval: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// Update Github Actions and Docker images weekly
|
// Update GitHub Actions and Docker images weekly
|
||||||
matchManagers: ['github-actions', 'dockerfile', 'docker-compose'],
|
matchManagers: ['github-actions', 'dockerfile', 'docker-compose'],
|
||||||
extends: ['schedule:weekly'],
|
extends: ['schedule:weekly'],
|
||||||
},
|
},
|
||||||
|
@ -86,6 +88,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// Update devDependencies every week, with one grouped PR
|
// Update devDependencies every week, with one grouped PR
|
||||||
|
matchManagers: ['npm'],
|
||||||
matchDepTypes: 'devDependencies',
|
matchDepTypes: 'devDependencies',
|
||||||
matchUpdateTypes: ['patch', 'minor'],
|
matchUpdateTypes: ['patch', 'minor'],
|
||||||
groupName: 'devDependencies (non-major)',
|
groupName: 'devDependencies (non-major)',
|
||||||
|
@ -94,8 +97,7 @@
|
||||||
{
|
{
|
||||||
// Group all eslint-related packages with `eslint` in the same PR
|
// Group all eslint-related packages with `eslint` in the same PR
|
||||||
matchManagers: ['npm'],
|
matchManagers: ['npm'],
|
||||||
matchPackageNames: ['eslint'],
|
matchPackageNames: ['eslint', 'eslint-*', '@typescript-eslint/*'],
|
||||||
matchPackagePrefixes: ['eslint-', '@typescript-eslint/'],
|
|
||||||
matchUpdateTypes: ['patch', 'minor'],
|
matchUpdateTypes: ['patch', 'minor'],
|
||||||
groupName: 'eslint (non-major)',
|
groupName: 'eslint (non-major)',
|
||||||
},
|
},
|
||||||
|
@ -111,7 +113,8 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// Update @types/* packages every week, with one grouped PR
|
// Update @types/* packages every week, with one grouped PR
|
||||||
matchPackagePrefixes: '@types/',
|
matchManagers: ['npm'],
|
||||||
|
matchPackageNames: '@types/*',
|
||||||
matchUpdateTypes: ['patch', 'minor'],
|
matchUpdateTypes: ['patch', 'minor'],
|
||||||
groupName: 'DefinitelyTyped types (non-major)',
|
groupName: 'DefinitelyTyped types (non-major)',
|
||||||
extends: ['schedule:weekly'],
|
extends: ['schedule:weekly'],
|
||||||
|
@ -128,23 +131,21 @@
|
||||||
{
|
{
|
||||||
// Group all RuboCop packages with `rubocop` in the same PR
|
// Group all RuboCop packages with `rubocop` in the same PR
|
||||||
matchManagers: ['bundler'],
|
matchManagers: ['bundler'],
|
||||||
matchPackageNames: ['rubocop'],
|
matchPackageNames: ['rubocop', 'rubocop-*'],
|
||||||
matchPackagePrefixes: ['rubocop-'],
|
|
||||||
matchUpdateTypes: ['patch', 'minor'],
|
matchUpdateTypes: ['patch', 'minor'],
|
||||||
groupName: 'RuboCop (non-major)',
|
groupName: 'RuboCop (non-major)',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// Group all RSpec packages with `rspec` in the same PR
|
// Group all RSpec packages with `rspec` in the same PR
|
||||||
matchManagers: ['bundler'],
|
matchManagers: ['bundler'],
|
||||||
matchPackageNames: ['rspec'],
|
matchPackageNames: ['rspec', 'rspec-*'],
|
||||||
matchPackagePrefixes: ['rspec-'],
|
|
||||||
matchUpdateTypes: ['patch', 'minor'],
|
matchUpdateTypes: ['patch', 'minor'],
|
||||||
groupName: 'RSpec (non-major)',
|
groupName: 'RSpec (non-major)',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// Group all opentelemetry-ruby packages in the same PR
|
// Group all opentelemetry-ruby packages in the same PR
|
||||||
matchManagers: ['bundler'],
|
matchManagers: ['bundler'],
|
||||||
matchPackagePrefixes: ['opentelemetry-'],
|
matchPackageNames: ['opentelemetry-*'],
|
||||||
matchUpdateTypes: ['patch', 'minor'],
|
matchUpdateTypes: ['patch', 'minor'],
|
||||||
groupName: 'opentelemetry-ruby (non-major)',
|
groupName: 'opentelemetry-ruby (non-major)',
|
||||||
},
|
},
|
||||||
|
|
5
.github/workflows/build-container-image.yml
vendored
5
.github/workflows/build-container-image.yml
vendored
|
@ -68,7 +68,7 @@ jobs:
|
||||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||||
|
|
||||||
- name: Log in to the Github Container registry
|
- name: Log in to the GitHub Container registry
|
||||||
if: contains(inputs.push_to_images, 'ghcr.io')
|
if: contains(inputs.push_to_images, 'ghcr.io')
|
||||||
uses: docker/login-action@v3
|
uses: docker/login-action@v3
|
||||||
with:
|
with:
|
||||||
|
@ -85,13 +85,14 @@ jobs:
|
||||||
tags: ${{ inputs.tags }}
|
tags: ${{ inputs.tags }}
|
||||||
labels: ${{ inputs.labels }}
|
labels: ${{ inputs.labels }}
|
||||||
|
|
||||||
- uses: docker/build-push-action@v5
|
- uses: docker/build-push-action@v6
|
||||||
with:
|
with:
|
||||||
context: .
|
context: .
|
||||||
file: ${{ inputs.file_to_build }}
|
file: ${{ inputs.file_to_build }}
|
||||||
build-args: |
|
build-args: |
|
||||||
MASTODON_VERSION_PRERELEASE=${{ inputs.version_prerelease }}
|
MASTODON_VERSION_PRERELEASE=${{ inputs.version_prerelease }}
|
||||||
MASTODON_VERSION_METADATA=${{ inputs.version_metadata }}
|
MASTODON_VERSION_METADATA=${{ inputs.version_metadata }}
|
||||||
|
SOURCE_COMMIT=${{ github.sha }}
|
||||||
platforms: ${{ inputs.platforms }}
|
platforms: ${{ inputs.platforms }}
|
||||||
provenance: false
|
provenance: false
|
||||||
builder: ${{ steps.buildx.outputs.name || steps.buildx-native.outputs.name }}
|
builder: ${{ steps.buildx.outputs.name || steps.buildx-native.outputs.name }}
|
||||||
|
|
6
.github/workflows/build-push-pr.yml
vendored
6
.github/workflows/build-push-pr.yml
vendored
|
@ -21,9 +21,11 @@ jobs:
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
- id: version_vars
|
- id: version_vars
|
||||||
run: |
|
run: |
|
||||||
echo mastodon_version_metadata=pr-${{ github.event.pull_request.number }}-$(git rev-parse --short HEAD) >> $GITHUB_OUTPUT
|
echo mastodon_version_metadata=pr-${{ github.event.pull_request.number }}-$(git rev-parse --short ${{github.event.pull_request.head.sha}}) >> $GITHUB_OUTPUT
|
||||||
|
echo mastodon_short_sha=$(git rev-parse --short ${{github.event.pull_request.head.sha}}) >> $GITHUB_OUTPUT
|
||||||
outputs:
|
outputs:
|
||||||
metadata: ${{ steps.version_vars.outputs.mastodon_version_metadata }}
|
metadata: ${{ steps.version_vars.outputs.mastodon_version_metadata }}
|
||||||
|
short_sha: ${{ steps.version_vars.outputs.mastodon_short_sha }}
|
||||||
|
|
||||||
build-image:
|
build-image:
|
||||||
needs: compute-suffix
|
needs: compute-suffix
|
||||||
|
@ -39,6 +41,7 @@ jobs:
|
||||||
latest=auto
|
latest=auto
|
||||||
tags: |
|
tags: |
|
||||||
type=ref,event=pr
|
type=ref,event=pr
|
||||||
|
type=ref,event=pr,suffix=-${{ needs.compute-suffix.outputs.short_sha }}
|
||||||
secrets: inherit
|
secrets: inherit
|
||||||
|
|
||||||
build-image-streaming:
|
build-image-streaming:
|
||||||
|
@ -55,4 +58,5 @@ jobs:
|
||||||
latest=auto
|
latest=auto
|
||||||
tags: |
|
tags: |
|
||||||
type=ref,event=pr
|
type=ref,event=pr
|
||||||
|
type=ref,event=pr,suffix=-${{ needs.compute-suffix.outputs.short_sha }}
|
||||||
secrets: inherit
|
secrets: inherit
|
||||||
|
|
2
.github/workflows/build-releases.yml
vendored
2
.github/workflows/build-releases.yml
vendored
|
@ -23,7 +23,7 @@ jobs:
|
||||||
# Only tag with latest when ran against the latest stable branch
|
# Only tag with latest when ran against the latest stable branch
|
||||||
# This needs to be updated after each minor version release
|
# This needs to be updated after each minor version release
|
||||||
flavor: |
|
flavor: |
|
||||||
latest=${{ startsWith(github.ref, 'refs/tags/v4.2.') }}
|
latest=${{ startsWith(github.ref, 'refs/tags/v4.3.') }}
|
||||||
tags: |
|
tags: |
|
||||||
type=pep440,pattern={{raw}}
|
type=pep440,pattern={{raw}}
|
||||||
type=pep440,pattern=v{{major}}.{{minor}}
|
type=pep440,pattern=v{{major}}.{{minor}}
|
||||||
|
|
19
.github/workflows/bundler-audit.yml
vendored
19
.github/workflows/bundler-audit.yml
vendored
|
@ -1,19 +1,19 @@
|
||||||
name: Bundler Audit
|
name: Bundler Audit
|
||||||
on:
|
on:
|
||||||
|
merge_group:
|
||||||
push:
|
push:
|
||||||
branches-ignore:
|
branches:
|
||||||
- 'dependabot/**'
|
- 'main'
|
||||||
|
- 'stable-*'
|
||||||
paths:
|
paths:
|
||||||
- 'Gemfile*'
|
- 'Gemfile*'
|
||||||
- '.ruby-version'
|
- '.ruby-version'
|
||||||
- '.bundler-audit.yml'
|
|
||||||
- '.github/workflows/bundler-audit.yml'
|
- '.github/workflows/bundler-audit.yml'
|
||||||
|
|
||||||
pull_request:
|
pull_request:
|
||||||
paths:
|
paths:
|
||||||
- 'Gemfile*'
|
- 'Gemfile*'
|
||||||
- '.ruby-version'
|
- '.ruby-version'
|
||||||
- '.bundler-audit.yml'
|
|
||||||
- '.github/workflows/bundler-audit.yml'
|
- '.github/workflows/bundler-audit.yml'
|
||||||
|
|
||||||
schedule:
|
schedule:
|
||||||
|
@ -23,12 +23,17 @@ jobs:
|
||||||
security:
|
security:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
env:
|
||||||
|
BUNDLE_ONLY: development
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Clone repository
|
- name: Clone repository
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Set up Ruby environment
|
- name: Set up Ruby
|
||||||
uses: ./.github/actions/setup-ruby
|
uses: ruby/setup-ruby@v1
|
||||||
|
with:
|
||||||
|
bundler-cache: true
|
||||||
|
|
||||||
- name: Run bundler-audit
|
- name: Run bundler-audit
|
||||||
run: bundle exec bundler-audit
|
run: bundle exec bundler-audit check --update
|
||||||
|
|
10
.github/workflows/check-i18n.yml
vendored
10
.github/workflows/check-i18n.yml
vendored
|
@ -2,9 +2,13 @@ name: Check i18n
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches: [main]
|
branches:
|
||||||
|
- 'main'
|
||||||
|
- 'stable-*'
|
||||||
pull_request:
|
pull_request:
|
||||||
branches: [main]
|
branches:
|
||||||
|
- 'main'
|
||||||
|
- 'stable-*'
|
||||||
|
|
||||||
env:
|
env:
|
||||||
RAILS_ENV: test
|
RAILS_ENV: test
|
||||||
|
@ -14,7 +18,7 @@ permissions:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
check-i18n:
|
check-i18n:
|
||||||
runs-on: ubuntu-22.04
|
runs-on: ubuntu-24.04
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
|
10
.github/workflows/codeql.yml
vendored
10
.github/workflows/codeql.yml
vendored
|
@ -1,11 +1,15 @@
|
||||||
name: 'CodeQL'
|
name: 'CodeQL'
|
||||||
|
|
||||||
on:
|
on:
|
||||||
|
merge_group:
|
||||||
push:
|
push:
|
||||||
branches: ['main']
|
branches:
|
||||||
|
- 'main'
|
||||||
|
- 'stable-*'
|
||||||
pull_request:
|
pull_request:
|
||||||
# The branches below must be a subset of the branches above
|
branches:
|
||||||
branches: ['main']
|
- 'main'
|
||||||
|
- 'stable-*'
|
||||||
schedule:
|
schedule:
|
||||||
- cron: '22 6 * * 1'
|
- cron: '22 6 * * 1'
|
||||||
|
|
||||||
|
|
69
.github/workflows/crowdin-download-stable.yml
vendored
Normal file
69
.github/workflows/crowdin-download-stable.yml
vendored
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
name: Crowdin / Download translations (stable branches)
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
pull-requests: write
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
download-translations-stable:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
if: github.repository == 'mastodon/mastodon'
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Increase Git http.postBuffer
|
||||||
|
# This is needed due to a bug in Ubuntu's cURL version?
|
||||||
|
# See https://github.com/orgs/community/discussions/55820
|
||||||
|
run: |
|
||||||
|
git config --global http.version HTTP/1.1
|
||||||
|
git config --global http.postBuffer 157286400
|
||||||
|
|
||||||
|
# Download the translation files from Crowdin
|
||||||
|
- name: crowdin action
|
||||||
|
uses: crowdin/github-action@v2
|
||||||
|
with:
|
||||||
|
upload_sources: false
|
||||||
|
upload_translations: false
|
||||||
|
download_translations: true
|
||||||
|
crowdin_branch_name: ${{ github.base_ref || github.ref_name }}
|
||||||
|
push_translations: false
|
||||||
|
create_pull_request: false
|
||||||
|
env:
|
||||||
|
CROWDIN_PROJECT_ID: ${{ vars.CROWDIN_PROJECT_ID }}
|
||||||
|
CROWDIN_PERSONAL_TOKEN: ${{ secrets.CROWDIN_PERSONAL_TOKEN }}
|
||||||
|
|
||||||
|
# As the files are extracted from a Docker container, they belong to root:root
|
||||||
|
# We need to fix this before the next steps
|
||||||
|
- name: Fix file permissions
|
||||||
|
run: sudo chown -R runner:docker .
|
||||||
|
|
||||||
|
# This is needed to run the normalize step
|
||||||
|
- name: Set up Ruby environment
|
||||||
|
uses: ./.github/actions/setup-ruby
|
||||||
|
|
||||||
|
- name: Run i18n normalize task
|
||||||
|
run: bundle exec i18n-tasks normalize
|
||||||
|
|
||||||
|
# Create or update the pull request
|
||||||
|
- name: Create Pull Request
|
||||||
|
uses: peter-evans/create-pull-request@v7.0.5
|
||||||
|
with:
|
||||||
|
commit-message: 'New Crowdin translations'
|
||||||
|
title: 'New Crowdin Translations for ${{ github.base_ref || github.ref_name }} (automated)'
|
||||||
|
author: 'GitHub Actions <noreply@github.com>'
|
||||||
|
body: |
|
||||||
|
New Crowdin translations, automated with GitHub Actions
|
||||||
|
|
||||||
|
See `.github/workflows/crowdin-download.yml`
|
||||||
|
|
||||||
|
This PR will be updated every day with new translations.
|
||||||
|
|
||||||
|
Due to a limitation in GitHub Actions, checks are not running on this PR without manual action.
|
||||||
|
If you want to run the checks, then close and re-open it.
|
||||||
|
branch: i18n/crowdin/translations-${{ github.base_ref || github.ref_name }}
|
||||||
|
base: ${{ github.base_ref || github.ref_name }}
|
||||||
|
labels: i18n
|
8
.github/workflows/crowdin-download.yml
vendored
8
.github/workflows/crowdin-download.yml
vendored
|
@ -26,7 +26,7 @@ jobs:
|
||||||
|
|
||||||
# Download the translation files from Crowdin
|
# Download the translation files from Crowdin
|
||||||
- name: crowdin action
|
- name: crowdin action
|
||||||
uses: crowdin/github-action@v1
|
uses: crowdin/github-action@v2
|
||||||
with:
|
with:
|
||||||
upload_sources: false
|
upload_sources: false
|
||||||
upload_translations: false
|
upload_translations: false
|
||||||
|
@ -52,19 +52,19 @@ jobs:
|
||||||
|
|
||||||
# Create or update the pull request
|
# Create or update the pull request
|
||||||
- name: Create Pull Request
|
- name: Create Pull Request
|
||||||
uses: peter-evans/create-pull-request@v6.0.5
|
uses: peter-evans/create-pull-request@v7.0.5
|
||||||
with:
|
with:
|
||||||
commit-message: 'New Crowdin translations'
|
commit-message: 'New Crowdin translations'
|
||||||
title: 'New Crowdin Translations (automated)'
|
title: 'New Crowdin Translations (automated)'
|
||||||
author: 'GitHub Actions <noreply@github.com>'
|
author: 'GitHub Actions <noreply@github.com>'
|
||||||
body: |
|
body: |
|
||||||
New Crowdin translations, automated with Github Actions
|
New Crowdin translations, automated with GitHub Actions
|
||||||
|
|
||||||
See `.github/workflows/crowdin-download.yml`
|
See `.github/workflows/crowdin-download.yml`
|
||||||
|
|
||||||
This PR will be updated every day with new translations.
|
This PR will be updated every day with new translations.
|
||||||
|
|
||||||
Due to a limitation in Github Actions, checks are not running on this PR without manual action.
|
Due to a limitation in GitHub Actions, checks are not running on this PR without manual action.
|
||||||
If you want to run the checks, then close and re-open it.
|
If you want to run the checks, then close and re-open it.
|
||||||
branch: i18n/crowdin/translations
|
branch: i18n/crowdin/translations
|
||||||
base: main
|
base: main
|
||||||
|
|
8
.github/workflows/crowdin-upload.yml
vendored
8
.github/workflows/crowdin-upload.yml
vendored
|
@ -3,7 +3,8 @@ name: Crowdin / Upload translations
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- main
|
- 'main'
|
||||||
|
- 'stable-*'
|
||||||
paths:
|
paths:
|
||||||
- crowdin.yml
|
- crowdin.yml
|
||||||
- app/javascript/mastodon/locales/en.json
|
- app/javascript/mastodon/locales/en.json
|
||||||
|
@ -17,18 +18,19 @@ on:
|
||||||
jobs:
|
jobs:
|
||||||
upload-translations:
|
upload-translations:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
if: github.repository == 'mastodon/mastodon'
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: crowdin action
|
- name: crowdin action
|
||||||
uses: crowdin/github-action@v1
|
uses: crowdin/github-action@v2
|
||||||
with:
|
with:
|
||||||
upload_sources: true
|
upload_sources: true
|
||||||
upload_translations: false
|
upload_translations: false
|
||||||
download_translations: false
|
download_translations: false
|
||||||
crowdin_branch_name: main
|
crowdin_branch_name: ${{ github.base_ref || github.ref_name }}
|
||||||
|
|
||||||
env:
|
env:
|
||||||
CROWDIN_PROJECT_ID: ${{ vars.CROWDIN_PROJECT_ID }}
|
CROWDIN_PROJECT_ID: ${{ vars.CROWDIN_PROJECT_ID }}
|
||||||
|
|
4
.github/workflows/format-check.yml
vendored
4
.github/workflows/format-check.yml
vendored
|
@ -1,6 +1,10 @@
|
||||||
name: Check formatting
|
name: Check formatting
|
||||||
on:
|
on:
|
||||||
|
merge_group:
|
||||||
push:
|
push:
|
||||||
|
branches:
|
||||||
|
- 'main'
|
||||||
|
- 'stable-*'
|
||||||
pull_request:
|
pull_request:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
|
|
7
.github/workflows/lint-css.yml
vendored
7
.github/workflows/lint-css.yml
vendored
|
@ -1,9 +1,10 @@
|
||||||
name: CSS Linting
|
name: CSS Linting
|
||||||
on:
|
on:
|
||||||
|
merge_group:
|
||||||
push:
|
push:
|
||||||
branches-ignore:
|
branches:
|
||||||
- 'dependabot/**'
|
- 'main'
|
||||||
- 'renovate/**'
|
- 'stable-*'
|
||||||
paths:
|
paths:
|
||||||
- 'package.json'
|
- 'package.json'
|
||||||
- 'yarn.lock'
|
- 'yarn.lock'
|
||||||
|
|
17
.github/workflows/lint-haml.yml
vendored
17
.github/workflows/lint-haml.yml
vendored
|
@ -1,9 +1,10 @@
|
||||||
name: Haml Linting
|
name: Haml Linting
|
||||||
on:
|
on:
|
||||||
|
merge_group:
|
||||||
push:
|
push:
|
||||||
branches-ignore:
|
branches:
|
||||||
- 'dependabot/**'
|
- 'main'
|
||||||
- 'renovate/**'
|
- 'stable-*'
|
||||||
paths:
|
paths:
|
||||||
- '.github/workflows/haml-lint-problem-matcher.json'
|
- '.github/workflows/haml-lint-problem-matcher.json'
|
||||||
- '.github/workflows/lint-haml.yml'
|
- '.github/workflows/lint-haml.yml'
|
||||||
|
@ -26,12 +27,18 @@ on:
|
||||||
jobs:
|
jobs:
|
||||||
lint:
|
lint:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
env:
|
||||||
|
BUNDLE_ONLY: development
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Clone repository
|
- name: Clone repository
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Set up Ruby environment
|
- name: Set up Ruby
|
||||||
uses: ./.github/actions/setup-ruby
|
uses: ruby/setup-ruby@v1
|
||||||
|
with:
|
||||||
|
bundler-cache: true
|
||||||
|
|
||||||
- name: Run haml-lint
|
- name: Run haml-lint
|
||||||
run: |
|
run: |
|
||||||
|
|
7
.github/workflows/lint-js.yml
vendored
7
.github/workflows/lint-js.yml
vendored
|
@ -1,9 +1,10 @@
|
||||||
name: JavaScript Linting
|
name: JavaScript Linting
|
||||||
on:
|
on:
|
||||||
|
merge_group:
|
||||||
push:
|
push:
|
||||||
branches-ignore:
|
branches:
|
||||||
- 'dependabot/**'
|
- 'main'
|
||||||
- 'renovate/**'
|
- 'stable-*'
|
||||||
paths:
|
paths:
|
||||||
- 'package.json'
|
- 'package.json'
|
||||||
- 'yarn.lock'
|
- 'yarn.lock'
|
||||||
|
|
20
.github/workflows/lint-ruby.yml
vendored
20
.github/workflows/lint-ruby.yml
vendored
|
@ -1,9 +1,10 @@
|
||||||
name: Ruby Linting
|
name: Ruby Linting
|
||||||
on:
|
on:
|
||||||
|
merge_group:
|
||||||
push:
|
push:
|
||||||
branches-ignore:
|
branches:
|
||||||
- 'dependabot/**'
|
- 'main'
|
||||||
- 'renovate/**'
|
- 'stable-*'
|
||||||
paths:
|
paths:
|
||||||
- 'Gemfile*'
|
- 'Gemfile*'
|
||||||
- '.rubocop*.yml'
|
- '.rubocop*.yml'
|
||||||
|
@ -27,19 +28,24 @@ jobs:
|
||||||
lint:
|
lint:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
env:
|
||||||
|
BUNDLE_ONLY: development
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Clone repository
|
- name: Clone repository
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Set up Ruby environment
|
- name: Set up Ruby
|
||||||
uses: ./.github/actions/setup-ruby
|
uses: ruby/setup-ruby@v1
|
||||||
|
with:
|
||||||
|
bundler-cache: true
|
||||||
|
|
||||||
- name: Set-up RuboCop Problem Matcher
|
- name: Set-up RuboCop Problem Matcher
|
||||||
uses: r7kamura/rubocop-problem-matchers-action@v1
|
uses: r7kamura/rubocop-problem-matchers-action@v1
|
||||||
|
|
||||||
- name: Run rubocop
|
- name: Run rubocop
|
||||||
run: bundle exec rubocop
|
run: bin/rubocop
|
||||||
|
|
||||||
- name: Run brakeman
|
- name: Run brakeman
|
||||||
if: always() # Run both checks, even if the first failed
|
if: always() # Run both checks, even if the first failed
|
||||||
run: bundle exec brakeman
|
run: bin/brakeman
|
||||||
|
|
3
.github/workflows/rebase-needed.yml
vendored
3
.github/workflows/rebase-needed.yml
vendored
|
@ -10,6 +10,7 @@ permissions:
|
||||||
jobs:
|
jobs:
|
||||||
label-rebase-needed:
|
label-rebase-needed:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
if: github.repository == 'mastodon/mastodon'
|
||||||
|
|
||||||
concurrency:
|
concurrency:
|
||||||
group: ${{ github.workflow }}-${{ github.ref }}
|
group: ${{ github.workflow }}-${{ github.ref }}
|
||||||
|
@ -17,7 +18,7 @@ jobs:
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Check for merge conflicts
|
- name: Check for merge conflicts
|
||||||
uses: eps1lon/actions-label-merge-conflict@releases/2.x
|
uses: eps1lon/actions-label-merge-conflict@v3
|
||||||
with:
|
with:
|
||||||
dirtyLabel: 'rebase needed :construction:'
|
dirtyLabel: 'rebase needed :construction:'
|
||||||
repoToken: '${{ secrets.GITHUB_TOKEN }}'
|
repoToken: '${{ secrets.GITHUB_TOKEN }}'
|
||||||
|
|
7
.github/workflows/test-js.yml
vendored
7
.github/workflows/test-js.yml
vendored
|
@ -1,9 +1,10 @@
|
||||||
name: JavaScript Testing
|
name: JavaScript Testing
|
||||||
on:
|
on:
|
||||||
|
merge_group:
|
||||||
push:
|
push:
|
||||||
branches-ignore:
|
branches:
|
||||||
- 'dependabot/**'
|
- 'main'
|
||||||
- 'renovate/**'
|
- 'stable-*'
|
||||||
paths:
|
paths:
|
||||||
- 'package.json'
|
- 'package.json'
|
||||||
- 'yarn.lock'
|
- 'yarn.lock'
|
||||||
|
|
88
.github/workflows/test-migrations-one-step.yml
vendored
88
.github/workflows/test-migrations-one-step.yml
vendored
|
@ -1,88 +0,0 @@
|
||||||
name: Test one step migrations
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches-ignore:
|
|
||||||
- 'dependabot/**'
|
|
||||||
- 'renovate/**'
|
|
||||||
pull_request:
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
pre_job:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
outputs:
|
|
||||||
should_skip: ${{ steps.skip_check.outputs.should_skip }}
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- id: skip_check
|
|
||||||
uses: fkirc/skip-duplicate-actions@v5
|
|
||||||
with:
|
|
||||||
paths: '["Gemfile*", ".ruby-version", "**/*.rb", ".github/workflows/test-migrations-one-step.yml", "lib/tasks/tests.rake"]'
|
|
||||||
|
|
||||||
test:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
needs: pre_job
|
|
||||||
if: needs.pre_job.outputs.should_skip != 'true'
|
|
||||||
|
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
|
|
||||||
matrix:
|
|
||||||
postgres:
|
|
||||||
- 14-alpine
|
|
||||||
- 15-alpine
|
|
||||||
|
|
||||||
services:
|
|
||||||
postgres:
|
|
||||||
image: postgres:${{ matrix.postgres}}
|
|
||||||
env:
|
|
||||||
POSTGRES_PASSWORD: postgres
|
|
||||||
POSTGRES_USER: postgres
|
|
||||||
options: >-
|
|
||||||
--health-cmd pg_isready
|
|
||||||
--health-interval 10s
|
|
||||||
--health-timeout 5s
|
|
||||||
--health-retries 5
|
|
||||||
ports:
|
|
||||||
- 5432:5432
|
|
||||||
|
|
||||||
redis:
|
|
||||||
image: redis:7-alpine
|
|
||||||
options: >-
|
|
||||||
--health-cmd "redis-cli ping"
|
|
||||||
--health-interval 10s
|
|
||||||
--health-timeout 5s
|
|
||||||
--health-retries 5
|
|
||||||
ports:
|
|
||||||
- 6379:6379
|
|
||||||
|
|
||||||
env:
|
|
||||||
CONTINUOUS_INTEGRATION: true
|
|
||||||
DB_HOST: localhost
|
|
||||||
DB_USER: postgres
|
|
||||||
DB_PASS: postgres
|
|
||||||
DISABLE_SIMPLECOV: true
|
|
||||||
RAILS_ENV: test
|
|
||||||
BUNDLE_CLEAN: true
|
|
||||||
BUNDLE_FROZEN: true
|
|
||||||
BUNDLE_WITHOUT: 'development production'
|
|
||||||
BUNDLE_JOBS: 3
|
|
||||||
BUNDLE_RETRY: 3
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
|
|
||||||
- name: Set up Ruby environment
|
|
||||||
uses: ./.github/actions/setup-ruby
|
|
||||||
|
|
||||||
- name: Create database
|
|
||||||
run: './bin/rails db:create'
|
|
||||||
|
|
||||||
- name: Run historical migrations with data population
|
|
||||||
run: './bin/rails tests:migrations:prepare_database'
|
|
||||||
|
|
||||||
- name: Run all remaining migrations
|
|
||||||
run: './bin/rails db:migrate'
|
|
||||||
|
|
||||||
- name: Check migration result
|
|
||||||
run: './bin/rails tests:migrations:check_database'
|
|
95
.github/workflows/test-migrations-two-step.yml
vendored
95
.github/workflows/test-migrations-two-step.yml
vendored
|
@ -1,95 +0,0 @@
|
||||||
name: Test two step migrations
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches-ignore:
|
|
||||||
- 'dependabot/**'
|
|
||||||
- 'renovate/**'
|
|
||||||
pull_request:
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
pre_job:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
outputs:
|
|
||||||
should_skip: ${{ steps.skip_check.outputs.should_skip }}
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- id: skip_check
|
|
||||||
uses: fkirc/skip-duplicate-actions@v5
|
|
||||||
with:
|
|
||||||
paths: '["Gemfile*", ".ruby-version", "**/*.rb", ".github/workflows/test-migrations-two-step.yml", "lib/tasks/tests.rake"]'
|
|
||||||
|
|
||||||
test:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
needs: pre_job
|
|
||||||
if: needs.pre_job.outputs.should_skip != 'true'
|
|
||||||
|
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
|
|
||||||
matrix:
|
|
||||||
postgres:
|
|
||||||
- 14-alpine
|
|
||||||
- 15-alpine
|
|
||||||
|
|
||||||
services:
|
|
||||||
postgres:
|
|
||||||
image: postgres:${{ matrix.postgres}}
|
|
||||||
env:
|
|
||||||
POSTGRES_PASSWORD: postgres
|
|
||||||
POSTGRES_USER: postgres
|
|
||||||
options: >-
|
|
||||||
--health-cmd pg_isready
|
|
||||||
--health-interval 10s
|
|
||||||
--health-timeout 5s
|
|
||||||
--health-retries 5
|
|
||||||
ports:
|
|
||||||
- 5432:5432
|
|
||||||
|
|
||||||
redis:
|
|
||||||
image: redis:7-alpine
|
|
||||||
options: >-
|
|
||||||
--health-cmd "redis-cli ping"
|
|
||||||
--health-interval 10s
|
|
||||||
--health-timeout 5s
|
|
||||||
--health-retries 5
|
|
||||||
ports:
|
|
||||||
- 6379:6379
|
|
||||||
|
|
||||||
env:
|
|
||||||
CONTINUOUS_INTEGRATION: true
|
|
||||||
DB_HOST: localhost
|
|
||||||
DB_USER: postgres
|
|
||||||
DB_PASS: postgres
|
|
||||||
DISABLE_SIMPLECOV: true
|
|
||||||
RAILS_ENV: test
|
|
||||||
BUNDLE_CLEAN: true
|
|
||||||
BUNDLE_FROZEN: true
|
|
||||||
BUNDLE_WITHOUT: 'development production'
|
|
||||||
BUNDLE_JOBS: 3
|
|
||||||
BUNDLE_RETRY: 3
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
|
|
||||||
- name: Set up Ruby environment
|
|
||||||
uses: ./.github/actions/setup-ruby
|
|
||||||
|
|
||||||
- name: Create database
|
|
||||||
run: './bin/rails db:create'
|
|
||||||
|
|
||||||
- name: Run historical migrations with data population
|
|
||||||
run: './bin/rails tests:migrations:prepare_database'
|
|
||||||
env:
|
|
||||||
SKIP_POST_DEPLOYMENT_MIGRATIONS: true
|
|
||||||
|
|
||||||
- name: Run all remaining pre-deployment migrations
|
|
||||||
run: './bin/rails db:migrate'
|
|
||||||
env:
|
|
||||||
SKIP_POST_DEPLOYMENT_MIGRATIONS: true
|
|
||||||
|
|
||||||
- name: Run all post-deployment migrations
|
|
||||||
run: './bin/rails db:migrate'
|
|
||||||
|
|
||||||
- name: Check migration result
|
|
||||||
run: './bin/rails tests:migrations:check_database'
|
|
95
.github/workflows/test-migrations.yml
vendored
Normal file
95
.github/workflows/test-migrations.yml
vendored
Normal file
|
@ -0,0 +1,95 @@
|
||||||
|
name: Historical data migration test
|
||||||
|
|
||||||
|
on:
|
||||||
|
merge_group:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- 'main'
|
||||||
|
- 'stable-*'
|
||||||
|
paths:
|
||||||
|
- 'Gemfile*'
|
||||||
|
- '.ruby-version'
|
||||||
|
- '**/*.rb'
|
||||||
|
- '.github/workflows/test-migrations.yml'
|
||||||
|
- 'lib/tasks/tests.rake'
|
||||||
|
|
||||||
|
pull_request:
|
||||||
|
paths:
|
||||||
|
- 'Gemfile*'
|
||||||
|
- '.ruby-version'
|
||||||
|
- '**/*.rb'
|
||||||
|
- '.github/workflows/test-migrations.yml'
|
||||||
|
- 'lib/tasks/tests.rake'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
test:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
|
||||||
|
matrix:
|
||||||
|
postgres:
|
||||||
|
- 14-alpine
|
||||||
|
- 15-alpine
|
||||||
|
- 16-alpine
|
||||||
|
- 17-alpine
|
||||||
|
|
||||||
|
services:
|
||||||
|
postgres:
|
||||||
|
image: postgres:${{ matrix.postgres}}
|
||||||
|
env:
|
||||||
|
POSTGRES_PASSWORD: postgres
|
||||||
|
POSTGRES_USER: postgres
|
||||||
|
options: >-
|
||||||
|
--health-cmd pg_isready
|
||||||
|
--health-interval 10ms
|
||||||
|
--health-timeout 3s
|
||||||
|
--health-retries 50
|
||||||
|
ports:
|
||||||
|
- 5432:5432
|
||||||
|
|
||||||
|
redis:
|
||||||
|
image: redis:7-alpine
|
||||||
|
options: >-
|
||||||
|
--health-cmd "redis-cli ping"
|
||||||
|
--health-interval 10ms
|
||||||
|
--health-timeout 3s
|
||||||
|
--health-retries 50
|
||||||
|
ports:
|
||||||
|
- 6379:6379
|
||||||
|
|
||||||
|
env:
|
||||||
|
DB_HOST: localhost
|
||||||
|
DB_USER: postgres
|
||||||
|
DB_PASS: postgres
|
||||||
|
DISABLE_SIMPLECOV: true
|
||||||
|
RAILS_ENV: test
|
||||||
|
BUNDLE_CLEAN: true
|
||||||
|
BUNDLE_FROZEN: true
|
||||||
|
BUNDLE_WITHOUT: 'development:production'
|
||||||
|
BUNDLE_JOBS: 3
|
||||||
|
BUNDLE_RETRY: 3
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Set up Ruby environment
|
||||||
|
uses: ./.github/actions/setup-ruby
|
||||||
|
|
||||||
|
- name: Test "one step migration" flow
|
||||||
|
run: |
|
||||||
|
bin/rails db:drop
|
||||||
|
bin/rails db:create
|
||||||
|
bin/rails tests:migrations:prepare_database
|
||||||
|
bin/rails db:migrate
|
||||||
|
bin/rails tests:migrations:check_database
|
||||||
|
|
||||||
|
- name: Test "two step migration" flow
|
||||||
|
run: |
|
||||||
|
bin/rails db:drop
|
||||||
|
bin/rails db:create
|
||||||
|
SKIP_POST_DEPLOYMENT_MIGRATIONS=true bin/rails tests:migrations:prepare_database
|
||||||
|
SKIP_POST_DEPLOYMENT_MIGRATIONS=true bin/rails db:migrate
|
||||||
|
bin/rails db:migrate
|
||||||
|
bin/rails tests:migrations:check_database
|
135
.github/workflows/test-ruby.yml
vendored
135
.github/workflows/test-ruby.yml
vendored
|
@ -1,10 +1,11 @@
|
||||||
name: Ruby Testing
|
name: Ruby Testing
|
||||||
|
|
||||||
on:
|
on:
|
||||||
|
merge_group:
|
||||||
push:
|
push:
|
||||||
branches-ignore:
|
branches:
|
||||||
- 'dependabot/**'
|
- 'main'
|
||||||
- 'renovate/**'
|
- 'stable-*'
|
||||||
pull_request:
|
pull_request:
|
||||||
|
|
||||||
env:
|
env:
|
||||||
|
@ -28,11 +29,7 @@ jobs:
|
||||||
env:
|
env:
|
||||||
RAILS_ENV: ${{ matrix.mode }}
|
RAILS_ENV: ${{ matrix.mode }}
|
||||||
BUNDLE_WITH: ${{ matrix.mode }}
|
BUNDLE_WITH: ${{ matrix.mode }}
|
||||||
ACTIVE_RECORD_ENCRYPTION_DETERMINISTIC_KEY: precompile_placeholder
|
SECRET_KEY_BASE_DUMMY: 1
|
||||||
ACTIVE_RECORD_ENCRYPTION_KEY_DERIVATION_SALT: precompile_placeholder
|
|
||||||
ACTIVE_RECORD_ENCRYPTION_PRIMARY_KEY: precompile_placeholder
|
|
||||||
OTP_SECRET: precompile_placeholder
|
|
||||||
SECRET_KEY_BASE: precompile_placeholder
|
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
@ -45,11 +42,24 @@ jobs:
|
||||||
with:
|
with:
|
||||||
onlyProduction: 'true'
|
onlyProduction: 'true'
|
||||||
|
|
||||||
|
- name: Cache assets from compilation
|
||||||
|
uses: actions/cache@v4
|
||||||
|
with:
|
||||||
|
path: |
|
||||||
|
public/assets
|
||||||
|
public/packs
|
||||||
|
public/packs-test
|
||||||
|
tmp/cache/webpacker
|
||||||
|
key: ${{ matrix.mode }}-assets-${{ github.head_ref || github.ref_name }}-${{ github.sha }}
|
||||||
|
restore-keys: |
|
||||||
|
${{ matrix.mode }}-assets-${{ github.head_ref || github.ref_name }}-${{ github.sha }}
|
||||||
|
${{ matrix.mode }}-assets-${{ github.head_ref || github.ref_name }}
|
||||||
|
${{ matrix.mode }}-assets-main
|
||||||
|
${{ matrix.mode }}-assets
|
||||||
|
|
||||||
- name: Precompile assets
|
- name: Precompile assets
|
||||||
# Previously had set this, but it's not supported
|
|
||||||
# export NODE_OPTIONS=--openssl-legacy-provider
|
|
||||||
run: |-
|
run: |-
|
||||||
./bin/rails assets:precompile
|
bin/rails assets:precompile
|
||||||
|
|
||||||
- name: Archive asset artifacts
|
- name: Archive asset artifacts
|
||||||
run: |
|
run: |
|
||||||
|
@ -77,9 +87,9 @@ jobs:
|
||||||
POSTGRES_USER: postgres
|
POSTGRES_USER: postgres
|
||||||
options: >-
|
options: >-
|
||||||
--health-cmd pg_isready
|
--health-cmd pg_isready
|
||||||
--health-interval 10s
|
--health-interval 10ms
|
||||||
--health-timeout 5s
|
--health-timeout 3s
|
||||||
--health-retries 5
|
--health-retries 50
|
||||||
ports:
|
ports:
|
||||||
- 5432:5432
|
- 5432:5432
|
||||||
|
|
||||||
|
@ -87,9 +97,9 @@ jobs:
|
||||||
image: redis:7-alpine
|
image: redis:7-alpine
|
||||||
options: >-
|
options: >-
|
||||||
--health-cmd "redis-cli ping"
|
--health-cmd "redis-cli ping"
|
||||||
--health-interval 10s
|
--health-interval 10ms
|
||||||
--health-timeout 5s
|
--health-timeout 3s
|
||||||
--health-retries 5
|
--health-retries 50
|
||||||
ports:
|
ports:
|
||||||
- 6379:6379
|
- 6379:6379
|
||||||
|
|
||||||
|
@ -114,7 +124,6 @@ jobs:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
ruby-version:
|
ruby-version:
|
||||||
- '3.1'
|
|
||||||
- '3.2'
|
- '3.2'
|
||||||
- '.ruby-version'
|
- '.ruby-version'
|
||||||
steps:
|
steps:
|
||||||
|
@ -133,18 +142,33 @@ jobs:
|
||||||
uses: ./.github/actions/setup-ruby
|
uses: ./.github/actions/setup-ruby
|
||||||
with:
|
with:
|
||||||
ruby-version: ${{ matrix.ruby-version}}
|
ruby-version: ${{ matrix.ruby-version}}
|
||||||
additional-system-dependencies: ffmpeg libpam-dev
|
additional-system-dependencies: ffmpeg imagemagick libpam-dev
|
||||||
|
|
||||||
- name: Load database schema
|
- name: Load database schema
|
||||||
run: './bin/rails db:create db:schema:load db:seed'
|
run: |
|
||||||
|
bin/rails db:setup
|
||||||
|
bin/flatware fan bin/rails db:test:prepare
|
||||||
|
|
||||||
- run: bin/rspec
|
- name: Cache RSpec persistence file
|
||||||
|
uses: actions/cache@v4
|
||||||
|
with:
|
||||||
|
path: |
|
||||||
|
tmp/rspec/examples.txt
|
||||||
|
key: rspec-persistence-${{ github.head_ref || github.ref_name }}-${{ github.sha }}
|
||||||
|
restore-keys: |
|
||||||
|
rspec-persistence-${{ github.head_ref || github.ref_name }}-${{ github.sha }}-${{ matrix.ruby-version }}
|
||||||
|
rspec-persistence-${{ github.head_ref || github.ref_name }}-${{ github.sha }}
|
||||||
|
rspec-persistence-${{ github.head_ref || github.ref_name }}
|
||||||
|
rspec-persistence-main
|
||||||
|
rspec-persistence
|
||||||
|
|
||||||
|
- run: bin/flatware rspec -r ./spec/flatware_helper.rb
|
||||||
|
|
||||||
- name: Upload coverage reports to Codecov
|
- name: Upload coverage reports to Codecov
|
||||||
if: matrix.ruby-version == '.ruby-version'
|
if: matrix.ruby-version == '.ruby-version'
|
||||||
uses: codecov/codecov-action@v4
|
uses: codecov/codecov-action@v4
|
||||||
with:
|
with:
|
||||||
files: coverage/lcov/mastodon.lcov
|
files: coverage/lcov/*.lcov
|
||||||
env:
|
env:
|
||||||
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
|
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
|
||||||
|
|
||||||
|
@ -163,9 +187,9 @@ jobs:
|
||||||
POSTGRES_USER: postgres
|
POSTGRES_USER: postgres
|
||||||
options: >-
|
options: >-
|
||||||
--health-cmd pg_isready
|
--health-cmd pg_isready
|
||||||
--health-interval 10s
|
--health-interval 10ms
|
||||||
--health-timeout 5s
|
--health-timeout 3s
|
||||||
--health-retries 5
|
--health-retries 50
|
||||||
ports:
|
ports:
|
||||||
- 5432:5432
|
- 5432:5432
|
||||||
|
|
||||||
|
@ -173,9 +197,9 @@ jobs:
|
||||||
image: redis:7-alpine
|
image: redis:7-alpine
|
||||||
options: >-
|
options: >-
|
||||||
--health-cmd "redis-cli ping"
|
--health-cmd "redis-cli ping"
|
||||||
--health-interval 10s
|
--health-interval 10ms
|
||||||
--health-timeout 5s
|
--health-timeout 3s
|
||||||
--health-retries 5
|
--health-retries 50
|
||||||
ports:
|
ports:
|
||||||
- 6379:6379
|
- 6379:6379
|
||||||
|
|
||||||
|
@ -201,7 +225,6 @@ jobs:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
ruby-version:
|
ruby-version:
|
||||||
- '3.1'
|
|
||||||
- '3.2'
|
- '3.2'
|
||||||
- '.ruby-version'
|
- '.ruby-version'
|
||||||
steps:
|
steps:
|
||||||
|
@ -220,12 +243,12 @@ jobs:
|
||||||
uses: ./.github/actions/setup-ruby
|
uses: ./.github/actions/setup-ruby
|
||||||
with:
|
with:
|
||||||
ruby-version: ${{ matrix.ruby-version}}
|
ruby-version: ${{ matrix.ruby-version}}
|
||||||
additional-system-dependencies: ffmpeg libpam-dev libyaml-dev
|
additional-system-dependencies: ffmpeg libpam-dev
|
||||||
|
|
||||||
- name: Load database schema
|
- name: Load database schema
|
||||||
run: './bin/rails db:create db:schema:load db:seed'
|
run: './bin/rails db:create db:schema:load db:seed'
|
||||||
|
|
||||||
- run: bin/rspec --tag paperclip_processing
|
- run: bin/rspec --tag attachment_processing
|
||||||
|
|
||||||
- name: Upload coverage reports to Codecov
|
- name: Upload coverage reports to Codecov
|
||||||
if: matrix.ruby-version == '.ruby-version'
|
if: matrix.ruby-version == '.ruby-version'
|
||||||
|
@ -250,9 +273,9 @@ jobs:
|
||||||
POSTGRES_USER: postgres
|
POSTGRES_USER: postgres
|
||||||
options: >-
|
options: >-
|
||||||
--health-cmd pg_isready
|
--health-cmd pg_isready
|
||||||
--health-interval 10s
|
--health-interval 10ms
|
||||||
--health-timeout 5s
|
--health-timeout 3s
|
||||||
--health-retries 5
|
--health-retries 50
|
||||||
ports:
|
ports:
|
||||||
- 5432:5432
|
- 5432:5432
|
||||||
|
|
||||||
|
@ -260,9 +283,9 @@ jobs:
|
||||||
image: redis:7-alpine
|
image: redis:7-alpine
|
||||||
options: >-
|
options: >-
|
||||||
--health-cmd "redis-cli ping"
|
--health-cmd "redis-cli ping"
|
||||||
--health-interval 10s
|
--health-interval 10ms
|
||||||
--health-timeout 5s
|
--health-timeout 3s
|
||||||
--health-retries 5
|
--health-retries 50
|
||||||
ports:
|
ports:
|
||||||
- 6379:6379
|
- 6379:6379
|
||||||
|
|
||||||
|
@ -280,7 +303,6 @@ jobs:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
ruby-version:
|
ruby-version:
|
||||||
- '3.1'
|
|
||||||
- '3.2'
|
- '3.2'
|
||||||
- '.ruby-version'
|
- '.ruby-version'
|
||||||
|
|
||||||
|
@ -289,14 +311,18 @@ jobs:
|
||||||
|
|
||||||
- uses: actions/download-artifact@v4
|
- uses: actions/download-artifact@v4
|
||||||
with:
|
with:
|
||||||
path: './public'
|
path: './'
|
||||||
name: ${{ github.sha }}
|
name: ${{ github.sha }}
|
||||||
|
|
||||||
|
- name: Expand archived asset artifacts
|
||||||
|
run: |
|
||||||
|
tar xvzf artifacts.tar.gz
|
||||||
|
|
||||||
- name: Set up Ruby environment
|
- name: Set up Ruby environment
|
||||||
uses: ./.github/actions/setup-ruby
|
uses: ./.github/actions/setup-ruby
|
||||||
with:
|
with:
|
||||||
ruby-version: ${{ matrix.ruby-version}}
|
ruby-version: ${{ matrix.ruby-version}}
|
||||||
additional-system-dependencies: ffmpeg
|
additional-system-dependencies: ffmpeg imagemagick
|
||||||
|
|
||||||
- name: Set up Javascript environment
|
- name: Set up Javascript environment
|
||||||
uses: ./.github/actions/setup-javascript
|
uses: ./.github/actions/setup-javascript
|
||||||
|
@ -335,9 +361,9 @@ jobs:
|
||||||
POSTGRES_USER: postgres
|
POSTGRES_USER: postgres
|
||||||
options: >-
|
options: >-
|
||||||
--health-cmd pg_isready
|
--health-cmd pg_isready
|
||||||
--health-interval 10s
|
--health-interval 10ms
|
||||||
--health-timeout 5s
|
--health-timeout 3s
|
||||||
--health-retries 5
|
--health-retries 50
|
||||||
ports:
|
ports:
|
||||||
- 5432:5432
|
- 5432:5432
|
||||||
|
|
||||||
|
@ -345,9 +371,9 @@ jobs:
|
||||||
image: redis:7-alpine
|
image: redis:7-alpine
|
||||||
options: >-
|
options: >-
|
||||||
--health-cmd "redis-cli ping"
|
--health-cmd "redis-cli ping"
|
||||||
--health-interval 10s
|
--health-interval 10ms
|
||||||
--health-timeout 5s
|
--health-timeout 3s
|
||||||
--health-retries 5
|
--health-retries 50
|
||||||
ports:
|
ports:
|
||||||
- 6379:6379
|
- 6379:6379
|
||||||
|
|
||||||
|
@ -358,9 +384,9 @@ jobs:
|
||||||
xpack.security.enabled: false
|
xpack.security.enabled: false
|
||||||
options: >-
|
options: >-
|
||||||
--health-cmd "curl http://localhost:9200/_cluster/health"
|
--health-cmd "curl http://localhost:9200/_cluster/health"
|
||||||
--health-interval 10s
|
--health-interval 2s
|
||||||
--health-timeout 5s
|
--health-timeout 3s
|
||||||
--health-retries 10
|
--health-retries 50
|
||||||
ports:
|
ports:
|
||||||
- 9200:9200
|
- 9200:9200
|
||||||
|
|
||||||
|
@ -372,9 +398,9 @@ jobs:
|
||||||
DISABLE_SECURITY_PLUGIN: true
|
DISABLE_SECURITY_PLUGIN: true
|
||||||
options: >-
|
options: >-
|
||||||
--health-cmd "curl http://localhost:9200/_cluster/health"
|
--health-cmd "curl http://localhost:9200/_cluster/health"
|
||||||
--health-interval 10s
|
--health-interval 2s
|
||||||
--health-timeout 5s
|
--health-timeout 3s
|
||||||
--health-retries 10
|
--health-retries 50
|
||||||
ports:
|
ports:
|
||||||
- 9200:9200
|
- 9200:9200
|
||||||
|
|
||||||
|
@ -393,7 +419,6 @@ jobs:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
ruby-version:
|
ruby-version:
|
||||||
- '3.1'
|
|
||||||
- '3.2'
|
- '3.2'
|
||||||
- '.ruby-version'
|
- '.ruby-version'
|
||||||
search-image:
|
search-image:
|
||||||
|
@ -409,14 +434,14 @@ jobs:
|
||||||
|
|
||||||
- uses: actions/download-artifact@v4
|
- uses: actions/download-artifact@v4
|
||||||
with:
|
with:
|
||||||
path: './public'
|
path: './'
|
||||||
name: ${{ github.sha }}
|
name: ${{ github.sha }}
|
||||||
|
|
||||||
- name: Set up Ruby environment
|
- name: Set up Ruby environment
|
||||||
uses: ./.github/actions/setup-ruby
|
uses: ./.github/actions/setup-ruby
|
||||||
with:
|
with:
|
||||||
ruby-version: ${{ matrix.ruby-version}}
|
ruby-version: ${{ matrix.ruby-version}}
|
||||||
additional-system-dependencies: ffmpeg
|
additional-system-dependencies: ffmpeg imagemagick
|
||||||
|
|
||||||
- name: Set up Javascript environment
|
- name: Set up Javascript environment
|
||||||
uses: ./.github/actions/setup-javascript
|
uses: ./.github/actions/setup-javascript
|
||||||
|
|
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -71,3 +71,6 @@ docker-compose.override.yml
|
||||||
|
|
||||||
# Ignore dotenv .local files
|
# Ignore dotenv .local files
|
||||||
.env*.local
|
.env*.local
|
||||||
|
|
||||||
|
# Ignore local-only rspec configuration
|
||||||
|
.rspec-local
|
||||||
|
|
2
.nvmrc
2
.nvmrc
|
@ -1 +1 @@
|
||||||
20.14
|
22.11
|
||||||
|
|
1
.profile
1
.profile
|
@ -1 +0,0 @@
|
||||||
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/app/.apt/lib/x86_64-linux-gnu:/app/.apt/usr/lib/x86_64-linux-gnu/mesa:/app/.apt/usr/lib/x86_64-linux-gnu/pulseaudio:/app/.apt/usr/lib/x86_64-linux-gnu/openblas-pthread
|
|
1
.rspec
1
.rspec
|
@ -1,3 +1,2 @@
|
||||||
--color
|
--color
|
||||||
--require spec_helper
|
--require spec_helper
|
||||||
--format Fuubar
|
|
||||||
|
|
252
.rubocop.yml
252
.rubocop.yml
|
@ -1,7 +1,27 @@
|
||||||
# Can be removed once all rules are addressed or moved to this file as documented overrides
|
---
|
||||||
inherit_from: .rubocop_todo.yml
|
AllCops:
|
||||||
|
CacheRootDirectory: tmp
|
||||||
|
DisplayStyleGuide: true
|
||||||
|
Exclude:
|
||||||
|
- Vagrantfile
|
||||||
|
- config/initializers/json_ld*
|
||||||
|
- lib/mastodon/migration_helpers.rb
|
||||||
|
ExtraDetails: true
|
||||||
|
NewCops: enable
|
||||||
|
TargetRubyVersion: 3.2 # Oldest supported ruby version
|
||||||
|
|
||||||
|
inherit_from:
|
||||||
|
- .rubocop/layout.yml
|
||||||
|
- .rubocop/metrics.yml
|
||||||
|
- .rubocop/naming.yml
|
||||||
|
- .rubocop/rails.yml
|
||||||
|
- .rubocop/rspec_rails.yml
|
||||||
|
- .rubocop/rspec.yml
|
||||||
|
- .rubocop/style.yml
|
||||||
|
- .rubocop/custom.yml
|
||||||
|
- .rubocop_todo.yml
|
||||||
|
- .rubocop/strict.yml
|
||||||
|
|
||||||
# Used for merging with exclude lists with .rubocop_todo.yml
|
|
||||||
inherit_mode:
|
inherit_mode:
|
||||||
merge:
|
merge:
|
||||||
- Exclude
|
- Exclude
|
||||||
|
@ -12,229 +32,3 @@ require:
|
||||||
- rubocop-rspec_rails
|
- rubocop-rspec_rails
|
||||||
- rubocop-performance
|
- rubocop-performance
|
||||||
- rubocop-capybara
|
- rubocop-capybara
|
||||||
- ./lib/linter/rubocop_middle_dot
|
|
||||||
|
|
||||||
AllCops:
|
|
||||||
TargetRubyVersion: 3.1 # Set to minimum supported version of CI
|
|
||||||
DisplayCopNames: true
|
|
||||||
DisplayStyleGuide: true
|
|
||||||
ExtraDetails: true
|
|
||||||
UseCache: true
|
|
||||||
CacheRootDirectory: tmp
|
|
||||||
NewCops: enable # Opt-in to newly added rules
|
|
||||||
Exclude:
|
|
||||||
- db/schema.rb
|
|
||||||
- 'bin/*'
|
|
||||||
- 'node_modules/**/*'
|
|
||||||
- 'Vagrantfile'
|
|
||||||
- 'vendor/**/*'
|
|
||||||
- 'config/initializers/json_ld*' # Generated files
|
|
||||||
- 'lib/mastodon/migration_helpers.rb' # Vendored from GitLab
|
|
||||||
- 'lib/templates/**/*'
|
|
||||||
|
|
||||||
# Reason: Prefer Hashes without extreme indentation
|
|
||||||
# https://docs.rubocop.org/rubocop/cops_layout.html#layoutfirsthashelementindentation
|
|
||||||
Layout/FirstHashElementIndentation:
|
|
||||||
EnforcedStyle: consistent
|
|
||||||
|
|
||||||
# Reason: Currently disabled in .rubocop_todo.yml
|
|
||||||
# https://docs.rubocop.org/rubocop/cops_layout.html#layoutlinelength
|
|
||||||
Layout/LineLength:
|
|
||||||
Max: 300 # Default of 120 causes a duplicate entry in generated todo file
|
|
||||||
|
|
||||||
## Disable most Metrics/*Length cops
|
|
||||||
# Reason: those are often triggered and force significant refactors when this happend
|
|
||||||
# but the team feel they are not really improving the code quality.
|
|
||||||
|
|
||||||
# https://docs.rubocop.org/rubocop/cops_metrics.html#metricsblocklength
|
|
||||||
Metrics/BlockLength:
|
|
||||||
Enabled: false
|
|
||||||
|
|
||||||
# https://docs.rubocop.org/rubocop/cops_metrics.html#metricsclasslength
|
|
||||||
Metrics/ClassLength:
|
|
||||||
Enabled: false
|
|
||||||
|
|
||||||
# https://docs.rubocop.org/rubocop/cops_metrics.html#metricsmethodlength
|
|
||||||
Metrics/MethodLength:
|
|
||||||
Enabled: false
|
|
||||||
|
|
||||||
# https://docs.rubocop.org/rubocop/cops_metrics.html#metricsmodulelength
|
|
||||||
Metrics/ModuleLength:
|
|
||||||
Enabled: false
|
|
||||||
|
|
||||||
## End Disable Metrics/*Length cops
|
|
||||||
|
|
||||||
# Reason: Currently disabled in .rubocop_todo.yml
|
|
||||||
# https://docs.rubocop.org/rubocop/cops_metrics.html#metricsabcsize
|
|
||||||
Metrics/AbcSize:
|
|
||||||
Exclude:
|
|
||||||
- 'lib/mastodon/cli/*.rb'
|
|
||||||
|
|
||||||
# Reason: Currently disabled in .rubocop_todo.yml
|
|
||||||
# https://docs.rubocop.org/rubocop/cops_metrics.html#metricscyclomaticcomplexity
|
|
||||||
Metrics/CyclomaticComplexity:
|
|
||||||
Exclude:
|
|
||||||
- lib/mastodon/cli/*.rb
|
|
||||||
|
|
||||||
# Reason:
|
|
||||||
# https://docs.rubocop.org/rubocop/cops_metrics.html#metricsparameterlists
|
|
||||||
Metrics/ParameterLists:
|
|
||||||
CountKeywordArgs: false
|
|
||||||
|
|
||||||
# Reason: Prefer seeing a variable name
|
|
||||||
# https://docs.rubocop.org/rubocop/cops_naming.html#namingblockforwarding
|
|
||||||
Naming/BlockForwarding:
|
|
||||||
EnforcedStyle: explicit
|
|
||||||
|
|
||||||
# Reason: Prevailing style is argument file paths
|
|
||||||
# https://docs.rubocop.org/rubocop-rails/cops_rails.html#railsfilepath
|
|
||||||
Rails/FilePath:
|
|
||||||
EnforcedStyle: arguments
|
|
||||||
|
|
||||||
# Reason: Prevailing style uses numeric status codes, matches RSpec/Rails/HttpStatus
|
|
||||||
# https://docs.rubocop.org/rubocop-rails/cops_rails.html#railshttpstatus
|
|
||||||
Rails/HttpStatus:
|
|
||||||
EnforcedStyle: numeric
|
|
||||||
|
|
||||||
# Reason: Conflicts with `Lint/UselessMethodDefinition` for inherited controller actions
|
|
||||||
# https://docs.rubocop.org/rubocop-rails/cops_rails.html#railslexicallyscopedactionfilter
|
|
||||||
Rails/LexicallyScopedActionFilter:
|
|
||||||
Exclude:
|
|
||||||
- 'app/controllers/auth/*'
|
|
||||||
|
|
||||||
# Reason: These tasks are doing local work which do not need full env loaded
|
|
||||||
# https://docs.rubocop.org/rubocop-rails/cops_rails.html#railsrakeenvironment
|
|
||||||
Rails/RakeEnvironment:
|
|
||||||
Exclude:
|
|
||||||
- 'lib/tasks/auto_annotate_models.rake'
|
|
||||||
- 'lib/tasks/emojis.rake'
|
|
||||||
- 'lib/tasks/mastodon.rake'
|
|
||||||
- 'lib/tasks/repo.rake'
|
|
||||||
- 'lib/tasks/statistics.rake'
|
|
||||||
|
|
||||||
# Reason: There are appropriate times to use these features
|
|
||||||
# https://docs.rubocop.org/rubocop-rails/cops_rails.html#railsskipsmodelvalidations
|
|
||||||
Rails/SkipsModelValidations:
|
|
||||||
Enabled: false
|
|
||||||
|
|
||||||
# Reason: We want to preserve the ability to migrate from arbitrary old versions,
|
|
||||||
# and cannot guarantee that every installation has run every migration as they upgrade.
|
|
||||||
# https://docs.rubocop.org/rubocop-rails/cops_rails.html#railsunusedignoredcolumns
|
|
||||||
Rails/UnusedIgnoredColumns:
|
|
||||||
Enabled: false
|
|
||||||
|
|
||||||
# Reason: Prevailing style choice
|
|
||||||
# https://docs.rubocop.org/rubocop-rails/cops_rails.html#railsnegateinclude
|
|
||||||
Rails/NegateInclude:
|
|
||||||
Enabled: false
|
|
||||||
|
|
||||||
# Reason: Enforce default limit, but allow some elements to span lines
|
|
||||||
# https://docs.rubocop.org/rubocop-rspec/cops_rspec.html#rspecexamplelength
|
|
||||||
RSpec/ExampleLength:
|
|
||||||
CountAsOne: ['array', 'heredoc', 'method_call']
|
|
||||||
|
|
||||||
# Reason: Deprecated cop, will be removed in 3.0, replaced by SpecFilePathFormat
|
|
||||||
# https://docs.rubocop.org/rubocop-rspec/cops_rspec.html#rspecfilepath
|
|
||||||
RSpec/FilePath:
|
|
||||||
Enabled: false
|
|
||||||
|
|
||||||
# Reason:
|
|
||||||
# https://docs.rubocop.org/rubocop-rspec/cops_rspec.html#rspecnamedsubject
|
|
||||||
RSpec/NamedSubject:
|
|
||||||
EnforcedStyle: named_only
|
|
||||||
|
|
||||||
# Reason: Prevailing style choice
|
|
||||||
# https://docs.rubocop.org/rubocop-rspec/cops_rspec.html#rspecnottonot
|
|
||||||
RSpec/NotToNot:
|
|
||||||
EnforcedStyle: to_not
|
|
||||||
|
|
||||||
# Reason: Match overrides from Rspec/FilePath rule above
|
|
||||||
# https://docs.rubocop.org/rubocop-rspec/cops_rspec.html#rspecspecfilepathformat
|
|
||||||
RSpec/SpecFilePathFormat:
|
|
||||||
CustomTransform:
|
|
||||||
ActivityPub: activitypub
|
|
||||||
DeepL: deepl
|
|
||||||
FetchOEmbedService: fetch_oembed_service
|
|
||||||
OEmbedController: oembed_controller
|
|
||||||
OStatus: ostatus
|
|
||||||
|
|
||||||
# Reason: Prevailing style uses numeric status codes, matches Rails/HttpStatus
|
|
||||||
# https://docs.rubocop.org/rubocop-rspec/cops_rspec_rails.html#rspecrailshttpstatus
|
|
||||||
RSpecRails/HttpStatus:
|
|
||||||
EnforcedStyle: numeric
|
|
||||||
|
|
||||||
# Reason:
|
|
||||||
# https://docs.rubocop.org/rubocop/cops_style.html#styleclassandmodulechildren
|
|
||||||
Style/ClassAndModuleChildren:
|
|
||||||
Enabled: false
|
|
||||||
|
|
||||||
# Reason: Classes mostly self-document with their names
|
|
||||||
# https://docs.rubocop.org/rubocop/cops_style.html#styledocumentation
|
|
||||||
Style/Documentation:
|
|
||||||
Enabled: false
|
|
||||||
|
|
||||||
# Reason: Route redirects are not token-formatted and must be skipped
|
|
||||||
# https://docs.rubocop.org/rubocop/cops_style.html#styleformatstringtoken
|
|
||||||
Style/FormatStringToken:
|
|
||||||
inherit_mode:
|
|
||||||
merge:
|
|
||||||
- AllowedMethods # The rubocop-rails config adds `redirect`
|
|
||||||
AllowedMethods:
|
|
||||||
- redirect_with_vary
|
|
||||||
|
|
||||||
# Reason: Prevailing style choice
|
|
||||||
# https://docs.rubocop.org/rubocop/cops_style.html#stylehashaslastarrayitem
|
|
||||||
Style/HashAsLastArrayItem:
|
|
||||||
Enabled: false
|
|
||||||
|
|
||||||
# Reason: Enforce modern Ruby style
|
|
||||||
# https://docs.rubocop.org/rubocop/cops_style.html#stylehashsyntax
|
|
||||||
Style/HashSyntax:
|
|
||||||
EnforcedStyle: ruby19_no_mixed_keys
|
|
||||||
EnforcedShorthandSyntax: either
|
|
||||||
|
|
||||||
# Reason:
|
|
||||||
# https://docs.rubocop.org/rubocop/cops_style.html#stylenumericliterals
|
|
||||||
Style/NumericLiterals:
|
|
||||||
AllowedPatterns:
|
|
||||||
- \d{4}_\d{2}_\d{2}_\d{6} # For DB migration date version number readability
|
|
||||||
|
|
||||||
# Reason:
|
|
||||||
# https://docs.rubocop.org/rubocop/cops_style.html#stylepercentliteraldelimiters
|
|
||||||
Style/PercentLiteralDelimiters:
|
|
||||||
PreferredDelimiters:
|
|
||||||
'%i': '()'
|
|
||||||
'%w': '()'
|
|
||||||
|
|
||||||
# Reason: Prefer less indentation in conditional assignments
|
|
||||||
# https://docs.rubocop.org/rubocop/cops_style.html#styleredundantbegin
|
|
||||||
Style/RedundantBegin:
|
|
||||||
Enabled: false
|
|
||||||
|
|
||||||
# Reason: Prevailing style choice
|
|
||||||
# https://docs.rubocop.org/rubocop/cops_style.html#styleredundantfetchblock
|
|
||||||
Style/RedundantFetchBlock:
|
|
||||||
Enabled: false
|
|
||||||
|
|
||||||
# Reason: Overridden to reduce implicit StandardError rescues
|
|
||||||
# https://docs.rubocop.org/rubocop/cops_style.html#stylerescuestandarderror
|
|
||||||
Style/RescueStandardError:
|
|
||||||
EnforcedStyle: implicit
|
|
||||||
|
|
||||||
# Reason: Originally disabled for CodeClimate, and no config consensus has been found
|
|
||||||
# https://docs.rubocop.org/rubocop/cops_style.html#stylesymbolarray
|
|
||||||
Style/SymbolArray:
|
|
||||||
Enabled: false
|
|
||||||
|
|
||||||
# Reason:
|
|
||||||
# https://docs.rubocop.org/rubocop/cops_style.html#styletrailingcommainarrayliteral
|
|
||||||
Style/TrailingCommaInArrayLiteral:
|
|
||||||
EnforcedStyleForMultiline: 'comma'
|
|
||||||
|
|
||||||
# Reason:
|
|
||||||
# https://docs.rubocop.org/rubocop/cops_style.html#styletrailingcommainhashliteral
|
|
||||||
Style/TrailingCommaInHashLiteral:
|
|
||||||
EnforcedStyleForMultiline: 'comma'
|
|
||||||
|
|
||||||
Style/MiddleDot:
|
|
||||||
Enabled: true
|
|
||||||
|
|
6
.rubocop/custom.yml
Normal file
6
.rubocop/custom.yml
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
---
|
||||||
|
require:
|
||||||
|
- ../lib/linter/rubocop_middle_dot
|
||||||
|
|
||||||
|
Style/MiddleDot:
|
||||||
|
Enabled: true
|
6
.rubocop/layout.yml
Normal file
6
.rubocop/layout.yml
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
---
|
||||||
|
Layout/FirstHashElementIndentation:
|
||||||
|
EnforcedStyle: consistent
|
||||||
|
|
||||||
|
Layout/LineLength:
|
||||||
|
Max: 300 # Default of 120 causes a duplicate entry in generated todo file
|
23
.rubocop/metrics.yml
Normal file
23
.rubocop/metrics.yml
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
---
|
||||||
|
Metrics/AbcSize:
|
||||||
|
Exclude:
|
||||||
|
- lib/mastodon/cli/*.rb
|
||||||
|
|
||||||
|
Metrics/BlockLength:
|
||||||
|
Enabled: false
|
||||||
|
|
||||||
|
Metrics/ClassLength:
|
||||||
|
Enabled: false
|
||||||
|
|
||||||
|
Metrics/CyclomaticComplexity:
|
||||||
|
Exclude:
|
||||||
|
- lib/mastodon/cli/*.rb
|
||||||
|
|
||||||
|
Metrics/MethodLength:
|
||||||
|
Enabled: false
|
||||||
|
|
||||||
|
Metrics/ModuleLength:
|
||||||
|
Enabled: false
|
||||||
|
|
||||||
|
Metrics/ParameterLists:
|
||||||
|
CountKeywordArgs: false
|
3
.rubocop/naming.yml
Normal file
3
.rubocop/naming.yml
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
---
|
||||||
|
Naming/BlockForwarding:
|
||||||
|
EnforcedStyle: explicit
|
23
.rubocop/rails.yml
Normal file
23
.rubocop/rails.yml
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
---
|
||||||
|
Rails/BulkChangeTable:
|
||||||
|
Enabled: false # Conflicts with strong_migrations features
|
||||||
|
|
||||||
|
Rails/FilePath:
|
||||||
|
EnforcedStyle: arguments
|
||||||
|
|
||||||
|
Rails/HttpStatus:
|
||||||
|
EnforcedStyle: numeric
|
||||||
|
|
||||||
|
Rails/NegateInclude:
|
||||||
|
Enabled: false
|
||||||
|
|
||||||
|
Rails/RakeEnvironment:
|
||||||
|
Exclude: # Tasks are doing local work which do not need full env loaded
|
||||||
|
- lib/tasks/auto_annotate_models.rake
|
||||||
|
- lib/tasks/emojis.rake
|
||||||
|
- lib/tasks/mastodon.rake
|
||||||
|
- lib/tasks/repo.rake
|
||||||
|
- lib/tasks/statistics.rake
|
||||||
|
|
||||||
|
Rails/SkipsModelValidations:
|
||||||
|
Enabled: false
|
27
.rubocop/rspec.yml
Normal file
27
.rubocop/rspec.yml
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
---
|
||||||
|
RSpec/ExampleLength:
|
||||||
|
CountAsOne: ['array', 'heredoc', 'method_call']
|
||||||
|
Max: 20 # Override default of 5
|
||||||
|
|
||||||
|
RSpec/MultipleExpectations:
|
||||||
|
Max: 10 # Overrides default of 1
|
||||||
|
|
||||||
|
RSpec/MultipleMemoizedHelpers:
|
||||||
|
Max: 20 # Overrides default of 5
|
||||||
|
|
||||||
|
RSpec/NamedSubject:
|
||||||
|
EnforcedStyle: named_only
|
||||||
|
|
||||||
|
RSpec/NestedGroups:
|
||||||
|
Max: 10 # Overrides default of 3
|
||||||
|
|
||||||
|
RSpec/NotToNot:
|
||||||
|
EnforcedStyle: to_not
|
||||||
|
|
||||||
|
RSpec/SpecFilePathFormat:
|
||||||
|
CustomTransform:
|
||||||
|
ActivityPub: activitypub
|
||||||
|
DeepL: deepl
|
||||||
|
FetchOEmbedService: fetch_oembed_service
|
||||||
|
OEmbedController: oembed_controller
|
||||||
|
OStatus: ostatus
|
3
.rubocop/rspec_rails.yml
Normal file
3
.rubocop/rspec_rails.yml
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
---
|
||||||
|
RSpecRails/HttpStatus:
|
||||||
|
EnforcedStyle: numeric
|
24
.rubocop/strict.yml
Normal file
24
.rubocop/strict.yml
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
Lint/Debugger: # Remove any `binding.pry`
|
||||||
|
Enabled: true
|
||||||
|
Exclude: []
|
||||||
|
|
||||||
|
RSpec/Focus: # Require full spec run on CI
|
||||||
|
Enabled: true
|
||||||
|
Exclude: []
|
||||||
|
|
||||||
|
Rails/Output: # Remove any `puts` debugging
|
||||||
|
inherit_mode:
|
||||||
|
merge:
|
||||||
|
- Include
|
||||||
|
Enabled: true
|
||||||
|
Exclude: []
|
||||||
|
Include:
|
||||||
|
- spec/**/*.rb
|
||||||
|
|
||||||
|
Rails/FindEach: # Using `each` could impact performance, use `find_each`
|
||||||
|
Enabled: true
|
||||||
|
Exclude: []
|
||||||
|
|
||||||
|
Rails/UniqBeforePluck: # Require `uniq.pluck` and not `pluck.uniq`
|
||||||
|
Enabled: true
|
||||||
|
Exclude: []
|
47
.rubocop/style.yml
Normal file
47
.rubocop/style.yml
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
---
|
||||||
|
Style/ClassAndModuleChildren:
|
||||||
|
Enabled: false
|
||||||
|
|
||||||
|
Style/Documentation:
|
||||||
|
Enabled: false
|
||||||
|
|
||||||
|
Style/FormatStringToken:
|
||||||
|
AllowedMethods:
|
||||||
|
- redirect_with_vary # Route redirects are not token-formatted
|
||||||
|
inherit_mode:
|
||||||
|
merge:
|
||||||
|
- AllowedMethods
|
||||||
|
|
||||||
|
Style/HashAsLastArrayItem:
|
||||||
|
Enabled: false
|
||||||
|
|
||||||
|
Style/HashSyntax:
|
||||||
|
EnforcedShorthandSyntax: either
|
||||||
|
EnforcedStyle: ruby19_no_mixed_keys
|
||||||
|
|
||||||
|
Style/NumericLiterals:
|
||||||
|
AllowedPatterns:
|
||||||
|
- \d{4}_\d{2}_\d{2}_\d{6}
|
||||||
|
|
||||||
|
Style/PercentLiteralDelimiters:
|
||||||
|
PreferredDelimiters:
|
||||||
|
'%i': ()
|
||||||
|
'%w': ()
|
||||||
|
|
||||||
|
Style/RedundantBegin:
|
||||||
|
Enabled: false
|
||||||
|
|
||||||
|
Style/RedundantFetchBlock:
|
||||||
|
Enabled: false
|
||||||
|
|
||||||
|
Style/RescueStandardError:
|
||||||
|
EnforcedStyle: implicit
|
||||||
|
|
||||||
|
Style/SymbolArray:
|
||||||
|
Enabled: false
|
||||||
|
|
||||||
|
Style/TrailingCommaInArrayLiteral:
|
||||||
|
EnforcedStyleForMultiline: comma
|
||||||
|
|
||||||
|
Style/TrailingCommaInHashLiteral:
|
||||||
|
EnforcedStyleForMultiline: comma
|
|
@ -1,6 +1,6 @@
|
||||||
# This configuration was generated by
|
# This configuration was generated by
|
||||||
# `rubocop --auto-gen-config --auto-gen-only-exclude --no-exclude-limit --no-offense-counts --no-auto-gen-timestamp`
|
# `rubocop --auto-gen-config --auto-gen-only-exclude --no-offense-counts --no-auto-gen-timestamp`
|
||||||
# using RuboCop version 1.63.5.
|
# using RuboCop version 1.66.1.
|
||||||
# The point is for the user to remove these configuration records
|
# The point is for the user to remove these configuration records
|
||||||
# one by one as the offenses are removed from the code base.
|
# one by one as the offenses are removed from the code base.
|
||||||
# Note that changes in the inspected code, or installation of new
|
# Note that changes in the inspected code, or installation of new
|
||||||
|
@ -14,7 +14,7 @@ Lint/NonLocalExitFromIterator:
|
||||||
Metrics/AbcSize:
|
Metrics/AbcSize:
|
||||||
Max: 82
|
Max: 82
|
||||||
|
|
||||||
# Configuration parameters: CountBlocks, Max.
|
# Configuration parameters: CountBlocks, CountModifierForms, Max.
|
||||||
Metrics/BlockNesting:
|
Metrics/BlockNesting:
|
||||||
Exclude:
|
Exclude:
|
||||||
- 'lib/tasks/mastodon.rake'
|
- 'lib/tasks/mastodon.rake'
|
||||||
|
@ -27,50 +27,23 @@ Metrics/CyclomaticComplexity:
|
||||||
Metrics/PerceivedComplexity:
|
Metrics/PerceivedComplexity:
|
||||||
Max: 27
|
Max: 27
|
||||||
|
|
||||||
# Configuration parameters: CountAsOne.
|
|
||||||
RSpec/ExampleLength:
|
|
||||||
Max: 18
|
|
||||||
|
|
||||||
RSpec/MultipleExpectations:
|
|
||||||
Max: 7
|
|
||||||
|
|
||||||
# Configuration parameters: AllowSubject.
|
|
||||||
RSpec/MultipleMemoizedHelpers:
|
|
||||||
Max: 17
|
|
||||||
|
|
||||||
# Configuration parameters: AllowedGroups.
|
|
||||||
RSpec/NestedGroups:
|
|
||||||
Max: 6
|
|
||||||
|
|
||||||
Rails/OutputSafety:
|
Rails/OutputSafety:
|
||||||
Exclude:
|
Exclude:
|
||||||
- 'config/initializers/simple_form.rb'
|
- 'config/initializers/simple_form.rb'
|
||||||
|
|
||||||
# This cop supports unsafe autocorrection (--autocorrect-all).
|
|
||||||
# Configuration parameters: AllowedMethods, AllowedPatterns.
|
|
||||||
# AllowedMethods: ==, equal?, eql?
|
|
||||||
Style/ClassEqualityComparison:
|
|
||||||
Exclude:
|
|
||||||
- 'app/helpers/jsonld_helper.rb'
|
|
||||||
- 'app/serializers/activitypub/outbox_serializer.rb'
|
|
||||||
|
|
||||||
# This cop supports safe autocorrection (--autocorrect).
|
# This cop supports safe autocorrection (--autocorrect).
|
||||||
# Configuration parameters: AllowedVars.
|
# Configuration parameters: AllowedVars.
|
||||||
Style/FetchEnvVar:
|
Style/FetchEnvVar:
|
||||||
Exclude:
|
Exclude:
|
||||||
- 'app/lib/redis_configuration.rb'
|
|
||||||
- 'app/lib/translation_service.rb'
|
- 'app/lib/translation_service.rb'
|
||||||
- 'config/environments/production.rb'
|
- 'config/environments/production.rb'
|
||||||
- 'config/initializers/2_limited_federation_mode.rb'
|
- 'config/initializers/2_limited_federation_mode.rb'
|
||||||
- 'config/initializers/3_omniauth.rb'
|
- 'config/initializers/3_omniauth.rb'
|
||||||
- 'config/initializers/blacklists.rb'
|
|
||||||
- 'config/initializers/cache_buster.rb'
|
- 'config/initializers/cache_buster.rb'
|
||||||
- 'config/initializers/devise.rb'
|
- 'config/initializers/devise.rb'
|
||||||
- 'config/initializers/paperclip.rb'
|
- 'config/initializers/paperclip.rb'
|
||||||
- 'config/initializers/vapid.rb'
|
- 'config/initializers/vapid.rb'
|
||||||
- 'lib/mastodon/redis_config.rb'
|
|
||||||
- 'lib/tasks/repo.rake'
|
- 'lib/tasks/repo.rake'
|
||||||
- 'spec/system/profile_spec.rb'
|
|
||||||
|
|
||||||
# This cop supports safe autocorrection (--autocorrect).
|
# This cop supports safe autocorrection (--autocorrect).
|
||||||
# Configuration parameters: EnforcedStyle, MaxUnannotatedPlaceholdersAllowed, AllowedMethods, AllowedPatterns.
|
# Configuration parameters: EnforcedStyle, MaxUnannotatedPlaceholdersAllowed, AllowedMethods, AllowedPatterns.
|
||||||
|
@ -81,40 +54,10 @@ Style/FormatStringToken:
|
||||||
- 'config/initializers/devise.rb'
|
- 'config/initializers/devise.rb'
|
||||||
- 'lib/paperclip/color_extractor.rb'
|
- 'lib/paperclip/color_extractor.rb'
|
||||||
|
|
||||||
# This cop supports unsafe autocorrection (--autocorrect-all).
|
|
||||||
Style/GlobalStdStream:
|
|
||||||
Exclude:
|
|
||||||
- 'config/environments/development.rb'
|
|
||||||
- 'config/environments/production.rb'
|
|
||||||
|
|
||||||
# This cop supports safe autocorrection (--autocorrect).
|
# This cop supports safe autocorrection (--autocorrect).
|
||||||
# Configuration parameters: MinBodyLength, AllowConsecutiveConditionals.
|
# Configuration parameters: MinBodyLength, AllowConsecutiveConditionals.
|
||||||
Style/GuardClause:
|
Style/GuardClause:
|
||||||
Exclude:
|
Enabled: false
|
||||||
- 'app/lib/activitypub/activity/block.rb'
|
|
||||||
- 'app/lib/request.rb'
|
|
||||||
- 'app/lib/request_pool.rb'
|
|
||||||
- 'app/lib/webfinger.rb'
|
|
||||||
- 'app/lib/webfinger_resource.rb'
|
|
||||||
- 'app/models/concerns/account/counters.rb'
|
|
||||||
- 'app/models/concerns/user/ldap_authenticable.rb'
|
|
||||||
- 'app/models/tag.rb'
|
|
||||||
- 'app/models/user.rb'
|
|
||||||
- 'app/services/fan_out_on_write_service.rb'
|
|
||||||
- 'app/services/post_status_service.rb'
|
|
||||||
- 'app/services/process_hashtags_service.rb'
|
|
||||||
- 'app/workers/move_worker.rb'
|
|
||||||
- 'app/workers/redownload_avatar_worker.rb'
|
|
||||||
- 'app/workers/redownload_header_worker.rb'
|
|
||||||
- 'app/workers/redownload_media_worker.rb'
|
|
||||||
- 'app/workers/remote_account_refresh_worker.rb'
|
|
||||||
- 'config/initializers/devise.rb'
|
|
||||||
- 'lib/devise/strategies/two_factor_ldap_authenticatable.rb'
|
|
||||||
- 'lib/devise/strategies/two_factor_pam_authenticatable.rb'
|
|
||||||
- 'lib/mastodon/cli/accounts.rb'
|
|
||||||
- 'lib/mastodon/cli/maintenance.rb'
|
|
||||||
- 'lib/mastodon/cli/media.rb'
|
|
||||||
- 'lib/tasks/repo.rake'
|
|
||||||
|
|
||||||
# This cop supports unsafe autocorrection (--autocorrect-all).
|
# This cop supports unsafe autocorrection (--autocorrect-all).
|
||||||
Style/HashTransformValues:
|
Style/HashTransformValues:
|
||||||
|
@ -136,16 +79,10 @@ Style/MutableConstant:
|
||||||
- 'app/services/delete_account_service.rb'
|
- 'app/services/delete_account_service.rb'
|
||||||
- 'lib/mastodon/migration_warning.rb'
|
- 'lib/mastodon/migration_warning.rb'
|
||||||
|
|
||||||
# This cop supports safe autocorrection (--autocorrect).
|
|
||||||
Style/NilLambda:
|
|
||||||
Exclude:
|
|
||||||
- 'config/initializers/paperclip.rb'
|
|
||||||
|
|
||||||
# Configuration parameters: AllowedMethods.
|
# Configuration parameters: AllowedMethods.
|
||||||
# AllowedMethods: respond_to_missing?
|
# AllowedMethods: respond_to_missing?
|
||||||
Style/OptionalBooleanParameter:
|
Style/OptionalBooleanParameter:
|
||||||
Exclude:
|
Exclude:
|
||||||
- 'app/helpers/admin/account_moderation_notes_helper.rb'
|
|
||||||
- 'app/helpers/jsonld_helper.rb'
|
- 'app/helpers/jsonld_helper.rb'
|
||||||
- 'app/lib/admin/system_check/message.rb'
|
- 'app/lib/admin/system_check/message.rb'
|
||||||
- 'app/lib/request.rb'
|
- 'app/lib/request.rb'
|
||||||
|
@ -154,7 +91,6 @@ Style/OptionalBooleanParameter:
|
||||||
- 'app/services/fetch_resource_service.rb'
|
- 'app/services/fetch_resource_service.rb'
|
||||||
- 'app/workers/domain_block_worker.rb'
|
- 'app/workers/domain_block_worker.rb'
|
||||||
- 'app/workers/unfollow_follow_worker.rb'
|
- 'app/workers/unfollow_follow_worker.rb'
|
||||||
- 'lib/mastodon/redis_config.rb'
|
|
||||||
|
|
||||||
# This cop supports unsafe autocorrection (--autocorrect-all).
|
# This cop supports unsafe autocorrection (--autocorrect-all).
|
||||||
# Configuration parameters: EnforcedStyle.
|
# Configuration parameters: EnforcedStyle.
|
||||||
|
@ -169,13 +105,6 @@ Style/RedundantConstantBase:
|
||||||
- 'config/environments/production.rb'
|
- 'config/environments/production.rb'
|
||||||
- 'config/initializers/sidekiq.rb'
|
- 'config/initializers/sidekiq.rb'
|
||||||
|
|
||||||
# This cop supports unsafe autocorrection (--autocorrect-all).
|
|
||||||
# Configuration parameters: ConvertCodeThatCanStartToReturnNil, AllowedMethods, MaxChainLength.
|
|
||||||
# AllowedMethods: present?, blank?, presence, try, try!
|
|
||||||
Style/SafeNavigation:
|
|
||||||
Exclude:
|
|
||||||
- 'app/models/concerns/account/finder_concern.rb'
|
|
||||||
|
|
||||||
# This cop supports safe autocorrection (--autocorrect).
|
# This cop supports safe autocorrection (--autocorrect).
|
||||||
# Configuration parameters: WordRegex.
|
# Configuration parameters: WordRegex.
|
||||||
# SupportedStyles: percent, brackets
|
# SupportedStyles: percent, brackets
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
3.3.2
|
3.3.6
|
||||||
|
|
10
Aptfile
10
Aptfile
|
@ -1,5 +1,5 @@
|
||||||
ffmpeg
|
libidn12
|
||||||
libopenblas0-pthread
|
# for idn-ruby on heroku-24 stack
|
||||||
libpq-dev
|
|
||||||
libxdamage1
|
# use https://github.com/heroku/heroku-buildpack-activestorage-preview
|
||||||
libxfixes3
|
# in place for ffmpeg and its dependent packages to reduce slag size
|
||||||
|
|
461
CHANGELOG.md
461
CHANGELOG.md
|
@ -2,6 +2,467 @@
|
||||||
|
|
||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
|
|
||||||
|
## [4.3.1] - 2024-10-21
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- Add more explicit explanations about author attribution and `fediverse:creator` (#32383 by @ClearlyClaire)
|
||||||
|
- Add ability to group follow notifications in WebUI, can be disabled in the column settings (#32520 by @renchap)
|
||||||
|
- Add back a 6 hours mute duration option (#32522 by @renchap)
|
||||||
|
- Add note about not changing ActiveRecord encryption secrets once they are set (#32413, #32476, #32512, and #32537 by @ClearlyClaire and @mjankowski)
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- Change translation feature to translate to selected regional variant (e.g. pt-BR) if available (#32428 by @c960657)
|
||||||
|
|
||||||
|
### Removed
|
||||||
|
|
||||||
|
- Remove ability to get embed code for remote posts (#32578 by @ClearlyClaire)\
|
||||||
|
Getting the embed code is only reliable for local posts.\
|
||||||
|
It never worked for non-Mastodon servers, and stopped working correctly with the changes made in 4.3.0.\
|
||||||
|
We have therefore decided to remove the menu entry while we investigate solutions.
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Fix follow recommendation moderation page default language when using regional variant (#32580 by @ClearlyClaire)
|
||||||
|
- Fix column-settings spacing in local timeline in advanced view (#32567 by @lindwurm)
|
||||||
|
- Fix broken i18n in text welcome mailer tags area (#32571 by @mjankowski)
|
||||||
|
- Fix missing or incorrect cache-control headers for Streaming server (#32551 by @ThisIsMissEm)
|
||||||
|
- Fix only the first paragraph being displayed in some notifications (#32348 by @ClearlyClaire)
|
||||||
|
- Fix reblog icons on account media view (#32506 by @tribela)
|
||||||
|
- Fix Content-Security-Policy not allowing OpenStack SWIFT object storage URI (#32439 by @kenkiku1021)
|
||||||
|
- Fix back arrow pointing to the incorrect direction in RTL languages (#32485 by @renchap)
|
||||||
|
- Fix streaming server using `REDIS_USERNAME` instead of `REDIS_USER` (#32493 by @ThisIsMissEm)
|
||||||
|
- Fix follow recommendation carrousel scrolling on RTL layouts (#32462 and #32505 by @ClearlyClaire)
|
||||||
|
- Fix follow recommendation suppressions not applying immediately (#32392 by @ClearlyClaire)
|
||||||
|
- Fix language of push notifications (#32415 by @ClearlyClaire)
|
||||||
|
- Fix mute duration not being shown in list of muted accounts in web UI (#32388 by @ClearlyClaire)
|
||||||
|
- Fix “Mark every notification as read” not updating the read marker if scrolled down (#32385 by @ClearlyClaire)
|
||||||
|
- Fix “Mention” appearing for otherwise filtered posts (#32356 by @ClearlyClaire)
|
||||||
|
- Fix notification requests from suspended accounts still being listed (#32354 by @ClearlyClaire)
|
||||||
|
- Fix list edition modal styling (#32358 and #32367 by @ClearlyClaire and @vmstan)
|
||||||
|
- Fix 4 columns barely not fitting on 1920px screen (#32361 by @ClearlyClaire)
|
||||||
|
- Fix icon alignment in applications list (#32293 by @mjankowski)
|
||||||
|
|
||||||
|
## [4.3.0] - 2024-10-08
|
||||||
|
|
||||||
|
The following changelog entries focus on changes visible to users, administrators, client developers or federated software developers, but there has also been a lot of code modernization, refactoring, and tooling work, in particular by @mjankowski.
|
||||||
|
|
||||||
|
### Security
|
||||||
|
|
||||||
|
- **Add confirmation interstitial instead of silently redirecting logged-out visitors to remote resources** (#27792, #28902, and #30651 by @ClearlyClaire and @Gargron)\
|
||||||
|
This fixes a longstanding open redirect in Mastodon, at the cost of added friction when local links to remote resources are shared.
|
||||||
|
- Fix ReDoS vulnerability on some Ruby versions ([GHSA-jpxp-r43f-rhvx](https://github.com/mastodon/mastodon/security/advisories/GHSA-jpxp-r43f-rhvx))
|
||||||
|
- Change `form-action` Content-Security-Policy directive to be more restrictive (#26897 and #32241 by @ClearlyClaire)
|
||||||
|
- Update dependencies
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- **Add server-side notification grouping** (#29889, #30576, #30685, #30688, #30707, #30776, #30779, #30781, #30440, #31062, #31098, #31076, #31111, #31123, #31223, #31214, #31224, #31299, #31325, #31347, #31304, #31326, #31384, #31403, #31433, #31509, #31486, #31513, #31592, #31594, #31638, #31746, #31652, #31709, #31725, #31745, #31613, #31657, #31840, #31610, #31929, #32089, #32085, #32243, #32179 and #32254 by @ClearlyClaire, @Gargron, @mgmn, and @renchap)\
|
||||||
|
Group notifications of the same type for the same target, so that your notifications no longer get cluttered by boost and favorite notifications as soon as a couple of your posts get traction.\
|
||||||
|
This is done server-side so that clients can efficiently get relevant groups without having to go through numerous pages of individual notifications.\
|
||||||
|
As part of this, the visual design of the entire notifications feature has been revamped.\
|
||||||
|
This feature is intended to eventually replace the existing notifications column, but for this first beta, users will have to enable it in the “Experimental features” section of the notifications column settings.\
|
||||||
|
The API is not final yet, but it consists of:
|
||||||
|
- a new `group_key` attribute to `Notification` entities
|
||||||
|
- `GET /api/v2/notifications`: https://docs.joinmastodon.org/methods/grouped_notifications/#get-grouped
|
||||||
|
- `GET /api/v2/notifications/:group_key`: https://docs.joinmastodon.org/methods/grouped_notifications/#get-notification-group
|
||||||
|
- `GET /api/v2/notifications/:group_key/accounts`: https://docs.joinmastodon.org/methods/grouped_notifications/#get-group-accounts
|
||||||
|
- `POST /api/v2/notifications/:group_key/dimsiss`: https://docs.joinmastodon.org/methods/grouped_notifications/#dismiss-group
|
||||||
|
- `GET /api/v2/notifications/:unread_count`: https://docs.joinmastodon.org/methods/grouped_notifications/#unread-group-count
|
||||||
|
- **Add notification policies, filtered notifications and notification requests** (#29366, #29529, #29433, #29565, #29567, #29572, #29575, #29588, #29646, #29652, #29658, #29666, #29693, #29699, #29737, #29706, #29570, #29752, #29810, #29826, #30114, #30251, #30559, #29868, #31008, #31011, #30996, #31149, #31220, #31222, #31225, #31242, #31262, #31250, #31273, #31310, #31316, #31322, #31329, #31324, #31331, #31343, #31342, #31309, #31358, #31378, #31406, #31256, #31456, #31419, #31457, #31508, #31540, #31541, #31723, #32062 and #32281 by @ClearlyClaire, @Gargron, @TheEssem, @mgmn, @oneiros, and @renchap)\
|
||||||
|
The old “Block notifications from non-followers”, “Block notifications from people you don't follow” and “Block direct messages from people you don't follow” notification settings have been replaced by a new set of settings found directly in the notification column.\
|
||||||
|
You can now separately filter or drop notifications from people you don't follow, people who don't follow you, accounts created within the past 30 days, as well as unsolicited private mentions, and accounts limited by the moderation.\
|
||||||
|
Instead of being outright dropped, notifications that you chose to filter are put in a separate “Filtered notifications” box that you can review separately without it clogging your main notifications.\
|
||||||
|
This adds the following REST API endpoints:
|
||||||
|
|
||||||
|
- `GET /api/v2/notifications/policy`: https://docs.joinmastodon.org/methods/notifications/#get-policy
|
||||||
|
- `PATCH /api/v2/notifications/policy`: https://docs.joinmastodon.org/methods/notifications/#update-the-filtering-policy-for-notifications
|
||||||
|
- `GET /api/v1/notifications/requests`: https://docs.joinmastodon.org/methods/notifications/#get-requests
|
||||||
|
- `GET /api/v1/notifications/requests/:id`: https://docs.joinmastodon.org/methods/notifications/#get-one-request
|
||||||
|
- `POST /api/v1/notifications/requests/:id/accept`: https://docs.joinmastodon.org/methods/notifications/#accept-request
|
||||||
|
- `POST /api/v1/notifications/requests/:id/dismiss`: https://docs.joinmastodon.org/methods/notifications/#dismiss-request
|
||||||
|
- `POST /api/v1/notifications/requests/accept`: https://docs.joinmastodon.org/methods/notifications/#accept-multiple-requests
|
||||||
|
- `POST /api/v1/notifications/requests/dismiss`: https://docs.joinmastodon.org/methods/notifications/#dismiss-multiple-requests
|
||||||
|
- `GET /api/v1/notifications/requests/merged`: https://docs.joinmastodon.org/methods/notifications/#requests-merged
|
||||||
|
|
||||||
|
In addition, accepting one or more notification requests generates a new streaming event:
|
||||||
|
|
||||||
|
- `notifications_merged`: an event of this type indicates accepted notification requests have finished merging, and the notifications list should be refreshed
|
||||||
|
|
||||||
|
- **Add notifications of severed relationships** (#27511, #29665, #29668, #29670, #29700, #29714, #29712, and #29731 by @ClearlyClaire and @Gargron)\
|
||||||
|
Notify local users when they lose relationships as a result of a local moderator blocking a remote account or server, allowing the affected user to retrieve the list of broken relationships.\
|
||||||
|
Note that this does not notify remote users.\
|
||||||
|
This adds the `severed_relationships` notification type to the REST API and streaming, with a new [`relationship_severance_event` attribute](https://docs.joinmastodon.org/entities/Notification/#relationship_severance_event).
|
||||||
|
- **Add hover cards in web UI** (#30754, #30864, #30850, #30879, #30928, #30949, #30948, #30931, and #31300 by @ClearlyClaire, @Gargron, and @renchap)\
|
||||||
|
Hovering over an avatar or username will now display a hover card with the first two lines of the user's description and their first two profile fields.\
|
||||||
|
This can be disabled in the “Animations and accessibility” section of the preferences.
|
||||||
|
- **Add "system" theme setting (light/dark theme depending on user system preference)** (#29748, #29553, #29795, #29918, #30839, and #30861 by @nshki, @ErikUden, @mjankowski, @renchap, and @vmstan)\
|
||||||
|
Add a “system” theme that automatically switch between default dark and light themes depending on the user's system preferences.\
|
||||||
|
Also changes the default server theme to this new “system” theme so that automatic theme selection happens even when logged out.
|
||||||
|
- **Add timeline of public posts about a trending link** (#30381 and #30840 by @Gargron)\
|
||||||
|
You can now see public posts mentioning currently-trending articles from people who have opted into discovery features.\
|
||||||
|
This adds a new REST API endpoint: https://docs.joinmastodon.org/methods/timelines/#link
|
||||||
|
- **Add author highlight for news articles whose authors are on the fediverse** (#30398, #30670, #30521, #30846, #31819, #31900 and #32188 by @Gargron, @mjankowski and @oneiros)\
|
||||||
|
This adds a mechanism to [highlight the author of news articles](https://blog.joinmastodon.org/2024/07/highlighting-journalism-on-mastodon/) shared on Mastodon.\
|
||||||
|
Articles hosted outside the fediverse can indicate a fediverse author with a meta tag:
|
||||||
|
```html
|
||||||
|
<meta name="fediverse:creator" content="username@domain" />
|
||||||
|
```
|
||||||
|
On the API side, this is represented by a new `authors` attribute to the `PreviewCard` entity: https://docs.joinmastodon.org/entities/PreviewCard/#authors \
|
||||||
|
Users can allow arbitrary domains to use `fediverse:creator` to credit them by visiting `/settings/verification`.\
|
||||||
|
This is federated as a new `attributionDomains` property in the `http://joinmastodon.org/ns` namespace, containing an array of domain names: https://docs.joinmastodon.org/spec/activitypub/#properties-used-1
|
||||||
|
- **Add in-app notifications for moderation actions and warnings** (#30065, #30082, and #30081 by @ClearlyClaire)\
|
||||||
|
In addition to email notifications, also notify users of moderation actions or warnings against them directly within the app, so they are less likely to miss important communication from their moderators.\
|
||||||
|
This adds the `moderation_warning` notification type to the REST API and streaming, with a new [`moderation_warning` attribute](https://docs.joinmastodon.org/entities/Notification/#moderation_warning).
|
||||||
|
- **Add domain information to profiles in web UI** (#29602 by @Gargron)\
|
||||||
|
Clicking the domain of a user in their profile will now open a tooltip with a short explanation about servers and federation.
|
||||||
|
- **Add support for Redis sentinel** (#31694, #31623, #31744, #31767, and #31768 by @ThisIsMissEm and @oneiros)\
|
||||||
|
See https://docs.joinmastodon.org/admin/scaling/#redis-sentinel
|
||||||
|
- **Add ability to reorder uploaded media before posting in web UI** (#28456 and #32093 by @Gargron)
|
||||||
|
- Add “A Mastodon update is available.” message on admin dashboard for non-bugfix updates (#32106 by @ClearlyClaire)
|
||||||
|
- Add ability to view alt text by clicking the ALT badge in web UI (#32058 by @Gargron)
|
||||||
|
- Add preview of followers removed in domain block modal in web UI (#32032 and #32105 by @ClearlyClaire and @Gargron)
|
||||||
|
- Add reblogs and favourites counts to statuses in ActivityPub (#32007 by @Gargron)
|
||||||
|
- Add moderation interface for searching hashtags (#30880 by @ThisIsMissEm)
|
||||||
|
- Add ability for admins to configure instance favicon and logo (#30040, #30208, #30259, #30375, #30734, #31016, and #30205 by @ClearlyClaire, @FawazFarid, @JasonPunyon, @mgmn, and @renchap)\
|
||||||
|
This is also exposed through the REST API: https://docs.joinmastodon.org/entities/Instance/#icon
|
||||||
|
- Add `api_versions` to `/api/v2/instance` (#31354 by @ClearlyClaire)\
|
||||||
|
Add API version number to make it easier for clients to detect compatible features going forward.\
|
||||||
|
See API documentation at https://docs.joinmastodon.org/entities/Instance/#api-versions
|
||||||
|
- Add quick links to Administration and Moderation Reports from Web UI (#24838 by @ThisIsMissEm)
|
||||||
|
- Add link to `/admin/roles` in moderation interface when changing someone's role (#31791 by @ClearlyClaire)
|
||||||
|
- Add recent audit log entries in federation moderation interface (#27386 by @ThisIsMissEm)
|
||||||
|
- Add profile setup to onboarding in web UI (#27829, #27876, and #28453 by @Gargron)
|
||||||
|
- Add prominent share/copy button on profiles in web UI (#27865 and #27889 by @ClearlyClaire and @Gargron)
|
||||||
|
- Add optional hints for server rules (#29539 and #29758 by @ClearlyClaire and @Gargron)\
|
||||||
|
Server rules can now be broken into a short rule name and a longer explanation of the rule.\
|
||||||
|
This adds a new [`hint` attribute](https://docs.joinmastodon.org/entities/Rule/#hint) to `Rule` entities in the REST API.
|
||||||
|
- Add support for PKCE in OAuth flow (#31129 by @ThisIsMissEm)
|
||||||
|
- Add CDN cache busting on media deletion (#31353 and #31414 by @ClearlyClaire and @tribela)
|
||||||
|
- Add the OAuth application used in local reports (#30539 by @ThisIsMissEm)
|
||||||
|
- Add hint to user that other remote statuses may be missing (#26910, #31387, and #31516 by @Gargron, @audiodude, and @renchap)
|
||||||
|
- Add lang attribute on preview card title (#31303 by @c960657)
|
||||||
|
- Add check for `Content-Length` in `ResponseWithLimitAdapter` (#31285 by @c960657)
|
||||||
|
- Add `Accept-Language` header to fetch preview cards in the server's default language (#31232 by @c960657)
|
||||||
|
- Add support for PKCE Extension in OmniAuth OIDC through the `OIDC_USE_PKCE` environment variable (#31131 by @ThisIsMissEm)
|
||||||
|
- Add API endpoints for unread notifications count (#31191 by @ClearlyClaire)\
|
||||||
|
This adds the following REST API endpoints:
|
||||||
|
- `GET /api/v1/notifications/unread_count`: https://docs.joinmastodon.org/methods/notifications/#unread-count
|
||||||
|
- Add `/` keyboard shortcut to focus the search field (#29921 by @ClearlyClaire)
|
||||||
|
- Add button to view the Hashtag on the instance from Hashtags in Moderation UI (#31533 by @ThisIsMissEm)
|
||||||
|
- Add list of pending releases directly in mail notifications for version updates (#29436 and #30035 by @ClearlyClaire)
|
||||||
|
- Add “Appeals” link under “Moderation” navigation category in moderation interface (#31071 by @ThisIsMissEm)
|
||||||
|
- Add badge on account card in report moderation interface when account is already suspended (#29592 by @ClearlyClaire)
|
||||||
|
- Add admin comments directly to the `admin/instances` page (#29240 by @tribela)
|
||||||
|
- Add ability to require approval when users sign up using specific email domains (#28468, #28732, #28607, and #28608 by @ClearlyClaire)
|
||||||
|
- Add banner for forwarded reports made by remote users about remote content (#27549 by @ClearlyClaire)
|
||||||
|
- Add support HTML ruby tags in remote posts for east-asian languages (#30897 by @ThisIsMissEm)
|
||||||
|
- Add link to manage warning presets in admin navigation (#26199 by @vmstan)
|
||||||
|
- Add volume saving/reuse to video player (#27488 by @thehydrogen)
|
||||||
|
- Add Elasticsearch index size, ffmpeg and ImageMagick versions to the admin dashboard (#27301, #30710, #31130, and #30845 by @vmstan)
|
||||||
|
- Add `MASTODON_SIDEKIQ_READY_FILENAME` environment variable to use a file for Sidekiq to signal it is ready to process jobs (#30971 and #30988 by @renchap)\
|
||||||
|
In the official Docker image, this is set to `sidekiq_process_has_started_and_will_begin_processing_jobs` so that Sidekiq will touch `tmp/sidekiq_process_has_started_and_will_begin_processing_jobs` to signal readiness.
|
||||||
|
- Add `S3_RETRY_LIMIT` environment variable to make S3 retries configurable (#23215 by @smiba)
|
||||||
|
- Add `S3_KEY_PREFIX` environment variable (#30181 by @S0yKaf)
|
||||||
|
- Add support for multiple `redirect_uris` when creating OAuth 2.0 Applications (#29192 by @ThisIsMissEm)
|
||||||
|
- Add Interlingue and Interlingua to interface languages (#28630 and #30828 by @Dhghomon and @renchap)
|
||||||
|
- Add Kashubian, Pennsylvania Dutch, Vai, Jawi Malay, Mohawk and Low German to posting languages (#26024, #26634, #27136, #29098, #27115, and #27434 by @EngineerDali, @HelgeKrueger, and @gunchleoc)
|
||||||
|
- Add option to use native Ruby driver for Redis through `REDIS_DRIVER=ruby` (#30717 by @vmstan)
|
||||||
|
- Add support for libvips in addition to ImageMagick (#30090, #30590, #30597, #30632, #30857, #30869, #30858 and #32104 by @ClearlyClaire, @Gargron, and @mjankowski)\
|
||||||
|
Server admins can now use libvips as a faster and lighter alternative to ImageMagick for processing user-uploaded images.\
|
||||||
|
This requires libvips 8.13 or newer, and needs to be enabled with `MASTODON_USE_LIBVIPS=true`.\
|
||||||
|
This is enabled by default in the official Docker images, and is intended to completely replace ImageMagick in the future.
|
||||||
|
- Add validations to `Web::PushSubscription` (#30540 and #30542 by @ThisIsMissEm)
|
||||||
|
- Add anchors to each authorized application in `/oauth/authorized_applications` (#31677 by @fowl2)
|
||||||
|
- Add active animation to header settings button (#30221, #30307, and #30388 by @daudix)
|
||||||
|
- Add OpenTelemetry instrumentation (#30130, #30322, #30353, #30350 and #31998 by @julianocosta89, @renchap, @robbkidd and @timetinytim)\
|
||||||
|
See https://docs.joinmastodon.org/admin/config/#otel for documentation
|
||||||
|
- Add API to get multiple accounts and statuses (#27871 and #30465 by @ClearlyClaire)\
|
||||||
|
This adds `GET /api/v1/accounts` and `GET /api/v1/statuses` to the REST API, see https://docs.joinmastodon.org/methods/accounts/#index and https://docs.joinmastodon.org/methods/statuses/#index
|
||||||
|
- Add support for CORS to `POST /oauth/revoke` (#31743 by @ClearlyClaire)
|
||||||
|
- Add redirection back to previous page after site upload deletion (#30141 by @FawazFarid)
|
||||||
|
- Add RFC8414 OAuth 2.0 server metadata (#29191 by @ThisIsMissEm)
|
||||||
|
- Add loading indicator and empty result message to advanced interface search (#30085 by @ClearlyClaire)
|
||||||
|
- Add `profile` OAuth 2.0 scope, allowing more limited access to user data (#29087 and #30357 by @ThisIsMissEm)
|
||||||
|
- Add the role ID to the badge component (#29707 by @renchap)
|
||||||
|
- Add diagnostic message for failure during CLI search deploy (#29462 by @mjankowski)
|
||||||
|
- Add pagination `Link` headers on API accounts/statuses when pinned true (#29442 by @mjankowski)
|
||||||
|
- Add support for specifying custom CA cert for Elasticsearch through `ES_CA_FILE` (#29122 and #29147 by @ClearlyClaire)
|
||||||
|
- Add groundwork for annual reports for accounts (#28693 by @Gargron)\
|
||||||
|
This lays the groundwork for a “year-in-review”/“wrapped” style report for local users, but is currently not in use.
|
||||||
|
- Add notification email on invalid second authenticator (#28822 by @ClearlyClaire)
|
||||||
|
- Add date of account deletion in list of accounts in the admin interface (#25640 by @tribela)
|
||||||
|
- Add new emojis from `jdecked/twemoji` 15.0 (#28404 by @TheEssem)
|
||||||
|
- Add configurable error handling in attachment batch deletion (#28184 by @vmstan)\
|
||||||
|
This makes the S3 batch size configurable through the `S3_BATCH_DELETE_LIMIT` environment variable (defaults to 1000), and adds some retry logic, configurable through the `S3_BATCH_DELETE_RETRY` environment variable (defaults to 3).
|
||||||
|
- Add VAPID public key to instance serializer (#28006 by @ThisIsMissEm)
|
||||||
|
- Add support for serving JRD `/.well-known/host-meta.json` in addition to XRD host-meta (#32206 by @c960657)
|
||||||
|
- Add `nodeName` and `nodeDescription` to nodeinfo `metadata` (#28079 by @6543)
|
||||||
|
- Add Thai diacritics and tone marks in `HASHTAG_INVALID_CHARS_RE` (#26576 by @ppnplus)
|
||||||
|
- Add variable delay before link verification of remote account links (#27774 by @ClearlyClaire)
|
||||||
|
- Add support for invite codes in the registration API (#27805 by @ClearlyClaire)
|
||||||
|
- Add HTML lang attribute to preview card descriptions (#27503 by @srapilly)
|
||||||
|
- Add display of relevant account warnings to report action logs (#27425 by @ClearlyClaire)
|
||||||
|
- Add validation of allowed schemes on preview card URLs (#27485 by @mjankowski)
|
||||||
|
- Add token introspection without read scope to `/api/v1/apps/verify_credentials` (#27142 by @ThisIsMissEm)
|
||||||
|
- Add support for cross-origin request to `/nodeinfo/2.0` (#27413 by @palant)
|
||||||
|
- Add variable delay before link verification of remote account links (#27351 by @ClearlyClaire)
|
||||||
|
- Add PWA shortcut to `/explore` page (#27235 by @jake-anto)
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- **Change icons throughout the web interface** (#27385, #27539, #27555, #27579, #27700, #27817, #28519, #28709, #28064, #28775, #28780, #27924, #29294, #29395, #29537, #29569, #29610, #29612, #29649, #29844, #27780, #30974, #30963, #30962, #30961, #31362, #31363, #31359, #31371, #31360, #31512, #31511, #31525, #32153, and #32201 by @ClearlyClaire, @Gargron, @arbolitoloco1, @mjankowski, @nclm, @renchap, @ronilaukkarinen, and @zunda)\
|
||||||
|
This changes all the interface icons from FontAwesome to Material Symbols for a more modern look, consistent with the official Mastodon Android app.\
|
||||||
|
In addition, better care is given to pixel alignment, and icon variants are used to better highlight active/inactive state.
|
||||||
|
- **Change design of compose form in web UI** (#28119, #29059, #29248, #29372, #29384, #29417, #29456, #29406, #29651, #29659, #31889 and #32033 by @ClearlyClaire, @Gargron, @eai04191, @hinaloe, and @ronilaukkarinen)\
|
||||||
|
The compose form has been completely redesigned for a more modern and consistent look, as well as spelling out the chosen privacy setting and language name at all times.\
|
||||||
|
As part of this, the “Unlisted” privacy setting has been renamed to “Quiet public”.
|
||||||
|
- **Change design of modals in the web UI** (#29576, #29614, #29640, #29644, #30131, #30884, #31399, #31555, #31752, #31801, #31883, #31844, #31864, and #31943 by @ClearlyClaire, @Gargron, @tribela and @vmstan)\
|
||||||
|
The mute, block, and domain block confirmation modals have been completely redesigned to be clearer and include more detailed information on the action to be performed.\
|
||||||
|
They also have a more modern and consistent design, along with other confirmation modals in the application.
|
||||||
|
- **Change colors throughout the web UI** (#29522, #29584, #29653, #29779, #29803, #29809, #29808, #29828, #31034, #31168, #31266, #31348, #31349, #31361, #31510 and #32128 by @ClearlyClaire, @Gargron, @mjankowski, @renchap, and @vmstan)
|
||||||
|
- **Change onboarding prompt to follow suggestions carousel in web UI** (#28878, #29272, and #31912 by @Gargron)
|
||||||
|
- **Change email templates** (#28416, #28755, #28814, #29064, #28883, #29470, #29607, #29761, #29760, #29879, #32073 and #32132 by @c960657, @ClearlyClaire, @Gargron, @hteumeuleu, and @mjankowski)\
|
||||||
|
All emails to end-users have been completely redesigned with a fresh new look, providing more information while making them easier to read and keeping maximum compatibility across mail clients.
|
||||||
|
- **Change follow recommendations algorithm** (#28314, #28433, #29017, #29108, #29306, #29550, #29619, and #31474 by @ClearlyClaire, @Gargron, @kernal053, @mjankowski, and @wheatear-dev)\
|
||||||
|
This replaces the “past interactions” recommendation algorithm with a “friends of friends” algorithm that suggests accounts followed by people you follow, and a “similar profiles” algorithm that suggests accounts with a profile similar to your most recent follows.\
|
||||||
|
In addition, the implementation has been significantly reworked, and all follow recommendations are now dismissable.\
|
||||||
|
This change deprecates the `source` attribute in `Suggestion` entities in the REST API, and replaces it with the new [`sources` attribute](https://docs.joinmastodon.org/entities/Suggestion/#sources).
|
||||||
|
- Change account search algorithm (#30803 by @Gargron)
|
||||||
|
- **Change streaming server to use its own dependencies and its own docker image** (#24702, #27967, #26850, #28112, #28115, #28137, #28138, #28497, #28548, #30795, #31612, and #31615 by @TheEssem, @ThisIsMissEm, @jippi, @renchap, @timetinytim, and @vmstan)\
|
||||||
|
In order to reduce the amount of runtime dependencies, the streaming server has been moved into a separate package and Docker image.\
|
||||||
|
The `mastodon` image does not contain the streaming server anymore, as it has been moved to its own `mastodon-streaming` image.\
|
||||||
|
Administrators may need to update their setup accordingly.
|
||||||
|
- Change how content warnings and filters are displayed in web UI (#31365, and #31761 by @Gargron)
|
||||||
|
- Change preview card processing to ignore `undefined` as canonical url (#31882 by @oneiros)
|
||||||
|
- Change embedded posts to use web UI (#31766, #32135 and #32271 by @Gargron)
|
||||||
|
- Change inner borders in media galleries in web UI (#31852 by @Gargron)
|
||||||
|
- Change design of media attachments and profile media tab in web UI (#31807, #32048, #31967, #32217, #32224 and #32257 by @ClearlyClaire and @Gargron)
|
||||||
|
- Change labels on thread indicators in web UI (#31806 by @Gargron)
|
||||||
|
- Change label of "Data export" menu item in settings interface (#32099 by @c960657)
|
||||||
|
- Change responsive break points on navigation panel in web UI (#32034 by @Gargron)
|
||||||
|
- Change cursor to `not-allowed` on disabled buttons (#32076 by @mjankowski)
|
||||||
|
- Change OAuth authorization prompt to not refer to apps as “third-party” (#32005 by @Gargron)
|
||||||
|
- Change Mastodon to issue correct HTTP signatures by default (#31994 by @ClearlyClaire)
|
||||||
|
- Change zoom icon in web UI (#29683 by @Gargron)
|
||||||
|
- Change directory page to use URL query strings for options (#31980, #31977 and #31984 by @ClearlyClaire and @renchap)
|
||||||
|
- Change report action buttons to be disabled when action has already been taken (#31773, #31822, and #31899 by @ClearlyClaire and @ThisIsMissEm)
|
||||||
|
- Change width of columns in advanced web UI (#31762 by @Gargron)
|
||||||
|
- Change design of unread conversations in web UI (#31763 by @Gargron)
|
||||||
|
- Change Web UI to allow viewing and severing relationships with suspended accounts (#27667 by @ClearlyClaire)\
|
||||||
|
This also adds a `with_suspended` parameter to `GET /api/v1/accounts/relationships` in the REST API.
|
||||||
|
- Change preview card image size limit from 2MB to 8MB when using libvips (#31904 by @ClearlyClaire)
|
||||||
|
- Change avatars border radius (#31390 by @renchap)
|
||||||
|
- Change counters to be displayed on profile timelines in web UI (#30525 by @Gargron)
|
||||||
|
- Change disabled buttons color in light mode to make the difference more visible (#30998 by @renchap)
|
||||||
|
- Change design of people tab on explore in web UI (#30059 by @Gargron)
|
||||||
|
- Change sidebar text in web UI (#30696 by @Gargron)
|
||||||
|
- Change "Follow" to "Follow back" and "Mutual" when appropriate in web UI (#28452, #28465, and #31934 by @ClearlyClaire, @Gargron and @renchap)
|
||||||
|
- Change media to be hidden/blurred by default in report modal (#28522 by @ClearlyClaire)
|
||||||
|
- Change order of the "muting" and "blocking" list options in “Data Exports” (#26088 by @fixermark)
|
||||||
|
- Change admin and moderation notes character limit from 500 to 2000 characters (#30288 by @ThisIsMissEm)
|
||||||
|
- Change mute options to be in dropdown on muted users list in web UI (#30049 and #31315 by @ClearlyClaire and @Gargron)
|
||||||
|
- Change out-of-band hashtags design in web UI (#29732 by @Gargron)
|
||||||
|
- Change design of metadata underneath detailed posts in web UI (#29585, #29605, and #29648 by @ClearlyClaire and @Gargron)
|
||||||
|
- Change action button to be last on profiles in web UI (#29533 and #29923 by @ClearlyClaire and @Gargron)
|
||||||
|
- Change confirmation prompts in trending moderation interface to be more specific (#19626 by @tribela)
|
||||||
|
- Change “Trends” moderation menu to “Recommendations & Trends” and move follow recommendations there (#31292 by @ThisIsMissEm)
|
||||||
|
- Change irrelevant fields in account cleanup settings to be disabled unless automatic cleanup is enabled (#26562 by @c960657)
|
||||||
|
- Change dropdown menu icon to not be replaced by close icon when open in web UI (#29532 by @Gargron)
|
||||||
|
- Change back button to always appear in advanced web UI (#29551 and #29669 by @Gargron)
|
||||||
|
- Change border of active compose field search inputs (#29832 and #29839 by @vmstan)
|
||||||
|
- Change instances of Nokogiri HTML4 parsing to HTML5 (#31812, #31815, #31813, and #31814 by @flavorjones)
|
||||||
|
- Change link detection to allow `@` at the end of an URL (#31124 by @adamniedzielski)
|
||||||
|
- Change User-Agent to use Mastodon as the product, and http.rb as platform details (#31192 by @ClearlyClaire)
|
||||||
|
- Change layout and wording of the Content Retention server settings page (#27733 by @vmstan)
|
||||||
|
- Change unconfirmed users to be kept for one week instead of two days (#30285 by @renchap)
|
||||||
|
- Change maximum page size for Admin Domain Management APIs from 200 to 500 (#31253 by @ThisIsMissEm)
|
||||||
|
- Change database pool size to default to Sidekiq concurrency settings in Sidekiq processes (#26488 by @sinoru)
|
||||||
|
- Change alt text to empty string for avatars (#21875 by @jasminjohal)
|
||||||
|
- Change Docker images to use custom-built libvips and ffmpeg (#30571, #30569, and #31498 by @vmstan)
|
||||||
|
- Change external links in the admin audit log to plain text or local administration pages (#27139 and #27150 by @ClearlyClaire and @ThisIsMissEm)
|
||||||
|
- Change YJIT to be enabled when available (#30310 and #27283 by @ClearlyClaire and @mjankowski)\
|
||||||
|
Enable Ruby's built-in just-in-time compiler. This improves performances substantially, at the cost of a slightly increased memory usage.
|
||||||
|
- Change `.env` file loading from deprecated `dotenv-rails` gem to `dotenv` gem (#29173 and #30121 by @mjankowski)\
|
||||||
|
This should have no effect except in the unlikely case an environment variable included a newline.
|
||||||
|
- Change “Panjabi” language name to the more common spelling “Punjabi” (#27117 by @gunchleoc)
|
||||||
|
- Change encryption of OTP secrets to use ActiveRecord Encryption (#29831, #28325, #30151, #30202, #30340, and #30344 by @ClearlyClaire and @mjankowski)\
|
||||||
|
This requires a manual step from administrators of existing servers. Indeed, they need to generate new secrets, which can be done using `bundle exec rails db:encryption:init`.\
|
||||||
|
Furthermore, there is a risk that the introduced migration fails if the server was misconfigured in the past. If that happens, the migration error will include the relevant information.
|
||||||
|
- Change `/api/v1/announcements` to return regular `Status` entities (#26736 by @ClearlyClaire)
|
||||||
|
- Change imports to convert case-insensitive fields to lowercase (#29739 and #29740 by @ThisIsMissEm)
|
||||||
|
- Change stats in the admin interface to be inclusive of the full selected range, from beginning of day to end of day (#29416 and #29841 by @mjankowski)
|
||||||
|
- Change materialized views to be refreshed concurrently to avoid locks (#29015 by @Gargron)
|
||||||
|
- Change compose form to use server-provided post character and poll options limits (#28928 and #29490 by @ClearlyClaire and @renchap)
|
||||||
|
- Change streaming server logging from `npmlog` to `pino` and `pino-http` (#27828 by @ThisIsMissEm)\
|
||||||
|
This changes the Mastodon streaming server log format, so this might be considered a breaking change if you were parsing the logs.
|
||||||
|
- Change media “ALT” label to use a specific CSS class (#28777 by @ClearlyClaire)
|
||||||
|
- Change streaming API host to not be overridden to localhost in development mode (#28557 by @ClearlyClaire)
|
||||||
|
- Change cookie rotator to use SHA1 digest for new cookies (#27392 by @ClearlyClaire)\
|
||||||
|
Note that this requires that no pre-4.2.0 Mastodon web server is running when this code is deployed, as those would not understand the new cookies.\
|
||||||
|
Therefore, zero-downtime updates are only supported if you're coming from 4.2.0 or newer. If you want to skip Mastodon 4.2, you will need to completely stop Mastodon services before updating.
|
||||||
|
- Change preview card deletes to be done using batch method (#28183 by @vmstan)
|
||||||
|
- Change `img-src` and `media-src` CSP directives to not include `https:` (#28025 and #28561 by @ClearlyClaire)
|
||||||
|
- Change self-destruct procedure (#26439, #29049, and #29420 by @ClearlyClaire and @zunda)\
|
||||||
|
Instead of enqueuing deletion jobs immediately, `tootctl self-destruct` now outputs a value for the `SELF_DESTRUCT` environment variable, which puts a server in self-destruct mode, processing deletions in the background, while giving users access to their export archives.
|
||||||
|
|
||||||
|
### Removed
|
||||||
|
|
||||||
|
- Remove unused E2EE messaging code and related `crypto` OAuth scope (#31193, #31945, #31963, and #31964 by @ClearlyClaire and @mjankowski)
|
||||||
|
- Remove StatsD integration (replaced by OpenTelemetry) (#30240 by @mjankowski)
|
||||||
|
- Remove `CacheBuster` default options (#30718 by @mjankowski)
|
||||||
|
- Remove home marker updates from the Web UI (#22721 by @davbeck)\
|
||||||
|
The web interface was unconditionally updating the home marker to the most recent received post, discarding any value set by other clients, thus making the feature unreliable.
|
||||||
|
- Remove support for Ruby 3.0 (reaching EOL) (#29702 by @mjankowski)
|
||||||
|
- Remove setting for unfollow confirmation modal (#29373 by @ClearlyClaire)\
|
||||||
|
Instead, the unfollow confirmation modal will always be displayed.
|
||||||
|
- Remove support for Capistrano (#27295 and #30009 by @mjankowski and @renchap)
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- **Fix link preview cards not always preserving the original URL from the status** (#27312 by @Gargron)
|
||||||
|
- Fix log out from user menu not working on Safari (#31402 by @renchap)
|
||||||
|
- Fix various issues when in link preview card generation (#28748, #30017, #30362, #30173, #30853, #30929, #30933, #30957, #30987, and #31144 by @adamniedzielski, @oneiros, @phocks, @timothyjrogers, and @tribela)
|
||||||
|
- Fix handling of missing links in Webfinger responses (#31030 by @adamniedzielski)
|
||||||
|
- Fix error when accepting an appeal for sensitive posts deleted in the meantime (#32037 by @ClearlyClaire)
|
||||||
|
- Fix error when encountering reblog of deleted post in feed rebuild (#32001 by @ClearlyClaire)
|
||||||
|
- Fix Safari browser glitch related to horizontal scrolling (#31960 by @Gargron)
|
||||||
|
- Fix unresolvable mentions sometimes preventing processing incoming posts (#29215 by @tribela and @ClearlyClaire)
|
||||||
|
- Fix too many requests caused by relationship look-ups in web UI (#32042 by @Gargron)
|
||||||
|
- Fix links for reblogs in moderation interface (#31979 by @ClearlyClaire)
|
||||||
|
- Fix the appearance of avatars when they do not load (#31966 and #32270 by @Gargron and @renchap)
|
||||||
|
- Fix spurious error notifications for aborted requests in web UI (#31952 by @c960657)
|
||||||
|
- Fix HTTP 500 error in `/api/v1/polls/:id/votes` when required `choices` parameter is missing (#25598 by @danielmbrasil)
|
||||||
|
- Fix security context sometimes not being added in LD-Signed activities (#31871 by @ClearlyClaire)
|
||||||
|
- Fix cross-origin loading of `inert.css` polyfill (#30687 by @louis77)
|
||||||
|
- Fix wrapping in dashboard quick access buttons (#32043 by @renchap)
|
||||||
|
- Fix recently used tags hint being displayed in profile edition page when there is none (#32120 by @mjankowski)
|
||||||
|
- Fix checkbox lists on narrow screens in the settings interface (#32112 by @mjankowski)
|
||||||
|
- Fix the position of status action buttons being affected by interaction counters (#32084 by @renchap)
|
||||||
|
- Fix the summary of converted ActivityPub object types to be treated as HTML (#28629 by @Menrath)
|
||||||
|
- Fix cutoff of instance name in sign-up form (#30598 by @oneiros)
|
||||||
|
- Fix invalid date searches returning 503 errors (#31526 by @notchairmk)
|
||||||
|
- Fix invalid `visibility` values in `POST /api/v1/statuses` returning 500 errors (#31571 by @c960657)
|
||||||
|
- Fix some components re-rendering spuriously in web UI (#31879 and #31881 by @ClearlyClaire and @Gargron)
|
||||||
|
- Fix sort order of moderation notes on Reports and Accounts (#31528 by @ThisIsMissEm)
|
||||||
|
- Fix email language when recipient has no selected locale (#31747 by @ClearlyClaire)
|
||||||
|
- Fix frequently-used languages not correctly updating in the web UI (#31386 by @c960657)
|
||||||
|
- Fix `POST /api/v1/statuses` silently ignoring invalid `media_ids` parameter (#31681 by @c960657)
|
||||||
|
- Fix handling of the `BIND` environment variable in the streaming server (#31624 by @ThisIsMissEm)
|
||||||
|
- Fix empty `aria-hidden` attribute value in logo resources area (#30570 by @mjankowski)
|
||||||
|
- Fix “Redirect URI” field not being marked as required in “New application” form (#30311 by @ThisIsMissEm)
|
||||||
|
- Fix right-to-left text in preview cards (#30930 by @ClearlyClaire)
|
||||||
|
- Fix rack attack `match_type` value typo in logging config (#30514 by @mjankowski)
|
||||||
|
- Fix various cases of duplicate, missing, or inconsistent borders or scrollbar styles (#31068, #31286, #31268, #31275, #31284, #31305, #31346, #31372, #31373, #31389, #31432, #31391, #31445, #32091, #32147 and #32137 by @ClearlyClaire, @mjankowski, @valtlai and @vmstan)
|
||||||
|
- Fix editing description of media uploads with custom thumbnails (#32221 by @ClearlyClaire)
|
||||||
|
- Fix race condition in `POST /api/v1/push/subscription` (#30166 by @ClearlyClaire)
|
||||||
|
- Fix post deletion not being delayed when those are part of an account warning (#30163 by @ClearlyClaire)
|
||||||
|
- Fix rendering error on `/start` when not logged in (#30023 by @timothyjrogers)
|
||||||
|
- Fix unneeded requests to blocked domains when receiving relayed signed activities from them (#31161 by @ClearlyClaire)
|
||||||
|
- Fix logo pushing header buttons out of view on certain conditions in mobile layout (#29787 by @ClearlyClaire)
|
||||||
|
- Fix notification-related records not being reattributed when merging accounts (#29694 by @ClearlyClaire)
|
||||||
|
- Fix results/query in `api/v1/featured_tags/suggestions` (#29597 by @mjankowski)
|
||||||
|
- Fix distracting and confusing always-showing scrollbar track in boost confirmation modal (#31524 by @ClearlyClaire)
|
||||||
|
- Fix being able to upload more than 4 media attachments in some cases (#29183 by @mashirozx)
|
||||||
|
- Fix preview card player getting embedded when clicking on the external link button (#29457 by @ClearlyClaire)
|
||||||
|
- Fix full date display not respecting the locale 12/24h format (#29448 by @renchap)
|
||||||
|
- Fix filters title and keywords overflow (#29396 by @GeopJr)
|
||||||
|
- Fix incorrect date format in “Follows and followers” (#29390 by @JasonPunyon)
|
||||||
|
- Fix navigation item active highlight for some paths (#32159 by @mjankowski)
|
||||||
|
- Fix “Edit media” modal sizing and layout when space-constrained (#27095 by @ronilaukkarinen)
|
||||||
|
- Fix modal container bounds (#29185 by @nico3333fr)
|
||||||
|
- Fix inefficient HTTP signature parsing using regexps and `StringScanner` (#29133 by @ClearlyClaire)
|
||||||
|
- Fix moderation report updates through `PUT /api/v1/admin/reports/:id` not being logged in the audit log (#29044, #30342, and #31033 by @mjankowski, @tribela, and @vmstan)
|
||||||
|
- Fix moderation interface allowing to select rule violation when there are no server rules (#31458 by @ThisIsMissEm)
|
||||||
|
- Fix redirection from paths with url-encoded `@` to their decoded form (#31184 by @timothyjrogers)
|
||||||
|
- Fix Trending Tags pending review having an unstable sort order (#31473 by @ThisIsMissEm)
|
||||||
|
- Fix the emoji dropdown button always opening the dropdown instead of behaving like a toggle (#29012 by @jh97uk)
|
||||||
|
- Fix processing of incoming posts with bearcaps (#26527 by @kmycode)
|
||||||
|
- Fix support for IPv6 redis connections in streaming (#31229 by @ThisIsMissEm)
|
||||||
|
- Fix search form re-rendering spuriously in web UI (#28876 by @Gargron)
|
||||||
|
- Fix `RedownloadMediaWorker` not being called on transient S3 failure (#28714 by @ClearlyClaire)
|
||||||
|
- Fix ISO code for Canadian French from incorrect `fr-QC` to `fr-CA` (#26015 by @gunchleoc)
|
||||||
|
- Fix `.opus` file uploads being misidentified by Paperclip (#28580 by @vmstan)
|
||||||
|
- Fix loading local accounts with extraneous domain part in WebUI (#28559 by @ClearlyClaire)
|
||||||
|
- Fix destructive actions in dropdowns not using error color in light theme (#28484 by @logicalmoody)
|
||||||
|
- Fix call to inefficient `delete_matched` cache method in domain blocks (#28374 by @ClearlyClaire)
|
||||||
|
- Fix status edits not always being streamed to mentioned users (#28324 by @ClearlyClaire)
|
||||||
|
- Fix onboarding step descriptions being truncated on narrow screens (#28021 by @ClearlyClaire)
|
||||||
|
- Fix duplicate IDs in relationships and familiar_followers APIs (#27982 by @KevinBongart)
|
||||||
|
- Fix modal content not being selectable (#27813 by @pajowu)
|
||||||
|
- Fix Web UI not displaying appropriate explanation when a user hides their follows/followers (#27791 by @ClearlyClaire)
|
||||||
|
- Fix format-dependent redirects being cached regardless of requested format (#27632 by @ClearlyClaire)
|
||||||
|
- Fix confusing screen when visiting a confirmation link for an already-confirmed email (#27368 by @ClearlyClaire)
|
||||||
|
- Fix explore page reloading when you navigate back to it in web UI (#27489 by @Gargron)
|
||||||
|
- Fix missing redirection from `/home` to `/deck/home` in the advanced interface (#27378 by @Signez)
|
||||||
|
- Fix empty environment variables not using default nil value (#27400 by @renchap)
|
||||||
|
- Fix language sorting in settings (#27158 by @gunchleoc)
|
||||||
|
|
||||||
|
## |4.2.11] - 2024-08-16
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- Add support for incoming `<s>` tag ([mediaformat](https://github.com/mastodon/mastodon/pull/31375))
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- Change logic of block/mute bypass for mentions from moderators to only apply to visible roles with moderation powers ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/31271))
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Fix incorrect rate limit on PUT requests ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/31356))
|
||||||
|
- Fix presence of `ß` in adjacent word preventing mention and hashtag matching ([adamniedzielski](https://github.com/mastodon/mastodon/pull/31122))
|
||||||
|
- Fix processing of webfinger responses with multiple `self` links ([adamniedzielski](https://github.com/mastodon/mastodon/pull/31110))
|
||||||
|
- Fix duplicate `orderedItems` in user archive's `outbox.json` ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/31099))
|
||||||
|
- Fix click event handling when clicking outside of an open dropdown menu ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/31251))
|
||||||
|
- Fix status processing failing halfway when a remote post has a malformed `replies` attribute ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/31246))
|
||||||
|
- Fix `--verbose` option of `tootctl media remove`, which was previously erroneously removed ([mjankowski](https://github.com/mastodon/mastodon/pull/30536))
|
||||||
|
- Fix division by zero on some video/GIF files ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/30600))
|
||||||
|
- Fix Web UI trying to save user settings despite being logged out ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/30324))
|
||||||
|
- Fix hashtag regexp matching some link anchors ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/30190))
|
||||||
|
- Fix local account search on LDAP login being case-sensitive ([raucao](https://github.com/mastodon/mastodon/pull/30113))
|
||||||
|
- Fix development environment admin account not being auto-approved ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/29958))
|
||||||
|
- Fix report reason selector in moderation interface not unselecting rules when changing category ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/29026))
|
||||||
|
- Fix already-invalid reports failing to resolve ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/29027))
|
||||||
|
- Fix OCR when using S3/CDN for assets ([vmstan](https://github.com/mastodon/mastodon/pull/28551))
|
||||||
|
- Fix error when encountering malformed `Tag` objects from Kbin ([ShadowJonathan](https://github.com/mastodon/mastodon/pull/28235))
|
||||||
|
- Fix not all allowed image formats showing in file picker when uploading custom emoji ([june128](https://github.com/mastodon/mastodon/pull/28076))
|
||||||
|
- Fix search popout listing unusable search options when logged out ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/27918))
|
||||||
|
- Fix processing of featured collections lacking an `items` attribute ([tribela](https://github.com/mastodon/mastodon/pull/27581))
|
||||||
|
- Fix `mastodon:stats` decoration of stats rake task ([mjankowski](https://github.com/mastodon/mastodon/pull/31104))
|
||||||
|
|
||||||
|
## [4.2.10] - 2024-07-04
|
||||||
|
|
||||||
|
### Security
|
||||||
|
|
||||||
|
- Fix incorrect permission checking on multiple API endpoints ([GHSA-58x8-3qxw-6hm7](https://github.com/mastodon/mastodon/security/advisories/GHSA-58x8-3qxw-6hm7))
|
||||||
|
- Fix incorrect authorship checking when processing some activities (CVE-2024-37903, [GHSA-xjvf-fm67-4qc3](https://github.com/mastodon/mastodon/security/advisories/GHSA-xjvf-fm67-4qc3))
|
||||||
|
- Fix ongoing streaming sessions not being invalidated when application tokens get revoked ([GHSA-vp5r-5pgw-jwqx](https://github.com/mastodon/mastodon/security/advisories/GHSA-vp5r-5pgw-jwqx))
|
||||||
|
- Update dependencies
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- Add yarn version specification to avoid confusion with Yarn 3 and Yarn 4
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- Change preview cards generation to skip unusually long URLs ([oneiros](https://github.com/mastodon/mastodon/pull/30854))
|
||||||
|
- Change search modifiers to be case-insensitive ([Gargron](https://github.com/mastodon/mastodon/pull/30865))
|
||||||
|
- Change `STATSD_ADDR` handling to emit a warning rather than crashing if the address is unreachable ([timothyjrogers](https://github.com/mastodon/mastodon/pull/30691))
|
||||||
|
- Change PWA start URL from `/home` to `/` ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/27377))
|
||||||
|
|
||||||
|
### Removed
|
||||||
|
|
||||||
|
- Removed dependency on `posix-spawn` ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/18559))
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Fix scheduled statuses scheduled in less than 5 minutes being immediately published ([danielmbrasil](https://github.com/mastodon/mastodon/pull/30584))
|
||||||
|
- Fix encoding detection for link cards ([oneiros](https://github.com/mastodon/mastodon/pull/30780))
|
||||||
|
- Fix `/admin/accounts/:account_id/statuses/:id` for edited posts with media attachments ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/30819))
|
||||||
|
- Fix duplicate `@context` attribute in user archive export ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/30653))
|
||||||
|
|
||||||
## [4.2.9] - 2024-05-30
|
## [4.2.9] - 2024-05-30
|
||||||
|
|
||||||
### Security
|
### Security
|
||||||
|
|
|
@ -11,6 +11,11 @@ You can contribute in the following ways:
|
||||||
|
|
||||||
If your contributions are accepted into Mastodon, you can request to be paid through [our OpenCollective](https://opencollective.com/mastodon).
|
If your contributions are accepted into Mastodon, you can request to be paid through [our OpenCollective](https://opencollective.com/mastodon).
|
||||||
|
|
||||||
|
Please review the org-level [contribution guidelines] for high-level acceptance
|
||||||
|
criteria guidance.
|
||||||
|
|
||||||
|
[contribution guidelines]: https://github.com/mastodon/.github/blob/main/CONTRIBUTING.md
|
||||||
|
|
||||||
## API Changes and Additions
|
## API Changes and Additions
|
||||||
|
|
||||||
Please note that any changes or additions made to the API should have an accompanying pull request on [our documentation repository](https://github.com/mastodon/documentation).
|
Please note that any changes or additions made to the API should have an accompanying pull request on [our documentation repository](https://github.com/mastodon/documentation).
|
||||||
|
|
337
Dockerfile
337
Dockerfile
|
@ -1,4 +1,4 @@
|
||||||
# syntax=docker/dockerfile:1.7
|
# syntax=docker/dockerfile:1.10
|
||||||
|
|
||||||
# This file is designed for production server deployment, not local development work
|
# This file is designed for production server deployment, not local development work
|
||||||
# For a containerized local dev environment, see: https://github.com/mastodon/mastodon/blob/main/README.md#docker
|
# For a containerized local dev environment, see: https://github.com/mastodon/mastodon/blob/main/README.md#docker
|
||||||
|
@ -11,22 +11,26 @@ ARG TARGETPLATFORM=${TARGETPLATFORM}
|
||||||
ARG BUILDPLATFORM=${BUILDPLATFORM}
|
ARG BUILDPLATFORM=${BUILDPLATFORM}
|
||||||
|
|
||||||
# Ruby image to use for base image, change with [--build-arg RUBY_VERSION="3.3.x"]
|
# Ruby image to use for base image, change with [--build-arg RUBY_VERSION="3.3.x"]
|
||||||
ARG RUBY_VERSION="3.3.2"
|
# renovate: datasource=docker depName=docker.io/ruby
|
||||||
|
ARG RUBY_VERSION="3.3.6"
|
||||||
# # Node version to use in base image, change with [--build-arg NODE_MAJOR_VERSION="20"]
|
# # Node version to use in base image, change with [--build-arg NODE_MAJOR_VERSION="20"]
|
||||||
ARG NODE_MAJOR_VERSION="20"
|
# renovate: datasource=node-version depName=node
|
||||||
|
ARG NODE_MAJOR_VERSION="22"
|
||||||
# Debian image to use for base image, change with [--build-arg DEBIAN_VERSION="bookworm"]
|
# Debian image to use for base image, change with [--build-arg DEBIAN_VERSION="bookworm"]
|
||||||
ARG DEBIAN_VERSION="bookworm"
|
ARG DEBIAN_VERSION="bookworm"
|
||||||
# Node image to use for base image based on combined variables (ex: 20-bookworm-slim)
|
# Node image to use for base image based on combined variables (ex: 20-bookworm-slim)
|
||||||
FROM docker.io/node:${NODE_MAJOR_VERSION}-${DEBIAN_VERSION}-slim as node
|
FROM docker.io/node:${NODE_MAJOR_VERSION}-${DEBIAN_VERSION}-slim AS node
|
||||||
# Ruby image to use for base image based on combined variables (ex: 3.3.x-slim-bookworm)
|
# Ruby image to use for base image based on combined variables (ex: 3.3.x-slim-bookworm)
|
||||||
FROM docker.io/ruby:${RUBY_VERSION}-slim-${DEBIAN_VERSION} as ruby
|
FROM docker.io/ruby:${RUBY_VERSION}-slim-${DEBIAN_VERSION} AS ruby
|
||||||
|
|
||||||
# Resulting version string is vX.X.X-MASTODON_VERSION_PRERELEASE+MASTODON_VERSION_METADATA
|
# Resulting version string is vX.X.X-MASTODON_VERSION_PRERELEASE+MASTODON_VERSION_METADATA
|
||||||
# Example: v4.2.0-nightly.2023.11.09+something
|
# Example: v4.3.0-nightly.2023.11.09+pr-123456
|
||||||
# Overwrite existence of 'alpha.0' in version.rb [--build-arg MASTODON_VERSION_PRERELEASE="nightly.2023.11.09"]
|
# Overwrite existence of 'alpha.X' in version.rb [--build-arg MASTODON_VERSION_PRERELEASE="nightly.2023.11.09"]
|
||||||
ARG MASTODON_VERSION_PRERELEASE=""
|
ARG MASTODON_VERSION_PRERELEASE=""
|
||||||
# Append build metadata or fork information to version.rb [--build-arg MASTODON_VERSION_METADATA="pr-12345"]
|
# Append build metadata or fork information to version.rb [--build-arg MASTODON_VERSION_METADATA="pr-123456"]
|
||||||
ARG MASTODON_VERSION_METADATA=""
|
ARG MASTODON_VERSION_METADATA=""
|
||||||
|
# Will be available as Mastodon::Version.source_commit
|
||||||
|
ARG SOURCE_COMMIT=""
|
||||||
|
|
||||||
# Allow Ruby on Rails to serve static files
|
# Allow Ruby on Rails to serve static files
|
||||||
# See: https://docs.joinmastodon.org/admin/config/#rails_serve_static_files
|
# See: https://docs.joinmastodon.org/admin/config/#rails_serve_static_files
|
||||||
|
@ -43,29 +47,32 @@ ARG GID="991"
|
||||||
|
|
||||||
# Apply Mastodon build options based on options above
|
# Apply Mastodon build options based on options above
|
||||||
ENV \
|
ENV \
|
||||||
# Apply Mastodon version information
|
# Apply Mastodon version information
|
||||||
MASTODON_VERSION_PRERELEASE="${MASTODON_VERSION_PRERELEASE}" \
|
MASTODON_VERSION_PRERELEASE="${MASTODON_VERSION_PRERELEASE}" \
|
||||||
MASTODON_VERSION_METADATA="${MASTODON_VERSION_METADATA}" \
|
MASTODON_VERSION_METADATA="${MASTODON_VERSION_METADATA}" \
|
||||||
# Enable libvips
|
SOURCE_COMMIT="${SOURCE_COMMIT}" \
|
||||||
MASTODON_USE_LIBVIPS=true \
|
# Apply Mastodon static files and YJIT options
|
||||||
# Apply Mastodon static files and YJIT options
|
|
||||||
RAILS_SERVE_STATIC_FILES=${RAILS_SERVE_STATIC_FILES} \
|
RAILS_SERVE_STATIC_FILES=${RAILS_SERVE_STATIC_FILES} \
|
||||||
RUBY_YJIT_ENABLE=${RUBY_YJIT_ENABLE} \
|
RUBY_YJIT_ENABLE=${RUBY_YJIT_ENABLE} \
|
||||||
# Apply timezone
|
# Apply timezone
|
||||||
TZ=${TZ}
|
TZ=${TZ}
|
||||||
|
|
||||||
ENV \
|
ENV \
|
||||||
# Configure the IP to bind Mastodon to when serving traffic
|
# Configure the IP to bind Mastodon to when serving traffic
|
||||||
BIND="0.0.0.0" \
|
BIND="0.0.0.0" \
|
||||||
# Use production settings for Yarn, Node and related nodejs based tools
|
# Use production settings for Yarn, Node and related nodejs based tools
|
||||||
NODE_ENV="production" \
|
NODE_ENV="production" \
|
||||||
# Use production settings for Ruby on Rails
|
# Use production settings for Ruby on Rails
|
||||||
RAILS_ENV="production" \
|
RAILS_ENV="production" \
|
||||||
# Add Ruby and Mastodon installation to the PATH
|
# Add Ruby and Mastodon installation to the PATH
|
||||||
DEBIAN_FRONTEND="noninteractive" \
|
DEBIAN_FRONTEND="noninteractive" \
|
||||||
PATH="${PATH}:/opt/ruby/bin:/opt/mastodon/bin" \
|
PATH="${PATH}:/opt/ruby/bin:/opt/mastodon/bin" \
|
||||||
# Optimize jemalloc 5.x performance
|
# Optimize jemalloc 5.x performance
|
||||||
MALLOC_CONF="narenas:2,background_thread:true,thp:never,dirty_decay_ms:1000,muzzy_decay_ms:0"
|
MALLOC_CONF="narenas:2,background_thread:true,thp:never,dirty_decay_ms:1000,muzzy_decay_ms:0" \
|
||||||
|
# Enable libvips, should not be changed
|
||||||
|
MASTODON_USE_LIBVIPS=true \
|
||||||
|
# Sidekiq will touch tmp/sidekiq_process_has_started_and_will_begin_processing_jobs to indicate it is ready. This can be used for a readiness check in Kubernetes
|
||||||
|
MASTODON_SIDEKIQ_READY_FILENAME=sidekiq_process_has_started_and_will_begin_processing_jobs
|
||||||
|
|
||||||
# Set default shell used for running commands
|
# Set default shell used for running commands
|
||||||
SHELL ["/bin/bash", "-o", "pipefail", "-o", "errexit", "-c"]
|
SHELL ["/bin/bash", "-o", "pipefail", "-o", "errexit", "-c"]
|
||||||
|
@ -75,14 +82,14 @@ ARG TARGETPLATFORM
|
||||||
RUN echo "Target platform is $TARGETPLATFORM"
|
RUN echo "Target platform is $TARGETPLATFORM"
|
||||||
|
|
||||||
RUN \
|
RUN \
|
||||||
# Remove automatic apt cache Docker cleanup scripts
|
# Remove automatic apt cache Docker cleanup scripts
|
||||||
rm -f /etc/apt/apt.conf.d/docker-clean; \
|
rm -f /etc/apt/apt.conf.d/docker-clean; \
|
||||||
# Sets timezone
|
# Sets timezone
|
||||||
echo "${TZ}" > /etc/localtime; \
|
echo "${TZ}" > /etc/localtime; \
|
||||||
# Creates mastodon user/group and sets home directory
|
# Creates mastodon user/group and sets home directory
|
||||||
groupadd -g "${GID}" mastodon; \
|
groupadd -g "${GID}" mastodon; \
|
||||||
useradd -l -u "${UID}" -g "${GID}" -m -d /opt/mastodon mastodon; \
|
useradd -l -u "${UID}" -g "${GID}" -m -d /opt/mastodon mastodon; \
|
||||||
# Creates /mastodon symlink to /opt/mastodon
|
# Creates /mastodon symlink to /opt/mastodon
|
||||||
ln -s /opt/mastodon /mastodon;
|
ln -s /opt/mastodon /mastodon;
|
||||||
|
|
||||||
# Set /opt/mastodon as working directory
|
# Set /opt/mastodon as working directory
|
||||||
|
@ -90,35 +97,32 @@ WORKDIR /opt/mastodon
|
||||||
|
|
||||||
# hadolint ignore=DL3008,DL3005
|
# hadolint ignore=DL3008,DL3005
|
||||||
RUN \
|
RUN \
|
||||||
# Mount Apt cache and lib directories from Docker buildx caches
|
# Mount Apt cache and lib directories from Docker buildx caches
|
||||||
--mount=type=cache,id=apt-cache-${TARGETPLATFORM},target=/var/cache/apt,sharing=locked \
|
--mount=type=cache,id=apt-cache-${TARGETPLATFORM},target=/var/cache/apt,sharing=locked \
|
||||||
--mount=type=cache,id=apt-lib-${TARGETPLATFORM},target=/var/lib/apt,sharing=locked \
|
--mount=type=cache,id=apt-lib-${TARGETPLATFORM},target=/var/lib/apt,sharing=locked \
|
||||||
# Apt update & upgrade to check for security updates to Debian image
|
# Apt update & upgrade to check for security updates to Debian image
|
||||||
apt-get update; \
|
apt-get update; \
|
||||||
apt-get dist-upgrade -yq; \
|
apt-get dist-upgrade -yq; \
|
||||||
# Install jemalloc, curl and other necessary components
|
# Install jemalloc, curl and other necessary components
|
||||||
apt-get install -y --no-install-recommends \
|
apt-get install -y --no-install-recommends \
|
||||||
ca-certificates \
|
curl \
|
||||||
curl \
|
file \
|
||||||
ffmpeg \
|
libjemalloc2 \
|
||||||
file \
|
patchelf \
|
||||||
libvips42 \
|
procps \
|
||||||
libjemalloc2 \
|
tini \
|
||||||
patchelf \
|
tzdata \
|
||||||
procps \
|
wget \
|
||||||
tini \
|
|
||||||
tzdata \
|
|
||||||
wget \
|
|
||||||
; \
|
; \
|
||||||
# Patch Ruby to use jemalloc
|
# Patch Ruby to use jemalloc
|
||||||
patchelf --add-needed libjemalloc.so.2 /usr/local/bin/ruby; \
|
patchelf --add-needed libjemalloc.so.2 /usr/local/bin/ruby; \
|
||||||
# Discard patchelf after use
|
# Discard patchelf after use
|
||||||
apt-get purge -y \
|
apt-get purge -y \
|
||||||
patchelf \
|
patchelf \
|
||||||
;
|
;
|
||||||
|
|
||||||
# Create temporary build layer from base image
|
# Create temporary build layer from base image
|
||||||
FROM ruby as build
|
FROM ruby AS build
|
||||||
|
|
||||||
# Copy Node package configuration files into working directory
|
# Copy Node package configuration files into working directory
|
||||||
COPY package.json yarn.lock .yarnrc.yml /opt/mastodon/
|
COPY package.json yarn.lock .yarnrc.yml /opt/mastodon/
|
||||||
|
@ -131,33 +135,130 @@ ARG TARGETPLATFORM
|
||||||
|
|
||||||
# hadolint ignore=DL3008
|
# hadolint ignore=DL3008
|
||||||
RUN \
|
RUN \
|
||||||
# Mount Apt cache and lib directories from Docker buildx caches
|
# Mount Apt cache and lib directories from Docker buildx caches
|
||||||
--mount=type=cache,id=apt-cache-${TARGETPLATFORM},target=/var/cache/apt,sharing=locked \
|
--mount=type=cache,id=apt-cache-${TARGETPLATFORM},target=/var/cache/apt,sharing=locked \
|
||||||
--mount=type=cache,id=apt-lib-${TARGETPLATFORM},target=/var/lib/apt,sharing=locked \
|
--mount=type=cache,id=apt-lib-${TARGETPLATFORM},target=/var/lib/apt,sharing=locked \
|
||||||
# Install build tools and bundler dependencies from APT
|
# Install build tools and bundler dependencies from APT
|
||||||
apt-get install -y --no-install-recommends \
|
apt-get install -y --no-install-recommends \
|
||||||
g++ \
|
autoconf \
|
||||||
gcc \
|
automake \
|
||||||
git \
|
build-essential \
|
||||||
libgdbm-dev \
|
cmake \
|
||||||
libgmp-dev \
|
git \
|
||||||
libicu-dev \
|
libgdbm-dev \
|
||||||
libidn-dev \
|
libglib2.0-dev \
|
||||||
libpq-dev \
|
libgmp-dev \
|
||||||
libssl-dev \
|
libicu-dev \
|
||||||
make \
|
libidn-dev \
|
||||||
shared-mime-info \
|
libpq-dev \
|
||||||
zlib1g-dev \
|
libssl-dev \
|
||||||
|
libtool \
|
||||||
|
meson \
|
||||||
|
nasm \
|
||||||
|
pkg-config \
|
||||||
|
shared-mime-info \
|
||||||
|
xz-utils \
|
||||||
|
# libvips components
|
||||||
|
libcgif-dev \
|
||||||
|
libexif-dev \
|
||||||
|
libexpat1-dev \
|
||||||
|
libgirepository1.0-dev \
|
||||||
|
libheif-dev \
|
||||||
|
libimagequant-dev \
|
||||||
|
libjpeg62-turbo-dev \
|
||||||
|
liblcms2-dev \
|
||||||
|
liborc-dev \
|
||||||
|
libspng-dev \
|
||||||
|
libtiff-dev \
|
||||||
|
libwebp-dev \
|
||||||
|
# ffmpeg components
|
||||||
|
libdav1d-dev \
|
||||||
|
liblzma-dev \
|
||||||
|
libmp3lame-dev \
|
||||||
|
libopus-dev \
|
||||||
|
libsnappy-dev \
|
||||||
|
libvorbis-dev \
|
||||||
|
libvpx-dev \
|
||||||
|
libx264-dev \
|
||||||
|
libx265-dev \
|
||||||
;
|
;
|
||||||
|
|
||||||
RUN \
|
RUN \
|
||||||
# Configure Corepack
|
# Configure Corepack
|
||||||
rm /usr/local/bin/yarn*; \
|
rm /usr/local/bin/yarn*; \
|
||||||
corepack enable; \
|
corepack enable; \
|
||||||
corepack prepare --activate;
|
corepack prepare --activate;
|
||||||
|
|
||||||
|
# Create temporary libvips specific build layer from build layer
|
||||||
|
FROM build AS libvips
|
||||||
|
|
||||||
|
# libvips version to compile, change with [--build-arg VIPS_VERSION="8.15.2"]
|
||||||
|
# renovate: datasource=github-releases depName=libvips packageName=libvips/libvips
|
||||||
|
ARG VIPS_VERSION=8.16.0
|
||||||
|
# libvips download URL, change with [--build-arg VIPS_URL="https://github.com/libvips/libvips/releases/download"]
|
||||||
|
ARG VIPS_URL=https://github.com/libvips/libvips/releases/download
|
||||||
|
|
||||||
|
WORKDIR /usr/local/libvips/src
|
||||||
|
# Download and extract libvips source code
|
||||||
|
ADD ${VIPS_URL}/v${VIPS_VERSION}/vips-${VIPS_VERSION}.tar.xz /usr/local/libvips/src/
|
||||||
|
RUN tar xf vips-${VIPS_VERSION}.tar.xz;
|
||||||
|
|
||||||
|
WORKDIR /usr/local/libvips/src/vips-${VIPS_VERSION}
|
||||||
|
|
||||||
|
# Configure and compile libvips
|
||||||
|
RUN \
|
||||||
|
meson setup build --prefix /usr/local/libvips --libdir=lib -Ddeprecated=false -Dintrospection=disabled -Dmodules=disabled -Dexamples=false; \
|
||||||
|
cd build; \
|
||||||
|
ninja; \
|
||||||
|
ninja install;
|
||||||
|
|
||||||
|
# Create temporary ffmpeg specific build layer from build layer
|
||||||
|
FROM build AS ffmpeg
|
||||||
|
|
||||||
|
# ffmpeg version to compile, change with [--build-arg FFMPEG_VERSION="7.0.x"]
|
||||||
|
# renovate: datasource=repology depName=ffmpeg packageName=openpkg_current/ffmpeg
|
||||||
|
ARG FFMPEG_VERSION=7.1
|
||||||
|
# ffmpeg download URL, change with [--build-arg FFMPEG_URL="https://ffmpeg.org/releases"]
|
||||||
|
ARG FFMPEG_URL=https://ffmpeg.org/releases
|
||||||
|
|
||||||
|
WORKDIR /usr/local/ffmpeg/src
|
||||||
|
# Download and extract ffmpeg source code
|
||||||
|
ADD ${FFMPEG_URL}/ffmpeg-${FFMPEG_VERSION}.tar.xz /usr/local/ffmpeg/src/
|
||||||
|
RUN tar xf ffmpeg-${FFMPEG_VERSION}.tar.xz;
|
||||||
|
|
||||||
|
WORKDIR /usr/local/ffmpeg/src/ffmpeg-${FFMPEG_VERSION}
|
||||||
|
|
||||||
|
# Configure and compile ffmpeg
|
||||||
|
RUN \
|
||||||
|
./configure \
|
||||||
|
--prefix=/usr/local/ffmpeg \
|
||||||
|
--toolchain=hardened \
|
||||||
|
--disable-debug \
|
||||||
|
--disable-devices \
|
||||||
|
--disable-doc \
|
||||||
|
--disable-ffplay \
|
||||||
|
--disable-network \
|
||||||
|
--disable-static \
|
||||||
|
--enable-ffmpeg \
|
||||||
|
--enable-ffprobe \
|
||||||
|
--enable-gpl \
|
||||||
|
--enable-libdav1d \
|
||||||
|
--enable-libmp3lame \
|
||||||
|
--enable-libopus \
|
||||||
|
--enable-libsnappy \
|
||||||
|
--enable-libvorbis \
|
||||||
|
--enable-libvpx \
|
||||||
|
--enable-libwebp \
|
||||||
|
--enable-libx264 \
|
||||||
|
--enable-libx265 \
|
||||||
|
--enable-shared \
|
||||||
|
--enable-version3 \
|
||||||
|
; \
|
||||||
|
make -j$(nproc); \
|
||||||
|
make install;
|
||||||
|
|
||||||
# Create temporary bundler specific build layer from build layer
|
# Create temporary bundler specific build layer from build layer
|
||||||
FROM build as bundler
|
FROM build AS bundler
|
||||||
|
|
||||||
ARG TARGETPLATFORM
|
ARG TARGETPLATFORM
|
||||||
|
|
||||||
|
@ -165,21 +266,21 @@ ARG TARGETPLATFORM
|
||||||
COPY Gemfile* /opt/mastodon/
|
COPY Gemfile* /opt/mastodon/
|
||||||
|
|
||||||
RUN \
|
RUN \
|
||||||
# Mount Ruby Gem caches
|
# Mount Ruby Gem caches
|
||||||
--mount=type=cache,id=gem-cache-${TARGETPLATFORM},target=/usr/local/bundle/cache/,sharing=locked \
|
--mount=type=cache,id=gem-cache-${TARGETPLATFORM},target=/usr/local/bundle/cache/,sharing=locked \
|
||||||
# Configure bundle to prevent changes to Gemfile and Gemfile.lock
|
# Configure bundle to prevent changes to Gemfile and Gemfile.lock
|
||||||
bundle config set --global frozen "true"; \
|
bundle config set --global frozen "true"; \
|
||||||
# Configure bundle to not cache downloaded Gems
|
# Configure bundle to not cache downloaded Gems
|
||||||
bundle config set --global cache_all "false"; \
|
bundle config set --global cache_all "false"; \
|
||||||
# Configure bundle to only process production Gems
|
# Configure bundle to only process production Gems
|
||||||
bundle config set --local without "development test"; \
|
bundle config set --local without "development test"; \
|
||||||
# Configure bundle to not warn about root user
|
# Configure bundle to not warn about root user
|
||||||
bundle config set silence_root_warning "true"; \
|
bundle config set silence_root_warning "true"; \
|
||||||
# Download and install required Gems
|
# Download and install required Gems
|
||||||
bundle install -j"$(nproc)";
|
bundle install -j"$(nproc)";
|
||||||
|
|
||||||
# Create temporary node specific build layer from build layer
|
# Create temporary node specific build layer from build layer
|
||||||
FROM build as yarn
|
FROM build AS yarn
|
||||||
|
|
||||||
ARG TARGETPLATFORM
|
ARG TARGETPLATFORM
|
||||||
|
|
||||||
|
@ -190,13 +291,13 @@ COPY .yarn /opt/mastodon/.yarn
|
||||||
|
|
||||||
# hadolint ignore=DL3008
|
# hadolint ignore=DL3008
|
||||||
RUN \
|
RUN \
|
||||||
--mount=type=cache,id=corepack-cache-${TARGETPLATFORM},target=/usr/local/share/.cache/corepack,sharing=locked \
|
--mount=type=cache,id=corepack-cache-${TARGETPLATFORM},target=/usr/local/share/.cache/corepack,sharing=locked \
|
||||||
--mount=type=cache,id=yarn-cache-${TARGETPLATFORM},target=/usr/local/share/.cache/yarn,sharing=locked \
|
--mount=type=cache,id=yarn-cache-${TARGETPLATFORM},target=/usr/local/share/.cache/yarn,sharing=locked \
|
||||||
# Install Node packages
|
# Install Node packages
|
||||||
yarn workspaces focus --production @mastodon/mastodon;
|
yarn workspaces focus --production @mastodon/mastodon;
|
||||||
|
|
||||||
# Create temporary assets build layer from build layer
|
# Create temporary assets build layer from build layer
|
||||||
FROM build as precompiler
|
FROM build AS precompiler
|
||||||
|
|
||||||
# Copy Mastodon sources into precompiler layer
|
# Copy Mastodon sources into precompiler layer
|
||||||
COPY . /opt/mastodon/
|
COPY . /opt/mastodon/
|
||||||
|
@ -205,41 +306,70 @@ COPY . /opt/mastodon/
|
||||||
COPY --from=yarn /opt/mastodon /opt/mastodon/
|
COPY --from=yarn /opt/mastodon /opt/mastodon/
|
||||||
COPY --from=bundler /opt/mastodon /opt/mastodon/
|
COPY --from=bundler /opt/mastodon /opt/mastodon/
|
||||||
COPY --from=bundler /usr/local/bundle/ /usr/local/bundle/
|
COPY --from=bundler /usr/local/bundle/ /usr/local/bundle/
|
||||||
|
# Copy libvips components to layer for precompiler
|
||||||
|
COPY --from=libvips /usr/local/libvips/bin /usr/local/bin
|
||||||
|
COPY --from=libvips /usr/local/libvips/lib /usr/local/lib
|
||||||
|
|
||||||
ARG TARGETPLATFORM
|
ARG TARGETPLATFORM
|
||||||
|
|
||||||
RUN \
|
RUN \
|
||||||
# Use Ruby on Rails to create Mastodon assets
|
ldconfig; \
|
||||||
ACTIVE_RECORD_ENCRYPTION_DETERMINISTIC_KEY=precompile_placeholder \
|
# Use Ruby on Rails to create Mastodon assets
|
||||||
ACTIVE_RECORD_ENCRYPTION_KEY_DERIVATION_SALT=precompile_placeholder \
|
SECRET_KEY_BASE_DUMMY=1 \
|
||||||
ACTIVE_RECORD_ENCRYPTION_PRIMARY_KEY=precompile_placeholder \
|
|
||||||
OTP_SECRET=precompile_placeholder \
|
|
||||||
SECRET_KEY_BASE=precompile_placeholder \
|
|
||||||
bundle exec rails assets:precompile; \
|
bundle exec rails assets:precompile; \
|
||||||
# Cleanup temporary files
|
# Cleanup temporary files
|
||||||
rm -fr /opt/mastodon/tmp;
|
rm -fr /opt/mastodon/tmp;
|
||||||
|
|
||||||
# Prep final Mastodon Ruby layer
|
# Prep final Mastodon Ruby layer
|
||||||
FROM ruby as mastodon
|
FROM ruby AS mastodon
|
||||||
|
|
||||||
ARG TARGETPLATFORM
|
ARG TARGETPLATFORM
|
||||||
|
|
||||||
# hadolint ignore=DL3008
|
# hadolint ignore=DL3008
|
||||||
RUN \
|
RUN \
|
||||||
# Mount Apt cache and lib directories from Docker buildx caches
|
# Mount Apt cache and lib directories from Docker buildx caches
|
||||||
--mount=type=cache,id=apt-cache-${TARGETPLATFORM},target=/var/cache/apt,sharing=locked \
|
--mount=type=cache,id=apt-cache-${TARGETPLATFORM},target=/var/cache/apt,sharing=locked \
|
||||||
--mount=type=cache,id=apt-lib-${TARGETPLATFORM},target=/var/lib/apt,sharing=locked \
|
--mount=type=cache,id=apt-lib-${TARGETPLATFORM},target=/var/lib/apt,sharing=locked \
|
||||||
# Mount Corepack and Yarn caches from Docker buildx caches
|
# Mount Corepack and Yarn caches from Docker buildx caches
|
||||||
--mount=type=cache,id=corepack-cache-${TARGETPLATFORM},target=/usr/local/share/.cache/corepack,sharing=locked \
|
--mount=type=cache,id=corepack-cache-${TARGETPLATFORM},target=/usr/local/share/.cache/corepack,sharing=locked \
|
||||||
--mount=type=cache,id=yarn-cache-${TARGETPLATFORM},target=/usr/local/share/.cache/yarn,sharing=locked \
|
--mount=type=cache,id=yarn-cache-${TARGETPLATFORM},target=/usr/local/share/.cache/yarn,sharing=locked \
|
||||||
# Apt update install non-dev versions of necessary components
|
# Apt update install non-dev versions of necessary components
|
||||||
apt-get install -y --no-install-recommends \
|
apt-get install -y --no-install-recommends \
|
||||||
libssl3 \
|
libexpat1 \
|
||||||
libpq5 \
|
libglib2.0-0 \
|
||||||
libicu72 \
|
libicu72 \
|
||||||
libidn12 \
|
libidn12 \
|
||||||
libreadline8 \
|
libpq5 \
|
||||||
libyaml-0-2 \
|
libreadline8 \
|
||||||
|
libssl3 \
|
||||||
|
libyaml-0-2 \
|
||||||
|
# libvips components
|
||||||
|
libcgif0 \
|
||||||
|
libexif12 \
|
||||||
|
libheif1 \
|
||||||
|
libimagequant0 \
|
||||||
|
libjpeg62-turbo \
|
||||||
|
liblcms2-2 \
|
||||||
|
liborc-0.4-0 \
|
||||||
|
libspng0 \
|
||||||
|
libtiff6 \
|
||||||
|
libwebp7 \
|
||||||
|
libwebpdemux2 \
|
||||||
|
libwebpmux3 \
|
||||||
|
# ffmpeg components
|
||||||
|
libdav1d6 \
|
||||||
|
libmp3lame0 \
|
||||||
|
libopencore-amrnb0 \
|
||||||
|
libopencore-amrwb0 \
|
||||||
|
libopus0 \
|
||||||
|
libsnappy1v5 \
|
||||||
|
libtheora0 \
|
||||||
|
libvorbis0a \
|
||||||
|
libvorbisenc2 \
|
||||||
|
libvorbisfile3 \
|
||||||
|
libvpx7 \
|
||||||
|
libx264-164 \
|
||||||
|
libx265-199 \
|
||||||
;
|
;
|
||||||
|
|
||||||
# Copy Mastodon sources into final layer
|
# Copy Mastodon sources into final layer
|
||||||
|
@ -250,16 +380,29 @@ COPY --from=precompiler /opt/mastodon/public/packs /opt/mastodon/public/packs
|
||||||
COPY --from=precompiler /opt/mastodon/public/assets /opt/mastodon/public/assets
|
COPY --from=precompiler /opt/mastodon/public/assets /opt/mastodon/public/assets
|
||||||
# Copy bundler components to layer
|
# Copy bundler components to layer
|
||||||
COPY --from=bundler /usr/local/bundle/ /usr/local/bundle/
|
COPY --from=bundler /usr/local/bundle/ /usr/local/bundle/
|
||||||
|
# Copy libvips components to layer
|
||||||
|
COPY --from=libvips /usr/local/libvips/bin /usr/local/bin
|
||||||
|
COPY --from=libvips /usr/local/libvips/lib /usr/local/lib
|
||||||
|
# Copy ffpmeg components to layer
|
||||||
|
COPY --from=ffmpeg /usr/local/ffmpeg/bin /usr/local/bin
|
||||||
|
COPY --from=ffmpeg /usr/local/ffmpeg/lib /usr/local/lib
|
||||||
|
|
||||||
RUN \
|
RUN \
|
||||||
# Precompile bootsnap code for faster Rails startup
|
ldconfig; \
|
||||||
|
# Smoketest media processors
|
||||||
|
vips -v; \
|
||||||
|
ffmpeg -version; \
|
||||||
|
ffprobe -version;
|
||||||
|
|
||||||
|
RUN \
|
||||||
|
# Precompile bootsnap code for faster Rails startup
|
||||||
bundle exec bootsnap precompile --gemfile app/ lib/;
|
bundle exec bootsnap precompile --gemfile app/ lib/;
|
||||||
|
|
||||||
RUN \
|
RUN \
|
||||||
# Pre-create and chown system volume to Mastodon user
|
# Pre-create and chown system volume to Mastodon user
|
||||||
mkdir -p /opt/mastodon/public/system; \
|
mkdir -p /opt/mastodon/public/system; \
|
||||||
chown mastodon:mastodon /opt/mastodon/public/system; \
|
chown mastodon:mastodon /opt/mastodon/public/system; \
|
||||||
# Set Mastodon user as owner of tmp folder
|
# Set Mastodon user as owner of tmp folder
|
||||||
chown -R mastodon:mastodon /opt/mastodon/tmp;
|
chown -R mastodon:mastodon /opt/mastodon/tmp;
|
||||||
|
|
||||||
# Set the running user for resulting container
|
# Set the running user for resulting container
|
||||||
|
|
53
Gemfile
53
Gemfile
|
@ -1,17 +1,14 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
source 'https://rubygems.org'
|
source 'https://rubygems.org'
|
||||||
ruby '>= 3.1.0'
|
ruby '>= 3.2.0'
|
||||||
|
|
||||||
gem 'propshaft'
|
gem 'propshaft'
|
||||||
gem 'puma', '~> 6.3'
|
gem 'puma', '~> 6.3'
|
||||||
gem 'rack', '~> 2.2.7'
|
gem 'rack', '~> 2.2.7'
|
||||||
gem 'rails', '~> 7.1.1'
|
gem 'rails', '~> 7.2.0'
|
||||||
gem 'thor', '~> 1.2'
|
gem 'thor', '~> 1.2'
|
||||||
|
|
||||||
# For why irb is in the Gemfile, see: https://ruby.social/@st0012/111444685161478182
|
|
||||||
gem 'irb', '~> 1.8'
|
|
||||||
|
|
||||||
gem 'dotenv'
|
gem 'dotenv'
|
||||||
gem 'haml-rails', '~>2.0'
|
gem 'haml-rails', '~>2.0'
|
||||||
gem 'pg', '~> 1.5'
|
gem 'pg', '~> 1.5'
|
||||||
|
@ -19,10 +16,10 @@ gem 'pghero'
|
||||||
|
|
||||||
gem 'aws-sdk-s3', '~> 1.123', require: false
|
gem 'aws-sdk-s3', '~> 1.123', require: false
|
||||||
gem 'blurhash', '~> 0.1'
|
gem 'blurhash', '~> 0.1'
|
||||||
gem 'fog-core', '<= 2.4.0'
|
gem 'fog-core', '<= 2.6.0'
|
||||||
gem 'fog-openstack', '~> 1.0', require: false
|
gem 'fog-openstack', '~> 1.0', require: false
|
||||||
|
gem 'jd-paperclip-azure', '~> 3.0', require: false
|
||||||
gem 'kt-paperclip', '~> 7.2'
|
gem 'kt-paperclip', '~> 7.2'
|
||||||
gem 'md-paperclip-azure', '~> 2.2', require: false
|
|
||||||
gem 'ruby-vips', '~> 2.2', require: false
|
gem 'ruby-vips', '~> 2.2', require: false
|
||||||
|
|
||||||
gem 'active_model_serializers', '~> 0.10'
|
gem 'active_model_serializers', '~> 0.10'
|
||||||
|
@ -50,28 +47,29 @@ gem 'color_diff', '~> 0.1'
|
||||||
gem 'csv', '~> 3.2'
|
gem 'csv', '~> 3.2'
|
||||||
gem 'discard', '~> 1.2'
|
gem 'discard', '~> 1.2'
|
||||||
gem 'doorkeeper', '~> 5.6'
|
gem 'doorkeeper', '~> 5.6'
|
||||||
gem 'ed25519', '~> 1.3'
|
gem 'faraday-httpclient'
|
||||||
gem 'fast_blank', '~> 1.0'
|
gem 'fast_blank', '~> 1.0'
|
||||||
gem 'fastimage'
|
gem 'fastimage'
|
||||||
gem 'hiredis', '~> 0.6'
|
gem 'hiredis', '~> 0.6'
|
||||||
gem 'htmlentities', '~> 4.3'
|
gem 'htmlentities', '~> 4.3'
|
||||||
gem 'http', '~> 5.2.0'
|
gem 'http', '~> 5.2.0'
|
||||||
gem 'http_accept_language', '~> 2.1'
|
gem 'http_accept_language', '~> 2.1'
|
||||||
gem 'httplog', '~> 1.6.2'
|
gem 'httplog', '~> 1.7.0', require: false
|
||||||
gem 'i18n'
|
gem 'i18n'
|
||||||
gem 'idn-ruby', require: 'idn'
|
gem 'idn-ruby', require: 'idn'
|
||||||
gem 'inline_svg'
|
gem 'inline_svg'
|
||||||
|
gem 'irb', '~> 1.8'
|
||||||
gem 'kaminari', '~> 1.2'
|
gem 'kaminari', '~> 1.2'
|
||||||
gem 'link_header', '~> 0.0'
|
gem 'link_header', '~> 0.0'
|
||||||
gem 'mario-redis-lock', '~> 1.2', require: 'redis_lock'
|
gem 'mario-redis-lock', '~> 1.2', require: 'redis_lock'
|
||||||
gem 'mime-types', '~> 3.5.0', require: 'mime/types/columnar'
|
gem 'mime-types', '~> 3.6.0', require: 'mime/types/columnar'
|
||||||
|
gem 'mutex_m'
|
||||||
gem 'nokogiri', '~> 1.15'
|
gem 'nokogiri', '~> 1.15'
|
||||||
gem 'nsa'
|
|
||||||
gem 'oj', '~> 3.14'
|
gem 'oj', '~> 3.14'
|
||||||
gem 'ox', '~> 2.14'
|
gem 'ox', '~> 2.14'
|
||||||
gem 'parslet'
|
gem 'parslet'
|
||||||
gem 'premailer-rails'
|
gem 'premailer-rails'
|
||||||
gem 'public_suffix', '~> 5.0'
|
gem 'public_suffix', '~> 6.0'
|
||||||
gem 'pundit', '~> 2.3'
|
gem 'pundit', '~> 2.3'
|
||||||
gem 'rack-attack', '~> 6.6'
|
gem 'rack-attack', '~> 6.6'
|
||||||
gem 'rack-cors', '~> 2.0', require: 'rack/cors'
|
gem 'rack-cors', '~> 2.0', require: 'rack/cors'
|
||||||
|
@ -90,7 +88,7 @@ gem 'sidekiq-unique-jobs', '~> 7.1'
|
||||||
gem 'simple_form', '~> 5.2'
|
gem 'simple_form', '~> 5.2'
|
||||||
gem 'simple-navigation', '~> 4.4'
|
gem 'simple-navigation', '~> 4.4'
|
||||||
gem 'stoplight', '~> 4.1'
|
gem 'stoplight', '~> 4.1'
|
||||||
gem 'strong_migrations', '1.8.0'
|
gem 'strong_migrations'
|
||||||
gem 'tty-prompt', '~> 0.23', require: false
|
gem 'tty-prompt', '~> 0.23', require: false
|
||||||
gem 'twitter-text', '~> 3.1.0'
|
gem 'twitter-text', '~> 3.1.0'
|
||||||
gem 'tzinfo-data', '~> 1.2023'
|
gem 'tzinfo-data', '~> 1.2023'
|
||||||
|
@ -102,12 +100,10 @@ gem 'json-ld'
|
||||||
gem 'json-ld-preloaded', '~> 3.2'
|
gem 'json-ld-preloaded', '~> 3.2'
|
||||||
gem 'rdf-normalize', '~> 0.5'
|
gem 'rdf-normalize', '~> 0.5'
|
||||||
|
|
||||||
gem 'private_address_check', '~> 0.5'
|
gem 'opentelemetry-api', '~> 1.4.0'
|
||||||
|
|
||||||
gem 'opentelemetry-api', '~> 1.2.5'
|
|
||||||
|
|
||||||
group :opentelemetry do
|
group :opentelemetry do
|
||||||
gem 'opentelemetry-exporter-otlp', '~> 0.27.0', require: false
|
gem 'opentelemetry-exporter-otlp', '~> 0.29.0', require: false
|
||||||
gem 'opentelemetry-instrumentation-active_job', '~> 0.7.1', require: false
|
gem 'opentelemetry-instrumentation-active_job', '~> 0.7.1', require: false
|
||||||
gem 'opentelemetry-instrumentation-active_model_serializers', '~> 0.20.1', require: false
|
gem 'opentelemetry-instrumentation-active_model_serializers', '~> 0.20.1', require: false
|
||||||
gem 'opentelemetry-instrumentation-concurrent_ruby', '~> 0.21.2', require: false
|
gem 'opentelemetry-instrumentation-concurrent_ruby', '~> 0.21.2', require: false
|
||||||
|
@ -116,21 +112,21 @@ group :opentelemetry do
|
||||||
gem 'opentelemetry-instrumentation-http', '~> 0.23.2', require: false
|
gem 'opentelemetry-instrumentation-http', '~> 0.23.2', require: false
|
||||||
gem 'opentelemetry-instrumentation-http_client', '~> 0.22.3', require: false
|
gem 'opentelemetry-instrumentation-http_client', '~> 0.22.3', require: false
|
||||||
gem 'opentelemetry-instrumentation-net_http', '~> 0.22.4', require: false
|
gem 'opentelemetry-instrumentation-net_http', '~> 0.22.4', require: false
|
||||||
gem 'opentelemetry-instrumentation-pg', '~> 0.27.1', require: false
|
gem 'opentelemetry-instrumentation-pg', '~> 0.29.0', require: false
|
||||||
gem 'opentelemetry-instrumentation-rack', '~> 0.24.1', require: false
|
gem 'opentelemetry-instrumentation-rack', '~> 0.25.0', require: false
|
||||||
gem 'opentelemetry-instrumentation-rails', '~> 0.30.0', require: false
|
gem 'opentelemetry-instrumentation-rails', '~> 0.33.0', require: false
|
||||||
gem 'opentelemetry-instrumentation-redis', '~> 0.25.3', require: false
|
gem 'opentelemetry-instrumentation-redis', '~> 0.25.3', require: false
|
||||||
gem 'opentelemetry-instrumentation-sidekiq', '~> 0.25.2', require: false
|
gem 'opentelemetry-instrumentation-sidekiq', '~> 0.25.2', require: false
|
||||||
gem 'opentelemetry-sdk', '~> 1.4', require: false
|
gem 'opentelemetry-sdk', '~> 1.4', require: false
|
||||||
end
|
end
|
||||||
|
|
||||||
group :test do
|
group :test do
|
||||||
|
# Enable usage of all available CPUs/cores during spec runs
|
||||||
|
gem 'flatware-rspec'
|
||||||
|
|
||||||
# Adds RSpec Error/Warning annotations to GitHub PRs on the Files tab
|
# Adds RSpec Error/Warning annotations to GitHub PRs on the Files tab
|
||||||
gem 'rspec-github', '~> 2.4', require: false
|
gem 'rspec-github', '~> 2.4', require: false
|
||||||
|
|
||||||
# RSpec progress bar formatter
|
|
||||||
gem 'fuubar', '~> 2.5'
|
|
||||||
|
|
||||||
# RSpec helpers for email specs
|
# RSpec helpers for email specs
|
||||||
gem 'email_spec'
|
gem 'email_spec'
|
||||||
|
|
||||||
|
@ -151,11 +147,13 @@ group :test do
|
||||||
gem 'rails-controller-testing', '~> 1.0'
|
gem 'rails-controller-testing', '~> 1.0'
|
||||||
|
|
||||||
# Validate schemas in specs
|
# Validate schemas in specs
|
||||||
gem 'json-schema', '~> 4.0'
|
gem 'json-schema', '~> 5.0'
|
||||||
|
|
||||||
# Test harness fo rack components
|
# Test harness fo rack components
|
||||||
gem 'rack-test', '~> 2.1'
|
gem 'rack-test', '~> 2.1'
|
||||||
|
|
||||||
|
gem 'shoulda-matchers'
|
||||||
|
|
||||||
# Coverage formatter for RSpec test if DISABLE_SIMPLECOV is false
|
# Coverage formatter for RSpec test if DISABLE_SIMPLECOV is false
|
||||||
gem 'simplecov', '~> 0.22', require: false
|
gem 'simplecov', '~> 0.22', require: false
|
||||||
gem 'simplecov-lcov', '~> 0.8', require: false
|
gem 'simplecov-lcov', '~> 0.8', require: false
|
||||||
|
@ -171,9 +169,10 @@ group :development do
|
||||||
gem 'rubocop-performance', require: false
|
gem 'rubocop-performance', require: false
|
||||||
gem 'rubocop-rails', require: false
|
gem 'rubocop-rails', require: false
|
||||||
gem 'rubocop-rspec', require: false
|
gem 'rubocop-rspec', require: false
|
||||||
|
gem 'rubocop-rspec_rails', require: false
|
||||||
|
|
||||||
# Annotates modules with schema
|
# Annotates modules with schema
|
||||||
gem 'annotate', '~> 3.2'
|
gem 'annotaterb', '~> 4.13'
|
||||||
|
|
||||||
# Enhanced error message pages for development
|
# Enhanced error message pages for development
|
||||||
gem 'better_errors', '~> 2.9'
|
gem 'better_errors', '~> 2.9'
|
||||||
|
@ -211,7 +210,7 @@ group :development, :test do
|
||||||
gem 'test-prof'
|
gem 'test-prof'
|
||||||
|
|
||||||
# RSpec runner for rails
|
# RSpec runner for rails
|
||||||
gem 'rspec-rails', '~> 6.0'
|
gem 'rspec-rails', '~> 7.0'
|
||||||
end
|
end
|
||||||
|
|
||||||
group :production do
|
group :production do
|
||||||
|
@ -223,7 +222,7 @@ gem 'concurrent-ruby', require: false
|
||||||
gem 'connection_pool', require: false
|
gem 'connection_pool', require: false
|
||||||
gem 'xorcist', '~> 1.1'
|
gem 'xorcist', '~> 1.1'
|
||||||
|
|
||||||
gem 'net-http', '~> 0.4.0'
|
gem 'net-http', '~> 0.5.0'
|
||||||
gem 'rubyzip', '~> 2.3'
|
gem 'rubyzip', '~> 2.3'
|
||||||
|
|
||||||
gem 'hcaptcha', '~> 7.1'
|
gem 'hcaptcha', '~> 7.1'
|
||||||
|
|
646
Gemfile.lock
646
Gemfile.lock
File diff suppressed because it is too large
Load diff
2
Procfile
2
Procfile
|
@ -11,4 +11,4 @@ worker: bundle exec sidekiq
|
||||||
#
|
#
|
||||||
# and let the main app use the separate app:
|
# and let the main app use the separate app:
|
||||||
#
|
#
|
||||||
# heroku config:set STREAMING_API_BASE_URL=wss://<streaming-app>.herokuapp.com -a <main-app>
|
# heroku config:set STREAMING_API_BASE_URL=wss://<streaming-app-random>.herokuapp.com -a <main-app>
|
||||||
|
|
25
README.md
25
README.md
|
@ -62,14 +62,14 @@ Mastodon acts as an OAuth2 provider, so 3rd party apps can use the REST and Stre
|
||||||
### Tech stack
|
### Tech stack
|
||||||
|
|
||||||
- **Ruby on Rails** powers the REST API and other web pages
|
- **Ruby on Rails** powers the REST API and other web pages
|
||||||
- **React.js** and Redux are used for the dynamic parts of the interface
|
- **React.js** and **Redux** are used for the dynamic parts of the interface
|
||||||
- **Node.js** powers the streaming API
|
- **Node.js** powers the streaming API
|
||||||
|
|
||||||
### Requirements
|
### Requirements
|
||||||
|
|
||||||
- **PostgreSQL** 12+
|
- **PostgreSQL** 12+
|
||||||
- **Redis** 4+
|
- **Redis** 4+
|
||||||
- **Ruby** 3.1+
|
- **Ruby** 3.2+
|
||||||
- **Node.js** 18+
|
- **Node.js** 18+
|
||||||
|
|
||||||
The repository includes deployment configurations for **Docker and docker-compose** as well as specific platforms like **Heroku**, and **Scalingo**. For Helm charts, reference the [mastodon/chart repository](https://github.com/mastodon/chart). The [**standalone** installation guide](https://docs.joinmastodon.org/admin/install/) is available in the documentation.
|
The repository includes deployment configurations for **Docker and docker-compose** as well as specific platforms like **Heroku**, and **Scalingo**. For Helm charts, reference the [mastodon/chart repository](https://github.com/mastodon/chart). The [**standalone** installation guide](https://docs.joinmastodon.org/admin/install/) is available in the documentation.
|
||||||
|
@ -86,18 +86,18 @@ A **Vagrant** configuration is included for development purposes. To use it, com
|
||||||
- Run `vagrant ssh -c "cd /vagrant && bin/dev"`
|
- Run `vagrant ssh -c "cd /vagrant && bin/dev"`
|
||||||
- Open `http://mastodon.local` in your browser
|
- Open `http://mastodon.local` in your browser
|
||||||
|
|
||||||
### MacOS
|
### macOS
|
||||||
|
|
||||||
To set up **MacOS** for native development, complete the following steps:
|
To set up **macOS** for native development, complete the following steps:
|
||||||
|
|
||||||
- Use a Ruby version manager to install the specified version from `.ruby-version`
|
- Install [Homebrew] and run `brew install postgresql@14 redis imagemagick
|
||||||
- Run `bundle` to install required gems
|
libidn nvm` to install the required project dependencies
|
||||||
- Run `brew install postgresql@14 redis imagemagick libidn` to install required dependencies
|
- Use a Ruby version manager to activate the ruby in `.ruby-version` and run
|
||||||
- Navigate to Mastodon's root directory and run `brew install nvm` then `nvm use` to use the version from `.nvmrc`
|
`nvm use` to activate the node version from `.nvmrc`
|
||||||
- Run `yarn` to install required packages
|
- Run the `bin/setup` script, which will install the required ruby gems and node
|
||||||
- Run `corepack enable && corepack prepare`
|
packages and prepare the database for local development
|
||||||
- Run `RAILS_ENV=development bundle exec rails db:setup`
|
- Finally, run the `bin/dev` script which will launch services via `overmind`
|
||||||
- Finally, run `bin/dev` which will launch the local services via `overmind` (if installed) or `foreman`
|
(if installed) or `foreman`
|
||||||
|
|
||||||
### Docker
|
### Docker
|
||||||
|
|
||||||
|
@ -155,3 +155,4 @@ You should have received a copy of the GNU Affero General Public License along w
|
||||||
[Development Containers]: https://containers.dev/supporting
|
[Development Containers]: https://containers.dev/supporting
|
||||||
[Docker]: https://docs.docker.com
|
[Docker]: https://docs.docker.com
|
||||||
[GitHub Codespaces]: https://docs.github.com/en/codespaces
|
[GitHub Codespaces]: https://docs.github.com/en/codespaces
|
||||||
|
[Homebrew]: https://brew.sh
|
||||||
|
|
2
Rakefile
2
Rakefile
|
@ -3,6 +3,6 @@
|
||||||
# Add your own tasks in files placed in lib/tasks ending in .rake,
|
# Add your own tasks in files placed in lib/tasks ending in .rake,
|
||||||
# for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
|
# for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
|
||||||
|
|
||||||
require File.expand_path('config/application', __dir__)
|
require_relative 'config/application'
|
||||||
|
|
||||||
Rails.application.load_tasks
|
Rails.application.load_tasks
|
||||||
|
|
13
SECURITY.md
13
SECURITY.md
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
If you believe you've identified a security vulnerability in Mastodon (a bug that allows something to happen that shouldn't be possible), you can either:
|
If you believe you've identified a security vulnerability in Mastodon (a bug that allows something to happen that shouldn't be possible), you can either:
|
||||||
|
|
||||||
- open a [Github security issue on the Mastodon project](https://github.com/mastodon/mastodon/security/advisories/new)
|
- open a [GitHub security issue on the Mastodon project](https://github.com/mastodon/mastodon/security/advisories/new)
|
||||||
- reach us at <security@joinmastodon.org>
|
- reach us at <security@joinmastodon.org>
|
||||||
|
|
||||||
You should _not_ report such issues on public GitHub issues or in other public spaces to give us time to publish a fix for the issue without exposing Mastodon's users to increased risk.
|
You should _not_ report such issues on public GitHub issues or in other public spaces to give us time to publish a fix for the issue without exposing Mastodon's users to increased risk.
|
||||||
|
@ -13,8 +13,9 @@ A "vulnerability in Mastodon" is a vulnerability in the code distributed through
|
||||||
|
|
||||||
## Supported Versions
|
## Supported Versions
|
||||||
|
|
||||||
| Version | Supported |
|
| Version | Supported |
|
||||||
| ------- | --------- |
|
| ------- | ---------------- |
|
||||||
| 4.2.x | Yes |
|
| 4.3.x | Yes |
|
||||||
| 4.1.x | Yes |
|
| 4.2.x | Yes |
|
||||||
| < 4.1 | No |
|
| 4.1.x | Until 2025-04-08 |
|
||||||
|
| < 4.1 | No |
|
||||||
|
|
9
app.json
9
app.json
|
@ -90,9 +90,15 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"buildpacks": [
|
"buildpacks": [
|
||||||
|
{
|
||||||
|
"url": "https://github.com/heroku/heroku-buildpack-activestorage-preview"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"url": "https://github.com/heroku/heroku-buildpack-apt"
|
"url": "https://github.com/heroku/heroku-buildpack-apt"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"url": "heroku/nodejs"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"url": "heroku/ruby"
|
"url": "heroku/ruby"
|
||||||
}
|
}
|
||||||
|
@ -100,5 +106,6 @@
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"postdeploy": "bundle exec rails db:migrate && bundle exec rails db:seed"
|
"postdeploy": "bundle exec rails db:migrate && bundle exec rails db:seed"
|
||||||
},
|
},
|
||||||
"addons": ["heroku-postgresql", "heroku-redis"]
|
"addons": ["heroku-postgresql", "heroku-redis"],
|
||||||
|
"stack": "heroku-24"
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,18 +0,0 @@
|
||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
class ActivityPub::ClaimsController < ActivityPub::BaseController
|
|
||||||
skip_before_action :authenticate_user!
|
|
||||||
|
|
||||||
before_action :require_account_signature!
|
|
||||||
before_action :set_claim_result
|
|
||||||
|
|
||||||
def create
|
|
||||||
render json: @claim_result, serializer: ActivityPub::OneTimeKeySerializer
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def set_claim_result
|
|
||||||
@claim_result = ::Keys::ClaimService.new.call(@account.id, params[:id])
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -22,8 +22,6 @@ class ActivityPub::CollectionsController < ActivityPub::BaseController
|
||||||
@items = @items.map { |item| item.distributable? ? item : ActivityPub::TagManager.instance.uri_for(item) }
|
@items = @items.map { |item| item.distributable? ? item : ActivityPub::TagManager.instance.uri_for(item) }
|
||||||
when 'tags'
|
when 'tags'
|
||||||
@items = for_signed_account { @account.featured_tags }
|
@items = for_signed_account { @account.featured_tags }
|
||||||
when 'devices'
|
|
||||||
@items = @account.devices
|
|
||||||
else
|
else
|
||||||
not_found
|
not_found
|
||||||
end
|
end
|
||||||
|
@ -31,7 +29,7 @@ class ActivityPub::CollectionsController < ActivityPub::BaseController
|
||||||
|
|
||||||
def set_size
|
def set_size
|
||||||
case params[:id]
|
case params[:id]
|
||||||
when 'featured', 'devices', 'tags'
|
when 'featured', 'tags'
|
||||||
@size = @items.size
|
@size = @items.size
|
||||||
else
|
else
|
||||||
not_found
|
not_found
|
||||||
|
@ -42,7 +40,7 @@ class ActivityPub::CollectionsController < ActivityPub::BaseController
|
||||||
case params[:id]
|
case params[:id]
|
||||||
when 'featured'
|
when 'featured'
|
||||||
@type = :ordered
|
@type = :ordered
|
||||||
when 'devices', 'tags'
|
when 'tags'
|
||||||
@type = :unordered
|
@type = :unordered
|
||||||
else
|
else
|
||||||
not_found
|
not_found
|
||||||
|
|
36
app/controllers/activitypub/likes_controller.rb
Normal file
36
app/controllers/activitypub/likes_controller.rb
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
class ActivityPub::LikesController < ActivityPub::BaseController
|
||||||
|
include Authorization
|
||||||
|
|
||||||
|
vary_by -> { 'Signature' if authorized_fetch_mode? }
|
||||||
|
|
||||||
|
before_action :require_account_signature!, if: :authorized_fetch_mode?
|
||||||
|
before_action :set_status
|
||||||
|
|
||||||
|
def index
|
||||||
|
expires_in 0, public: @status.distributable? && public_fetch_mode?
|
||||||
|
render json: likes_collection_presenter, serializer: ActivityPub::CollectionSerializer, adapter: ActivityPub::Adapter, content_type: 'application/activity+json'
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def pundit_user
|
||||||
|
signed_request_account
|
||||||
|
end
|
||||||
|
|
||||||
|
def set_status
|
||||||
|
@status = @account.statuses.find(params[:status_id])
|
||||||
|
authorize @status, :show?
|
||||||
|
rescue Mastodon::NotPermittedError
|
||||||
|
not_found
|
||||||
|
end
|
||||||
|
|
||||||
|
def likes_collection_presenter
|
||||||
|
ActivityPub::CollectionPresenter.new(
|
||||||
|
id: account_status_likes_url(@account, @status),
|
||||||
|
type: :unordered,
|
||||||
|
size: @status.favourites_count
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
|
@ -41,11 +41,11 @@ class ActivityPub::OutboxesController < ActivityPub::BaseController
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def outbox_url(**kwargs)
|
def outbox_url(**)
|
||||||
if params[:account_username].present?
|
if params[:account_username].present?
|
||||||
account_outbox_url(@account, **kwargs)
|
account_outbox_url(@account, **)
|
||||||
else
|
else
|
||||||
instance_actor_outbox_url(**kwargs)
|
instance_actor_outbox_url(**)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@ class ActivityPub::RepliesController < ActivityPub::BaseController
|
||||||
before_action :set_replies
|
before_action :set_replies
|
||||||
|
|
||||||
def index
|
def index
|
||||||
expires_in 0, public: public_fetch_mode?
|
expires_in 0, public: @status.distributable? && public_fetch_mode?
|
||||||
render json: replies_collection_presenter, serializer: ActivityPub::CollectionSerializer, adapter: ActivityPub::Adapter, content_type: 'application/activity+json', skip_activities: true
|
render json: replies_collection_presenter, serializer: ActivityPub::CollectionSerializer, adapter: ActivityPub::Adapter, content_type: 'application/activity+json', skip_activities: true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
36
app/controllers/activitypub/shares_controller.rb
Normal file
36
app/controllers/activitypub/shares_controller.rb
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
class ActivityPub::SharesController < ActivityPub::BaseController
|
||||||
|
include Authorization
|
||||||
|
|
||||||
|
vary_by -> { 'Signature' if authorized_fetch_mode? }
|
||||||
|
|
||||||
|
before_action :require_account_signature!, if: :authorized_fetch_mode?
|
||||||
|
before_action :set_status
|
||||||
|
|
||||||
|
def index
|
||||||
|
expires_in 0, public: @status.distributable? && public_fetch_mode?
|
||||||
|
render json: shares_collection_presenter, serializer: ActivityPub::CollectionSerializer, adapter: ActivityPub::Adapter, content_type: 'application/activity+json'
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def pundit_user
|
||||||
|
signed_request_account
|
||||||
|
end
|
||||||
|
|
||||||
|
def set_status
|
||||||
|
@status = @account.statuses.find(params[:status_id])
|
||||||
|
authorize @status, :show?
|
||||||
|
rescue Mastodon::NotPermittedError
|
||||||
|
not_found
|
||||||
|
end
|
||||||
|
|
||||||
|
def shares_collection_presenter
|
||||||
|
ActivityPub::CollectionPresenter.new(
|
||||||
|
id: account_status_shares_url(@account, @status),
|
||||||
|
type: :unordered,
|
||||||
|
size: @status.reblogs_count
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
|
@ -13,7 +13,7 @@ module Admin
|
||||||
redirect_to admin_account_path(@account_moderation_note.target_account_id), notice: I18n.t('admin.account_moderation_notes.created_msg')
|
redirect_to admin_account_path(@account_moderation_note.target_account_id), notice: I18n.t('admin.account_moderation_notes.created_msg')
|
||||||
else
|
else
|
||||||
@account = @account_moderation_note.target_account
|
@account = @account_moderation_note.target_account
|
||||||
@moderation_notes = @account.targeted_moderation_notes.latest
|
@moderation_notes = @account.targeted_moderation_notes.chronological.includes(:account)
|
||||||
@warnings = @account.strikes.custom.latest
|
@warnings = @account.strikes.custom.latest
|
||||||
|
|
||||||
render 'admin/accounts/show'
|
render 'admin/accounts/show'
|
||||||
|
|
|
@ -33,7 +33,7 @@ module Admin
|
||||||
|
|
||||||
@deletion_request = @account.deletion_request
|
@deletion_request = @account.deletion_request
|
||||||
@account_moderation_note = current_account.account_moderation_notes.new(target_account: @account)
|
@account_moderation_note = current_account.account_moderation_notes.new(target_account: @account)
|
||||||
@moderation_notes = @account.targeted_moderation_notes.latest
|
@moderation_notes = @account.targeted_moderation_notes.chronological.includes(:account)
|
||||||
@warnings = @account.strikes.includes(:target_account, :account, :appeal).latest
|
@warnings = @account.strikes.includes(:target_account, :account, :appeal).latest
|
||||||
@domain_block = DomainBlock.rule_for(@account.domain)
|
@domain_block = DomainBlock.rule_for(@account.domain)
|
||||||
end
|
end
|
||||||
|
|
|
@ -6,6 +6,7 @@ class Admin::AnnouncementsController < Admin::BaseController
|
||||||
|
|
||||||
def index
|
def index
|
||||||
authorize :announcement, :index?
|
authorize :announcement, :index?
|
||||||
|
@published_announcements_count = Announcement.published.async_count
|
||||||
end
|
end
|
||||||
|
|
||||||
def new
|
def new
|
||||||
|
|
|
@ -7,17 +7,12 @@ module Admin
|
||||||
|
|
||||||
layout 'admin'
|
layout 'admin'
|
||||||
|
|
||||||
before_action :set_body_classes
|
|
||||||
before_action :set_cache_headers
|
before_action :set_cache_headers
|
||||||
|
|
||||||
after_action :verify_authorized
|
after_action :verify_authorized
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def set_body_classes
|
|
||||||
@body_classes = 'admin'
|
|
||||||
end
|
|
||||||
|
|
||||||
def set_cache_headers
|
def set_cache_headers
|
||||||
response.cache_control.replace(private: true, no_store: true)
|
response.cache_control.replace(private: true, no_store: true)
|
||||||
end
|
end
|
||||||
|
|
|
@ -7,12 +7,12 @@ module Admin
|
||||||
def index
|
def index
|
||||||
authorize :dashboard, :index?
|
authorize :dashboard, :index?
|
||||||
|
|
||||||
|
@pending_appeals_count = Appeal.pending.async_count
|
||||||
|
@pending_reports_count = Report.unresolved.async_count
|
||||||
|
@pending_tags_count = Tag.pending_review.async_count
|
||||||
|
@pending_users_count = User.pending.async_count
|
||||||
@system_checks = Admin::SystemCheck.perform(current_user)
|
@system_checks = Admin::SystemCheck.perform(current_user)
|
||||||
@time_period = (29.days.ago.to_date...Time.now.utc.to_date)
|
@time_period = (29.days.ago.to_date...Time.now.utc.to_date)
|
||||||
@pending_users_count = User.pending.count
|
|
||||||
@pending_reports_count = Report.unresolved.count
|
|
||||||
@pending_tags_count = Tag.pending_review.count
|
|
||||||
@pending_appeals_count = Appeal.pending.count
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -6,6 +6,7 @@ class Admin::Disputes::AppealsController < Admin::BaseController
|
||||||
def index
|
def index
|
||||||
authorize :appeal, :index?
|
authorize :appeal, :index?
|
||||||
|
|
||||||
|
@pending_appeals_count = Appeal.pending.async_count
|
||||||
@appeals = filtered_appeals.page(params[:page])
|
@appeals = filtered_appeals.page(params[:page])
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,18 @@ module Admin
|
||||||
class DomainBlocksController < BaseController
|
class DomainBlocksController < BaseController
|
||||||
before_action :set_domain_block, only: [:destroy, :edit, :update]
|
before_action :set_domain_block, only: [:destroy, :edit, :update]
|
||||||
|
|
||||||
|
PERMITTED_PARAMS = %i(
|
||||||
|
domain
|
||||||
|
obfuscate
|
||||||
|
private_comment
|
||||||
|
public_comment
|
||||||
|
reject_media
|
||||||
|
reject_reports
|
||||||
|
severity
|
||||||
|
).freeze
|
||||||
|
|
||||||
|
PERMITTED_UPDATE_PARAMS = PERMITTED_PARAMS.without(:domain).freeze
|
||||||
|
|
||||||
def batch
|
def batch
|
||||||
authorize :domain_block, :create?
|
authorize :domain_block, :create?
|
||||||
@form = Form::DomainBlockBatch.new(form_domain_block_batch_params.merge(current_account: current_account, action: action_from_button))
|
@form = Form::DomainBlockBatch.new(form_domain_block_batch_params.merge(current_account: current_account, action: action_from_button))
|
||||||
|
@ -88,11 +100,17 @@ module Admin
|
||||||
end
|
end
|
||||||
|
|
||||||
def update_params
|
def update_params
|
||||||
params.require(:domain_block).permit(:severity, :reject_media, :reject_reports, :private_comment, :public_comment, :obfuscate)
|
params
|
||||||
|
.require(:domain_block)
|
||||||
|
.slice(*PERMITTED_UPDATE_PARAMS)
|
||||||
|
.permit(*PERMITTED_UPDATE_PARAMS)
|
||||||
end
|
end
|
||||||
|
|
||||||
def resource_params
|
def resource_params
|
||||||
params.require(:domain_block).permit(:domain, :severity, :reject_media, :reject_reports, :private_comment, :public_comment, :obfuscate)
|
params
|
||||||
|
.require(:domain_block)
|
||||||
|
.slice(*PERMITTED_PARAMS)
|
||||||
|
.permit(*PERMITTED_PARAMS)
|
||||||
end
|
end
|
||||||
|
|
||||||
def form_domain_block_batch_params
|
def form_domain_block_batch_params
|
||||||
|
|
|
@ -5,7 +5,7 @@ module Admin
|
||||||
def index
|
def index
|
||||||
authorize :email_domain_block, :index?
|
authorize :email_domain_block, :index?
|
||||||
|
|
||||||
@email_domain_blocks = EmailDomainBlock.where(parent_id: nil).includes(:children).order(id: :desc).page(params[:page])
|
@email_domain_blocks = EmailDomainBlock.parents.includes(:children).order(id: :desc).page(params[:page])
|
||||||
@form = Form::EmailDomainBlockBatch.new
|
@form = Form::EmailDomainBlockBatch.new
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -58,10 +58,7 @@ module Admin
|
||||||
private
|
private
|
||||||
|
|
||||||
def set_resolved_records
|
def set_resolved_records
|
||||||
Resolv::DNS.open do |dns|
|
@resolved_records = DomainResource.new(@email_domain_block.domain).mx
|
||||||
dns.timeouts = 5
|
|
||||||
@resolved_records = dns.getresources(@email_domain_block.domain, Resolv::DNS::Resource::IN::MX).to_a
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def resource_params
|
def resource_params
|
||||||
|
|
|
@ -5,6 +5,8 @@ module Admin
|
||||||
before_action :set_instances, only: :index
|
before_action :set_instances, only: :index
|
||||||
before_action :set_instance, except: :index
|
before_action :set_instance, except: :index
|
||||||
|
|
||||||
|
LOGS_LIMIT = 5
|
||||||
|
|
||||||
def index
|
def index
|
||||||
authorize :instance, :index?
|
authorize :instance, :index?
|
||||||
preload_delivery_failures!
|
preload_delivery_failures!
|
||||||
|
@ -13,6 +15,7 @@ module Admin
|
||||||
def show
|
def show
|
||||||
authorize :instance, :show?
|
authorize :instance, :show?
|
||||||
@time_period = (6.days.ago.to_date...Time.now.utc.to_date)
|
@time_period = (6.days.ago.to_date...Time.now.utc.to_date)
|
||||||
|
@action_logs = Admin::ActionLogFilter.new(target_domain: @instance.domain).results.limit(LOGS_LIMIT)
|
||||||
end
|
end
|
||||||
|
|
||||||
def destroy
|
def destroy
|
||||||
|
|
|
@ -32,7 +32,7 @@ module Admin
|
||||||
|
|
||||||
def deactivate_all
|
def deactivate_all
|
||||||
authorize :invite, :deactivate_all?
|
authorize :invite, :deactivate_all?
|
||||||
Invite.available.in_batches.update_all(expires_at: Time.now.utc)
|
Invite.available.in_batches.touch_all(:expires_at)
|
||||||
redirect_to admin_invites_path
|
redirect_to admin_invites_path
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,7 @@ module Admin
|
||||||
@relay = Relay.new(resource_params)
|
@relay = Relay.new(resource_params)
|
||||||
|
|
||||||
if @relay.save
|
if @relay.save
|
||||||
|
log_action :create, @relay
|
||||||
@relay.enable!
|
@relay.enable!
|
||||||
redirect_to admin_relays_path
|
redirect_to admin_relays_path
|
||||||
else
|
else
|
||||||
|
@ -31,18 +32,21 @@ module Admin
|
||||||
def destroy
|
def destroy
|
||||||
authorize :relay, :update?
|
authorize :relay, :update?
|
||||||
@relay.destroy
|
@relay.destroy
|
||||||
|
log_action :destroy, @relay
|
||||||
redirect_to admin_relays_path
|
redirect_to admin_relays_path
|
||||||
end
|
end
|
||||||
|
|
||||||
def enable
|
def enable
|
||||||
authorize :relay, :update?
|
authorize :relay, :update?
|
||||||
@relay.enable!
|
@relay.enable!
|
||||||
|
log_action :enable, @relay
|
||||||
redirect_to admin_relays_path
|
redirect_to admin_relays_path
|
||||||
end
|
end
|
||||||
|
|
||||||
def disable
|
def disable
|
||||||
authorize :relay, :update?
|
authorize :relay, :update?
|
||||||
@relay.disable!
|
@relay.disable!
|
||||||
|
log_action :disable, @relay
|
||||||
redirect_to admin_relays_path
|
redirect_to admin_relays_path
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,7 @@ module Admin
|
||||||
|
|
||||||
redirect_to after_create_redirect_path, notice: I18n.t('admin.report_notes.created_msg')
|
redirect_to after_create_redirect_path, notice: I18n.t('admin.report_notes.created_msg')
|
||||||
else
|
else
|
||||||
@report_notes = @report.notes.includes(:account).order(id: :desc)
|
@report_notes = @report.notes.chronological.includes(:account)
|
||||||
@action_logs = @report.history.includes(:target)
|
@action_logs = @report.history.includes(:target)
|
||||||
@form = Admin::StatusBatchAction.new
|
@form = Admin::StatusBatchAction.new
|
||||||
@statuses = @report.statuses.with_includes
|
@statuses = @report.statuses.with_includes
|
||||||
|
|
|
@ -13,7 +13,7 @@ module Admin
|
||||||
authorize @report, :show?
|
authorize @report, :show?
|
||||||
|
|
||||||
@report_note = @report.notes.new
|
@report_note = @report.notes.new
|
||||||
@report_notes = @report.notes.includes(:account).order(id: :desc)
|
@report_notes = @report.notes.chronological.includes(:account)
|
||||||
@action_logs = @report.history.includes(:target)
|
@action_logs = @report.history.includes(:target)
|
||||||
@form = Admin::StatusBatchAction.new
|
@form = Admin::StatusBatchAction.new
|
||||||
@statuses = @report.statuses.with_includes
|
@statuses = @report.statuses.with_includes
|
||||||
|
|
|
@ -16,6 +16,8 @@ module Admin
|
||||||
|
|
||||||
def show
|
def show
|
||||||
authorize [:admin, @status], :show?
|
authorize [:admin, @status], :show?
|
||||||
|
|
||||||
|
@status_batch_action = Admin::StatusBatchAction.new
|
||||||
end
|
end
|
||||||
|
|
||||||
def batch
|
def batch
|
||||||
|
|
|
@ -2,7 +2,15 @@
|
||||||
|
|
||||||
module Admin
|
module Admin
|
||||||
class TagsController < BaseController
|
class TagsController < BaseController
|
||||||
before_action :set_tag
|
before_action :set_tag, except: [:index]
|
||||||
|
|
||||||
|
PER_PAGE = 20
|
||||||
|
|
||||||
|
def index
|
||||||
|
authorize :tag, :index?
|
||||||
|
|
||||||
|
@tags = filtered_tags.page(params[:page]).per(PER_PAGE)
|
||||||
|
end
|
||||||
|
|
||||||
def show
|
def show
|
||||||
authorize @tag, :show?
|
authorize @tag, :show?
|
||||||
|
@ -31,5 +39,13 @@ module Admin
|
||||||
def tag_params
|
def tag_params
|
||||||
params.require(:tag).permit(:name, :display_name, :trendable, :usable, :listable)
|
params.require(:tag).permit(:name, :display_name, :trendable, :usable, :listable)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def filtered_tags
|
||||||
|
TagFilter.new(filter_params.with_defaults(order: 'newest')).results
|
||||||
|
end
|
||||||
|
|
||||||
|
def filter_params
|
||||||
|
params.slice(:page, *TagFilter::KEYS).permit(:page, *TagFilter::KEYS)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -4,6 +4,7 @@ class Admin::Trends::Links::PreviewCardProvidersController < Admin::BaseControll
|
||||||
def index
|
def index
|
||||||
authorize :preview_card_provider, :review?
|
authorize :preview_card_provider, :review?
|
||||||
|
|
||||||
|
@pending_preview_card_providers_count = PreviewCardProvider.unreviewed.async_count
|
||||||
@preview_card_providers = filtered_preview_card_providers.page(params[:page])
|
@preview_card_providers = filtered_preview_card_providers.page(params[:page])
|
||||||
@form = Trends::PreviewCardProviderBatch.new
|
@form = Trends::PreviewCardProviderBatch.new
|
||||||
end
|
end
|
||||||
|
|
|
@ -4,7 +4,7 @@ class Admin::Trends::LinksController < Admin::BaseController
|
||||||
def index
|
def index
|
||||||
authorize :preview_card, :review?
|
authorize :preview_card, :review?
|
||||||
|
|
||||||
@locales = PreviewCardTrend.pluck('distinct language')
|
@locales = PreviewCardTrend.locales
|
||||||
@preview_cards = filtered_preview_cards.page(params[:page])
|
@preview_cards = filtered_preview_cards.page(params[:page])
|
||||||
@form = Trends::PreviewCardBatch.new
|
@form = Trends::PreviewCardBatch.new
|
||||||
end
|
end
|
||||||
|
|
|
@ -4,7 +4,7 @@ class Admin::Trends::StatusesController < Admin::BaseController
|
||||||
def index
|
def index
|
||||||
authorize [:admin, :status], :review?
|
authorize [:admin, :status], :review?
|
||||||
|
|
||||||
@locales = StatusTrend.pluck('distinct language')
|
@locales = StatusTrend.locales
|
||||||
@statuses = filtered_statuses.page(params[:page])
|
@statuses = filtered_statuses.page(params[:page])
|
||||||
@form = Trends::StatusBatch.new
|
@form = Trends::StatusBatch.new
|
||||||
end
|
end
|
||||||
|
|
|
@ -4,6 +4,7 @@ class Admin::Trends::TagsController < Admin::BaseController
|
||||||
def index
|
def index
|
||||||
authorize :tag, :review?
|
authorize :tag, :review?
|
||||||
|
|
||||||
|
@pending_tags_count = Tag.pending_review.async_count
|
||||||
@tags = filtered_tags.page(params[:page])
|
@tags = filtered_tags.page(params[:page])
|
||||||
@form = Trends::TagBatch.new
|
@form = Trends::TagBatch.new
|
||||||
end
|
end
|
||||||
|
|
|
@ -30,10 +30,10 @@ class Api::BaseController < ApplicationController
|
||||||
|
|
||||||
protected
|
protected
|
||||||
|
|
||||||
def limit_param(default_limit)
|
def limit_param(default_limit, max_limit = nil)
|
||||||
return default_limit unless params[:limit]
|
return default_limit unless params[:limit]
|
||||||
|
|
||||||
[params[:limit].to_i.abs, default_limit * 2].min
|
[params[:limit].to_i.abs, max_limit || (default_limit * 2)].min
|
||||||
end
|
end
|
||||||
|
|
||||||
def params_slice(*keys)
|
def params_slice(*keys)
|
||||||
|
|
|
@ -7,7 +7,7 @@ class Api::OEmbedController < Api::BaseController
|
||||||
before_action :require_public_status!
|
before_action :require_public_status!
|
||||||
|
|
||||||
def show
|
def show
|
||||||
render json: @status, serializer: OEmbedSerializer, width: maxwidth_or_default, height: maxheight_or_default
|
render json: @status, serializer: OEmbedSerializer, width: params[:maxwidth], height: params[:maxheight]
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
@ -23,12 +23,4 @@ class Api::OEmbedController < Api::BaseController
|
||||||
def status_finder
|
def status_finder
|
||||||
StatusFinder.new(params[:url])
|
StatusFinder.new(params[:url])
|
||||||
end
|
end
|
||||||
|
|
||||||
def maxwidth_or_default
|
|
||||||
(params[:maxwidth].presence || 400).to_i
|
|
||||||
end
|
|
||||||
|
|
||||||
def maxheight_or_default
|
|
||||||
params[:maxheight].present? ? params[:maxheight].to_i : nil
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -12,7 +12,7 @@ class Api::V1::Accounts::FamiliarFollowersController < Api::BaseController
|
||||||
private
|
private
|
||||||
|
|
||||||
def set_accounts
|
def set_accounts
|
||||||
@accounts = Account.without_suspended.where(id: account_ids).select('id, hide_collections')
|
@accounts = Account.without_suspended.where(id: account_ids).select(:id, :hide_collections)
|
||||||
end
|
end
|
||||||
|
|
||||||
def familiar_followers
|
def familiar_followers
|
||||||
|
|
|
@ -16,6 +16,7 @@ class Api::V1::AccountsController < Api::BaseController
|
||||||
before_action :check_account_confirmation, except: [:index, :create]
|
before_action :check_account_confirmation, except: [:index, :create]
|
||||||
before_action :check_enabled_registrations, only: [:create]
|
before_action :check_enabled_registrations, only: [:create]
|
||||||
before_action :check_accounts_limit, only: [:index]
|
before_action :check_accounts_limit, only: [:index]
|
||||||
|
before_action :check_following_self, only: [:follow]
|
||||||
|
|
||||||
skip_before_action :require_authenticated_user!, only: :create
|
skip_before_action :require_authenticated_user!, only: :create
|
||||||
|
|
||||||
|
@ -101,8 +102,12 @@ class Api::V1::AccountsController < Api::BaseController
|
||||||
raise(Mastodon::ValidationError) if account_ids.size > DEFAULT_ACCOUNTS_LIMIT
|
raise(Mastodon::ValidationError) if account_ids.size > DEFAULT_ACCOUNTS_LIMIT
|
||||||
end
|
end
|
||||||
|
|
||||||
def relationships(**options)
|
def check_following_self
|
||||||
AccountRelationshipsPresenter.new([@account], current_user.account_id, **options)
|
render json: { error: I18n.t('accounts.self_follow_error') }, status: 403 if current_user.account.id == @account.id
|
||||||
|
end
|
||||||
|
|
||||||
|
def relationships(**)
|
||||||
|
AccountRelationshipsPresenter.new([@account], current_user.account_id, **)
|
||||||
end
|
end
|
||||||
|
|
||||||
def account_ids
|
def account_ids
|
||||||
|
|
|
@ -5,6 +5,7 @@ class Api::V1::Admin::DomainAllowsController < Api::BaseController
|
||||||
include AccountableConcern
|
include AccountableConcern
|
||||||
|
|
||||||
LIMIT = 100
|
LIMIT = 100
|
||||||
|
MAX_LIMIT = 500
|
||||||
|
|
||||||
before_action -> { authorize_if_got_token! :'admin:read', :'admin:read:domain_allows' }, only: [:index, :show]
|
before_action -> { authorize_if_got_token! :'admin:read', :'admin:read:domain_allows' }, only: [:index, :show]
|
||||||
before_action -> { authorize_if_got_token! :'admin:write', :'admin:write:domain_allows' }, except: [:index, :show]
|
before_action -> { authorize_if_got_token! :'admin:write', :'admin:write:domain_allows' }, except: [:index, :show]
|
||||||
|
@ -47,18 +48,13 @@ class Api::V1::Admin::DomainAllowsController < Api::BaseController
|
||||||
private
|
private
|
||||||
|
|
||||||
def set_domain_allows
|
def set_domain_allows
|
||||||
@domain_allows = filtered_domain_allows.order(id: :desc).to_a_paginated_by_id(limit_param(LIMIT), params_slice(:max_id, :since_id, :min_id))
|
@domain_allows = DomainAllow.order(id: :desc).to_a_paginated_by_id(limit_param(LIMIT, MAX_LIMIT), params_slice(:max_id, :since_id, :min_id))
|
||||||
end
|
end
|
||||||
|
|
||||||
def set_domain_allow
|
def set_domain_allow
|
||||||
@domain_allow = DomainAllow.find(params[:id])
|
@domain_allow = DomainAllow.find(params[:id])
|
||||||
end
|
end
|
||||||
|
|
||||||
def filtered_domain_allows
|
|
||||||
# TODO: no filtering yet
|
|
||||||
DomainAllow.all
|
|
||||||
end
|
|
||||||
|
|
||||||
def next_path
|
def next_path
|
||||||
api_v1_admin_domain_allows_url(pagination_params(max_id: pagination_max_id)) if records_continue?
|
api_v1_admin_domain_allows_url(pagination_params(max_id: pagination_max_id)) if records_continue?
|
||||||
end
|
end
|
||||||
|
@ -72,7 +68,7 @@ class Api::V1::Admin::DomainAllowsController < Api::BaseController
|
||||||
end
|
end
|
||||||
|
|
||||||
def records_continue?
|
def records_continue?
|
||||||
@domain_allows.size == limit_param(LIMIT)
|
@domain_allows.size == limit_param(LIMIT, MAX_LIMIT)
|
||||||
end
|
end
|
||||||
|
|
||||||
def resource_params
|
def resource_params
|
||||||
|
|
|
@ -5,6 +5,7 @@ class Api::V1::Admin::DomainBlocksController < Api::BaseController
|
||||||
include AccountableConcern
|
include AccountableConcern
|
||||||
|
|
||||||
LIMIT = 100
|
LIMIT = 100
|
||||||
|
MAX_LIMIT = 500
|
||||||
|
|
||||||
before_action -> { authorize_if_got_token! :'admin:read', :'admin:read:domain_blocks' }, only: [:index, :show]
|
before_action -> { authorize_if_got_token! :'admin:read', :'admin:read:domain_blocks' }, only: [:index, :show]
|
||||||
before_action -> { authorize_if_got_token! :'admin:write', :'admin:write:domain_blocks' }, except: [:index, :show]
|
before_action -> { authorize_if_got_token! :'admin:write', :'admin:write:domain_blocks' }, except: [:index, :show]
|
||||||
|
@ -59,18 +60,13 @@ class Api::V1::Admin::DomainBlocksController < Api::BaseController
|
||||||
end
|
end
|
||||||
|
|
||||||
def set_domain_blocks
|
def set_domain_blocks
|
||||||
@domain_blocks = filtered_domain_blocks.order(id: :desc).to_a_paginated_by_id(limit_param(LIMIT), params_slice(:max_id, :since_id, :min_id))
|
@domain_blocks = DomainBlock.order(id: :desc).to_a_paginated_by_id(limit_param(LIMIT, MAX_LIMIT), params_slice(:max_id, :since_id, :min_id))
|
||||||
end
|
end
|
||||||
|
|
||||||
def set_domain_block
|
def set_domain_block
|
||||||
@domain_block = DomainBlock.find(params[:id])
|
@domain_block = DomainBlock.find(params[:id])
|
||||||
end
|
end
|
||||||
|
|
||||||
def filtered_domain_blocks
|
|
||||||
# TODO: no filtering yet
|
|
||||||
DomainBlock.all
|
|
||||||
end
|
|
||||||
|
|
||||||
def domain_block_params
|
def domain_block_params
|
||||||
params.permit(:severity, :reject_media, :reject_reports, :private_comment, :public_comment, :obfuscate)
|
params.permit(:severity, :reject_media, :reject_reports, :private_comment, :public_comment, :obfuscate)
|
||||||
end
|
end
|
||||||
|
@ -88,7 +84,7 @@ class Api::V1::Admin::DomainBlocksController < Api::BaseController
|
||||||
end
|
end
|
||||||
|
|
||||||
def records_continue?
|
def records_continue?
|
||||||
@domain_blocks.size == limit_param(LIMIT)
|
@domain_blocks.size == limit_param(LIMIT, MAX_LIMIT)
|
||||||
end
|
end
|
||||||
|
|
||||||
def resource_params
|
def resource_params
|
||||||
|
|
|
@ -13,6 +13,13 @@ class Api::V1::Admin::TagsController < Api::BaseController
|
||||||
|
|
||||||
LIMIT = 100
|
LIMIT = 100
|
||||||
|
|
||||||
|
PERMITTED_PARAMS = %i(
|
||||||
|
display_name
|
||||||
|
listable
|
||||||
|
trendable
|
||||||
|
usable
|
||||||
|
).freeze
|
||||||
|
|
||||||
def index
|
def index
|
||||||
authorize :tag, :index?
|
authorize :tag, :index?
|
||||||
render json: @tags, each_serializer: REST::Admin::TagSerializer
|
render json: @tags, each_serializer: REST::Admin::TagSerializer
|
||||||
|
@ -40,7 +47,9 @@ class Api::V1::Admin::TagsController < Api::BaseController
|
||||||
end
|
end
|
||||||
|
|
||||||
def tag_params
|
def tag_params
|
||||||
params.permit(:display_name, :trendable, :usable, :listable)
|
params
|
||||||
|
.slice(*PERMITTED_PARAMS)
|
||||||
|
.permit(*PERMITTED_PARAMS)
|
||||||
end
|
end
|
||||||
|
|
||||||
def next_path
|
def next_path
|
||||||
|
|
|
@ -17,6 +17,17 @@ class Api::V1::AnnualReportsController < Api::BaseController
|
||||||
relationships: @relationships
|
relationships: @relationships
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def show
|
||||||
|
with_read_replica do
|
||||||
|
@presenter = AnnualReportsPresenter.new([@annual_report])
|
||||||
|
@relationships = StatusRelationshipsPresenter.new(@presenter.statuses, current_account.id)
|
||||||
|
end
|
||||||
|
|
||||||
|
render json: @presenter,
|
||||||
|
serializer: REST::AnnualReportsSerializer,
|
||||||
|
relationships: @relationships
|
||||||
|
end
|
||||||
|
|
||||||
def read
|
def read
|
||||||
@annual_report.view!
|
@annual_report.view!
|
||||||
render_empty
|
render_empty
|
||||||
|
|
|
@ -1,30 +0,0 @@
|
||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
class Api::V1::Crypto::DeliveriesController < Api::BaseController
|
|
||||||
before_action -> { doorkeeper_authorize! :crypto }
|
|
||||||
before_action :require_user!
|
|
||||||
before_action :set_current_device
|
|
||||||
|
|
||||||
def create
|
|
||||||
devices.each do |device_params|
|
|
||||||
DeliverToDeviceService.new.call(current_account, @current_device, device_params)
|
|
||||||
end
|
|
||||||
|
|
||||||
render_empty
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def set_current_device
|
|
||||||
@current_device = Device.find_by!(access_token: doorkeeper_token)
|
|
||||||
end
|
|
||||||
|
|
||||||
def resource_params
|
|
||||||
params.require(:device)
|
|
||||||
params.permit(device: [:account_id, :device_id, :type, :body, :hmac])
|
|
||||||
end
|
|
||||||
|
|
||||||
def devices
|
|
||||||
Array(resource_params[:device])
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,47 +0,0 @@
|
||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
class Api::V1::Crypto::EncryptedMessagesController < Api::BaseController
|
|
||||||
LIMIT = 80
|
|
||||||
|
|
||||||
before_action -> { doorkeeper_authorize! :crypto }
|
|
||||||
before_action :require_user!
|
|
||||||
before_action :set_current_device
|
|
||||||
|
|
||||||
before_action :set_encrypted_messages, only: :index
|
|
||||||
after_action :insert_pagination_headers, only: :index
|
|
||||||
|
|
||||||
def index
|
|
||||||
render json: @encrypted_messages, each_serializer: REST::EncryptedMessageSerializer
|
|
||||||
end
|
|
||||||
|
|
||||||
def clear
|
|
||||||
@current_device.encrypted_messages.up_to(params[:up_to_id]).delete_all
|
|
||||||
render_empty
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def set_current_device
|
|
||||||
@current_device = Device.find_by!(access_token: doorkeeper_token)
|
|
||||||
end
|
|
||||||
|
|
||||||
def set_encrypted_messages
|
|
||||||
@encrypted_messages = @current_device.encrypted_messages.to_a_paginated_by_id(limit_param(LIMIT), params_slice(:max_id, :since_id, :min_id))
|
|
||||||
end
|
|
||||||
|
|
||||||
def next_path
|
|
||||||
api_v1_crypto_encrypted_messages_url pagination_params(max_id: pagination_max_id) if records_continue?
|
|
||||||
end
|
|
||||||
|
|
||||||
def prev_path
|
|
||||||
api_v1_crypto_encrypted_messages_url pagination_params(min_id: pagination_since_id) unless @encrypted_messages.empty?
|
|
||||||
end
|
|
||||||
|
|
||||||
def pagination_collection
|
|
||||||
@encrypted_messages
|
|
||||||
end
|
|
||||||
|
|
||||||
def records_continue?
|
|
||||||
@encrypted_messages.size == limit_param(LIMIT)
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,25 +0,0 @@
|
||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
class Api::V1::Crypto::Keys::ClaimsController < Api::BaseController
|
|
||||||
before_action -> { doorkeeper_authorize! :crypto }
|
|
||||||
before_action :require_user!
|
|
||||||
before_action :set_claim_results
|
|
||||||
|
|
||||||
def create
|
|
||||||
render json: @claim_results, each_serializer: REST::Keys::ClaimResultSerializer
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def set_claim_results
|
|
||||||
@claim_results = devices.filter_map { |device_params| ::Keys::ClaimService.new.call(current_account, device_params[:account_id], device_params[:device_id]) }
|
|
||||||
end
|
|
||||||
|
|
||||||
def resource_params
|
|
||||||
params.permit(device: [:account_id, :device_id])
|
|
||||||
end
|
|
||||||
|
|
||||||
def devices
|
|
||||||
Array(resource_params[:device])
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,17 +0,0 @@
|
||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
class Api::V1::Crypto::Keys::CountsController < Api::BaseController
|
|
||||||
before_action -> { doorkeeper_authorize! :crypto }
|
|
||||||
before_action :require_user!
|
|
||||||
before_action :set_current_device
|
|
||||||
|
|
||||||
def show
|
|
||||||
render json: { one_time_keys: @current_device.one_time_keys.count }
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def set_current_device
|
|
||||||
@current_device = Device.find_by!(access_token: doorkeeper_token)
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,26 +0,0 @@
|
||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
class Api::V1::Crypto::Keys::QueriesController < Api::BaseController
|
|
||||||
before_action -> { doorkeeper_authorize! :crypto }
|
|
||||||
before_action :require_user!
|
|
||||||
before_action :set_accounts
|
|
||||||
before_action :set_query_results
|
|
||||||
|
|
||||||
def create
|
|
||||||
render json: @query_results, each_serializer: REST::Keys::QueryResultSerializer
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def set_accounts
|
|
||||||
@accounts = Account.where(id: account_ids).includes(:devices)
|
|
||||||
end
|
|
||||||
|
|
||||||
def set_query_results
|
|
||||||
@query_results = @accounts.filter_map { |account| ::Keys::QueryService.new.call(account) }
|
|
||||||
end
|
|
||||||
|
|
||||||
def account_ids
|
|
||||||
Array(params[:id]).map(&:to_i)
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,29 +0,0 @@
|
||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
class Api::V1::Crypto::Keys::UploadsController < Api::BaseController
|
|
||||||
before_action -> { doorkeeper_authorize! :crypto }
|
|
||||||
before_action :require_user!
|
|
||||||
|
|
||||||
def create
|
|
||||||
device = Device.find_or_initialize_by(access_token: doorkeeper_token)
|
|
||||||
|
|
||||||
device.transaction do
|
|
||||||
device.account = current_account
|
|
||||||
device.update!(resource_params[:device])
|
|
||||||
|
|
||||||
if resource_params[:one_time_keys].present? && resource_params[:one_time_keys].is_a?(Enumerable)
|
|
||||||
resource_params[:one_time_keys].each do |one_time_key_params|
|
|
||||||
device.one_time_keys.create!(one_time_key_params)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
render json: device, serializer: REST::Keys::DeviceSerializer
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def resource_params
|
|
||||||
params.permit(device: [:device_id, :name, :fingerprint_key, :identity_key], one_time_keys: [:key_id, :key, :signature])
|
|
||||||
end
|
|
||||||
end
|
|
27
app/controllers/api/v1/domain_blocks/previews_controller.rb
Normal file
27
app/controllers/api/v1/domain_blocks/previews_controller.rb
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
class Api::V1::DomainBlocks::PreviewsController < Api::BaseController
|
||||||
|
before_action -> { doorkeeper_authorize! :follow, :write, :'write:blocks' }
|
||||||
|
before_action :require_user!
|
||||||
|
before_action :set_domain
|
||||||
|
before_action :set_domain_block_preview
|
||||||
|
|
||||||
|
def show
|
||||||
|
render json: @domain_block_preview, serializer: REST::DomainBlockPreviewSerializer
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def set_domain
|
||||||
|
@domain = TagManager.instance.normalize_domain(params[:domain])
|
||||||
|
end
|
||||||
|
|
||||||
|
def set_domain_block_preview
|
||||||
|
@domain_block_preview = with_read_replica do
|
||||||
|
DomainBlockPreviewPresenter.new(
|
||||||
|
following_count: current_account.following.where(domain: @domain).count,
|
||||||
|
followers_count: current_account.followers.where(domain: @domain).count
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue