Compare commits

..

No commits in common. "main" and "v4.2.0-beta1" have entirely different histories.

3614 changed files with 75391 additions and 149283 deletions

View File

@ -1,10 +1,7 @@
[production] [production]
defaults defaults
> 0.2% not IE 11
firefox >= 78
ios >= 15.6
not dead not dead
not OperaMini all
[development] [development]
supports es6-module supports es6-module

View File

@ -1,18 +1,24 @@
# 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.2-bullseye
# Install node version from .nvmrc # Install Rails
WORKDIR /app # RUN gem install rails webdrivers
COPY .nvmrc .
RUN /bin/bash --login -i -c "nvm install"
# Install additional OS packages # Default value to allow debug server to serve content over GitHub Codespace's port forwarding service
RUN apt-get update && \ # The value is a comma-separated list of allowed domains
export DEBIAN_FRONTEND=noninteractive && \ ENV RAILS_DEVELOPMENT_HOSTS=".githubpreview.dev,.preview.app.github.dev,.app.github.dev"
apt-get -y install --no-install-recommends libicu-dev libidn11-dev ffmpeg imagemagick libvips42 libpam-dev
# Disable download prompt for Corepack ARG NODE_VERSION="16"
ENV COREPACK_ENABLE_DOWNLOAD_PROMPT=0 RUN su vscode -c "source /usr/local/share/nvm/nvm.sh && nvm install ${NODE_VERSION} 2>&1"
# Move welcome message to where VS Code expects it # [Optional] Uncomment this section to install additional OS packages.
COPY .devcontainer/welcome-message.txt /usr/local/etc/vscode-dev-containers/first-run-notice.txt RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
&& apt-get -y install --no-install-recommends libicu-dev libidn11-dev ffmpeg imagemagick libpam-dev
# [Optional] Uncomment this line to install additional gems.
RUN gem install foreman
# [Optional] Uncomment this line to install global node packages.
RUN su vscode -c "source /usr/local/share/nvm/nvm.sh && npm install -g yarn" 2>&1
COPY welcome-message.txt /usr/local/etc/vscode-dev-containers/first-run-notice.txt

View File

@ -1,51 +0,0 @@
{
"name": "Mastodon on GitHub Codespaces",
"dockerComposeFile": "../compose.yaml",
"service": "app",
"workspaceFolder": "/workspaces/${localWorkspaceFolderBasename}",
"features": {
"ghcr.io/devcontainers/features/sshd:1": {}
},
"runServices": ["app", "db", "redis"],
"forwardPorts": [3000, 4000],
"portsAttributes": {
"3000": {
"label": "web",
"onAutoForward": "notify"
},
"4000": {
"label": "stream",
"onAutoForward": "silent"
}
},
"remoteUser": "root",
"otherPortsAttributes": {
"onAutoForward": "silent"
},
"remoteEnv": {
"LOCAL_DOMAIN": "${localEnv:CODESPACE_NAME}-3000.app.github.dev",
"LOCAL_HTTPS": "true",
"STREAMING_API_BASE_URL": "https://${localEnv:CODESPACE_NAME}-4000.app.github.dev",
"DISABLE_FORGERY_REQUEST_PROTECTION": "true",
"ES_ENABLED": "",
"LIBRE_TRANSLATE_ENDPOINT": ""
},
"onCreateCommand": "git config --global --add safe.directory ${containerWorkspaceFolder}",
"postCreateCommand": "bin/setup",
"waitFor": "postCreateCommand",
"customizations": {
"vscode": {
"settings": {},
"extensions": ["EditorConfig.EditorConfig", "webben.browserslist"]
}
}
}

View File

@ -1,41 +1,31 @@
// For more details, see https://aka.ms/devcontainer.json.
{ {
"name": "Mastodon on local machine", "name": "Mastodon",
"dockerComposeFile": "compose.yaml", "dockerComposeFile": "docker-compose.yml",
"service": "app", "service": "app",
"workspaceFolder": "/workspaces/${localWorkspaceFolderBasename}", "workspaceFolder": "/workspaces/${localWorkspaceFolderBasename}",
// Features to add to the dev container. More info: https://containers.dev/features.
"features": { "features": {
"ghcr.io/devcontainers/features/sshd:1": {} "ghcr.io/devcontainers/features/sshd:1": {}
}, },
// Use 'forwardPorts' to make a list of ports inside the container available locally.
// This can be used to network with other containers or the host.
"forwardPorts": [3000, 4000], "forwardPorts": [3000, 4000],
"portsAttributes": { // Use 'postCreateCommand' to run commands after the container is created.
"3000": {
"label": "web",
"onAutoForward": "notify",
"requireLocalPort": true
},
"4000": {
"label": "stream",
"onAutoForward": "silent",
"requireLocalPort": true
}
},
"remoteUser": "root",
"otherPortsAttributes": {
"onAutoForward": "silent"
},
"onCreateCommand": "git config --global --add safe.directory ${containerWorkspaceFolder}", "onCreateCommand": "git config --global --add safe.directory ${containerWorkspaceFolder}",
"postCreateCommand": "bin/setup", "postCreateCommand": ".devcontainer/post-create.sh",
"waitFor": "postCreateCommand", "waitFor": "postCreateCommand",
// Configure tool-specific properties.
"customizations": { "customizations": {
// Configure properties specific to VS Code.
"vscode": { "vscode": {
// Set *default* container specific settings.json values on container create.
"settings": {}, "settings": {},
// Add the IDs of extensions you want installed when the container is created.
"extensions": ["EditorConfig.EditorConfig", "webben.browserslist"] "extensions": ["EditorConfig.EditorConfig", "webben.browserslist"]
} }
} }

View File

@ -1,11 +1,12 @@
version: '3'
services: services:
app: app:
working_dir: /workspaces/mastodon/
build: build:
context: .. context: .
dockerfile: .devcontainer/Dockerfile dockerfile: Dockerfile
volumes: volumes:
- ..:/workspaces/mastodon:cached - ../..:/workspaces:cached
environment: environment:
RAILS_ENV: development RAILS_ENV: development
NODE_ENV: development NODE_ENV: development
@ -24,7 +25,6 @@ services:
command: sleep infinity command: sleep infinity
ports: ports:
- '127.0.0.1:3000:3000' - '127.0.0.1:3000:3000'
- '127.0.0.1:3035:3035'
- '127.0.0.1:4000:4000' - '127.0.0.1:4000:4000'
networks: networks:
- external_network - external_network
@ -69,7 +69,7 @@ services:
hard: -1 hard: -1
libretranslate: libretranslate:
image: libretranslate/libretranslate:v1.6.1 image: libretranslate/libretranslate:v1.3.11
restart: unless-stopped restart: unless-stopped
volumes: volumes:
- lt-data:/home/libretranslate/.local - lt-data:/home/libretranslate/.local

26
.devcontainer/post-create.sh Executable file
View File

@ -0,0 +1,26 @@
#!/bin/bash
set -e # Fail the whole script on first error
# Fetch Ruby gem dependencies
bundle config path 'vendor/bundle'
bundle config with 'development test'
bundle install
# Make Gemfile.lock pristine again
git checkout -- Gemfile.lock
# Fetch Javascript dependencies
yarn --frozen-lockfile
# [re]create, migrate, and seed the test database
RAILS_ENV=test ./bin/rails db:setup
# [re]create, migrate, and seed the development database
RAILS_ENV=development ./bin/rails db:setup
# Precompile assets for development
RAILS_ENV=development ./bin/rails assets:precompile
# Precompile assets for test
RAILS_ENV=test NODE_ENV=tests ./bin/rails assets:precompile

View File

@ -1,7 +1,8 @@
👋 Welcome to your Mastodon Dev Container! 👋 Welcome to "Mastodon" in GitHub Codespaces!
🛠️ Your environment is fully setup with all the required software. 🛠️ Your environment is fully setup with all the required software.
💥 Run `bin/dev` to start the application processes. 🔍 To explore VS Code to its fullest, search using the Command Palette (Cmd/Ctrl + Shift + P or F1).
📝 Edit away, run your app as usual, and we'll automatically make it available for you to access.
🥼 Run `RAILS_ENV=test bin/rails assets:precompile && RAILS_ENV=test bin/rspec` to run the test suite.

View File

@ -8,7 +8,6 @@
public/system public/system
public/assets public/assets
public/packs public/packs
public/packs-test
node_modules node_modules
neo4j neo4j
vendor/bundle vendor/bundle

View File

@ -1,4 +0,0 @@
# Required by ActiveRecord encryption feature
ACTIVE_RECORD_ENCRYPTION_DETERMINISTIC_KEY=fkSxKD2bF396kdQbrP1EJ7WbU7ZgNokR
ACTIVE_RECORD_ENCRYPTION_KEY_DERIVATION_SALT=r0hvVmzBVsjxC7AMlwhOzmtc36ZCOS1E
ACTIVE_RECORD_ENCRYPTION_PRIMARY_KEY=PhdFyyfy5xJ7WVd2lWBpcPScRQHzRTNr

View File

@ -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 `bundle exec rails mastodon:setup` interactive setup wizard, but to customize # with the `rake 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,14 @@ ES_PASS=password
# Secrets # Secrets
# ------- # -------
# Make sure to use `bundle exec rails secret` to generate secrets # Make sure to use `rake secret` to generate secrets
# ------- # -------
SECRET_KEY_BASE= SECRET_KEY_BASE=
OTP_SECRET= OTP_SECRET=
# Web Push # Web Push
# -------- # --------
# Generate with `bundle exec rails mastodon:webpush:generate_vapid_key` # Generate with `rake mastodon:webpush:generate_vapid_key`
# -------- # --------
VAPID_PRIVATE_KEY= VAPID_PRIVATE_KEY=
VAPID_PUBLIC_KEY= VAPID_PUBLIC_KEY=

View File

@ -1,11 +1,5 @@
# In test, compile the NodeJS code as if we are in production # Node.js
NODE_ENV=production NODE_ENV=tests
# Federation # Federation
LOCAL_DOMAIN=cb6e6126.ngrok.io LOCAL_DOMAIN=cb6e6126.ngrok.io
LOCAL_HTTPS=true LOCAL_HTTPS=true
# Secret values required by ActiveRecord encryption feature
# Use `bin/rails db:encryption:init` to generate fresh secrets
ACTIVE_RECORD_ENCRYPTION_DETERMINISTIC_KEY=test_determinist_key_DO_NOT_USE_IN_PRODUCTION
ACTIVE_RECORD_ENCRYPTION_KEY_DERIVATION_SALT=test_salt_DO_NOT_USE_IN_PRODUCTION
ACTIVE_RECORD_ENCRYPTION_PRIMARY_KEY=test_primary_key_DO_NOT_USE_IN_PRODUCTION

View File

@ -2,7 +2,3 @@ VAGRANT=true
LOCAL_DOMAIN=mastodon.local LOCAL_DOMAIN=mastodon.local
BIND=0.0.0.0 BIND=0.0.0.0
DB_HOST=/var/run/postgresql/ DB_HOST=/var/run/postgresql/
ES_ENABLED=true
ES_HOST=localhost
ES_PORT=9200

View File

@ -1,7 +1,4 @@
// @ts-check module.exports = {
const { defineConfig } = require('eslint-define-config');
module.exports = defineConfig({
root: true, root: true,
extends: [ extends: [
@ -12,6 +9,7 @@ module.exports = defineConfig({
'plugin:import/recommended', 'plugin:import/recommended',
'plugin:promise/recommended', 'plugin:promise/recommended',
'plugin:jsdoc/recommended', 'plugin:jsdoc/recommended',
'plugin:prettier/recommended',
], ],
env: { env: {
@ -20,6 +18,10 @@ module.exports = defineConfig({
es6: true, es6: true,
}, },
globals: {
ATTACHMENT_HOST: false,
},
parser: '@typescript-eslint/parser', parser: '@typescript-eslint/parser',
plugins: [ plugins: [
@ -61,9 +63,7 @@ module.exports = defineConfig({
'consistent-return': 'error', 'consistent-return': 'error',
'dot-notation': 'error', 'dot-notation': 'error',
eqeqeq: ['error', 'always', { 'null': 'ignore' }], eqeqeq: ['error', 'always', { 'null': 'ignore' }],
'indent': ['error', 2],
'jsx-quotes': ['error', 'prefer-single'], 'jsx-quotes': ['error', 'prefer-single'],
'semi': ['error', 'always'],
'no-case-declarations': 'off', 'no-case-declarations': 'off',
'no-catch-shadow': 'error', 'no-catch-shadow': 'error',
'no-console': [ 'no-console': [
@ -75,7 +75,7 @@ module.exports = defineConfig({
], ],
}, },
], ],
'no-empty': ['error', { "allowEmptyCatch": true }], 'no-empty': 'off',
'no-restricted-properties': [ 'no-restricted-properties': [
'error', 'error',
{ property: 'substring', message: 'Use .slice instead of .substring.' }, { property: 'substring', message: 'Use .slice instead of .substring.' },
@ -90,6 +90,7 @@ 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': [
@ -114,10 +115,13 @@ 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/no-unknown-property': '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/main/src/index.js
'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',
@ -132,6 +136,23 @@ 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',
// { // {
@ -141,6 +162,7 @@ module.exports = defineConfig({
// }, // },
// ], // ],
'jsx-a11y/no-noninteractive-tabindex': 'off', 'jsx-a11y/no-noninteractive-tabindex': 'off',
'jsx-a11y/no-onchange': 'warn',
// recommended is full 'error' // recommended is full 'error'
'jsx-a11y/no-static-element-interactions': [ 'jsx-a11y/no-static-element-interactions': [
'warn', 'warn',
@ -151,7 +173,7 @@ module.exports = defineConfig({
}, },
], ],
// See https://github.com/import-js/eslint-plugin-import/blob/v2.29.1/config/recommended.js // See https://github.com/import-js/eslint-plugin-import/blob/main/config/recommended.js
'import/extensions': [ 'import/extensions': [
'error', 'error',
'always', 'always',
@ -170,7 +192,6 @@ module.exports = defineConfig({
'error', 'error',
{ {
devDependencies: [ devDependencies: [
'.eslintrc.js',
'config/webpack/**', 'config/webpack/**',
'app/javascript/mastodon/performance.js', 'app/javascript/mastodon/performance.js',
'app/javascript/mastodon/test_setup.js', 'app/javascript/mastodon/test_setup.js',
@ -214,13 +235,13 @@ module.exports = defineConfig({
}, },
// Common React utilities // Common React utilities
{ {
pattern: '{classnames,react-helmet,react-router,react-router-dom}', pattern: '{classnames,react-helmet,react-router-dom}',
group: 'external', group: 'external',
position: 'before', position: 'before',
}, },
// Immutable / Redux / data store // Immutable / Redux / data store
{ {
pattern: '{immutable,@reduxjs/toolkit,react-redux,react-immutable-proptypes,react-immutable-pure-component}', pattern: '{immutable,react-redux,react-immutable-proptypes,react-immutable-pure-component,reselect}',
group: 'external', group: 'external',
position: 'before', position: 'before',
}, },
@ -258,6 +279,7 @@ module.exports = defineConfig({
'formatjs/no-id': 'off', // IDs are used for translation keys 'formatjs/no-id': 'off', // IDs are used for translation keys
'formatjs/no-invalid-icu': 'error', 'formatjs/no-invalid-icu': 'error',
'formatjs/no-literal-string-in-jsx': 'off', // Should be looked at, but mainly flagging punctuation outside of strings 'formatjs/no-literal-string-in-jsx': 'off', // Should be looked at, but mainly flagging punctuation outside of strings
'formatjs/no-multiple-plurals': 'off', // Only used by hashtag.jsx
'formatjs/no-multiple-whitespaces': 'error', 'formatjs/no-multiple-whitespaces': 'error',
'formatjs/no-offset': 'error', 'formatjs/no-offset': 'error',
'formatjs/no-useless-message': 'error', 'formatjs/no-useless-message': 'error',
@ -276,7 +298,6 @@ module.exports = defineConfig({
overrides: [ overrides: [
{ {
files: [ files: [
'.eslintrc.js',
'*.config.js', '*.config.js',
'.*rc.js', '.*rc.js',
'ide-helper.js', 'ide-helper.js',
@ -313,35 +334,22 @@ module.exports = defineConfig({
'plugin:import/typescript', 'plugin:import/typescript',
'plugin:promise/recommended', 'plugin:promise/recommended',
'plugin:jsdoc/recommended-typescript', 'plugin:jsdoc/recommended-typescript',
'plugin:prettier/recommended',
], ],
parserOptions: { parserOptions: {
projectService: true, project: true,
tsconfigRootDir: __dirname, tsconfigRootDir: __dirname,
}, },
rules: { rules: {
// Disable formatting rules that have been enabled in the base config
'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'],
'@typescript-eslint/consistent-type-exports': 'error', '@typescript-eslint/consistent-type-exports': 'error',
'@typescript-eslint/consistent-type-imports': 'error', '@typescript-eslint/consistent-type-imports': 'error',
"@typescript-eslint/prefer-nullish-coalescing": ['error', { ignorePrimitives: { boolean: true } }], "@typescript-eslint/prefer-nullish-coalescing": ['error', {ignorePrimitives: {boolean: true}}],
"@typescript-eslint/no-restricted-imports": [
"warn",
{
"name": "react-redux",
"importNames": ["useSelector", "useDispatch"],
"message": "Use typed hooks `useAppDispatch` and `useAppSelector` instead."
}
],
"@typescript-eslint/restrict-template-expressions": ['warn', { allowNumber: true }],
'jsdoc/require-jsdoc': 'off', 'jsdoc/require-jsdoc': 'off',
// Those rules set stricter rules for TS files // Those rules set stricter rules for TS files
@ -363,6 +371,14 @@ module.exports = defineConfig({
env: { env: {
jest: true, jest: true,
}, },
} },
{
files: [
'streaming/**/*',
],
rules: {
'import/no-commonjs': 'off',
},
},
], ],
}); };

3
.github/FUNDING.yml vendored Normal file
View File

@ -0,0 +1,3 @@
patreon: mastodon
open_collective: mastodon
custom: https://sponsor.joinmastodon.org

View File

@ -1,42 +0,0 @@
name: 'Setup Javascript'
description: 'Setup a Javascript environment ready to run the Mastodon code'
inputs:
onlyProduction:
description: Only install production dependencies
default: 'false'
runs:
using: 'composite'
steps:
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version-file: '.nvmrc'
# The following is needed because we can not use `cache: true` for `setup-node`, as it does not support Corepack yet and mess up with the cache location if ran after Node is installed
- name: Enable corepack
shell: bash
run: corepack enable
- name: Get yarn cache directory path
id: yarn-cache-dir-path
shell: bash
run: echo "dir=$(yarn config get cacheFolder)" >> $GITHUB_OUTPUT
- uses: actions/cache@v4
id: yarn-cache # use this to check for `cache-hit` (`steps.yarn-cache.outputs.cache-hit != 'true'`)
with:
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
restore-keys: |
${{ runner.os }}-yarn-
- name: Install all yarn packages
shell: bash
run: yarn install --immutable
if: inputs.onlyProduction == 'false'
- name: Install all production yarn packages
shell: bash
run: yarn workspaces focus --production
if: inputs.onlyProduction != 'false'

View File

@ -1,23 +0,0 @@
name: 'Setup RUby'
description: 'Setup a Ruby environment ready to run the Mastodon code'
inputs:
ruby-version:
description: The Ruby version to install
default: '.ruby-version'
additional-system-dependencies:
description: 'Additional packages to install'
runs:
using: 'composite'
steps:
- name: Install system dependencies
shell: bash
run: |
sudo apt-get update
sudo apt-get install -y libicu-dev libidn11-dev libvips42 ${{ inputs.additional-system-dependencies }}
- name: Set up Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: ${{ inputs.ruby-version }}
bundler-cache: true

13
.github/codecov.yml vendored
View File

@ -1,13 +0,0 @@
comment: false # Do not leave PR comments
coverage:
status:
project:
default:
# GitHub status check is not blocking
informational: true
patch:
default:
# GitHub status check is not blocking
informational: true
github_checks:
annotations: false

View File

@ -1,30 +1,26 @@
{ {
$schema: 'https://docs.renovatebot.com/renovate-schema.json', $schema: 'https://docs.renovatebot.com/renovate-schema.json',
extends: [ extends: [
'config:recommended', 'config:base',
'customManagers:dockerfileVersions', ':dependencyDashboard',
':labels(dependencies)', ':labels(dependencies)',
':prConcurrentLimitNone', // Remove limit for open PRs at any time. ':maintainLockFilesMonthly', // update non-direct dependencies monthly
':prHourlyLimit2', // Rate limit PR creation to a maximum of two per hour. ':prConcurrentLimit10', // only 10 open PRs at the same time
], ],
rebaseWhen: 'conflicted', stabilityDays: 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
// If we do not want a package to be grouped with others, we need to set its groupName // If we do not want a package to be grouped with others, we need to set its groupName
// to `null` after any other rule set it to something. // to `null` after any other rule set it to something.
dependencyDashboardHeader: 'This issue lists Renovate updates and detected dependencies. Read the [Dependency Dashboard](https://docs.renovatebot.com/key-concepts/dashboard/) docs to learn more. Before approving any upgrade: read the description and comments in the [`renovate.json5` file](https://github.com/mastodon/mastodon/blob/main/.github/renovate.json5).',
postUpdateOptions: ['yarnDedupeHighest'],
packageRules: [ packageRules: [
{ {
// Require Dependency Dashboard Approval for major version bumps of these node packages // Ignore major version bumps for these node packages
matchManagers: ['npm'], matchManagers: ['npm'],
matchPackageNames: [ matchPackageNames: [
'tesseract.js', // Requires code changes 'tesseract.js', // Requires code changes
'react-hotkeys', // Requires code changes 'react-hotkeys', // Requires code changes
// Requires Webpacker upgrade or replacement // Requires Webpacker upgrade or replacement
'@svgr/webpack',
'@types/webpack', '@types/webpack',
'babel-loader', 'babel-loader',
'compression-webpack-plugin', 'compression-webpack-plugin',
@ -45,50 +41,50 @@
'react-router-dom', 'react-router-dom',
], ],
matchUpdateTypes: ['major'], matchUpdateTypes: ['major'],
dependencyDashboardApproval: true, enabled: false,
}, },
{ {
// Require Dependency Dashboard Approval for major version bumps of these Ruby packages // Ignore major version bumps for these Ruby packages
matchManagers: ['bundler'], matchManagers: ['bundler'],
matchPackageNames: [ matchPackageNames: [
'rack', // Needs to be synced with Rails version 'rack', // Needs to be synced with Rails version
'sprockets', // Requires manual upgrade https://github.com/rails/sprockets/blob/master/UPGRADING.md#guide-to-upgrading-from-sprockets-3x-to-4x
'strong_migrations', // Requires manual upgrade 'strong_migrations', // Requires manual upgrade
'sidekiq', // Requires manual upgrade 'sidekiq', // Requires manual upgrade
'sidekiq-unique-jobs', // Requires manual upgrades and sync with Sidekiq version 'sidekiq-unique-jobs', // Requires manual upgrades and sync with Sidekiq version
'redis', // Requires manual upgrade and sync with Sidekiq version 'redis', // Requires manual upgrade and sync with Sidekiq version
], ],
matchUpdateTypes: ['major'], matchUpdateTypes: ['major'],
dependencyDashboardApproval: true, enabled: false,
}, },
{ {
// 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'],
}, },
{ {
// Require Dependency Dashboard Approval for major & minor bumps for the ruby image, this needs to be synced with .ruby-version // Ignore major & minor bumps for the ruby image, this needs to be synced with .ruby-version
matchManagers: ['dockerfile'], matchManagers: ['dockerfile'],
matchPackageNames: ['moritzheiber/ruby-jemalloc'], matchPackageNames: ['moritzheiber/ruby-jemalloc'],
matchUpdateTypes: ['minor', 'major'], matchUpdateTypes: ['minor', 'major'],
dependencyDashboardApproval: true, enabled: false,
}, },
{ {
// Require Dependency Dashboard Approval for major bumps for the node image, this needs to be synced with .nvmrc // Ignore major bump for the node image, this needs to be synced with .nvmrc
matchManagers: ['dockerfile'], matchManagers: ['dockerfile'],
matchPackageNames: ['node'], matchPackageNames: ['node'],
matchUpdateTypes: ['major'], matchUpdateTypes: ['major'],
dependencyDashboardApproval: true, enabled: false,
}, },
{ {
// Require Dependency Dashboard Approval for major postgres bumps in the docker-compose file, as those break dev environments // Ignore major postgres bumps in the docker-compose file, as those break dev environments
matchManagers: ['docker-compose'], matchManagers: ['docker-compose'],
matchPackageNames: ['postgres'], matchPackageNames: ['postgres'],
matchUpdateTypes: ['major'], matchUpdateTypes: ['major'],
dependencyDashboardApproval: true, enabled: false,
}, },
{ {
// 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)',
@ -97,24 +93,14 @@
{ {
// 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', 'eslint-*', '@typescript-eslint/*'], matchPackageNames: ['eslint'],
matchPackagePrefixes: ['eslint-', '@typescript-eslint/'],
matchUpdateTypes: ['patch', 'minor'], matchUpdateTypes: ['patch', 'minor'],
groupName: 'eslint (non-major)', groupName: 'eslint (non-major)',
}, },
{
// Group actions/*-artifact in the same PR
matchManagers: ['github-actions'],
matchPackageNames: [
'actions/download-artifact',
'actions/upload-artifact',
],
matchUpdateTypes: ['major'],
groupName: 'artifact actions (major)',
},
{ {
// Update @types/* packages every week, with one grouped PR // Update @types/* packages every week, with one grouped PR
matchManagers: ['npm'], matchPackagePrefixes: '@types/',
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,27 +114,6 @@
], ],
groupName: null, // We dont want them to belong to any group groupName: null, // We dont want them to belong to any group
}, },
{
// Group all RuboCop packages with `rubocop` in the same PR
matchManagers: ['bundler'],
matchPackageNames: ['rubocop', 'rubocop-*'],
matchUpdateTypes: ['patch', 'minor'],
groupName: 'RuboCop (non-major)',
},
{
// Group all RSpec packages with `rspec` in the same PR
matchManagers: ['bundler'],
matchPackageNames: ['rspec', 'rspec-*'],
matchUpdateTypes: ['patch', 'minor'],
groupName: 'RSpec (non-major)',
},
{
// Group all opentelemetry-ruby packages in the same PR
matchManagers: ['bundler'],
matchPackageNames: ['opentelemetry-*'],
matchUpdateTypes: ['patch', 'minor'],
groupName: 'opentelemetry-ruby (non-major)',
},
// Add labels depending on package manager // Add labels depending on package manager
{ matchManagers: ['npm', 'nvm'], addLabels: ['javascript'] }, { matchManagers: ['npm', 'nvm'], addLabels: ['javascript'] },
{ matchManagers: ['bundler', 'ruby-version'], addLabels: ['ruby'] }, { matchManagers: ['bundler', 'ruby-version'], addLabels: ['ruby'] },

21
.github/stylelint-matcher.json vendored Normal file
View File

@ -0,0 +1,21 @@
{
"problemMatcher": [
{
"owner": "stylelint",
"pattern": [
{
"regexp": "^([^\\s].*)$",
"file": 1
},
{
"regexp": "^\\s+((\\d+):(\\d+))?\\s+(✖|×)\\s+(.*)\\s{2,}(.*)$",
"line": 2,
"column": 3,
"message": 5,
"code": 6,
"loop": true
}
]
}
]
}

View File

@ -4,16 +4,11 @@ on:
platforms: platforms:
required: true required: true
type: string type: string
cache:
type: boolean
default: true
use_native_arm64_builder: use_native_arm64_builder:
type: boolean type: boolean
push_to_images: push_to_images:
type: string type: string
version_prerelease: version_suffix:
type: string
version_metadata:
type: string type: string
flavor: flavor:
type: string type: string
@ -21,20 +16,18 @@ on:
type: string type: string
labels: labels:
type: string type: string
file_to_build:
type: string
jobs: jobs:
build-image: build-image:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v3
- uses: docker/setup-qemu-action@v3 - uses: docker/setup-qemu-action@v2
if: contains(inputs.platforms, 'linux/arm64') && !inputs.use_native_arm64_builder if: contains(inputs.platforms, 'linux/arm64') && !inputs.use_native_arm64_builder
- uses: docker/setup-buildx-action@v3 - uses: docker/setup-buildx-action@v2
id: buildx id: buildx
if: ${{ !(inputs.use_native_arm64_builder && contains(inputs.platforms, 'linux/arm64')) }} if: ${{ !(inputs.use_native_arm64_builder && contains(inputs.platforms, 'linux/arm64')) }}
@ -43,7 +36,7 @@ jobs:
run: | run: |
docker run --rm -d --name buildkitd -p 1234:1234 --privileged moby/buildkit:latest --addr tcp://0.0.0.0:1234 docker run --rm -d --name buildkitd -p 1234:1234 --privileged moby/buildkit:latest --addr tcp://0.0.0.0:1234
- uses: docker/setup-buildx-action@v3 - uses: docker/setup-buildx-action@v2
id: buildx-native id: buildx-native
if: inputs.use_native_arm64_builder && contains(inputs.platforms, 'linux/arm64') if: inputs.use_native_arm64_builder && contains(inputs.platforms, 'linux/arm64')
with: with:
@ -63,40 +56,39 @@ jobs:
- name: Log in to Docker Hub - name: Log in to Docker Hub
if: contains(inputs.push_to_images, 'tootsuite') if: contains(inputs.push_to_images, 'tootsuite')
uses: docker/login-action@v3 uses: docker/login-action@v2
with: with:
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@v2
with: with:
registry: ghcr.io registry: ghcr.io
username: ${{ github.actor }} username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }} password: ${{ secrets.GITHUB_TOKEN }}
- uses: docker/metadata-action@v5 - uses: docker/metadata-action@v4
id: meta id: meta
if: ${{ inputs.push_to_images != '' }} if: ${{ inputs.push_to_images != '' }}
with: with:
images: ${{ inputs.push_to_images }} images: ${{ inputs.push_to_images }}
# Only tag with latest when ran against the latest stable branch
# This needs to be updated after each minor version release
flavor: ${{ inputs.flavor }} flavor: ${{ inputs.flavor }}
tags: ${{ inputs.tags }} tags: ${{ inputs.tags }}
labels: ${{ inputs.labels }} labels: ${{ inputs.labels }}
- uses: docker/build-push-action@v6 - uses: docker/build-push-action@v4
with: with:
context: . context: .
file: ${{ inputs.file_to_build }} build-args: MASTODON_VERSION_SUFFIX=${{ inputs.version_suffix }}
build-args: |
MASTODON_VERSION_PRERELEASE=${{ inputs.version_prerelease }}
MASTODON_VERSION_METADATA=${{ inputs.version_metadata }}
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 }}
push: ${{ inputs.push_to_images != '' }} push: ${{ inputs.push_to_images != '' }}
tags: ${{ steps.meta.outputs.tags }} tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }} labels: ${{ steps.meta.outputs.labels }}
cache-from: ${{ inputs.cache && 'type=gha' || '' }} cache-from: type=gha
cache-to: ${{ inputs.cache && 'type=gha,mode=max' || '' }} cache-to: type=gha,mode=max

View File

@ -11,28 +11,26 @@ permissions:
jobs: jobs:
compute-suffix: compute-suffix:
runs-on: ubuntu-latest runs-on: ubuntu-latest
if: github.repository == 'mastodon/mastodon'
steps: steps:
- id: version_vars - id: version_vars
env: env:
TZ: Etc/UTC TZ: Etc/UTC
run: | run: |
echo mastodon_version_prerelease=nightly.$(date +'%Y-%m-%d')>> $GITHUB_OUTPUT echo mastodon_version_suffix=nightly-$(date +'%Y-%m-%d')>> $GITHUB_OUTPUT
outputs: outputs:
prerelease: ${{ steps.version_vars.outputs.mastodon_version_prerelease }} suffix: ${{ steps.version_vars.outputs.mastodon_version_suffix }}
build-image: build-image:
needs: compute-suffix needs: compute-suffix
uses: ./.github/workflows/build-container-image.yml uses: ./.github/workflows/build-container-image.yml
with: with:
file_to_build: Dockerfile
platforms: linux/amd64,linux/arm64 platforms: linux/amd64,linux/arm64
use_native_arm64_builder: true use_native_arm64_builder: true
cache: false
push_to_images: | push_to_images: |
tootsuite/mastodon tootsuite/mastodon
ghcr.io/mastodon/mastodon ghcr.io/mastodon/mastodon
version_prerelease: ${{ needs.compute-suffix.outputs.prerelease }} # The `+` is important here, result will be v4.1.2+nightly-2022-03-05
version_suffix: +${{ needs.compute-suffix.outputs.suffix }}
labels: | labels: |
org.opencontainers.image.description=Nightly build image used for testing purposes org.opencontainers.image.description=Nightly build image used for testing purposes
flavor: | flavor: |
@ -40,27 +38,5 @@ jobs:
tags: | tags: |
type=raw,value=edge type=raw,value=edge
type=raw,value=nightly type=raw,value=nightly
type=schedule,pattern=${{ needs.compute-suffix.outputs.prerelease }} type=schedule,pattern=${{ needs.compute-suffix.outputs.suffix }}
secrets: inherit
build-image-streaming:
needs: compute-suffix
uses: ./.github/workflows/build-container-image.yml
with:
file_to_build: streaming/Dockerfile
platforms: linux/amd64,linux/arm64
use_native_arm64_builder: true
cache: false
push_to_images: |
tootsuite/mastodon-streaming
ghcr.io/mastodon/mastodon-streaming
version_prerelease: ${{ needs.compute-suffix.outputs.prerelease }}
labels: |
org.opencontainers.image.description=Nightly build image used for testing purposes
flavor: |
latest=auto
tags: |
type=raw,value=edge
type=raw,value=nightly
type=schedule,pattern=${{ needs.compute-suffix.outputs.prerelease }}
secrets: inherit secrets: inherit

View File

@ -18,39 +18,22 @@ jobs:
steps: steps:
# Repository needs to be cloned so `git rev-parse` below works # Repository needs to be cloned so `git rev-parse` below works
- name: Clone repository - name: Clone repository
uses: actions/checkout@v4 uses: actions/checkout@v3
- 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_suffix=+pr-${{ github.event.pull_request.number }}-$(git rev-parse --short HEAD) >> $GITHUB_OUTPUT
outputs: outputs:
metadata: ${{ steps.version_vars.outputs.mastodon_version_metadata }} suffix: ${{ steps.version_vars.outputs.mastodon_version_suffix }}
build-image: build-image:
needs: compute-suffix needs: compute-suffix
uses: ./.github/workflows/build-container-image.yml uses: ./.github/workflows/build-container-image.yml
with: with:
file_to_build: Dockerfile
platforms: linux/amd64,linux/arm64 platforms: linux/amd64,linux/arm64
use_native_arm64_builder: true use_native_arm64_builder: true
push_to_images: | push_to_images: |
ghcr.io/mastodon/mastodon ghcr.io/mastodon/mastodon
version_metadata: ${{ needs.compute-suffix.outputs.metadata }} version_suffix: ${{ needs.compute-suffix.outputs.suffix }}
flavor: |
latest=auto
tags: |
type=ref,event=pr
secrets: inherit
build-image-streaming:
needs: compute-suffix
uses: ./.github/workflows/build-container-image.yml
with:
file_to_build: streaming/Dockerfile
platforms: linux/amd64,linux/arm64
use_native_arm64_builder: true
push_to_images: |
ghcr.io/mastodon/mastodon-streaming
version_metadata: ${{ needs.compute-suffix.outputs.metadata }}
flavor: | flavor: |
latest=auto latest=auto
tags: | tags: |

View File

@ -12,39 +12,13 @@ jobs:
build-image: build-image:
uses: ./.github/workflows/build-container-image.yml uses: ./.github/workflows/build-container-image.yml
with: with:
file_to_build: Dockerfile
platforms: linux/amd64,linux/arm64 platforms: linux/amd64,linux/arm64
use_native_arm64_builder: true use_native_arm64_builder: true
push_to_images: | push_to_images: |
tootsuite/mastodon tootsuite/mastodon
ghcr.io/mastodon/mastodon ghcr.io/mastodon/mastodon
# Do not use cache when building releases, so apt update is always ran and the release always contain the latest packages
cache: false
# Only tag with latest when ran against the latest stable branch
# 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.1.') }}
tags: |
type=pep440,pattern={{raw}}
type=pep440,pattern=v{{major}}.{{minor}}
secrets: inherit
build-image-streaming:
if: startsWith(github.ref, 'refs/tags/v4.3.')
uses: ./.github/workflows/build-container-image.yml
with:
file_to_build: streaming/Dockerfile
platforms: linux/amd64,linux/arm64
use_native_arm64_builder: true
push_to_images: |
tootsuite/mastodon-streaming
ghcr.io/mastodon/mastodon-streaming
# Do not use cache when building releases, so apt update is always ran and the release always contain the latest packages
cache: false
# Only tag with latest when ran against the latest stable branch
# This needs to be updated after each minor version release
flavor: |
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}}

View File

@ -1,64 +0,0 @@
name: Build security nightly container image
on:
workflow_dispatch:
permissions:
contents: read
packages: write
jobs:
compute-suffix:
runs-on: ubuntu-latest
if: github.repository == 'mastodon/mastodon'
steps:
- id: version_vars
env:
TZ: Etc/UTC
run: |
echo mastodon_version_prerelease=nightly.$(date --date='next day' +'%Y-%m-%d')-security>> $GITHUB_OUTPUT
outputs:
prerelease: ${{ steps.version_vars.outputs.mastodon_version_prerelease }}
build-image:
needs: compute-suffix
uses: ./.github/workflows/build-container-image.yml
with:
file_to_build: Dockerfile
platforms: linux/amd64,linux/arm64
use_native_arm64_builder: true
cache: false
push_to_images: |
tootsuite/mastodon
ghcr.io/mastodon/mastodon
version_prerelease: ${{ needs.compute-suffix.outputs.prerelease }}
labels: |
org.opencontainers.image.description=Nightly build image used for testing purposes
flavor: |
latest=auto
tags: |
type=raw,value=edge
type=raw,value=nightly
type=raw,value=${{ needs.compute-suffix.outputs.prerelease }}
secrets: inherit
build-image-streaming:
needs: compute-suffix
uses: ./.github/workflows/build-container-image.yml
with:
file_to_build: streaming/Dockerfile
platforms: linux/amd64,linux/arm64
use_native_arm64_builder: true
cache: false
push_to_images: |
tootsuite/mastodon-streaming
ghcr.io/mastodon/mastodon-streaming
version_prerelease: ${{ needs.compute-suffix.outputs.prerelease }}
labels: |
org.opencontainers.image.description=Nightly build image used for testing purposes
flavor: |
latest=auto
tags: |
type=raw,value=edge
type=raw,value=nightly
type=raw,value=${{ needs.compute-suffix.outputs.prerelease }}
secrets: inherit

View File

@ -1,19 +1,19 @@
name: Bundler Audit name: Bundler Audit
on: on:
merge_group:
push: push:
branches: branches-ignore:
- 'main' - 'dependabot/**'
- '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,17 +23,18 @@ 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@v3
- name: Install native Ruby dependencies
run: sudo apt-get install -y libicu-dev libidn11-dev
- name: Set up Ruby - name: Set up Ruby
uses: ruby/setup-ruby@v1 uses: ruby/setup-ruby@v1
with: with:
ruby-version: .ruby-version
bundler-cache: true bundler-cache: true
- name: Run bundler-audit - name: Run bundler-audit
run: bundle exec bundler-audit check --update run: bundle exec bundler-audit

View File

@ -2,13 +2,9 @@ name: Check i18n
on: on:
push: push:
branches: branches: [main]
- 'main'
- 'stable-*'
pull_request: pull_request:
branches: branches: [main]
- 'main'
- 'stable-*'
env: env:
RAILS_ENV: test RAILS_ENV: test
@ -21,13 +17,27 @@ jobs:
runs-on: ubuntu-22.04 runs-on: ubuntu-22.04
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v3
- name: Set up Ruby environment - name: Install system dependencies
uses: ./.github/actions/setup-ruby run: |
sudo apt-get update
sudo apt-get install -y libicu-dev libidn11-dev
- name: Set up Javascript environment - name: Set up Ruby
uses: ./.github/actions/setup-javascript uses: ruby/setup-ruby@v1
with:
ruby-version: .ruby-version
bundler-cache: true
- name: Set up Node.js
uses: actions/setup-node@v3
with:
cache: yarn
node-version-file: '.nvmrc'
- name: Install all yarn packages
run: yarn --frozen-lockfile
- name: Check for missing strings in English JSON - name: Check for missing strings in English JSON
run: | run: |

View File

@ -1,15 +1,11 @@
name: 'CodeQL' name: 'CodeQL'
on: on:
merge_group:
push: push:
branches: branches: ['main']
- 'main'
- 'stable-*'
pull_request: pull_request:
branches: # The branches below must be a subset of the branches above
- 'main' branches: ['main']
- 'stable-*'
schedule: schedule:
- cron: '22 6 * * 1' - cron: '22 6 * * 1'
@ -31,11 +27,11 @@ jobs:
steps: steps:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@v4 uses: actions/checkout@v3
# Initializes the CodeQL tools for scanning. # Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL - name: Initialize CodeQL
uses: github/codeql-action/init@v3 uses: github/codeql-action/init@v2
with: with:
languages: ${{ matrix.language }} languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file. # If you wish to specify custom queries, you can do so here or in a config file.
@ -48,7 +44,7 @@ jobs:
# Autobuild attempts to build any compiled languages (C/C++, C#, Go, or Java). # Autobuild attempts to build any compiled languages (C/C++, C#, Go, or Java).
# If this step fails, then you should remove it and run the build manually (see below) # If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild - name: Autobuild
uses: github/codeql-action/autobuild@v3 uses: github/codeql-action/autobuild@v2
# Command-line programs to run using the OS shell. # Command-line programs to run using the OS shell.
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
@ -61,6 +57,6 @@ jobs:
# ./location_of_script_within_repo/buildscript.sh # ./location_of_script_within_repo/buildscript.sh
- name: Perform CodeQL Analysis - name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v3 uses: github/codeql-action/analyze@v2
with: with:
category: '/language:${{matrix.language}}' category: '/language:${{matrix.language}}'

View File

@ -11,11 +11,10 @@ permissions:
jobs: jobs:
download-translations: download-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@v3
- name: Increase Git http.postBuffer - name: Increase Git http.postBuffer
# This is needed due to a bug in Ubuntu's cURL version? # This is needed due to a bug in Ubuntu's cURL version?
@ -26,7 +25,7 @@ jobs:
# Download the translation files from Crowdin # Download the translation files from Crowdin
- name: crowdin action - name: crowdin action
uses: crowdin/github-action@v2 uses: crowdin/github-action@v1
with: with:
upload_sources: false upload_sources: false
upload_translations: false upload_translations: false
@ -44,27 +43,33 @@ jobs:
run: sudo chown -R runner:docker . run: sudo chown -R runner:docker .
# This is needed to run the normalize step # This is needed to run the normalize step
- name: Set up Ruby environment - name: Install native Ruby dependencies
uses: ./.github/actions/setup-ruby run: sudo apt-get install -y libicu-dev libidn11-dev
- name: Set up Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: .ruby-version
bundler-cache: true
- name: Run i18n normalize task - name: Run i18n normalize task
run: bundle exec i18n-tasks normalize run: bundle exec i18n-tasks normalize
# 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@v7.0.1 uses: peter-evans/create-pull-request@v5.0.2
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

View File

@ -1,11 +1,9 @@
name: Crowdin / Upload translations name: Crowdin / Upload translations
on: on:
merge_group:
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
@ -19,14 +17,13 @@ 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@v3
- name: crowdin action - name: crowdin action
uses: crowdin/github-action@v2 uses: crowdin/github-action@v1
with: with:
upload_sources: true upload_sources: true
upload_translations: false upload_translations: false

View File

@ -1,22 +0,0 @@
name: Check formatting
on:
merge_group:
push:
branches:
- 'main'
- 'stable-*'
pull_request:
jobs:
lint:
runs-on: ubuntu-latest
steps:
- name: Clone repository
uses: actions/checkout@v4
- name: Set up Javascript environment
uses: ./.github/actions/setup-javascript
- name: Check formatting with Prettier
run: yarn format:check

View File

@ -1,10 +1,9 @@
name: CSS Linting name: CSS Linting
on: on:
merge_group:
push: push:
branches: branches-ignore:
- 'main' - 'dependabot/**'
- 'stable-*' - 'renovate/**'
paths: paths:
- 'package.json' - 'package.json'
- 'yarn.lock' - 'yarn.lock'
@ -34,10 +33,20 @@ jobs:
steps: steps:
- name: Clone repository - name: Clone repository
uses: actions/checkout@v4 uses: actions/checkout@v3
- name: Set up Javascript environment - name: Set up Node.js
uses: ./.github/actions/setup-javascript uses: actions/setup-node@v3
with:
cache: yarn
node-version-file: '.nvmrc'
- name: Install all yarn packages
run: yarn --frozen-lockfile
- uses: xt0rted/stylelint-problem-matcher@v1
- run: echo "::add-matcher::.github/stylelint-matcher.json"
- name: Stylelint - name: Stylelint
run: yarn lint:css -f github run: yarn lint:sass

View File

@ -1,10 +1,9 @@
name: Haml Linting name: Haml Linting
on: on:
merge_group:
push: push:
branches: branches-ignore:
- 'main' - 'dependabot/**'
- 'stable-*' - 'renovate/**'
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'
@ -27,20 +26,22 @@ 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@v3
- name: Install native Ruby dependencies
run: |
sudo apt-get update
sudo apt-get install -y libicu-dev libidn11-dev
- name: Set up Ruby - name: Set up Ruby
uses: ruby/setup-ruby@v1 uses: ruby/setup-ruby@v1
with: with:
ruby-version: .ruby-version
bundler-cache: true bundler-cache: true
- name: Run haml-lint - name: Run haml-lint
run: | run: |
echo "::add-matcher::.github/workflows/haml-lint-problem-matcher.json" echo "::add-matcher::.github/workflows/haml-lint-problem-matcher.json"
bundle exec haml-lint --reporter github bundle exec haml-lint

View File

@ -1,10 +1,9 @@
name: JavaScript Linting name: JavaScript Linting
on: on:
merge_group:
push: push:
branches: branches-ignore:
- 'main' - 'dependabot/**'
- 'stable-*' - 'renovate/**'
paths: paths:
- 'package.json' - 'package.json'
- 'yarn.lock' - 'yarn.lock'
@ -38,10 +37,16 @@ jobs:
steps: steps:
- name: Clone repository - name: Clone repository
uses: actions/checkout@v4 uses: actions/checkout@v3
- name: Set up Javascript environment - name: Set up Node.js
uses: ./.github/actions/setup-javascript uses: actions/setup-node@v3
with:
cache: yarn
node-version-file: '.nvmrc'
- name: Install all yarn packages
run: yarn --frozen-lockfile
- name: ESLint - name: ESLint
run: yarn lint:js --max-warnings 0 run: yarn lint:js --max-warnings 0

44
.github/workflows/lint-json.yml vendored Normal file
View File

@ -0,0 +1,44 @@
name: JSON Linting
on:
push:
branches-ignore:
- 'dependabot/**'
- 'renovate/**'
paths:
- 'package.json'
- 'yarn.lock'
- '.nvmrc'
- '.prettier*'
- '**/*.json'
- '.github/workflows/lint-json.yml'
- '!app/javascript/mastodon/locales/*.json'
pull_request:
paths:
- 'package.json'
- 'yarn.lock'
- '.nvmrc'
- '.prettier*'
- '**/*.json'
- '.github/workflows/lint-json.yml'
- '!app/javascript/mastodon/locales/*.json'
jobs:
lint:
runs-on: ubuntu-latest
steps:
- name: Clone repository
uses: actions/checkout@v3
- name: Set up Node.js
uses: actions/setup-node@v3
with:
cache: yarn
node-version-file: '.nvmrc'
- name: Install all yarn packages
run: yarn --frozen-lockfile
- name: Prettier
run: yarn lint:json

44
.github/workflows/lint-md.yml vendored Normal file
View File

@ -0,0 +1,44 @@
name: Markdown Linting
on:
push:
branches-ignore:
- 'dependabot/**'
- 'renovate/**'
paths:
- '.github/workflows/lint-md.yml'
- '.nvmrc'
- '.prettier*'
- '**/*.md'
- '!AUTHORS.md'
- 'package.json'
- 'yarn.lock'
pull_request:
paths:
- '.github/workflows/lint-md.yml'
- '.nvmrc'
- '.prettier*'
- '**/*.md'
- '!AUTHORS.md'
- 'package.json'
- 'yarn.lock'
jobs:
lint:
runs-on: ubuntu-latest
steps:
- name: Clone repository
uses: actions/checkout@v3
- name: Set up Node.js
uses: actions/setup-node@v3
with:
cache: yarn
node-version-file: '.nvmrc'
- name: Install all yarn packages
run: yarn --frozen-lockfile
- name: Prettier
run: yarn lint:md

View File

@ -1,10 +1,9 @@
name: Ruby Linting name: Ruby Linting
on: on:
merge_group:
push: push:
branches: branches-ignore:
- 'main' - 'dependabot/**'
- 'stable-*' - 'renovate/**'
paths: paths:
- 'Gemfile*' - 'Gemfile*'
- '.rubocop*.yml' - '.rubocop*.yml'
@ -28,24 +27,25 @@ 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@v3
- name: Install native Ruby dependencies
run: sudo apt-get install -y libicu-dev libidn11-dev
- name: Set up Ruby - name: Set up Ruby
uses: ruby/setup-ruby@v1 uses: ruby/setup-ruby@v1
with: with:
ruby-version: .ruby-version
bundler-cache: true 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: bin/rubocop run: bundle exec 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: bin/brakeman run: bundle exec brakeman

46
.github/workflows/lint-yml.yml vendored Normal file
View File

@ -0,0 +1,46 @@
name: YML Linting
on:
push:
branches-ignore:
- 'dependabot/**'
- 'renovate/**'
paths:
- 'package.json'
- 'yarn.lock'
- '.nvmrc'
- '.prettier*'
- '**/*.yaml'
- '**/*.yml'
- '.github/workflows/lint-yml.yml'
- '!config/locales/*.yml'
pull_request:
paths:
- 'package.json'
- 'yarn.lock'
- '.nvmrc'
- '.prettier*'
- '**/*.yaml'
- '**/*.yml'
- '.github/workflows/lint-yml.yml'
- '!config/locales/*.yml'
jobs:
lint:
runs-on: ubuntu-latest
steps:
- name: Clone repository
uses: actions/checkout@v3
- name: Set up Node.js
uses: actions/setup-node@v3
with:
cache: yarn
node-version-file: '.nvmrc'
- name: Install all yarn packages
run: yarn --frozen-lockfile
- name: Prettier
run: yarn lint:yml

View File

@ -10,7 +10,6 @@ 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 }}
@ -18,7 +17,7 @@ jobs:
steps: steps:
- name: Check for merge conflicts - name: Check for merge conflicts
uses: eps1lon/actions-label-merge-conflict@v3 uses: eps1lon/actions-label-merge-conflict@releases/2.x
with: with:
dirtyLabel: 'rebase needed :construction:' dirtyLabel: 'rebase needed :construction:'
repoToken: '${{ secrets.GITHUB_TOKEN }}' repoToken: '${{ secrets.GITHUB_TOKEN }}'

View File

@ -7,7 +7,6 @@ on:
- .github/workflows/build-releases.yml - .github/workflows/build-releases.yml
- .github/workflows/test-image-build.yml - .github/workflows/test-image-build.yml
- Dockerfile - Dockerfile
- streaming/Dockerfile
permissions: permissions:
contents: read contents: read
@ -19,17 +18,4 @@ jobs:
uses: ./.github/workflows/build-container-image.yml uses: ./.github/workflows/build-container-image.yml
with: with:
file_to_build: Dockerfile
platforms: linux/amd64 # Testing only on native platform so it is performant platforms: linux/amd64 # Testing only on native platform so it is performant
cache: true
build-image-streaming:
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}-streaming
cancel-in-progress: true
uses: ./.github/workflows/build-container-image.yml
with:
file_to_build: streaming/Dockerfile
platforms: linux/amd64 # Testing only on native platform so it is performant
cache: true

View File

@ -1,10 +1,9 @@
name: JavaScript Testing name: JavaScript Testing
on: on:
merge_group:
push: push:
branches: branches-ignore:
- 'main' - 'dependabot/**'
- 'stable-*' - 'renovate/**'
paths: paths:
- 'package.json' - 'package.json'
- 'yarn.lock' - 'yarn.lock'
@ -34,10 +33,16 @@ jobs:
steps: steps:
- name: Clone repository - name: Clone repository
uses: actions/checkout@v4 uses: actions/checkout@v3
- name: Set up Javascript environment - name: Set up Node.js
uses: ./.github/actions/setup-javascript uses: actions/setup-node@v3
with:
cache: yarn
node-version-file: '.nvmrc'
- name: JavaScript testing - name: Install all yarn packages
run: yarn --frozen-lockfile
- name: Jest testing
run: yarn jest --reporters github-actions summary run: yarn jest --reporters github-actions summary

View File

@ -0,0 +1,111 @@
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@v3
- name: Install native Ruby dependencies
run: |
sudo apt-get update
sudo apt-get install -y libicu-dev libidn11-dev
- name: Set up bundler cache
uses: ruby/setup-ruby@v1
with:
ruby-version: .ruby-version
bundler-cache: true
- name: Create database
run: './bin/rails db:create'
- name: Run migrations up to v2.0.0
run: './bin/rails db:migrate VERSION=20171010025614'
- name: Populate database with test data
run: './bin/rails tests:migrations:populate_v2'
- name: Run migrations up to v2.4.0
run: './bin/rails db:migrate VERSION=20180514140000'
- name: Populate database with test data
run: './bin/rails tests:migrations:populate_v2_4'
- name: Run migrations up to v2.4.3
run: './bin/rails db:migrate VERSION=20180707154237'
- name: Populate database with test data
run: './bin/rails tests:migrations:populate_v2_4_3'
- name: Run all remaining migrations
run: './bin/rails db:migrate'
- name: Check migration result
run: './bin/rails tests:migrations:check_database'

View File

@ -0,0 +1,119 @@
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@v3
- name: Install native Ruby dependencies
run: |
sudo apt-get update
sudo apt-get install -y libicu-dev libidn11-dev
- name: Set up bundler cache
uses: ruby/setup-ruby@v1
with:
ruby-version: .ruby-version
bundler-cache: true
- name: Create database
run: './bin/rails db:create'
- name: Run migrations up to v2.0.0
run: './bin/rails db:migrate VERSION=20171010025614'
- name: Populate database with test data
run: './bin/rails tests:migrations:populate_v2'
- name: Run pre-deployment migrations up to v2.4.0
run: './bin/rails db:migrate VERSION=20180514140000'
env:
SKIP_POST_DEPLOYMENT_MIGRATIONS: true
- name: Populate database with test data
run: './bin/rails tests:migrations:populate_v2_4'
- name: Run migrations up to v2.4.3
run: './bin/rails db:migrate VERSION=20180707154237'
env:
SKIP_POST_DEPLOYMENT_MIGRATIONS: true
- name: Populate database with test data
run: './bin/rails tests:migrations:populate_v2_4_3'
- 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'

View File

@ -1,93 +0,0 @@
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
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

View File

@ -1,11 +1,10 @@
name: Ruby Testing name: Ruby Testing
on: on:
merge_group:
push: push:
branches: branches-ignore:
- 'main' - 'dependabot/**'
- 'stable-*' - 'renovate/**'
pull_request: pull_request:
env: env:
@ -29,47 +28,42 @@ jobs:
env: env:
RAILS_ENV: ${{ matrix.mode }} RAILS_ENV: ${{ matrix.mode }}
BUNDLE_WITH: ${{ matrix.mode }} BUNDLE_WITH: ${{ matrix.mode }}
SECRET_KEY_BASE_DUMMY: 1 OTP_SECRET: precompile_placeholder
SECRET_KEY_BASE: precompile_placeholder
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v3
- name: Set up Ruby environment - name: Set up Node.js
uses: ./.github/actions/setup-ruby uses: actions/setup-node@v3
- name: Set up Javascript environment
uses: ./.github/actions/setup-javascript
with: with:
onlyProduction: 'true' cache: yarn
node-version-file: '.nvmrc'
- name: Cache assets from compilation - name: Install native Ruby dependencies
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
run: |-
bin/rails assets:precompile
- name: Archive asset artifacts
run: | run: |
tar --exclude={"*.br","*.gz"} -zcf artifacts.tar.gz public/assets public/packs* sudo apt-get update
sudo apt-get install -y libicu-dev libidn11-dev
- uses: actions/upload-artifact@v4 - name: Set up bundler cache
uses: ruby/setup-ruby@v1
with:
ruby-version: .ruby-version
bundler-cache: true
- run: yarn --frozen-lockfile --production
- name: Precompile assets
# Previously had set this, but it's not supported
# export NODE_OPTIONS=--openssl-legacy-provider
run: |-
./bin/rails assets:precompile
- uses: actions/upload-artifact@v3
if: matrix.mode == 'test' if: matrix.mode == 'test'
with: with:
path: |- path: |-
./artifacts.tar.gz ./public/assets
./public/packs-test
name: ${{ github.sha }} name: ${{ github.sha }}
retention-days: 0 retention-days: 0
@ -87,9 +81,9 @@ jobs:
POSTGRES_USER: postgres POSTGRES_USER: postgres
options: >- options: >-
--health-cmd pg_isready --health-cmd pg_isready
--health-interval 10ms --health-interval 10s
--health-timeout 3s --health-timeout 5s
--health-retries 50 --health-retries 5
ports: ports:
- 5432:5432 - 5432:5432
@ -97,9 +91,9 @@ jobs:
image: redis:7-alpine image: redis:7-alpine
options: >- options: >-
--health-cmd "redis-cli ping" --health-cmd "redis-cli ping"
--health-interval 10ms --health-interval 10s
--health-timeout 3s --health-timeout 5s
--health-retries 50 --health-retries 5
ports: ports:
- 6379:6379 - 6379:6379
@ -107,7 +101,7 @@ jobs:
DB_HOST: localhost DB_HOST: localhost
DB_USER: postgres DB_USER: postgres
DB_PASS: postgres DB_PASS: postgres
DISABLE_SIMPLECOV: ${{ matrix.ruby-version != '.ruby-version' }} DISABLE_SIMPLECOV: true
RAILS_ENV: test RAILS_ENV: test
ALLOW_NOPAM: true ALLOW_NOPAM: true
PAM_ENABLED: true PAM_ENABLED: true
@ -118,147 +112,47 @@ jobs:
SAML_ENABLED: true SAML_ENABLED: true
CAS_ENABLED: true CAS_ENABLED: true
BUNDLE_WITH: 'pam_authentication test' BUNDLE_WITH: 'pam_authentication test'
GITHUB_RSPEC: ${{ matrix.ruby-version == '.ruby-version' && github.event.pull_request && 'true' }} CI_JOBS: ${{ matrix.ci_job }}/4
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
ruby-version: ruby-version:
- '3.0'
- '3.1' - '3.1'
- '3.2'
- '.ruby-version' - '.ruby-version'
ci_job:
- 1
- 2
- 3
- 4
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v3
- uses: actions/download-artifact@v4 - uses: actions/download-artifact@v3
with: with:
path: './' path: './public'
name: ${{ github.sha }} name: ${{ github.sha }}
- name: Expand archived asset artifacts - name: Update package index
run: | run: sudo apt-get update
tar xvzf artifacts.tar.gz
- name: Set up Ruby environment - name: Install native Ruby dependencies
uses: ./.github/actions/setup-ruby run: sudo apt-get install -y libicu-dev libidn11-dev
- name: Install additional system dependencies
run: sudo apt-get install -y ffmpeg imagemagick libpam-dev
- name: Set up bundler cache
uses: ruby/setup-ruby@v1
with: with:
ruby-version: ${{ matrix.ruby-version}} ruby-version: ${{ matrix.ruby-version}}
additional-system-dependencies: ffmpeg libpam-dev bundler-cache: true
- name: Load database schema
run: |
bin/rails db:setup
bin/flatware fan bin/rails db:test:prepare
- 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
if: matrix.ruby-version == '.ruby-version'
uses: codecov/codecov-action@v4
with:
files: coverage/lcov/*.lcov
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
test-libvips:
name: Libvips tests
runs-on: ubuntu-24.04
needs:
- build
services:
postgres:
image: postgres:14-alpine
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: ${{ matrix.ruby-version != '.ruby-version' }}
RAILS_ENV: test
ALLOW_NOPAM: true
PAM_ENABLED: true
PAM_DEFAULT_SERVICE: pam_test
PAM_CONTROLLED_SERVICE: pam_test_controlled
OIDC_ENABLED: true
OIDC_SCOPE: read
SAML_ENABLED: true
CAS_ENABLED: true
BUNDLE_WITH: 'pam_authentication test'
GITHUB_RSPEC: ${{ matrix.ruby-version == '.ruby-version' && github.event.pull_request && 'true' }}
MASTODON_USE_LIBVIPS: true
strategy:
fail-fast: false
matrix:
ruby-version:
- '3.1'
- '3.2'
- '.ruby-version'
steps:
- uses: actions/checkout@v4
- uses: actions/download-artifact@v4
with:
path: './'
name: ${{ github.sha }}
- name: Expand archived asset artifacts
run: |
tar xvzf artifacts.tar.gz
- name: Set up Ruby environment
uses: ./.github/actions/setup-ruby
with:
ruby-version: ${{ matrix.ruby-version}}
additional-system-dependencies: ffmpeg libpam-dev libyaml-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 attachment_processing - run: bundle exec rake rspec_chunked
- name: Upload coverage reports to Codecov
if: matrix.ruby-version == '.ruby-version'
uses: codecov/codecov-action@v4
with:
files: coverage/lcov/mastodon.lcov
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
test-e2e: test-e2e:
name: End to End testing name: End to End testing
@ -275,9 +169,9 @@ jobs:
POSTGRES_USER: postgres POSTGRES_USER: postgres
options: >- options: >-
--health-cmd pg_isready --health-cmd pg_isready
--health-interval 10ms --health-interval 10s
--health-timeout 3s --health-timeout 5s
--health-retries 50 --health-retries 5
ports: ports:
- 5432:5432 - 5432:5432
@ -285,9 +179,9 @@ jobs:
image: redis:7-alpine image: redis:7-alpine
options: >- options: >-
--health-cmd "redis-cli ping" --health-cmd "redis-cli ping"
--health-interval 10ms --health-interval 10s
--health-timeout 3s --health-timeout 5s
--health-retries 50 --health-retries 5
ports: ports:
- 6379:6379 - 6379:6379
@ -298,173 +192,61 @@ jobs:
DISABLE_SIMPLECOV: true DISABLE_SIMPLECOV: true
RAILS_ENV: test RAILS_ENV: test
BUNDLE_WITH: test BUNDLE_WITH: test
LOCAL_DOMAIN: localhost:3000
LOCAL_HTTPS: false
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
ruby-version: ruby-version:
- '3.0'
- '3.1' - '3.1'
- '3.2'
- '.ruby-version' - '.ruby-version'
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v3
- uses: actions/download-artifact@v4 - uses: actions/download-artifact@v3
with: with:
path: './' path: './public'
name: ${{ github.sha }} name: ${{ github.sha }}
- name: Expand archived asset artifacts - name: Update package index
run: | run: sudo apt-get update
tar xvzf artifacts.tar.gz
- name: Set up Ruby environment - name: Set up Node.js
uses: ./.github/actions/setup-ruby uses: actions/setup-node@v3
with:
cache: yarn
node-version-file: '.nvmrc'
- name: Install native Ruby dependencies
run: sudo apt-get install -y libicu-dev libidn11-dev
- name: Install additional system dependencies
run: sudo apt-get install -y ffmpeg imagemagick
- name: Set up bundler cache
uses: ruby/setup-ruby@v1
with: with:
ruby-version: ${{ matrix.ruby-version}} ruby-version: ${{ matrix.ruby-version}}
additional-system-dependencies: ffmpeg bundler-cache: true
- name: Set up Javascript environment - run: yarn --frozen-lockfile
uses: ./.github/actions/setup-javascript
- 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 spec/system --tag streaming --tag js - run: bundle exec rake spec:system
- name: Archive logs - name: Archive logs
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v3
if: failure() if: failure()
with: with:
name: e2e-logs-${{ matrix.ruby-version }} name: e2e-logs-${{ matrix.ruby-version }}
path: log/ path: log/
- name: Archive test screenshots - name: Archive test screenshots
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v3
if: failure() if: failure()
with: with:
name: e2e-screenshots name: e2e-screenshots
path: tmp/capybara/ path: tmp/screenshots/
test-search:
name: Elastic Search integration testing
runs-on: ubuntu-latest
needs:
- build
services:
postgres:
image: postgres:14-alpine
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
elasticsearch:
image: ${{ contains(matrix.search-image, 'elasticsearch') && matrix.search-image || '' }}
env:
discovery.type: single-node
xpack.security.enabled: false
options: >-
--health-cmd "curl http://localhost:9200/_cluster/health"
--health-interval 2s
--health-timeout 3s
--health-retries 50
ports:
- 9200:9200
opensearch:
image: ${{ contains(matrix.search-image, 'opensearch') && matrix.search-image || '' }}
env:
discovery.type: single-node
DISABLE_INSTALL_DEMO_CONFIG: true
DISABLE_SECURITY_PLUGIN: true
options: >-
--health-cmd "curl http://localhost:9200/_cluster/health"
--health-interval 2s
--health-timeout 3s
--health-retries 50
ports:
- 9200:9200
env:
DB_HOST: localhost
DB_USER: postgres
DB_PASS: postgres
DISABLE_SIMPLECOV: true
RAILS_ENV: test
BUNDLE_WITH: test
ES_ENABLED: true
ES_HOST: localhost
ES_PORT: 9200
strategy:
fail-fast: false
matrix:
ruby-version:
- '3.1'
- '3.2'
- '.ruby-version'
search-image:
- docker.elastic.co/elasticsearch/elasticsearch:7.17.13
include:
- ruby-version: '.ruby-version'
search-image: docker.elastic.co/elasticsearch/elasticsearch:8.10.2
- ruby-version: '.ruby-version'
search-image: opensearchproject/opensearch:2
steps:
- uses: actions/checkout@v4
- uses: actions/download-artifact@v4
with:
path: './'
name: ${{ github.sha }}
- name: Set up Ruby environment
uses: ./.github/actions/setup-ruby
with:
ruby-version: ${{ matrix.ruby-version}}
additional-system-dependencies: ffmpeg
- name: Set up Javascript environment
uses: ./.github/actions/setup-javascript
- name: Load database schema
run: './bin/rails db:create db:schema:load db:seed'
- run: bin/rspec --tag search
- name: Archive logs
uses: actions/upload-artifact@v4
if: failure()
with:
name: test-search-logs-${{ matrix.ruby-version }}
path: log/
- name: Archive test screenshots
uses: actions/upload-artifact@v4
if: failure()
with:
name: test-search-screenshots
path: tmp/capybara/

19
.gitignore vendored
View File

@ -24,12 +24,16 @@
/public/packs-test /public/packs-test
.env .env
.env.production .env.production
.env.development
/node_modules/ /node_modules/
/build/ /build/
# Ignore Vagrant files # Ignore Vagrant files
.vagrant/ .vagrant/
# Ignore Capistrano customizations
/config/deploy/*
# Ignore IDE files # Ignore IDE files
.vscode/ .vscode/
.idea/ .idea/
@ -54,23 +58,8 @@ npm-debug.log
yarn-error.log yarn-error.log
yarn-debug.log yarn-debug.log
# From https://yarnpkg.com/getting-started/qa#which-files-should-be-gitignored
.pnp.*
.yarn/*
!.yarn/patches
!.yarn/plugins
!.yarn/releases
!.yarn/sdks
!.yarn/versions
# Ignore vagrant log files # Ignore vagrant log files
*-cloudimg-console.log *-cloudimg-console.log
# Ignore Docker option files # Ignore Docker option files
docker-compose.override.yml docker-compose.override.yml
# Ignore dotenv .local files
.env*.local
# Ignore local-only rspec configuration
.rspec-local

View File

@ -1,5 +1,8 @@
inherits_from: .haml-lint_todo.yml
exclude: exclude:
- 'vendor/**/*' - 'vendor/**/*'
- lib/templates/haml/scaffold/_form.html.haml
require: require:
- ./lib/linter/haml_middle_dot.rb - ./lib/linter/haml_middle_dot.rb
@ -9,7 +12,3 @@ linters:
enabled: true enabled: true
MiddleDot: MiddleDot:
enabled: true enabled: true
LineLength:
max: 300
ViewLength:
max: 200 # Override default value of 100 inherited from rubocop

47
.haml-lint_todo.yml Normal file
View File

@ -0,0 +1,47 @@
# This configuration was generated by
# `haml-lint --auto-gen-config`
# on 2023-07-20 09:47:50 -0400 using Haml-Lint version 0.48.0.
# The point is for the user to remove these configuration records
# one by one as the lints are removed from the code base.
# Note that changes in the inspected code, or installation of new
# versions of Haml-Lint, may require this file to be generated again.
linters:
# Offense count: 951
LineLength:
enabled: false
# Offense count: 22
UnnecessaryStringOutput:
enabled: false
# Offense count: 57
RuboCop:
enabled: false
# Offense count: 3
ViewLength:
exclude:
- 'app/views/admin/accounts/show.html.haml'
- 'app/views/admin/reports/show.html.haml'
- 'app/views/disputes/strikes/show.html.haml'
# Offense count: 32
InstanceVariables:
exclude:
- 'app/views/admin/reports/_actions.html.haml'
- 'app/views/admin/roles/_form.html.haml'
- 'app/views/admin/webhooks/_form.html.haml'
- 'app/views/auth/registrations/_status.html.haml'
- 'app/views/auth/sessions/two_factor/_otp_authentication_form.html.haml'
- 'app/views/authorize_interactions/_post_follow_actions.html.haml'
- 'app/views/invites/_form.html.haml'
- 'app/views/relationships/_account.html.haml'
- 'app/views/shared/_og.html.haml'
# Offense count: 3
IdNames:
exclude:
- 'app/views/authorize_interactions/error.html.haml'
- 'app/views/oauth/authorizations/error.html.haml'
- 'app/views/shared/_error_messages.html.haml'

View File

@ -1 +1,4 @@
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
yarn lint-staged yarn lint-staged

19
.nanoignore Normal file
View File

@ -0,0 +1,19 @@
.DS_Store
.git/
.gitignore
.bundle/
.cache/
config/deploy/*
coverage
docs/
.env
log/*.log
neo4j/
node_modules/
public/assets/
public/system/
spec/
tmp/
.vagrant/
vendor/bundle/

2
.nvmrc
View File

@ -1 +1 @@
20.17 16.20

View File

@ -31,6 +31,9 @@
# Ignore Vagrant files # Ignore Vagrant files
.vagrant/ .vagrant/
# Ignore Capistrano customizations
/config/deploy/*
# Ignore IDE files # Ignore IDE files
.vscode/ .vscode/
.idea/ .idea/
@ -54,13 +57,6 @@
# Ignore Docker option files # Ignore Docker option files
docker-compose.override.yml docker-compose.override.yml
# Ignore public
/public/assets
/public/emoji
/public/packs
/public/packs-test
/public/system
# Ignore emoji map file # Ignore emoji map file
/app/javascript/mastodon/features/emoji/emoji_map.json /app/javascript/mastodon/features/emoji/emoji_map.json
@ -80,6 +76,3 @@ app/javascript/styles/mastodon/reset.scss
# Ignore the generated AUTHORS.md # Ignore the generated AUTHORS.md
AUTHORS.md AUTHORS.md
# Process a few selected JS files
!lint-staged.config.js

1
.profile Normal file
View File

@ -0,0 +1 @@
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
View File

@ -1,2 +1,3 @@
--color --color
--require spec_helper --require spec_helper
--format Fuubar

View File

@ -1,27 +1,7 @@
--- # Can be removed once all rules are addressed or moved to this file as documented overrides
AllCops: inherit_from: .rubocop_todo.yml
CacheRootDirectory: tmp
DisplayStyleGuide: true
Exclude:
- Vagrantfile
- config/initializers/json_ld*
- lib/mastodon/migration_helpers.rb
ExtraDetails: true
NewCops: enable
TargetRubyVersion: 3.1 # 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
@ -29,6 +9,194 @@ inherit_mode:
require: require:
- rubocop-rails - rubocop-rails
- rubocop-rspec - rubocop-rspec
- rubocop-rspec_rails
- rubocop-performance - rubocop-performance
- rubocop-capybara - rubocop-capybara
- ./lib/linter/rubocop_middle_dot
AllCops:
TargetRubyVersion: 3.0 # 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/**/*'
- 'lib/json_ld/*' # Generated files
- '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: 320 # Default of 120 causes a duplicate entry in generated todo file
# Reason:
# https://docs.rubocop.org/rubocop/cops_lint.html#lintuselessaccessmodifier
Lint/UselessAccessModifier:
ContextCreatingMethods:
- class_methods
## 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'
- db/*migrate/**/*
# Reason:
# https://docs.rubocop.org/rubocop/cops_metrics.html#metricsblocknesting
Metrics/BlockNesting:
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
- db/*migrate/**/*
# Reason:
# https://docs.rubocop.org/rubocop/cops_metrics.html#metricsparameterlists
Metrics/ParameterLists:
CountKeywordArgs: false
# 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: Allowed in `tootctl` CLI code and in boot ENV checker
# https://docs.rubocop.org/rubocop-rails/cops_rails.html#railsexit
Rails/Exit:
Exclude:
- 'config/boot.rb'
- 'lib/mastodon/cli/*.rb'
# Reason: Some single letter camel case files shouldn't be split
# https://docs.rubocop.org/rubocop-rspec/cops_rspec.html#rspecfilepath
RSpec/FilePath:
CustomTransform:
ActivityPub: activitypub # Ignore the snake_case due to the amount of files to rename
DeepL: deepl
FetchOEmbedService: fetch_oembed_service
JsonLdHelper: jsonld_helper
OEmbedController: oembed_controller
OStatus: ostatus
NodeInfoController: nodeinfo_controller # NodeInfo isn't snake_cased for any of the instances
Exclude:
- 'spec/config/initializers/rack_attack_spec.rb' # namespaces usually have separate folder
- 'spec/lib/sanitize_config_spec.rb' # namespaces usually have separate folder
# 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: Prevailing style uses numeric status codes, matches Rails/HttpStatus
# https://docs.rubocop.org/rubocop-rspec/cops_rspec_rails.html#rspecrailshttpstatus
RSpec/Rails/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: Enforce modern Ruby style
# https://docs.rubocop.org/rubocop/cops_style.html#stylehashsyntax
Style/HashSyntax:
EnforcedStyle: ruby19_no_mixed_keys
# 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: Overridden to reduce implicit StandardError rescues
# https://docs.rubocop.org/rubocop/cops_style.html#stylerescuestandarderror
Style/RescueStandardError:
EnforcedStyle: implicit
# Reason: Simplify some spec layouts
# https://docs.rubocop.org/rubocop/cops_style.html#stylesemicolon
Style/Semicolon:
AllowAsExpressionSeparator: true
# 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

View File

@ -1,6 +0,0 @@
---
require:
- ../lib/linter/rubocop_middle_dot
Style/MiddleDot:
Enabled: true

View File

@ -1,6 +0,0 @@
---
Layout/FirstHashElementIndentation:
EnforcedStyle: consistent
Layout/LineLength:
Max: 300 # Default of 120 causes a duplicate entry in generated todo file

View File

@ -1,23 +0,0 @@
---
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

View File

@ -1,3 +0,0 @@
---
Naming/BlockForwarding:
EnforcedStyle: explicit

View File

@ -1,23 +0,0 @@
---
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

View File

@ -1,27 +0,0 @@
---
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

View File

@ -1,3 +0,0 @@
---
RSpecRails/HttpStatus:
EnforcedStyle: numeric

View File

@ -1,24 +0,0 @@
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: []

View File

@ -1,47 +0,0 @@
---
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

View File

@ -1,20 +1,143 @@
# This configuration was generated by # This configuration was generated by
# `rubocop --auto-gen-config --auto-gen-only-exclude --no-offense-counts --no-auto-gen-timestamp` # `rubocop --auto-gen-config --auto-gen-only-exclude --no-exclude-limit --no-offense-counts --no-auto-gen-timestamp`
# using RuboCop version 1.66.1. # using RuboCop version 1.54.2.
# 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
# versions of RuboCop, may require this file to be generated again. # versions of RuboCop, may require this file to be generated again.
# This cop supports safe autocorrection (--autocorrect).
# Configuration parameters: TreatCommentsAsGroupSeparators, ConsiderPunctuation, Include.
# Include: **/*.gemfile, **/Gemfile, **/gems.rb
Bundler/OrderedGems:
Exclude:
- 'Gemfile'
# This cop supports safe autocorrection (--autocorrect).
# Configuration parameters: EnforcedStyle, IndentationWidth.
# SupportedStyles: with_first_argument, with_fixed_indentation
Layout/ArgumentAlignment:
Exclude:
- 'config/initializers/cors.rb'
- 'config/initializers/session_store.rb'
# This cop supports safe autocorrection (--autocorrect).
# Configuration parameters: AllowMultipleStyles, EnforcedHashRocketStyle, EnforcedColonStyle, EnforcedLastArgumentHashStyle.
# SupportedHashRocketStyles: key, separator, table
# SupportedColonStyles: key, separator, table
# SupportedLastArgumentHashStyles: always_inspect, always_ignore, ignore_implicit, ignore_explicit
Layout/HashAlignment:
Exclude:
- 'config/environments/production.rb'
- 'config/initializers/rack_attack.rb'
- 'config/routes.rb'
# This cop supports safe autocorrection (--autocorrect).
# Configuration parameters: AllowDoxygenCommentStyle, AllowGemfileRubyComment.
Layout/LeadingCommentSpace:
Exclude:
- 'config/application.rb'
- 'config/initializers/omniauth.rb'
# This cop supports safe autocorrection (--autocorrect).
# Configuration parameters: Max, AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, AllowedPatterns.
# URISchemes: http, https
Layout/LineLength:
Exclude:
- 'app/models/account.rb'
# This cop supports safe autocorrection (--autocorrect).
# Configuration parameters: EnforcedStyle.
# SupportedStyles: require_no_space, require_space
Layout/SpaceInLambdaLiteral:
Exclude:
- 'config/environments/production.rb'
- 'config/initializers/content_security_policy.rb'
# Configuration parameters: AllowComments, AllowEmptyLambdas.
Lint/EmptyBlock:
Exclude:
- 'spec/controllers/api/v2/search_controller_spec.rb'
- 'spec/fabricators/access_token_fabricator.rb'
- 'spec/fabricators/conversation_fabricator.rb'
- 'spec/fabricators/system_key_fabricator.rb'
- 'spec/helpers/admin/action_logs_helper_spec.rb'
- 'spec/lib/activitypub/adapter_spec.rb'
- 'spec/models/account_alias_spec.rb'
- 'spec/models/account_deletion_request_spec.rb'
- 'spec/models/account_moderation_note_spec.rb'
- 'spec/models/announcement_mute_spec.rb'
- 'spec/models/announcement_reaction_spec.rb'
- 'spec/models/announcement_spec.rb'
- 'spec/models/backup_spec.rb'
- 'spec/models/conversation_mute_spec.rb'
- 'spec/models/custom_filter_keyword_spec.rb'
- 'spec/models/custom_filter_spec.rb'
- 'spec/models/device_spec.rb'
- 'spec/models/encrypted_message_spec.rb'
- 'spec/models/featured_tag_spec.rb'
- 'spec/models/follow_recommendation_suppression_spec.rb'
- 'spec/models/list_account_spec.rb'
- 'spec/models/list_spec.rb'
- 'spec/models/login_activity_spec.rb'
- 'spec/models/mute_spec.rb'
- 'spec/models/preview_card_spec.rb'
- 'spec/models/preview_card_trend_spec.rb'
- 'spec/models/relay_spec.rb'
- 'spec/models/scheduled_status_spec.rb'
- 'spec/models/status_stat_spec.rb'
- 'spec/models/status_trend_spec.rb'
- 'spec/models/system_key_spec.rb'
- 'spec/models/tag_follow_spec.rb'
- 'spec/models/unavailable_domain_spec.rb'
- 'spec/models/user_invite_request_spec.rb'
- 'spec/models/user_role_spec.rb'
- 'spec/models/web/setting_spec.rb'
Lint/NonLocalExitFromIterator: Lint/NonLocalExitFromIterator:
Exclude: Exclude:
- 'app/helpers/jsonld_helper.rb' - 'app/helpers/jsonld_helper.rb'
# This cop supports unsafe autocorrection (--autocorrect-all).
Lint/OrAssignmentToConstant:
Exclude:
- 'lib/sanitize_ext/sanitize_config.rb'
# This cop supports safe autocorrection (--autocorrect).
# Configuration parameters: IgnoreEmptyBlocks, AllowUnusedKeywordArguments.
Lint/UnusedBlockArgument:
Exclude:
- 'config/initializers/content_security_policy.rb'
- 'config/initializers/doorkeeper.rb'
- 'config/initializers/paperclip.rb'
- 'config/initializers/simple_form.rb'
# This cop supports unsafe autocorrection (--autocorrect-all).
Lint/UselessAssignment:
Exclude:
- 'app/services/activitypub/process_status_update_service.rb'
- 'config/initializers/omniauth.rb'
- 'db/migrate/20190511134027_add_silenced_at_suspended_at_to_accounts.rb'
- 'db/post_migrate/20190511152737_remove_suspended_silenced_account_fields.rb'
- 'spec/controllers/api/v1/favourites_controller_spec.rb'
- 'spec/controllers/concerns/account_controller_concern_spec.rb'
- 'spec/helpers/jsonld_helper_spec.rb'
- 'spec/models/account_spec.rb'
- 'spec/models/domain_block_spec.rb'
- 'spec/models/status_spec.rb'
- 'spec/models/user_spec.rb'
- 'spec/models/webauthn_credentials_spec.rb'
- 'spec/services/account_search_service_spec.rb'
- 'spec/services/post_status_service_spec.rb'
- 'spec/services/precompute_feed_service_spec.rb'
- 'spec/services/resolve_url_service_spec.rb'
- 'spec/views/statuses/show.html.haml_spec.rb'
# Configuration parameters: AllowedMethods, AllowedPatterns, CountRepeatedAttributes. # Configuration parameters: AllowedMethods, AllowedPatterns, CountRepeatedAttributes.
Metrics/AbcSize: Metrics/AbcSize:
Max: 82 Max: 146
# Configuration parameters: CountBlocks, CountModifierForms, Max. # Configuration parameters: CountBlocks, Max.
Metrics/BlockNesting: Metrics/BlockNesting:
Exclude: Exclude:
- 'lib/tasks/mastodon.rake' - 'lib/tasks/mastodon.rake'
@ -27,23 +150,457 @@ Metrics/CyclomaticComplexity:
Metrics/PerceivedComplexity: Metrics/PerceivedComplexity:
Max: 27 Max: 27
# Configuration parameters: EnforcedStyle, CheckMethodNames, CheckSymbols, AllowedIdentifiers, AllowedPatterns.
# SupportedStyles: snake_case, normalcase, non_integer
# AllowedIdentifiers: capture3, iso8601, rfc1123_date, rfc822, rfc2822, rfc3339, x86_64
Naming/VariableNumber:
Exclude:
- 'db/migrate/20180106000232_add_index_on_statuses_for_api_v1_accounts_account_id_statuses.rb'
- 'db/migrate/20180514140000_revert_index_change_on_statuses_for_api_v1_accounts_account_id_statuses.rb'
- 'db/migrate/20190820003045_update_statuses_index.rb'
- 'db/migrate/20190823221802_add_local_index_to_statuses.rb'
- 'db/migrate/20200119112504_add_public_index_to_statuses.rb'
- 'spec/models/account_spec.rb'
- 'spec/models/domain_block_spec.rb'
- 'spec/models/user_spec.rb'
RSpec/AnyInstance:
Exclude:
- 'spec/controllers/activitypub/inboxes_controller_spec.rb'
- 'spec/controllers/admin/accounts_controller_spec.rb'
- 'spec/controllers/admin/resets_controller_spec.rb'
- 'spec/controllers/admin/settings/branding_controller_spec.rb'
- 'spec/controllers/api/v1/media_controller_spec.rb'
- 'spec/controllers/auth/sessions_controller_spec.rb'
- 'spec/controllers/settings/two_factor_authentication/confirmations_controller_spec.rb'
- 'spec/controllers/settings/two_factor_authentication/recovery_codes_controller_spec.rb'
- 'spec/lib/request_spec.rb'
- 'spec/lib/status_filter_spec.rb'
- 'spec/models/account_spec.rb'
- 'spec/models/setting_spec.rb'
- 'spec/services/activitypub/process_collection_service_spec.rb'
- 'spec/validators/follow_limit_validator_spec.rb'
- 'spec/workers/activitypub/delivery_worker_spec.rb'
- 'spec/workers/web/push_notification_worker_spec.rb'
# Configuration parameters: CountAsOne.
RSpec/ExampleLength:
Max: 22
# This cop supports safe autocorrection (--autocorrect).
# Configuration parameters: EnforcedStyle.
# SupportedStyles: implicit, each, example
RSpec/HookArgument:
Exclude:
- 'spec/controllers/api/v1/streaming_controller_spec.rb'
- 'spec/controllers/well_known/webfinger_controller_spec.rb'
- 'spec/helpers/instance_helper_spec.rb'
- 'spec/models/user_spec.rb'
- 'spec/rails_helper.rb'
- 'spec/serializers/activitypub/note_serializer_spec.rb'
- 'spec/serializers/activitypub/update_poll_serializer_spec.rb'
- 'spec/services/import_service_spec.rb'
# Configuration parameters: AssignmentOnly.
RSpec/InstanceVariable:
Exclude:
- 'spec/controllers/api/v1/streaming_controller_spec.rb'
- 'spec/controllers/auth/confirmations_controller_spec.rb'
- 'spec/controllers/auth/passwords_controller_spec.rb'
- 'spec/controllers/auth/sessions_controller_spec.rb'
- 'spec/controllers/concerns/export_controller_concern_spec.rb'
- 'spec/controllers/home_controller_spec.rb'
- 'spec/controllers/settings/two_factor_authentication/webauthn_credentials_controller_spec.rb'
- 'spec/controllers/statuses_cleanup_controller_spec.rb'
- 'spec/models/concerns/account_finder_concern_spec.rb'
- 'spec/models/concerns/account_interactions_spec.rb'
- 'spec/models/public_feed_spec.rb'
- 'spec/serializers/activitypub/note_serializer_spec.rb'
- 'spec/serializers/activitypub/update_poll_serializer_spec.rb'
- 'spec/services/remove_status_service_spec.rb'
- 'spec/services/search_service_spec.rb'
- 'spec/services/unblock_domain_service_spec.rb'
RSpec/LetSetup:
Exclude:
- 'spec/controllers/admin/accounts_controller_spec.rb'
- 'spec/controllers/admin/action_logs_controller_spec.rb'
- 'spec/controllers/admin/instances_controller_spec.rb'
- 'spec/controllers/admin/reports/actions_controller_spec.rb'
- 'spec/controllers/admin/statuses_controller_spec.rb'
- 'spec/controllers/api/v1/accounts/statuses_controller_spec.rb'
- 'spec/controllers/api/v1/admin/accounts_controller_spec.rb'
- 'spec/controllers/api/v1/filters_controller_spec.rb'
- 'spec/controllers/api/v1/followed_tags_controller_spec.rb'
- 'spec/controllers/api/v2/admin/accounts_controller_spec.rb'
- 'spec/controllers/api/v2/filters/keywords_controller_spec.rb'
- 'spec/controllers/api/v2/filters/statuses_controller_spec.rb'
- 'spec/controllers/auth/confirmations_controller_spec.rb'
- 'spec/controllers/auth/passwords_controller_spec.rb'
- 'spec/controllers/auth/sessions_controller_spec.rb'
- 'spec/controllers/follower_accounts_controller_spec.rb'
- 'spec/controllers/following_accounts_controller_spec.rb'
- 'spec/controllers/oauth/authorized_applications_controller_spec.rb'
- 'spec/controllers/oauth/tokens_controller_spec.rb'
- 'spec/controllers/settings/imports_controller_spec.rb'
- 'spec/lib/activitypub/activity/delete_spec.rb'
- 'spec/lib/vacuum/applications_vacuum_spec.rb'
- 'spec/lib/vacuum/preview_cards_vacuum_spec.rb'
- 'spec/models/account_spec.rb'
- 'spec/models/account_statuses_cleanup_policy_spec.rb'
- 'spec/models/canonical_email_block_spec.rb'
- 'spec/models/status_spec.rb'
- 'spec/models/user_spec.rb'
- 'spec/services/account_statuses_cleanup_service_spec.rb'
- 'spec/services/activitypub/fetch_featured_collection_service_spec.rb'
- 'spec/services/activitypub/fetch_remote_status_service_spec.rb'
- 'spec/services/activitypub/process_account_service_spec.rb'
- 'spec/services/activitypub/process_collection_service_spec.rb'
- 'spec/services/batched_remove_status_service_spec.rb'
- 'spec/services/block_domain_service_spec.rb'
- 'spec/services/bulk_import_service_spec.rb'
- 'spec/services/delete_account_service_spec.rb'
- 'spec/services/import_service_spec.rb'
- 'spec/services/notify_service_spec.rb'
- 'spec/services/remove_status_service_spec.rb'
- 'spec/services/report_service_spec.rb'
- 'spec/services/resolve_account_service_spec.rb'
- 'spec/services/suspend_account_service_spec.rb'
- 'spec/services/unallow_domain_service_spec.rb'
- 'spec/services/unsuspend_account_service_spec.rb'
- 'spec/workers/scheduler/user_cleanup_scheduler_spec.rb'
RSpec/MessageChain:
Exclude:
- 'spec/controllers/api/v1/media_controller_spec.rb'
- 'spec/models/concerns/remotable_spec.rb'
- 'spec/models/session_activation_spec.rb'
- 'spec/models/setting_spec.rb'
# Configuration parameters: EnforcedStyle.
# SupportedStyles: have_received, receive
RSpec/MessageSpies:
Exclude:
- 'spec/controllers/admin/accounts_controller_spec.rb'
- 'spec/helpers/admin/account_moderation_notes_helper_spec.rb'
- 'spec/lib/webfinger_resource_spec.rb'
- 'spec/models/admin/account_action_spec.rb'
- 'spec/models/concerns/remotable_spec.rb'
- 'spec/models/follow_request_spec.rb'
- 'spec/models/identity_spec.rb'
- 'spec/models/session_activation_spec.rb'
- 'spec/models/setting_spec.rb'
- 'spec/services/activitypub/fetch_replies_service_spec.rb'
- 'spec/services/activitypub/process_collection_service_spec.rb'
- 'spec/spec_helper.rb'
- 'spec/validators/status_length_validator_spec.rb'
RSpec/MultipleExpectations:
Max: 8
# Configuration parameters: AllowSubject.
RSpec/MultipleMemoizedHelpers:
Max: 21
# Configuration parameters: AllowedGroups.
RSpec/NestedGroups:
Max: 6
RSpec/PendingWithoutReason:
Exclude:
- 'spec/models/account_spec.rb'
# This cop supports unsafe autocorrection (--autocorrect-all).
Rails/ApplicationController:
Exclude:
- 'app/controllers/health_controller.rb'
# Configuration parameters: Include.
# Include: db/**/*.rb
Rails/CreateTableWithTimestamps:
Exclude:
- 'db/migrate/20170508230434_create_conversation_mutes.rb'
- 'db/migrate/20170823162448_create_status_pins.rb'
- 'db/migrate/20171116161857_create_list_accounts.rb'
- 'db/migrate/20180929222014_create_account_conversations.rb'
- 'db/migrate/20181007025445_create_pghero_space_stats.rb'
- 'db/migrate/20190103124649_create_scheduled_statuses.rb'
- 'db/migrate/20220824233535_create_status_trends.rb'
- 'db/migrate/20221006061337_create_preview_card_trends.rb'
# This cop supports safe autocorrection (--autocorrect).
# Configuration parameters: Severity.
Rails/DuplicateAssociation:
Exclude:
- 'app/serializers/activitypub/collection_serializer.rb'
- 'app/serializers/activitypub/note_serializer.rb'
# Configuration parameters: Include.
# Include: app/models/**/*.rb
Rails/HasAndBelongsToMany:
Exclude:
- 'app/models/concerns/account_associations.rb'
- 'app/models/preview_card.rb'
- 'app/models/status.rb'
- 'app/models/tag.rb'
# Configuration parameters: Include.
# Include: app/models/**/*.rb
Rails/HasManyOrHasOneDependent:
Exclude:
- 'app/models/concerns/account_counters.rb'
- 'app/models/conversation.rb'
- 'app/models/custom_emoji.rb'
- 'app/models/custom_emoji_category.rb'
- 'app/models/domain_block.rb'
- 'app/models/invite.rb'
- 'app/models/status.rb'
- 'app/models/user.rb'
- 'app/models/web/push_subscription.rb'
Rails/I18nLocaleTexts:
Exclude:
- 'lib/tasks/mastodon.rake'
- 'spec/helpers/flashes_helper_spec.rb'
# Configuration parameters: Include.
# Include: app/controllers/**/*.rb, app/mailers/**/*.rb
Rails/LexicallyScopedActionFilter:
Exclude:
- 'app/controllers/auth/passwords_controller.rb'
- 'app/controllers/auth/registrations_controller.rb'
- 'app/controllers/auth/sessions_controller.rb'
# This cop supports unsafe autocorrection (--autocorrect-all).
Rails/NegateInclude:
Exclude:
- 'app/controllers/concerns/signature_verification.rb'
- 'app/helpers/jsonld_helper.rb'
- 'app/lib/activitypub/activity/create.rb'
- 'app/lib/activitypub/activity/move.rb'
- 'app/lib/feed_manager.rb'
- 'app/lib/link_details_extractor.rb'
- 'app/models/concerns/attachmentable.rb'
- 'app/models/concerns/remotable.rb'
- 'app/models/custom_filter.rb'
- 'app/services/activitypub/process_status_update_service.rb'
- 'app/services/fetch_link_card_service.rb'
- 'app/services/search_service.rb'
- 'app/workers/web/push_notification_worker.rb'
- 'lib/paperclip/color_extractor.rb'
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: Include.
# Include: **/Rakefile, **/*.rake
Rails/RakeEnvironment:
Exclude:
- 'lib/tasks/auto_annotate_models.rake'
- 'lib/tasks/db.rake'
- 'lib/tasks/emojis.rake'
- 'lib/tasks/mastodon.rake'
- 'lib/tasks/repo.rake'
- 'lib/tasks/statistics.rake'
# Configuration parameters: Include.
# Include: db/**/*.rb
Rails/ReversibleMigration:
Exclude:
- 'db/migrate/20160223164502_make_uris_nullable_in_statuses.rb'
- 'db/migrate/20161122163057_remove_unneeded_indexes.rb'
- 'db/migrate/20170205175257_remove_devices.rb'
- 'db/migrate/20170322143850_change_primary_key_to_bigint_on_statuses.rb'
- 'db/migrate/20170520145338_change_language_filter_to_opt_out.rb'
- 'db/migrate/20170609145826_remove_default_language_from_statuses.rb'
- 'db/migrate/20170711225116_fix_null_booleans.rb'
- 'db/migrate/20171129172043_add_index_on_stream_entries.rb'
- 'db/migrate/20171212195226_remove_duplicate_indexes_in_lists.rb'
- 'db/migrate/20171226094803_more_faster_index_on_notifications.rb'
- 'db/migrate/20180106000232_add_index_on_statuses_for_api_v1_accounts_account_id_statuses.rb'
- 'db/migrate/20180617162849_remove_unused_indexes.rb'
- 'db/migrate/20220827195229_change_canonical_email_blocks_nullable.rb'
# Configuration parameters: ForbiddenMethods, AllowedMethods.
# ForbiddenMethods: decrement!, decrement_counter, increment!, increment_counter, insert, insert!, insert_all, insert_all!, toggle!, touch, touch_all, update_all, update_attribute, update_column, update_columns, update_counters, upsert, upsert_all
Rails/SkipsModelValidations:
Exclude:
- 'app/controllers/admin/invites_controller.rb'
- 'app/controllers/concerns/session_tracking_concern.rb'
- 'app/models/concerns/account_merging.rb'
- 'app/models/concerns/expireable.rb'
- 'app/models/status.rb'
- 'app/models/trends/links.rb'
- 'app/models/trends/preview_card_batch.rb'
- 'app/models/trends/preview_card_provider_batch.rb'
- 'app/models/trends/status_batch.rb'
- 'app/models/trends/statuses.rb'
- 'app/models/trends/tag_batch.rb'
- 'app/models/trends/tags.rb'
- 'app/models/user.rb'
- 'app/services/activitypub/process_status_update_service.rb'
- 'app/services/approve_appeal_service.rb'
- 'app/services/block_domain_service.rb'
- 'app/services/delete_account_service.rb'
- 'app/services/process_mentions_service.rb'
- 'app/services/unallow_domain_service.rb'
- 'app/services/unblock_domain_service.rb'
- 'app/services/update_status_service.rb'
- 'app/workers/activitypub/post_upgrade_worker.rb'
- 'app/workers/move_worker.rb'
- 'app/workers/scheduler/ip_cleanup_scheduler.rb'
- 'app/workers/scheduler/scheduled_statuses_scheduler.rb'
- 'db/migrate/20161203164520_add_from_account_id_to_notifications.rb'
- 'db/migrate/20170105224407_add_shortcode_to_media_attachments.rb'
- 'db/migrate/20170209184350_add_reply_to_statuses.rb'
- 'db/migrate/20170304202101_add_type_to_media_attachments.rb'
- 'db/migrate/20180528141303_fix_accounts_unique_index.rb'
- 'db/migrate/20180609104432_migrate_web_push_subscriptions2.rb'
- 'db/migrate/20181207011115_downcase_custom_emoji_domains.rb'
- 'db/migrate/20190511134027_add_silenced_at_suspended_at_to_accounts.rb'
- 'db/migrate/20191007013357_update_pt_locales.rb'
- 'db/migrate/20220316233212_update_kurdish_locales.rb'
- 'db/post_migrate/20190511152737_remove_suspended_silenced_account_fields.rb'
- 'db/post_migrate/20200917193528_migrate_notifications_type.rb'
- 'db/post_migrate/20201017234926_fill_account_suspension_origin.rb'
- 'db/post_migrate/20220617202502_migrate_roles.rb'
- 'db/post_migrate/20221101190723_backfill_admin_action_logs.rb'
- 'db/post_migrate/20221206114142_backfill_admin_action_logs_again.rb'
- 'lib/mastodon/cli/accounts.rb'
- 'lib/mastodon/cli/main.rb'
- 'lib/mastodon/cli/maintenance.rb'
- 'spec/controllers/api/v1/admin/accounts_controller_spec.rb'
- 'spec/lib/activitypub/activity/follow_spec.rb'
- 'spec/services/follow_service_spec.rb'
- 'spec/services/update_account_service_spec.rb'
# Configuration parameters: Include.
# Include: db/**/*.rb
Rails/ThreeStateBooleanColumn:
Exclude:
- 'db/migrate/20160325130944_add_admin_to_users.rb'
- 'db/migrate/20161123093447_add_sensitive_to_statuses.rb'
- 'db/migrate/20170123203248_add_reject_media_to_domain_blocks.rb'
- 'db/migrate/20170127165745_add_devise_two_factor_to_users.rb'
- 'db/migrate/20170209184350_add_reply_to_statuses.rb'
- 'db/migrate/20170330163835_create_imports.rb'
- 'db/migrate/20170905165803_add_local_to_statuses.rb'
- 'db/migrate/20181203021853_add_discoverable_to_accounts.rb'
- 'db/migrate/20190509164208_add_by_moderator_to_tombstone.rb'
- 'db/migrate/20190805123746_add_capabilities_to_tags.rb'
- 'db/migrate/20191212163405_add_hide_collections_to_accounts.rb'
- 'db/migrate/20200309150742_add_forwarded_to_reports.rb'
- 'db/migrate/20210609202149_create_login_activities.rb'
- 'db/migrate/20210621221010_add_skip_sign_in_token_to_users.rb'
- 'db/migrate/20211031031021_create_preview_card_providers.rb'
- 'db/migrate/20211115032527_add_trendable_to_preview_cards.rb'
- 'db/migrate/20220202200743_add_trendable_to_accounts.rb'
- 'db/migrate/20220202200926_add_trendable_to_statuses.rb'
- 'db/migrate/20220303000827_add_ordered_media_attachment_ids_to_status_edits.rb'
# Configuration parameters: Include.
# Include: app/models/**/*.rb
Rails/UniqueValidationWithoutIndex:
Exclude:
- 'app/models/account_alias.rb'
- 'app/models/custom_filter_status.rb'
- 'app/models/identity.rb'
- 'app/models/webauthn_credential.rb'
# Configuration parameters: Include.
# Include: app/models/**/*.rb
Rails/UnusedIgnoredColumns:
Exclude:
- 'app/models/account.rb'
- 'app/models/account_stat.rb'
- 'app/models/admin/action_log.rb'
- 'app/models/custom_filter.rb'
- 'app/models/email_domain_block.rb'
- 'app/models/report.rb'
- 'app/models/status_edit.rb'
- 'app/models/user.rb'
# This cop supports unsafe autocorrection (--autocorrect-all).
# Configuration parameters: EnforcedStyle.
# SupportedStyles: exists, where
Rails/WhereExists:
Exclude:
- 'app/controllers/activitypub/inboxes_controller.rb'
- 'app/controllers/admin/email_domain_blocks_controller.rb'
- 'app/controllers/auth/registrations_controller.rb'
- 'app/lib/activitypub/activity/create.rb'
- 'app/lib/delivery_failure_tracker.rb'
- 'app/lib/feed_manager.rb'
- 'app/lib/status_cache_hydrator.rb'
- 'app/lib/suspicious_sign_in_detector.rb'
- 'app/models/concerns/account_interactions.rb'
- 'app/models/featured_tag.rb'
- 'app/models/poll.rb'
- 'app/models/session_activation.rb'
- 'app/models/status.rb'
- 'app/models/user.rb'
- 'app/policies/status_policy.rb'
- 'app/serializers/rest/announcement_serializer.rb'
- 'app/serializers/rest/tag_serializer.rb'
- 'app/services/activitypub/fetch_remote_status_service.rb'
- 'app/services/app_sign_up_service.rb'
- 'app/services/vote_service.rb'
- 'app/validators/reaction_validator.rb'
- 'app/validators/vote_validator.rb'
- 'app/workers/move_worker.rb'
- 'db/migrate/20190529143559_preserve_old_layout_for_existing_users.rb'
- 'lib/tasks/tests.rake'
- 'spec/models/account_spec.rb'
- 'spec/services/activitypub/process_collection_service_spec.rb'
- 'spec/services/purge_domain_service_spec.rb'
- 'spec/services/unallow_domain_service_spec.rb'
# This cop supports safe autocorrection (--autocorrect).
# Configuration parameters: AllowOnConstant, AllowOnSelfClass.
Style/CaseEquality:
Exclude:
- 'config/initializers/trusted_proxies.rb'
# This cop supports safe autocorrection (--autocorrect).
# Configuration parameters: AllowedMethods, AllowedPatterns.
# AllowedMethods: ==, equal?, eql?
Style/ClassEqualityComparison:
Exclude:
- 'app/helpers/jsonld_helper.rb'
- 'app/serializers/activitypub/outbox_serializer.rb'
Style/ClassVars:
Exclude:
- 'config/initializers/devise.rb'
# This cop supports unsafe autocorrection (--autocorrect-all).
Style/CombinableLoops:
Exclude:
- 'app/models/form/custom_emoji_batch.rb'
- 'app/models/form/ip_block_batch.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/development.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/blacklists.rb'
- 'config/initializers/cache_buster.rb' - 'config/initializers/cache_buster.rb'
- 'config/initializers/content_security_policy.rb'
- 'config/initializers/devise.rb' - 'config/initializers/devise.rb'
- 'config/initializers/omniauth.rb'
- 'config/initializers/paperclip.rb' - 'config/initializers/paperclip.rb'
- 'config/initializers/vapid.rb' - 'config/initializers/vapid.rb'
- 'lib/mastodon/premailer_webpack_strategy.rb'
- 'lib/mastodon/redis_config.rb'
- 'lib/tasks/repo.rake' - 'lib/tasks/repo.rake'
- 'spec/features/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.
@ -51,13 +608,66 @@ Style/FetchEnvVar:
# AllowedMethods: redirect # AllowedMethods: redirect
Style/FormatStringToken: Style/FormatStringToken:
Exclude: Exclude:
- 'app/models/privacy_policy.rb'
- '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/boot.rb'
- '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:
Enabled: false Exclude:
- 'app/controllers/admin/confirmations_controller.rb'
- 'app/controllers/auth/confirmations_controller.rb'
- 'app/controllers/auth/passwords_controller.rb'
- 'app/controllers/settings/two_factor_authentication/webauthn_credentials_controller.rb'
- '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/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'
- 'db/migrate/20170901141119_truncate_preview_cards.rb'
- 'db/post_migrate/20220704024901_migrate_settings_to_user_roles.rb'
- 'lib/devise/two_factor_ldap_authenticatable.rb'
- 'lib/devise/two_factor_pam_authenticatable.rb'
- 'lib/mastodon/cli/accounts.rb'
- 'lib/mastodon/cli/maintenance.rb'
- 'lib/mastodon/cli/media.rb'
- 'lib/paperclip/attachment_extensions.rb'
- 'lib/tasks/repo.rake'
# This cop supports safe autocorrection (--autocorrect).
# Configuration parameters: EnforcedStyle.
# SupportedStyles: braces, no_braces
Style/HashAsLastArrayItem:
Exclude:
- 'app/controllers/admin/statuses_controller.rb'
- 'app/controllers/api/v1/statuses_controller.rb'
- 'app/models/concerns/account_counters.rb'
- 'app/models/concerns/status_threading_concern.rb'
- 'app/models/status.rb'
- 'app/services/batched_remove_status_service.rb'
- 'app/services/notify_service.rb'
- 'db/migrate/20181024224956_migrate_account_conversations.rb'
# This cop supports unsafe autocorrection (--autocorrect-all). # This cop supports unsafe autocorrection (--autocorrect-all).
Style/HashTransformValues: Style/HashTransformValues:
@ -65,6 +675,29 @@ Style/HashTransformValues:
- 'app/serializers/rest/web_push_subscription_serializer.rb' - 'app/serializers/rest/web_push_subscription_serializer.rb'
- 'app/services/import_service.rb' - 'app/services/import_service.rb'
# This cop supports safe autocorrection (--autocorrect).
Style/IfUnlessModifier:
Exclude:
- 'config/environments/production.rb'
- 'config/initializers/devise.rb'
- 'config/initializers/ffmpeg.rb'
# This cop supports unsafe autocorrection (--autocorrect-all).
# Configuration parameters: InverseMethods, InverseBlocks.
Style/InverseMethods:
Exclude:
- 'app/models/custom_filter.rb'
- 'app/services/update_account_service.rb'
- 'spec/controllers/activitypub/replies_controller_spec.rb'
# This cop supports safe autocorrection (--autocorrect).
# Configuration parameters: EnforcedStyle.
# SupportedStyles: line_count_dependent, lambda, literal
Style/Lambda:
Exclude:
- 'config/initializers/simple_form.rb'
- 'config/routes.rb'
# This cop supports unsafe autocorrection (--autocorrect-all). # This cop supports unsafe autocorrection (--autocorrect-all).
Style/MapToHash: Style/MapToHash:
Exclude: Exclude:
@ -79,10 +712,16 @@ 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'
@ -91,6 +730,14 @@ 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 safe autocorrection (--autocorrect).
# Configuration parameters: PreferredDelimiters.
Style/PercentLiteralDelimiters:
Exclude:
- 'config/deploy.rb'
- 'config/initializers/doorkeeper.rb'
# This cop supports unsafe autocorrection (--autocorrect-all). # This cop supports unsafe autocorrection (--autocorrect-all).
# Configuration parameters: EnforcedStyle. # Configuration parameters: EnforcedStyle.
@ -105,9 +752,103 @@ 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: SafeForConstants.
Style/RedundantFetchBlock:
Exclude:
- 'config/initializers/1_hosts.rb'
- 'config/initializers/chewy.rb'
- 'config/initializers/devise.rb'
- 'config/initializers/paperclip.rb'
- 'config/puma.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'
- 'app/models/status.rb'
# This cop supports safe autocorrection (--autocorrect). # This cop supports safe autocorrection (--autocorrect).
# Configuration parameters: WordRegex. # Configuration parameters: EnforcedStyle.
# SupportedStyles: only_raise, only_fail, semantic
Style/SignalException:
Exclude:
- 'lib/devise/two_factor_ldap_authenticatable.rb'
- 'lib/devise/two_factor_pam_authenticatable.rb'
# This cop supports unsafe autocorrection (--autocorrect-all).
Style/SingleArgumentDig:
Exclude:
- 'lib/webpacker/manifest_extensions.rb'
# This cop supports safe autocorrection (--autocorrect).
# Configuration parameters: EnforcedStyle.
# SupportedStyles: require_parentheses, require_no_parentheses
Style/StabbyLambdaParentheses:
Exclude:
- 'config/environments/production.rb'
- 'config/initializers/content_security_policy.rb'
# This cop supports safe autocorrection (--autocorrect).
Style/StderrPuts:
Exclude:
- 'config/boot.rb'
# This cop supports unsafe autocorrection (--autocorrect-all).
# Configuration parameters: Mode.
Style/StringConcatenation:
Exclude:
- 'config/initializers/paperclip.rb'
# This cop supports safe autocorrection (--autocorrect).
# Configuration parameters: EnforcedStyle, ConsistentQuotesInMultiline.
# SupportedStyles: single_quotes, double_quotes
Style/StringLiterals:
Exclude:
- 'config/environments/production.rb'
- 'config/initializers/backtrace_silencers.rb'
- 'config/initializers/http_client_proxy.rb'
- 'config/initializers/rack_attack.rb'
- 'config/initializers/webauthn.rb'
- 'config/routes.rb'
# This cop supports unsafe autocorrection (--autocorrect-all).
# Configuration parameters: AllowMethodsWithArguments, AllowedMethods, AllowedPatterns, AllowComments.
# AllowedMethods: define_method, mail, respond_to
Style/SymbolProc:
Exclude:
- 'config/initializers/omniauth.rb'
# This cop supports safe autocorrection (--autocorrect).
# Configuration parameters: EnforcedStyle, AllowSafeAssignment.
# SupportedStyles: require_parentheses, require_no_parentheses, require_parentheses_when_complex
Style/TernaryParentheses:
Exclude:
- 'config/environments/development.rb'
# This cop supports safe autocorrection (--autocorrect).
# Configuration parameters: EnforcedStyleForMultiline.
# SupportedStylesForMultiline: comma, consistent_comma, no_comma
Style/TrailingCommaInArguments:
Exclude:
- 'config/initializers/paperclip.rb'
# This cop supports safe autocorrection (--autocorrect).
# Configuration parameters: EnforcedStyleForMultiline.
# SupportedStylesForMultiline: comma, consistent_comma, no_comma
Style/TrailingCommaInHashLiteral:
Exclude:
- 'config/environments/production.rb'
- 'config/environments/test.rb'
# This cop supports safe autocorrection (--autocorrect).
# Configuration parameters: EnforcedStyle, MinSize, WordRegex.
# SupportedStyles: percent, brackets # SupportedStyles: percent, brackets
Style/WordArray: Style/WordArray:
EnforcedStyle: percent Exclude:
MinSize: 3 - 'app/helpers/languages_helper.rb'
- 'config/initializers/cors.rb'
- 'spec/controllers/settings/imports_controller_spec.rb'
- 'spec/models/form/import_spec.rb'

View File

@ -1 +1 @@
3.3.5 3.2.2

View File

@ -1,3 +0,0 @@
{
"ignore_dirs": ["node_modules/", "public/"]
}

View File

View File

@ -1,13 +0,0 @@
diff --git a/lib/index.js b/lib/index.js
index 16ed6be8be8f555cc99096c2ff60954b42dc313d..d009c069770d066ad0db7ad02de1ea473a29334e 100644
--- a/lib/index.js
+++ b/lib/index.js
@@ -99,7 +99,7 @@ function lodash(_ref) {
var node = _ref3;
- if ((0, _types.isModuleDeclaration)(node)) {
+ if ((0, _types.isImportDeclaration)(node) || (0, _types.isExportDeclaration)(node)) {
isModule = true;
break;
}

49
.yarnclean Normal file
View File

@ -0,0 +1,49 @@
# test directories
__tests__
test
tests
powered-test
# asset directories
docs
doc
website
images
# assets
# examples
example
examples
# code coverage directories
coverage
.nyc_output
# build scripts
Makefile
Gulpfile.js
Gruntfile.js
# configs
.tern-project
.gitattributes
.editorconfig
.*ignore
.eslintrc
.jshintrc
.flowconfig
.documentup.json
.yarn-metadata.json
.*.yml
*.yml
# misc
*.gz
*.md
# for specific ignore
!.svgo.yml
!sass-lint/**/*.yml
# breaks lint-staged or generally anything using https://github.com/eemeli/yaml/issues/384
!**/yaml/dist/**/doc

View File

@ -1 +0,0 @@
nodeLinker: node-modules

1676
AUTHORS.md

File diff suppressed because it is too large Load Diff

10
Aptfile
View File

@ -1,5 +1,5 @@
libidn12 ffmpeg
# for idn-ruby on heroku-24 stack libopenblas0-pthread
libpq-dev
# use https://github.com/heroku/heroku-buildpack-activestorage-preview libxdamage1
# in place for ffmpeg and its dependent packages to reduce slag size libxfixes3

File diff suppressed because it is too large Load Diff

View File

@ -11,15 +11,6 @@ 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
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).
## Bug reports ## Bug reports
Bug reports and feature suggestions must use descriptive and concise titles and be submitted to [GitHub Issues](https://github.com/mastodon/mastodon/issues). Please use the search function to make sure that you are not submitting duplicates, and that a similar report or request has not already been resolved or rejected. Bug reports and feature suggestions must use descriptive and concise titles and be submitted to [GitHub Issues](https://github.com/mastodon/mastodon/issues). Please use the search function to make sure that you are not submitting duplicates, and that a similar report or request has not already been resolved or rejected.

15
Capfile Normal file
View File

@ -0,0 +1,15 @@
# frozen_string_literal: true
require 'capistrano/setup'
require 'capistrano/deploy'
require 'capistrano/scm/git'
install_plugin Capistrano::SCM::Git
require 'capistrano/rbenv'
require 'capistrano/bundler'
require 'capistrano/yarn'
require 'capistrano/rails/assets'
require 'capistrano/rails/migrations'
Dir.glob('lib/capistrano/tasks/*.rake').each { |r| import r }

View File

@ -1,410 +1,104 @@
# syntax=docker/dockerfile:1.9 # syntax=docker/dockerfile:1.4
# This needs to be bullseye-slim because the Ruby image is built on bullseye-slim
ARG NODE_VERSION="16.20-bullseye-slim"
# This file is designed for production server deployment, not local development work FROM ghcr.io/moritzheiber/ruby-jemalloc:3.2.2-slim as ruby
# For a containerized local dev environment, see: https://github.com/mastodon/mastodon/blob/main/README.md#docker FROM node:${NODE_VERSION} as build
# Please see https://docs.docker.com/engine/reference/builder for information about COPY --link --from=ruby /opt/ruby /opt/ruby
# the extended buildx capabilities used in this file.
# Make sure multiarch TARGETPLATFORM is available for interpolation
# See: https://docs.docker.com/build/building/multi-platform/
ARG TARGETPLATFORM=${TARGETPLATFORM}
ARG BUILDPLATFORM=${BUILDPLATFORM}
# Ruby image to use for base image, change with [--build-arg RUBY_VERSION="3.3.x"] ENV DEBIAN_FRONTEND="noninteractive" \
# renovate: datasource=docker depName=docker.io/ruby PATH="${PATH}:/opt/ruby/bin"
ARG RUBY_VERSION="3.3.5"
# # Node version to use in base image, change with [--build-arg NODE_MAJOR_VERSION="20"]
# renovate: datasource=node-version depName=node
ARG NODE_MAJOR_VERSION="20"
# Debian image to use for base image, change with [--build-arg DEBIAN_VERSION="bookworm"]
ARG DEBIAN_VERSION="bookworm"
# 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
# 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
# Resulting version string is vX.X.X-MASTODON_VERSION_PRERELEASE+MASTODON_VERSION_METADATA SHELL ["/bin/bash", "-o", "pipefail", "-c"]
# Example: v4.3.0-nightly.2023.11.09+pr-123456
# Overwrite existence of 'alpha.X' in version.rb [--build-arg MASTODON_VERSION_PRERELEASE="nightly.2023.11.09"] WORKDIR /opt/mastodon
ARG MASTODON_VERSION_PRERELEASE="" COPY Gemfile* package.json yarn.lock /opt/mastodon/
# Append build metadata or fork information to version.rb [--build-arg MASTODON_VERSION_METADATA="pr-123456"]
ARG MASTODON_VERSION_METADATA="" # hadolint ignore=DL3008
RUN apt-get update && \
apt-get install -y --no-install-recommends build-essential \
git \
libicu-dev \
libidn11-dev \
libpq-dev \
libjemalloc-dev \
zlib1g-dev \
libgdbm-dev \
libgmp-dev \
libssl-dev \
libyaml-0-2 \
ca-certificates \
libreadline8 \
python3 \
shared-mime-info && \
bundle config set --local deployment 'true' && \
bundle config set --local without 'development test' && \
bundle config set silence_root_warning true && \
bundle install -j"$(nproc)" && \
yarn install --pure-lockfile --production --network-timeout 600000 && \
yarn cache clean
FROM node:${NODE_VERSION}
# Use those args to specify your own version flags & suffixes
ARG MASTODON_VERSION_FLAGS=""
ARG MASTODON_VERSION_SUFFIX=""
# Allow Ruby on Rails to serve static files
# See: https://docs.joinmastodon.org/admin/config/#rails_serve_static_files
ARG RAILS_SERVE_STATIC_FILES="true"
# Allow to use YJIT compiler
# See: https://github.com/ruby/ruby/blob/v3_2_4/doc/yjit/yjit.md
ARG RUBY_YJIT_ENABLE="1"
# Timezone used by the Docker container and runtime, change with [--build-arg TZ=Europe/Berlin]
ARG TZ="Etc/UTC"
# Linux UID (user id) for the mastodon user, change with [--build-arg UID=1234]
ARG UID="991" ARG UID="991"
# Linux GID (group id) for the mastodon user, change with [--build-arg GID=1234]
ARG GID="991" ARG GID="991"
# Apply Mastodon build options based on options above COPY --link --from=ruby /opt/ruby /opt/ruby
ENV \
# Apply Mastodon version information
MASTODON_VERSION_PRERELEASE="${MASTODON_VERSION_PRERELEASE}" \
MASTODON_VERSION_METADATA="${MASTODON_VERSION_METADATA}" \
# Apply Mastodon static files and YJIT options
RAILS_SERVE_STATIC_FILES=${RAILS_SERVE_STATIC_FILES} \
RUBY_YJIT_ENABLE=${RUBY_YJIT_ENABLE} \
# Apply timezone
TZ=${TZ}
ENV \ SHELL ["/bin/bash", "-o", "pipefail", "-c"]
# Configure the IP to bind Mastodon to when serving traffic
BIND="0.0.0.0" \
# Use production settings for Yarn, Node and related nodejs based tools
NODE_ENV="production" \
# Use production settings for Ruby on Rails
RAILS_ENV="production" \
# Add Ruby and Mastodon installation to the PATH
DEBIAN_FRONTEND="noninteractive" \
PATH="${PATH}:/opt/ruby/bin:/opt/mastodon/bin" \
# Optimize jemalloc 5.x performance
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 ENV DEBIAN_FRONTEND="noninteractive" \
SHELL ["/bin/bash", "-o", "pipefail", "-o", "errexit", "-c"] PATH="${PATH}:/opt/ruby/bin:/opt/mastodon/bin"
ARG TARGETPLATFORM # Ignoring these here since we don't want to pin any versions and the Debian image removes apt-get content after use
# hadolint ignore=DL3008,DL3009
RUN apt-get update && \
echo "Etc/UTC" > /etc/localtime && \
groupadd -g "${GID}" mastodon && \
useradd -l -u "$UID" -g "${GID}" -m -d /opt/mastodon mastodon && \
apt-get -y --no-install-recommends install whois \
wget \
procps \
libssl1.1 \
libpq5 \
imagemagick \
ffmpeg \
libjemalloc2 \
libicu67 \
libidn11 \
libyaml-0-2 \
file \
ca-certificates \
tzdata \
libreadline8 \
tini && \
ln -s /opt/mastodon /mastodon
RUN echo "Target platform is $TARGETPLATFORM" # Note: no, cleaning here since Debian does this automatically
# See the file /etc/apt/apt.conf.d/docker-clean within the Docker image's filesystem
RUN \ COPY --chown=mastodon:mastodon . /opt/mastodon
# Remove automatic apt cache Docker cleanup scripts COPY --chown=mastodon:mastodon --from=build /opt/mastodon /opt/mastodon
rm -f /etc/apt/apt.conf.d/docker-clean; \
# Sets timezone
echo "${TZ}" > /etc/localtime; \
# Creates mastodon user/group and sets home directory
groupadd -g "${GID}" mastodon; \
useradd -l -u "${UID}" -g "${GID}" -m -d /opt/mastodon mastodon; \
# Creates /mastodon symlink to /opt/mastodon
ln -s /opt/mastodon /mastodon;
# Set /opt/mastodon as working directory ENV RAILS_ENV="production" \
NODE_ENV="production" \
RAILS_SERVE_STATIC_FILES="true" \
BIND="0.0.0.0" \
MASTODON_VERSION_FLAGS="${MASTODON_VERSION_FLAGS}" \
MASTODON_VERSION_SUFFIX="${MASTODON_VERSION_SUFFIX}"
# Set the run user
USER mastodon
WORKDIR /opt/mastodon WORKDIR /opt/mastodon
# hadolint ignore=DL3008,DL3005 # Precompile assets
RUN \ RUN OTP_SECRET=precompile_placeholder SECRET_KEY_BASE=precompile_placeholder rails assets:precompile
# 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-lib-${TARGETPLATFORM},target=/var/lib/apt,sharing=locked \
# Apt update & upgrade to check for security updates to Debian image
apt-get update; \
apt-get dist-upgrade -yq; \
# Install jemalloc, curl and other necessary components
apt-get install -y --no-install-recommends \
curl \
file \
libjemalloc2 \
patchelf \
procps \
tini \
tzdata \
wget \
; \
# Patch Ruby to use jemalloc
patchelf --add-needed libjemalloc.so.2 /usr/local/bin/ruby; \
# Discard patchelf after use
apt-get purge -y \
patchelf \
;
# Create temporary build layer from base image # Set the work dir and the container entry point
FROM ruby AS build
# Copy Node package configuration files into working directory
COPY package.json yarn.lock .yarnrc.yml /opt/mastodon/
COPY .yarn /opt/mastodon/.yarn
COPY --from=node /usr/local/bin /usr/local/bin
COPY --from=node /usr/local/lib /usr/local/lib
ARG TARGETPLATFORM
# hadolint ignore=DL3008
RUN \
# 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-lib-${TARGETPLATFORM},target=/var/lib/apt,sharing=locked \
# Install build tools and bundler dependencies from APT
apt-get install -y --no-install-recommends \
autoconf \
automake \
build-essential \
cmake \
git \
libgdbm-dev \
libglib2.0-dev \
libgmp-dev \
libicu-dev \
libidn-dev \
libpq-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 \
# Configure Corepack
rm /usr/local/bin/yarn*; \
corepack enable; \
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.15.3
# 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.0.2
# 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
FROM build AS bundler
ARG TARGETPLATFORM
# Copy Gemfile config into working directory
COPY Gemfile* /opt/mastodon/
RUN \
# Mount Ruby Gem caches
--mount=type=cache,id=gem-cache-${TARGETPLATFORM},target=/usr/local/bundle/cache/,sharing=locked \
# Configure bundle to prevent changes to Gemfile and Gemfile.lock
bundle config set --global frozen "true"; \
# Configure bundle to not cache downloaded Gems
bundle config set --global cache_all "false"; \
# Configure bundle to only process production Gems
bundle config set --local without "development test"; \
# Configure bundle to not warn about root user
bundle config set silence_root_warning "true"; \
# Download and install required Gems
bundle install -j"$(nproc)";
# Create temporary node specific build layer from build layer
FROM build AS yarn
ARG TARGETPLATFORM
# Copy Node package configuration files into working directory
COPY package.json yarn.lock .yarnrc.yml /opt/mastodon/
COPY streaming/package.json /opt/mastodon/streaming/
COPY .yarn /opt/mastodon/.yarn
# hadolint ignore=DL3008
RUN \
--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 \
# Install Node packages
yarn workspaces focus --production @mastodon/mastodon;
# Create temporary assets build layer from build layer
FROM build AS precompiler
# Copy Mastodon sources into precompiler layer
COPY . /opt/mastodon/
# Copy bundler and node packages from build layer to container
COPY --from=yarn /opt/mastodon /opt/mastodon/
COPY --from=bundler /opt/mastodon /opt/mastodon/
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
RUN \
ldconfig; \
# Use Ruby on Rails to create Mastodon assets
SECRET_KEY_BASE_DUMMY=1 \
bundle exec rails assets:precompile; \
# Cleanup temporary files
rm -fr /opt/mastodon/tmp;
# Prep final Mastodon Ruby layer
FROM ruby AS mastodon
ARG TARGETPLATFORM
# hadolint ignore=DL3008
RUN \
# 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-lib-${TARGETPLATFORM},target=/var/lib/apt,sharing=locked \
# 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=yarn-cache-${TARGETPLATFORM},target=/usr/local/share/.cache/yarn,sharing=locked \
# Apt update install non-dev versions of necessary components
apt-get install -y --no-install-recommends \
libexpat1 \
libglib2.0-0 \
libicu72 \
libidn12 \
libpq5 \
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 . /opt/mastodon/
# Copy compiled assets to layer
COPY --from=precompiler /opt/mastodon/public/packs /opt/mastodon/public/packs
COPY --from=precompiler /opt/mastodon/public/assets /opt/mastodon/public/assets
# Copy bundler components to layer
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 \
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/;
RUN \
# Pre-create and chown system volume to Mastodon user
mkdir -p /opt/mastodon/public/system; \
chown mastodon:mastodon /opt/mastodon/public/system; \
# Set Mastodon user as owner of tmp folder
chown -R mastodon:mastodon /opt/mastodon/tmp;
# Set the running user for resulting container
USER mastodon
# Expose default Puma ports
EXPOSE 3000
# Set container tini as default entry point
ENTRYPOINT ["/usr/bin/tini", "--"] ENTRYPOINT ["/usr/bin/tini", "--"]
EXPOSE 3000 4000

View File

@ -1,35 +1,19 @@
# Federation ## ActivityPub federation in Mastodon
## Supported federation protocols and standards
- [ActivityPub](https://www.w3.org/TR/activitypub/) (Server-to-Server)
- [WebFinger](https://webfinger.net/)
- [Http Signatures](https://datatracker.ietf.org/doc/html/draft-cavage-http-signatures)
- [NodeInfo](https://nodeinfo.diaspora.software/)
## Supported FEPs
- [FEP-67ff: FEDERATION.md](https://codeberg.org/fediverse/fep/src/branch/main/fep/67ff/fep-67ff.md)
- [FEP-f1d5: NodeInfo in Fediverse Software](https://codeberg.org/fediverse/fep/src/branch/main/fep/f1d5/fep-f1d5.md)
- [FEP-8fcf: Followers collection synchronization across servers](https://codeberg.org/fediverse/fep/src/branch/main/fep/8fcf/fep-8fcf.md)
- [FEP-5feb: Search indexing consent for actors](https://codeberg.org/fediverse/fep/src/branch/main/fep/5feb/fep-5feb.md)
## ActivityPub in Mastodon
Mastodon largely follows the ActivityPub server-to-server specification but it makes uses of some non-standard extensions, some of which are required for interacting with Mastodon at all. Mastodon largely follows the ActivityPub server-to-server specification but it makes uses of some non-standard extensions, some of which are required for interacting with Mastodon at all.
- [Supported ActivityPub vocabulary](https://docs.joinmastodon.org/spec/activitypub/) Supported vocabulary: https://docs.joinmastodon.org/spec/activitypub/
### Required extensions ### Required extensions
#### WebFinger #### Webfinger
In Mastodon, users are identified by a `username` and `domain` pair (e.g., `Gargron@mastodon.social`). In Mastodon, users are identified by a `username` and `domain` pair (e.g., `Gargron@mastodon.social`).
This is used both for discovery and for unambiguously mentioning users across the fediverse. Furthermore, this is part of Mastodon's database design from its very beginnings. This is used both for discovery and for unambiguously mentioning users across the fediverse. Furthermore, this is part of Mastodon's database design from its very beginnings.
As a result, Mastodon requires that each ActivityPub actor uniquely maps back to an `acct:` URI that can be resolved via WebFinger. As a result, Mastodon requires that each ActivityPub actor uniquely maps back to an `acct:` URI that can be resolved via WebFinger.
- [WebFinger information and examples](https://docs.joinmastodon.org/spec/webfinger/) More information and examples are available at: https://docs.joinmastodon.org/spec/webfinger/
#### HTTP Signatures #### HTTP Signatures
@ -37,13 +21,10 @@ In order to authenticate activities, Mastodon relies on HTTP Signatures, signing
Mastodon requires all `POST` requests to be signed, and MAY require `GET` requests to be signed, depending on the configuration of the Mastodon server. Mastodon requires all `POST` requests to be signed, and MAY require `GET` requests to be signed, depending on the configuration of the Mastodon server.
- [HTTP Signatures information and examples](https://docs.joinmastodon.org/spec/security/#http) More information on HTTP Signatures, as well as examples, can be found here: https://docs.joinmastodon.org/spec/security/#http
### Optional extensions ### Optional extensions
- [Linked-Data Signatures](https://docs.joinmastodon.org/spec/security/#ld) - Linked-Data Signatures: https://docs.joinmastodon.org/spec/security/#ld
- [Bearcaps](https://docs.joinmastodon.org/spec/bearcaps/) - Bearcaps: https://docs.joinmastodon.org/spec/bearcaps/
- Followers collection synchronization: https://git.activitypub.dev/ActivityPubDev/Fediverse-Enhancement-Proposals/src/branch/main/feps/fep-8fcf.md
### Additional documentation
- [Mastodon documentation](https://docs.joinmastodon.org/)

142
Gemfile
View File

@ -1,35 +1,34 @@
# frozen_string_literal: true # frozen_string_literal: true
source 'https://rubygems.org' source 'https://rubygems.org'
ruby '>= 3.1.0' ruby '>= 3.0.0'
gem 'propshaft'
gem 'puma', '~> 6.3' gem 'puma', '~> 6.3'
gem 'rack', '~> 2.2.7' gem 'rails', '~> 7.0'
gem 'rails', '~> 7.1.1' gem 'sprockets', '~> 3.7.2'
gem 'thor', '~> 1.2' gem 'thor', '~> 1.2'
gem 'rack', '~> 2.2.7'
gem 'dotenv'
gem 'haml-rails', '~>2.0' gem 'haml-rails', '~>2.0'
gem 'pg', '~> 1.5' gem 'pg', '~> 1.5'
gem 'pghero' gem 'pghero'
gem 'dotenv-rails', '~> 2.8'
gem 'aws-sdk-s3', '~> 1.123', require: false gem 'aws-sdk-s3', '~> 1.123', require: false
gem 'blurhash', '~> 0.1' gem 'fog-core', '<= 2.4.0'
gem 'fog-core', '<= 2.5.0' gem 'fog-openstack', '~> 0.3', require: false
gem 'fog-openstack', '~> 1.0', require: false
gem 'kt-paperclip', '~> 7.2' gem 'kt-paperclip', '~> 7.2'
gem 'md-paperclip-azure', '~> 2.2', require: false gem 'md-paperclip-azure', '~> 2.2', require: false
gem 'ruby-vips', '~> 2.2', require: false gem 'blurhash', '~> 0.1'
gem 'active_model_serializers', '~> 0.10' gem 'active_model_serializers', '~> 0.10'
gem 'addressable', '~> 2.8' gem 'addressable', '~> 2.8'
gem 'bootsnap', '~> 1.18.0', require: false gem 'bootsnap', '~> 1.16.0', require: false
gem 'browser', '< 6' # https://github.com/fnando/browser/issues/543 gem 'browser'
gem 'charlock_holmes', '~> 0.7.7' gem 'charlock_holmes', '~> 0.7.7'
gem 'chewy', '~> 7.3' gem 'chewy', '~> 7.3'
gem 'devise', '~> 4.9' gem 'devise', '~> 4.9'
gem 'devise-two-factor' gem 'devise-two-factor', '~> 4.1'
group :pam_authentication, optional: true do group :pam_authentication, optional: true do
gem 'devise_pam_authenticatable2', '~> 9.2' gem 'devise_pam_authenticatable2', '~> 9.2'
@ -37,99 +36,81 @@ end
gem 'net-ldap', '~> 0.18' gem 'net-ldap', '~> 0.18'
gem 'omniauth', '~> 2.0' # TODO: Point back at released omniauth-cas gem when PR merged
gem 'omniauth-cas', '~> 3.0.0.beta.1' # https://github.com/dlindahl/omniauth-cas/pull/68
gem 'omniauth_openid_connect', '~> 0.6.1' gem 'omniauth-cas', github: 'stanhu/omniauth-cas', ref: '4211e6d05941b4a981f9a36b49ec166cecd0e271'
gem 'omniauth-rails_csrf_protection', '~> 1.0'
gem 'omniauth-saml', '~> 2.0' gem 'omniauth-saml', '~> 2.0'
gem 'omniauth_openid_connect', '~> 0.6.1'
gem 'omniauth', '~> 2.0'
gem 'omniauth-rails_csrf_protection', '~> 1.0'
gem 'color_diff', '~> 0.1' gem 'color_diff', '~> 0.1'
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 'fast_blank', '~> 1.0' gem 'fast_blank', '~> 1.0'
gem 'fastimage' gem 'fastimage'
gem 'hiredis', '~> 0.6' gem 'hiredis', '~> 0.6'
gem 'redis-namespace', '~> 1.10'
gem 'htmlentities', '~> 4.3' gem 'htmlentities', '~> 4.3'
gem 'http', '~> 5.2.0' gem 'http', '~> 5.1'
gem 'http_accept_language', '~> 2.1' gem 'http_accept_language', '~> 2.1'
gem 'httplog', '~> 1.7.0' gem 'httplog', '~> 1.6.2'
gem 'i18n'
gem 'idn-ruby', require: 'idn' gem 'idn-ruby', require: 'idn'
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 'mime-types', '~> 3.4.1', require: 'mime/types/columnar'
gem 'mime-types', '~> 3.5.0', require: 'mime/types/columnar'
gem 'nokogiri', '~> 1.15' gem 'nokogiri', '~> 1.15'
gem 'nsa', github: 'jhawthorn/nsa', ref: 'e020fcc3a54d993ab45b7194d89ab720296c111b'
gem 'oj', '~> 3.14' gem 'oj', '~> 3.14'
gem 'ox', '~> 2.14' gem 'ox', '~> 2.14'
gem 'parslet' gem 'parslet'
gem 'premailer-rails' gem 'posix-spawn'
gem 'public_suffix', '~> 6.0' gem 'public_suffix', '~> 5.0'
gem 'pundit', '~> 2.3' gem 'pundit', '~> 2.3'
gem 'premailer-rails'
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'
gem 'rails-i18n', '~> 7.0' gem 'rails-i18n', '~> 7.0'
gem 'rails-settings-cached', '~> 0.6', git: 'https://github.com/mastodon/rails-settings-cached.git', branch: 'v0.6.6-aliases-true'
gem 'redcarpet', '~> 3.6' gem 'redcarpet', '~> 3.6'
gem 'redis', '~> 4.5', require: ['redis', 'redis/connection/hiredis'] gem 'redis', '~> 4.5', require: ['redis', 'redis/connection/hiredis']
gem 'redis-namespace', '~> 1.10' gem 'mario-redis-lock', '~> 1.2', require: 'redis_lock'
gem 'rqrcode', '~> 2.2' gem 'rqrcode', '~> 2.2'
gem 'ruby-progressbar', '~> 1.13' gem 'ruby-progressbar', '~> 1.13'
gem 'sanitize', '~> 6.0' gem 'sanitize', '~> 6.0'
gem 'scenic', '~> 1.7' gem 'scenic', '~> 1.7'
gem 'sidekiq', '~> 6.5' gem 'sidekiq', '~> 6.5'
gem 'sidekiq-bulk', '~> 0.2.0'
gem 'sidekiq-scheduler', '~> 5.0' gem 'sidekiq-scheduler', '~> 5.0'
gem 'sidekiq-unique-jobs', '~> 7.1' gem 'sidekiq-unique-jobs', '~> 7.1'
gem 'simple_form', '~> 5.2' gem 'sidekiq-bulk', '~> 0.2.0'
gem 'simple-navigation', '~> 4.4' gem 'simple-navigation', '~> 4.4'
gem 'stoplight', '~> 4.1' gem 'simple_form', '~> 5.2'
gem 'strong_migrations' gem 'sprockets-rails', '~> 3.4', require: 'sprockets/railtie'
gem 'stoplight', '~> 3.0.1'
gem 'strong_migrations', '~> 0.8'
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'
gem 'webauthn', '~> 3.0'
gem 'webpacker', '~> 5.4' gem 'webpacker', '~> 5.4'
gem 'webpush', github: 'ClearlyClaire/webpush', ref: 'f14a4d52e201128b1b00245d11b6de80d6cfdcd9' gem 'webpush', github: 'ClearlyClaire/webpush', ref: 'f14a4d52e201128b1b00245d11b6de80d6cfdcd9'
gem 'webauthn', '~> 3.0'
gem 'json-ld' 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 'opentelemetry-api', '~> 1.4.0' gem 'private_address_check', '~> 0.5'
group :opentelemetry do
gem 'opentelemetry-exporter-otlp', '~> 0.29.0', 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-concurrent_ruby', '~> 0.21.2', require: false
gem 'opentelemetry-instrumentation-excon', '~> 0.22.0', require: false
gem 'opentelemetry-instrumentation-faraday', '~> 0.24.1', require: false
gem 'opentelemetry-instrumentation-http', '~> 0.23.2', 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-pg', '~> 0.29.0', require: false
gem 'opentelemetry-instrumentation-rack', '~> 0.24.1', require: false
gem 'opentelemetry-instrumentation-rails', '~> 0.31.0', require: false
gem 'opentelemetry-instrumentation-redis', '~> 0.25.3', require: false
gem 'opentelemetry-instrumentation-sidekiq', '~> 0.25.2', require: false
gem 'opentelemetry-sdk', '~> 1.4', require: false
end
group :test do group :test do
# Enable usage of all available CPUs/cores during spec runs # Used to split testing into chunks in CI
gem 'flatware-rspec' gem 'rspec_chunked', '~> 0.6'
# Adds RSpec Error/Warning annotations to GitHub PRs on the Files tab # RSpec progress bar formatter
gem 'rspec-github', '~> 2.4', require: false gem 'fuubar', '~> 2.5'
# RSpec helpers for email specs # Extra RSpec extenion methods and helpers for sidekiq
gem 'email_spec' gem 'rspec-sidekiq', '~> 3.1'
# Extra RSpec extension methods and helpers for sidekiq
gem 'rspec-sidekiq', '~> 5.0'
# Browser integration testing # Browser integration testing
gem 'capybara', '~> 3.39' gem 'capybara', '~> 3.39'
@ -139,22 +120,25 @@ group :test do
gem 'database_cleaner-active_record' gem 'database_cleaner-active_record'
# Used to mock environment variables # Used to mock environment variables
gem 'climate_control' gem 'climate_control', '~> 0.2'
# Generating fake data for specs
gem 'faker', '~> 3.2'
# Generate test objects for specs
gem 'fabrication', '~> 2.30'
# Add back helpers functions removed in Rails 5.1 # Add back helpers functions removed in Rails 5.1
gem 'rails-controller-testing', '~> 1.0' gem 'rails-controller-testing', '~> 1.0'
# Validate schemas in specs # Validate schemas in specs
gem 'json-schema', '~> 5.0' gem 'json-schema', '~> 4.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
# Stub web requests for specs # Stub web requests for specs
gem 'webmock', '~> 3.18' gem 'webmock', '~> 3.18'
@ -167,7 +151,6 @@ 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 'annotate', '~> 3.2'
@ -178,7 +161,7 @@ group :development do
# Preview mail in the browser # Preview mail in the browser
gem 'letter_opener', '~> 1.8' gem 'letter_opener', '~> 1.8'
gem 'letter_opener_web', '~> 3.0' gem 'letter_opener_web', '~> 2.0'
# Security analysis CLI tools # Security analysis CLI tools
gem 'brakeman', '~> 6.0', require: false gem 'brakeman', '~> 6.0', require: false
@ -187,42 +170,39 @@ group :development do
# Linter CLI for HAML files # Linter CLI for HAML files
gem 'haml_lint', require: false gem 'haml_lint', require: false
# Deployment automation
gem 'capistrano', '~> 3.17'
gem 'capistrano-rails', '~> 1.6'
gem 'capistrano-rbenv', '~> 2.2'
gem 'capistrano-yarn', '~> 2.0'
# Validate missing i18n keys # Validate missing i18n keys
gem 'i18n-tasks', '~> 1.0', require: false gem 'i18n-tasks', '~> 1.0', require: false
end end
group :development, :test do group :development, :test do
# Interactive Debugging tools
gem 'debug', '~> 1.8'
# Generate fake data values
gem 'faker', '~> 3.2'
# Generate factory objects
gem 'fabrication', '~> 2.30'
# Profiling tools # Profiling tools
gem 'memory_profiler', require: false gem 'memory_profiler', require: false
gem 'ruby-prof', require: false gem 'ruby-prof', require: false
gem 'stackprof', require: false gem 'stackprof', require: false
gem 'test-prof' gem 'test-prof'
end
group :development, :test do
# RSpec runner for rails # RSpec runner for rails
gem 'rspec-rails', '~> 7.0' gem 'rspec-rails', '~> 6.0'
end end
group :production do group :production do
gem 'lograge', '~> 0.12' gem 'lograge', '~> 0.12'
end end
gem 'cocoon', '~> 1.2'
gem 'concurrent-ruby', require: false gem 'concurrent-ruby', require: false
gem 'connection_pool', require: false gem 'connection_pool', require: false
gem 'xorcist', '~> 1.1' gem 'xorcist', '~> 1.1'
gem 'cocoon', '~> 1.2'
gem 'net-http', '~> 0.4.0' gem 'net-http', '~> 0.3.2'
gem 'rubyzip', '~> 2.3' gem 'rubyzip', '~> 2.3'
gem 'hcaptcha', '~> 7.1' gem 'hcaptcha', '~> 7.1'
gem 'mail', '~> 2.8'

File diff suppressed because it is too large Load Diff

View File

@ -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-random>.herokuapp.com -a <main-app> # heroku config:set STREAMING_API_BASE_URL=wss://<streaming-app>.herokuapp.com -a <main-app>

View File

@ -1,4 +1,4 @@
web: env PORT=3000 RAILS_ENV=development bundle exec puma -C config/puma.rb web: env PORT=3000 RAILS_ENV=development bundle exec puma -C config/puma.rb
sidekiq: env PORT=3000 RAILS_ENV=development bundle exec sidekiq sidekiq: env PORT=3000 RAILS_ENV=development bundle exec sidekiq
stream: env PORT=4000 yarn workspace @mastodon/streaming start stream: env PORT=4000 yarn run start
webpack: bin/webpack-dev-server webpack: ./bin/webpack-dev-server --listen-host 0.0.0.0

View File

@ -59,78 +59,50 @@ Mastodon acts as an OAuth2 provider, so 3rd party apps can use the REST and Stre
## Deployment ## Deployment
### 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** 9.5+
- **Redis** 4+ - **Redis** 4+
- **Ruby** 3.1+ - **Ruby** 2.7+
- **Node.js** 18+ - **Node.js** 14+
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**, **Scalingo**, and **Nanobox**. 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.
## Development
### Vagrant
A **Vagrant** configuration is included for development purposes. To use it, complete the following steps: A **Vagrant** configuration is included for development purposes. To use it, complete the following steps:
- Install Vagrant and Virtualbox - Install Vagrant and Virtualbox
- Install the `vagrant-hostsupdater` plugin: `vagrant plugin install vagrant-hostsupdater` - Install the `vagrant-hostsupdater` plugin: `vagrant plugin install vagrant-hostsupdater`
- Run `vagrant up` - Run `vagrant up`
- Run `vagrant ssh -c "cd /vagrant && bin/dev"` - Run `vagrant ssh -c "cd /vagrant && foreman start"`
- Open `http://mastodon.local` in your browser - Open `http://mastodon.local` in your browser
### macOS To set up **MacOS** for native development, complete the following steps:
To set up **macOS** for native development, complete the following steps: - Install the latest stable Ruby version (use a ruby version manager for easy installation and management of ruby versions)
- Run `brew install postgresql@14`
- Run `brew install redis`
- Run `brew install imagemagick`
- Install Foreman or a similar tool (such as [overmind](https://github.com/DarthSim/overmind)) to handle multiple process launching.
- Navigate to Mastodon's root directory and run `brew install nvm` then `nvm use` to use the version from .nvmrc
- Run `corepack enable && yarn set version classic`
- Run `bundle exec rails db:setup` (optionally prepend `RAILS_ENV=development` to target the dev environment)
- Finally, run `overmind start -f Procfile.dev`
- Install [Homebrew] and run `brew install postgresql@14 redis imagemagick ### Getting Started with GitHub Codespaces
libidn nvm` to install the required project dependencies
- Use a Ruby version manager to activate the ruby in `.ruby-version` and run
`nvm use` to activate the node version from `.nvmrc`
- Run the `bin/setup` script, which will install the required ruby gems and node
packages and prepare the database for local development
- Finally, run the `bin/dev` script which will launch services via `overmind`
(if installed) or `foreman`
### Docker To get started, create a codespace for this repository by clicking this 👇
For production hosting and deployment with **Docker**, use the `Dockerfile` and [![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://github.com/codespaces/new?hide_repo_select=true&ref=main&repo=52281283)
`docker-compose.yml` in the project root directory.
For local development, install and launch [Docker], and run: A codespace will open in a web-based version of Visual Studio Code. The [dev container](.devcontainer/devcontainer.json) is fully configured with the software needed for this project.
```shell **Note**: Dev containers are an open spec that is supported by [GitHub Codespaces](https://github.com/codespaces) and [other tools](https://containers.dev/supporting).
docker compose -f .devcontainer/compose.yaml up -d
docker compose -f .devcontainer/compose.yaml exec app bin/setup
docker compose -f .devcontainer/compose.yaml exec app bin/dev
```
### Dev Containers
Within IDEs that support the [Development Containers] specification, start the
"Mastodon on local machine" container from the editor. The necessary `docker
compose` commands to build and setup the container should run automatically. For
**Visual Studio Code** this requires installing the [Dev Container extension].
### GitHub Codespaces
[GitHub Codespaces] provides a web-based version of VS Code and a cloud hosted
development environment configured with the software needed for this project.
[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)][codespace]
- Click the button to create a new codespace, and confirm the options
- Wait for the environment to build (takes a few minutes)
- When the editor is ready, run `bin/dev` in the terminal
- Wait for an _Open in Browser_ prompt. This will open Mastodon
- On the _Ports_ tab "stream" setting change _Port visibility_ → _Public_
## Contributing ## Contributing
@ -142,17 +114,10 @@ You can open issues for bugs you've found or features you think are missing. You
## License ## License
Copyright (C) 2016-2024 Eugen Rochko & other Mastodon contributors (see [AUTHORS.md](AUTHORS.md)) Copyright (C) 2016-2022 Eugen Rochko & other Mastodon contributors (see [AUTHORS.md](AUTHORS.md))
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License along with this program. If not, see <https://www.gnu.org/licenses/>. You should have received a copy of the GNU Affero General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
[codespace]: https://codespaces.new/mastodon/mastodon?quickstart=1&devcontainer_path=.devcontainer%2Fcodespaces%2Fdevcontainer.json
[Dev Container extension]: https://containers.dev/supporting#dev-containers
[Development Containers]: https://containers.dev/supporting
[Docker]: https://docs.docker.com
[GitHub Codespaces]: https://docs.github.com/en/codespaces
[Homebrew]: https://brew.sh

View File

@ -1,11 +1,8 @@
# Security Policy # Security Policy
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 reach us at <security@joinmastodon.org>.
- open a [GitHub security issue on the Mastodon project](https://github.com/mastodon/mastodon/security/advisories/new) You should _not_ report such issues on GitHub or in other public spaces to give us time to publish a fix for the issue without exposing Mastodon's users to increased risk.
- 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.
## Scope ## Scope
@ -15,6 +12,7 @@ A "vulnerability in Mastodon" is a vulnerability in the code distributed through
| Version | Supported | | Version | Supported |
| ------- | --------- | | ------- | --------- |
| 4.2.x | Yes |
| 4.1.x | Yes | | 4.1.x | Yes |
| < 4.1 | No | | 4.0.x | Yes |
| 3.5.x | Yes |
| < 3.5 | No |

63
Vagrantfile vendored
View File

@ -10,11 +10,7 @@ curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add -
sudo apt-add-repository 'deb https://dl.yarnpkg.com/debian/ stable main' sudo apt-add-repository 'deb https://dl.yarnpkg.com/debian/ stable main'
# Add repo for NodeJS # Add repo for NodeJS
sudo mkdir -p /etc/apt/keyrings curl -sL https://deb.nodesource.com/setup_16.x | sudo bash -
curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | sudo gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg
NODE_MAJOR=20
echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_$NODE_MAJOR.x nodistro main" | sudo tee /etc/apt/sources.list.d/nodesource.list
sudo apt-get update
# Add firewall rule to redirect 80 to PORT and save # Add firewall rule to redirect 80 to PORT and save
sudo iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port #{ENV["PORT"]} sudo iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port #{ENV["PORT"]}
@ -64,38 +60,6 @@ sudo usermod -a -G rvm $USER
SCRIPT SCRIPT
$provisionElasticsearch = <<SCRIPT
# Install Elastic Search
sudo apt install openjdk-17-jre-headless -y
sudo wget -O /usr/share/keyrings/elasticsearch.asc https://artifacts.elastic.co/GPG-KEY-elasticsearch
sudo sh -c 'echo "deb [signed-by=/usr/share/keyrings/elasticsearch.asc] https://artifacts.elastic.co/packages/7.x/apt stable main" > /etc/apt/sources.list.d/elastic-7.x.list'
sudo apt update
sudo apt install elasticsearch -y
sudo systemctl daemon-reload
sudo systemctl enable --now elasticsearch
echo 'path.data: /var/lib/elasticsearch
path.logs: /var/log/elasticsearch
network.host: 0.0.0.0
http.port: 9200
discovery.seed_hosts: ["localhost"]
cluster.initial_master_nodes: ["node-1"]
xpack.security.enabled: false' > /etc/elasticsearch/elasticsearch.yml
sudo systemctl restart elasticsearch
# Install Kibana
sudo apt install kibana -y
sudo systemctl enable --now kibana
echo 'server.host: "0.0.0.0"
elasticsearch.hosts: ["http://localhost:9200"]' > /etc/kibana/kibana.yml
sudo systemctl restart kibana
SCRIPT
$provisionB = <<SCRIPT $provisionB = <<SCRIPT
source "/etc/profile.d/rvm.sh" source "/etc/profile.d/rvm.sh"
@ -116,11 +80,11 @@ bundle install
# Install node modules # Install node modules
sudo corepack enable sudo corepack enable
corepack prepare yarn set version classic
yarn install yarn install
# Build Mastodon # Build Mastodon
export RAILS_ENV=development export RAILS_ENV=development
export $(cat ".env.vagrant" | xargs) export $(cat ".env.vagrant" | xargs)
bundle exec rails db:setup bundle exec rails db:setup
@ -138,8 +102,10 @@ Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
config.vm.provider :virtualbox do |vb| config.vm.provider :virtualbox do |vb|
vb.name = "mastodon" vb.name = "mastodon"
vb.customize ["modifyvm", :id, "--memory", "8192"] vb.customize ["modifyvm", :id, "--memory", "2048"]
vb.customize ["modifyvm", :id, "--cpus", "3"] # Increase the number of CPUs. Uncomment and adjust to
# increase performance
# vb.customize ["modifyvm", :id, "--cpus", "3"]
# Disable VirtualBox DNS proxy to skip long-delay IPv6 resolutions. # Disable VirtualBox DNS proxy to skip long-delay IPv6 resolutions.
# https://github.com/mitchellh/vagrant/issues/1172 # https://github.com/mitchellh/vagrant/issues/1172
@ -151,12 +117,6 @@ Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
vb.customize ["modifyvm", :id, "--nictype2", "virtio"] vb.customize ["modifyvm", :id, "--nictype2", "virtio"]
end end
config.vm.provider :libvirt do |libvirt|
libvirt.cpus = 3
libvirt.memory = 8192
end
# This uses the vagrant-hostsupdater plugin, and lets you # This uses the vagrant-hostsupdater plugin, and lets you
# access the development site at http://mastodon.local. # access the development site at http://mastodon.local.
# If you change it, also change it in .env.vagrant before provisioning # If you change it, also change it in .env.vagrant before provisioning
@ -179,23 +139,16 @@ Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
# Otherwise, you can access the site at http://localhost:3000 and http://localhost:4000 , http://localhost:8080 # Otherwise, you can access the site at http://localhost:3000 and http://localhost:4000 , http://localhost:8080
config.vm.network :forwarded_port, guest: 3000, host: 3000 config.vm.network :forwarded_port, guest: 3000, host: 3000
config.vm.network :forwarded_port, guest: 3035, host: 3035
config.vm.network :forwarded_port, guest: 4000, host: 4000 config.vm.network :forwarded_port, guest: 4000, host: 4000
config.vm.network :forwarded_port, guest: 8080, host: 8080 config.vm.network :forwarded_port, guest: 8080, host: 8080
config.vm.network :forwarded_port, guest: 9200, host: 9200
config.vm.network :forwarded_port, guest: 9300, host: 9300
config.vm.network :forwarded_port, guest: 9243, host: 9243
config.vm.network :forwarded_port, guest: 5601, host: 5601
# Full provisioning script, only runs on first 'vagrant up' or with 'vagrant provision' # Full provisioning script, only runs on first 'vagrant up' or with 'vagrant provision'
config.vm.provision :shell, inline: $provisionA, privileged: false, reset: true config.vm.provision :shell, inline: $provisionA, privileged: false, reset: true
# Run with elevated privileges for Elasticsearch installation
config.vm.provision :shell, inline: $provisionElasticsearch, privileged: true
config.vm.provision :shell, inline: $provisionB, privileged: false config.vm.provision :shell, inline: $provisionB, privileged: false
config.vm.post_up_message = <<MESSAGE config.vm.post_up_message = <<MESSAGE
To start server To start server
$ vagrant ssh -c "cd /vagrant && bin/dev" $ vagrant ssh -c "cd /vagrant && foreman start"
MESSAGE MESSAGE
end end

View File

@ -90,15 +90,9 @@
} }
}, },
"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"
} }
@ -106,6 +100,5 @@
"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"
} }

View File

@ -1,9 +1,7 @@
# frozen_string_literal: true # frozen_string_literal: true
class AccountsIndex < Chewy::Index class AccountsIndex < Chewy::Index
include DatetimeClampingConcern settings index: { refresh_interval: '30s' }, analysis: {
settings index: index_preset(refresh_interval: '30s'), analysis: {
filter: { filter: {
english_stop: { english_stop: {
type: 'stop', type: 'stop',
@ -23,13 +21,12 @@ class AccountsIndex < Chewy::Index
analyzer: { analyzer: {
natural: { natural: {
tokenizer: 'standard', tokenizer: 'uax_url_email',
filter: %w( filter: %w(
english_possessive_stemmer
lowercase lowercase
asciifolding asciifolding
cjk_width cjk_width
elision
english_possessive_stemmer
english_stop english_stop
english_stemmer english_stemmer
), ),
@ -62,9 +59,9 @@ class AccountsIndex < Chewy::Index
field(:following_count, type: 'long') field(:following_count, type: 'long')
field(:followers_count, type: 'long') field(:followers_count, type: 'long')
field(:properties, type: 'keyword', value: ->(account) { account.searchable_properties }) field(:properties, type: 'keyword', value: ->(account) { account.searchable_properties })
field(:last_status_at, type: 'date', value: ->(account) { clamp_date(account.last_status_at || account.created_at) }) field(:last_status_at, type: 'date', value: ->(account) { account.last_status_at || account.created_at })
field(:display_name, type: 'text', analyzer: 'verbatim') { field :edge_ngram, type: 'text', analyzer: 'edge_ngram', search_analyzer: 'verbatim' } field(:display_name, type: 'text', analyzer: 'verbatim') { field :edge_ngram, type: 'text', analyzer: 'edge_ngram', search_analyzer: 'verbatim' }
field(:username, type: 'text', analyzer: 'verbatim', value: ->(account) { [account.username, account.domain].compact.join('@') }) { field :edge_ngram, type: 'text', analyzer: 'edge_ngram', search_analyzer: 'verbatim' } field(:username, type: 'text', analyzer: 'verbatim', value: ->(account) { [account.username, account.domain].compact.join('@') }) { field :edge_ngram, type: 'text', analyzer: 'edge_ngram', search_analyzer: 'verbatim' }
field(:text, type: 'text', analyzer: 'verbatim', value: ->(account) { account.searchable_text }) { field :stemmed, type: 'text', analyzer: 'natural' } field(:text, type: 'text', value: ->(account) { account.searchable_text }) { field :stemmed, type: 'text', analyzer: 'natural' }
end end
end end

View File

@ -1,14 +0,0 @@
# frozen_string_literal: true
module DatetimeClampingConcern
extend ActiveSupport::Concern
MIN_ISO8601_DATETIME = '0000-01-01T00:00:00Z'.to_datetime.freeze
MAX_ISO8601_DATETIME = '9999-12-31T23:59:59Z'.to_datetime.freeze
class_methods do
def clamp_date(datetime)
datetime.clamp(MIN_ISO8601_DATETIME, MAX_ISO8601_DATETIME)
end
end
end

View File

@ -1,12 +1,12 @@
# frozen_string_literal: true # frozen_string_literal: true
class InstancesIndex < Chewy::Index class InstancesIndex < Chewy::Index
settings index: index_preset(refresh_interval: '30s') settings index: { refresh_interval: '30s' }
index_scope ::Instance.searchable index_scope ::Instance.searchable
root date_detection: false do root date_detection: false do
field :domain, type: 'text', index_prefixes: { min_chars: 1, max_chars: 5 } field :domain, type: 'text', index_prefixes: { min_chars: 1 }
field :accounts_count, type: 'long' field :accounts_count, type: 'long'
end end
end end

View File

@ -1,69 +0,0 @@
# frozen_string_literal: true
class PublicStatusesIndex < Chewy::Index
include DatetimeClampingConcern
settings index: index_preset(refresh_interval: '30s', number_of_shards: 5), analysis: {
filter: {
english_stop: {
type: 'stop',
stopwords: '_english_',
},
english_stemmer: {
type: 'stemmer',
language: 'english',
},
english_possessive_stemmer: {
type: 'stemmer',
language: 'possessive_english',
},
},
analyzer: {
verbatim: {
tokenizer: 'uax_url_email',
filter: %w(lowercase),
},
content: {
tokenizer: 'standard',
filter: %w(
lowercase
asciifolding
cjk_width
elision
english_possessive_stemmer
english_stop
english_stemmer
),
},
hashtag: {
tokenizer: 'keyword',
filter: %w(
word_delimiter_graph
lowercase
asciifolding
cjk_width
),
},
},
}
index_scope ::Status.unscoped
.kept
.indexable
.includes(:media_attachments, :preloadable_poll, :tags, preview_cards_status: :preview_card)
root date_detection: false do
field(:id, type: 'long')
field(:account_id, type: 'long')
field(:text, type: 'text', analyzer: 'verbatim', value: ->(status) { status.searchable_text }) { field(:stemmed, type: 'text', analyzer: 'content') }
field(:tags, type: 'text', analyzer: 'hashtag', value: ->(status) { status.tags.map(&:display_name) })
field(:language, type: 'keyword')
field(:properties, type: 'keyword', value: ->(status) { status.searchable_properties })
field(:created_at, type: 'date', value: ->(status) { clamp_date(status.created_at) })
end
end

View File

@ -1,67 +1,75 @@
# frozen_string_literal: true # frozen_string_literal: true
class StatusesIndex < Chewy::Index class StatusesIndex < Chewy::Index
include DatetimeClampingConcern include FormattingHelper
settings index: index_preset(refresh_interval: '30s', number_of_shards: 5), analysis: { settings index: { refresh_interval: '30s' }, analysis: {
filter: { filter: {
english_stop: { english_stop: {
type: 'stop', type: 'stop',
stopwords: '_english_', stopwords: '_english_',
}, },
english_stemmer: { english_stemmer: {
type: 'stemmer', type: 'stemmer',
language: 'english', language: 'english',
}, },
english_possessive_stemmer: { english_possessive_stemmer: {
type: 'stemmer', type: 'stemmer',
language: 'possessive_english', language: 'possessive_english',
}, },
}, },
analyzer: { analyzer: {
verbatim: {
tokenizer: 'uax_url_email',
filter: %w(lowercase),
},
content: { content: {
tokenizer: 'standard', tokenizer: 'uax_url_email',
filter: %w( filter: %w(
english_possessive_stemmer
lowercase lowercase
asciifolding asciifolding
cjk_width cjk_width
elision
english_possessive_stemmer
english_stop english_stop
english_stemmer english_stemmer
), ),
}, },
hashtag: {
tokenizer: 'keyword',
filter: %w(
word_delimiter_graph
lowercase
asciifolding
cjk_width
),
},
}, },
} }
index_scope ::Status.unscoped.kept.without_reblogs.includes(:media_attachments, :local_mentioned, :local_favorited, :local_reblogged, :local_bookmarked, :tags, preview_cards_status: :preview_card, preloadable_poll: :local_voters), delete_if: ->(status) { status.searchable_by.empty? } # We do not use delete_if option here because it would call a method that we
# expect to be called with crutches without crutches, causing n+1 queries
index_scope ::Status.unscoped.kept.without_reblogs.includes(:media_attachments, :preloadable_poll)
crutch :mentions do |collection|
data = ::Mention.where(status_id: collection.map(&:id)).where(account: Account.local, silent: false).pluck(:status_id, :account_id)
data.each.with_object({}) { |(id, name), result| (result[id] ||= []).push(name) }
end
crutch :favourites do |collection|
data = ::Favourite.where(status_id: collection.map(&:id)).where(account: Account.local).pluck(:status_id, :account_id)
data.each.with_object({}) { |(id, name), result| (result[id] ||= []).push(name) }
end
crutch :reblogs do |collection|
data = ::Status.where(reblog_of_id: collection.map(&:id)).where(account: Account.local).pluck(:reblog_of_id, :account_id)
data.each.with_object({}) { |(id, name), result| (result[id] ||= []).push(name) }
end
crutch :bookmarks do |collection|
data = ::Bookmark.where(status_id: collection.map(&:id)).where(account: Account.local).pluck(:status_id, :account_id)
data.each.with_object({}) { |(id, name), result| (result[id] ||= []).push(name) }
end
crutch :votes do |collection|
data = ::PollVote.joins(:poll).where(poll: { status_id: collection.map(&:id) }).where(account: Account.local).pluck(:status_id, :account_id)
data.each.with_object({}) { |(id, name), result| (result[id] ||= []).push(name) }
end
root date_detection: false do root date_detection: false do
field(:id, type: 'long') field :id, type: 'long'
field(:account_id, type: 'long') field :account_id, type: 'long'
field(:text, type: 'text', analyzer: 'verbatim', value: ->(status) { status.searchable_text }) { field(:stemmed, type: 'text', analyzer: 'content') }
field(:tags, type: 'text', analyzer: 'hashtag', value: ->(status) { status.tags.map(&:display_name) }) field :text, type: 'text', value: ->(status) { status.searchable_text } do
field(:searchable_by, type: 'long', value: ->(status) { status.searchable_by }) field :stemmed, type: 'text', analyzer: 'content'
field(:language, type: 'keyword') end
field(:properties, type: 'keyword', value: ->(status) { status.searchable_properties })
field(:created_at, type: 'date', value: ->(status) { clamp_date(status.created_at) }) field :searchable_by, type: 'long', value: ->(status, crutches) { status.searchable_by(crutches) }
end end
end end

View File

@ -1,27 +1,16 @@
# frozen_string_literal: true # frozen_string_literal: true
class TagsIndex < Chewy::Index class TagsIndex < Chewy::Index
include DatetimeClampingConcern settings index: { refresh_interval: '30s' }, analysis: {
settings index: index_preset(refresh_interval: '30s'), analysis: {
analyzer: { analyzer: {
content: { content: {
tokenizer: 'keyword', tokenizer: 'keyword',
filter: %w( filter: %w(lowercase asciifolding cjk_width),
word_delimiter_graph
lowercase
asciifolding
cjk_width
),
}, },
edge_ngram: { edge_ngram: {
tokenizer: 'edge_ngram', tokenizer: 'edge_ngram',
filter: %w( filter: %w(lowercase asciifolding cjk_width),
lowercase
asciifolding
cjk_width
),
}, },
}, },
@ -41,9 +30,12 @@ class TagsIndex < Chewy::Index
end end
root date_detection: false do root date_detection: false do
field(:name, type: 'text', analyzer: 'content', value: :display_name) { field(:edge_ngram, type: 'text', analyzer: 'edge_ngram', search_analyzer: 'content') } field :name, type: 'text', analyzer: 'content' do
field(:reviewed, type: 'boolean', value: ->(tag) { tag.reviewed? }) field :edge_ngram, type: 'text', analyzer: 'edge_ngram', search_analyzer: 'content'
field(:usage, type: 'long', value: ->(tag, crutches) { tag.history.aggregate(crutches.time_period).accounts }) end
field(:last_status_at, type: 'date', value: ->(tag) { clamp_date(tag.last_status_at || tag.created_at) })
field :reviewed, type: 'boolean', value: ->(tag) { tag.reviewed? }
field :usage, type: 'long', value: ->(tag, crutches) { tag.history.aggregate(crutches.time_period).accounts }
field :last_status_at, type: 'date', value: ->(tag) { tag.last_status_at || tag.created_at }
end end
end end

View File

@ -5,7 +5,15 @@ class AboutController < ApplicationController
skip_before_action :require_functional! skip_before_action :require_functional!
before_action :set_instance_presenter
def show def show
expires_in(15.seconds, public: true, stale_while_revalidate: 30.seconds, stale_if_error: 1.day) unless user_signed_in? expires_in(15.seconds, public: true, stale_while_revalidate: 30.seconds, stale_if_error: 1.day) unless user_signed_in?
end end
private
def set_instance_presenter
@instance_presenter = InstancePresenter.new
end
end end

View File

@ -18,6 +18,8 @@ class AccountsController < ApplicationController
respond_to do |format| respond_to do |format|
format.html do format.html do
expires_in(15.seconds, public: true, stale_while_revalidate: 30.seconds, stale_if_error: 1.hour) unless user_signed_in? expires_in(15.seconds, public: true, stale_while_revalidate: 30.seconds, stale_if_error: 1.hour) unless user_signed_in?
@rss_url = rss_url
end end
format.rss do format.rss do
@ -25,7 +27,7 @@ class AccountsController < ApplicationController
limit = params[:limit].present? ? [params[:limit].to_i, PAGE_SIZE_MAX].min : PAGE_SIZE limit = params[:limit].present? ? [params[:limit].to_i, PAGE_SIZE_MAX].min : PAGE_SIZE
@statuses = filtered_statuses.without_reblogs.limit(limit) @statuses = filtered_statuses.without_reblogs.limit(limit)
@statuses = preload_collection(@statuses, Status) @statuses = cache_collection(@statuses, Status)
end end
format.json do format.json do
@ -46,11 +48,11 @@ class AccountsController < ApplicationController
end end
def default_statuses def default_statuses
@account.statuses.distributable_visibility @account.statuses.where(visibility: [:public, :unlisted])
end end
def only_media_scope def only_media_scope
Status.joins(:media_attachments).merge(@account.media_attachments).group(:id) Status.joins(:media_attachments).merge(@account.media_attachments.reorder(nil)).group(:id)
end end
def no_replies_scope def no_replies_scope
@ -82,21 +84,29 @@ class AccountsController < ApplicationController
short_account_url(@account, format: 'rss') short_account_url(@account, format: 'rss')
end end
end end
helper_method :rss_url
def media_requested? def media_requested?
path_without_format.end_with?('/media') && !tag_requested? request.path.split('.').first.end_with?('/media') && !tag_requested?
end end
def replies_requested? def replies_requested?
path_without_format.end_with?('/with_replies') && !tag_requested? request.path.split('.').first.end_with?('/with_replies') && !tag_requested?
end end
def tag_requested? def tag_requested?
path_without_format.end_with?(Addressable::URI.parse("/tagged/#{params[:tag]}").normalize) request.path.split('.').first.end_with?(Addressable::URI.parse("/tagged/#{params[:tag]}").normalize)
end end
def path_without_format def cached_filtered_status_page
request.path.split('.').first cache_collection_paginated_by_id(
filtered_statuses,
Status,
PAGE_SIZE,
params_slice(:max_id, :min_id, :since_id)
)
end
def params_slice(*keys)
params.slice(*keys).permit(*keys)
end end
end end

View File

@ -1,9 +1,6 @@
# frozen_string_literal: true # frozen_string_literal: true
class ActivityPub::BaseController < Api::BaseController class ActivityPub::BaseController < Api::BaseController
include SignatureVerification
include AccountOwnedConcern
skip_before_action :require_authenticated_user! skip_before_action :require_authenticated_user!
skip_before_action :require_not_suspended! skip_before_action :require_not_suspended!
skip_around_action :set_locale skip_around_action :set_locale

View File

@ -0,0 +1,21 @@
# frozen_string_literal: true
class ActivityPub::ClaimsController < ActivityPub::BaseController
include SignatureVerification
include AccountOwnedConcern
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

View File

@ -1,6 +1,9 @@
# frozen_string_literal: true # frozen_string_literal: true
class ActivityPub::CollectionsController < ActivityPub::BaseController class ActivityPub::CollectionsController < ActivityPub::BaseController
include SignatureVerification
include AccountOwnedConcern
vary_by -> { 'Signature' if authorized_fetch_mode? } vary_by -> { 'Signature' if authorized_fetch_mode? }
before_action :require_account_signature!, if: :authorized_fetch_mode? before_action :require_account_signature!, if: :authorized_fetch_mode?
@ -18,10 +21,12 @@ class ActivityPub::CollectionsController < ActivityPub::BaseController
def set_items def set_items
case params[:id] case params[:id]
when 'featured' when 'featured'
@items = for_signed_account { preload_collection(@account.pinned_statuses, Status) } @items = for_signed_account { cache_collection(@account.pinned_statuses, Status) }
@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
@ -29,7 +34,7 @@ class ActivityPub::CollectionsController < ActivityPub::BaseController
def set_size def set_size
case params[:id] case params[:id]
when 'featured', 'tags' when 'featured', 'devices', 'tags'
@size = @items.size @size = @items.size
else else
not_found not_found
@ -40,7 +45,7 @@ class ActivityPub::CollectionsController < ActivityPub::BaseController
case params[:id] case params[:id]
when 'featured' when 'featured'
@type = :ordered @type = :ordered
when 'tags' when 'devices', 'tags'
@type = :unordered @type = :unordered
else else
not_found not_found

View File

@ -1,6 +1,9 @@
# frozen_string_literal: true # frozen_string_literal: true
class ActivityPub::FollowersSynchronizationsController < ActivityPub::BaseController class ActivityPub::FollowersSynchronizationsController < ActivityPub::BaseController
include SignatureVerification
include AccountOwnedConcern
vary_by -> { 'Signature' if authorized_fetch_mode? } vary_by -> { 'Signature' if authorized_fetch_mode? }
before_action :require_account_signature! before_action :require_account_signature!
@ -21,7 +24,7 @@ class ActivityPub::FollowersSynchronizationsController < ActivityPub::BaseContro
end end
def set_items def set_items
@items = @account.followers.matches_uri_prefix(uri_prefix).pluck(:uri) @items = @account.followers.where(Account.arel_table[:uri].matches("#{Account.sanitize_sql_like(uri_prefix)}/%", false, true)).or(@account.followers.where(uri: uri_prefix)).pluck(:uri)
end end
def collection_presenter def collection_presenter

View File

@ -1,7 +1,9 @@
# frozen_string_literal: true # frozen_string_literal: true
class ActivityPub::InboxesController < ActivityPub::BaseController class ActivityPub::InboxesController < ActivityPub::BaseController
include SignatureVerification
include JsonLdHelper include JsonLdHelper
include AccountOwnedConcern
before_action :skip_unknown_actor_activity before_action :skip_unknown_actor_activity
before_action :require_actor_signature! before_action :require_actor_signature!
@ -22,7 +24,7 @@ class ActivityPub::InboxesController < ActivityPub::BaseController
def unknown_affected_account? def unknown_affected_account?
json = Oj.load(body, mode: :strict) json = Oj.load(body, mode: :strict)
json.is_a?(Hash) && %w(Delete Update).include?(json['type']) && json['actor'].present? && json['actor'] == value_or_id(json['object']) && !Account.exists?(uri: json['actor']) json.is_a?(Hash) && %w(Delete Update).include?(json['type']) && json['actor'].present? && json['actor'] == value_or_id(json['object']) && !Account.where(uri: json['actor']).exists?
rescue Oj::ParseError rescue Oj::ParseError
false false
end end
@ -60,10 +62,11 @@ class ActivityPub::InboxesController < ActivityPub::BaseController
return if raw_params.blank? || ENV['DISABLE_FOLLOWERS_SYNCHRONIZATION'] == 'true' || signed_request_account.nil? return if raw_params.blank? || ENV['DISABLE_FOLLOWERS_SYNCHRONIZATION'] == 'true' || signed_request_account.nil?
# Re-using the syntax for signature parameters # Re-using the syntax for signature parameters
params = SignatureParser.parse(raw_params) tree = SignatureParamsParser.new.parse(raw_params)
params = SignatureParamsTransformer.new.apply(tree)
ActivityPub::PrepareFollowersSynchronizationService.new.call(signed_request_account, params) ActivityPub::PrepareFollowersSynchronizationService.new.call(signed_request_account, params)
rescue SignatureParser::ParsingError rescue Parslet::ParseFailed
Rails.logger.warn 'Error parsing Collection-Synchronization header' Rails.logger.warn 'Error parsing Collection-Synchronization header'
end end

View File

@ -1,36 +0,0 @@
# 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

View File

@ -3,6 +3,9 @@
class ActivityPub::OutboxesController < ActivityPub::BaseController class ActivityPub::OutboxesController < ActivityPub::BaseController
LIMIT = 20 LIMIT = 20
include SignatureVerification
include AccountOwnedConcern
vary_by -> { 'Signature' if authorized_fetch_mode? || page_requested? } vary_by -> { 'Signature' if authorized_fetch_mode? || page_requested? }
before_action :require_account_signature!, if: :authorized_fetch_mode? before_action :require_account_signature!, if: :authorized_fetch_mode?
@ -60,7 +63,7 @@ class ActivityPub::OutboxesController < ActivityPub::BaseController
def set_statuses def set_statuses
return unless page_requested? return unless page_requested?
@statuses = preload_collection_paginated_by_id( @statuses = cache_collection_paginated_by_id(
AccountStatusesFilter.new(@account, signed_request_account).results, AccountStatusesFilter.new(@account, signed_request_account).results,
Status, Status,
LIMIT, LIMIT,

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