Compare commits
4 Commits
master
...
tabler-ico
Author | SHA1 | Date | |
---|---|---|---|
|
963a01003c | ||
|
63e13110c6 | ||
|
ad3996aca3 | ||
|
89f2781791 |
@ -1,224 +0,0 @@
|
|||||||
#━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
||||||
# Misskey configuration
|
|
||||||
#━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
||||||
|
|
||||||
# ┌────────────────────────┐
|
|
||||||
#───┘ Initial Setup Password └─────────────────────────────────────────────────────
|
|
||||||
|
|
||||||
# Password to initiate setting up admin account.
|
|
||||||
# It will not be used after the initial setup is complete.
|
|
||||||
#
|
|
||||||
# Be sure to change this when you set up Misskey via the Internet.
|
|
||||||
#
|
|
||||||
# The provider of the service who sets up Misskey on behalf of the customer should
|
|
||||||
# set this value to something unique when generating the Misskey config file,
|
|
||||||
# and provide it to the customer.
|
|
||||||
setupPassword: example_password_please_change_this_or_you_will_get_hacked
|
|
||||||
|
|
||||||
# ┌─────┐
|
|
||||||
#───┘ URL └─────────────────────────────────────────────────────
|
|
||||||
|
|
||||||
# Final accessible URL seen by a user.
|
|
||||||
url: 'http://misskey.local'
|
|
||||||
|
|
||||||
# ONCE YOU HAVE STARTED THE INSTANCE, DO NOT CHANGE THE
|
|
||||||
# URL SETTINGS AFTER THAT!
|
|
||||||
|
|
||||||
# ┌───────────────────────┐
|
|
||||||
#───┘ Port and TLS settings └───────────────────────────────────
|
|
||||||
|
|
||||||
#
|
|
||||||
# Misskey requires a reverse proxy to support HTTPS connections.
|
|
||||||
#
|
|
||||||
# +----- https://example.tld/ ------------+
|
|
||||||
# +------+ |+-------------+ +----------------+|
|
|
||||||
# | User | ---> || Proxy (443) | ---> | Misskey (3000) ||
|
|
||||||
# +------+ |+-------------+ +----------------+|
|
|
||||||
# +---------------------------------------+
|
|
||||||
#
|
|
||||||
# You need to set up a reverse proxy. (e.g. nginx)
|
|
||||||
# An encrypted connection with HTTPS is highly recommended
|
|
||||||
# because tokens may be transferred in GET requests.
|
|
||||||
|
|
||||||
# The port that your Misskey server should listen on.
|
|
||||||
port: 61812
|
|
||||||
|
|
||||||
# ┌──────────────────────────┐
|
|
||||||
#───┘ PostgreSQL configuration └────────────────────────────────
|
|
||||||
|
|
||||||
db:
|
|
||||||
host: db
|
|
||||||
port: 5432
|
|
||||||
|
|
||||||
# Database name
|
|
||||||
db: misskey
|
|
||||||
|
|
||||||
# Auth
|
|
||||||
user: postgres
|
|
||||||
pass: postgres
|
|
||||||
|
|
||||||
# Whether disable Caching queries
|
|
||||||
#disableCache: true
|
|
||||||
|
|
||||||
# Extra Connection options
|
|
||||||
#extra:
|
|
||||||
# ssl: true
|
|
||||||
|
|
||||||
dbReplications: false
|
|
||||||
|
|
||||||
# You can configure any number of replicas here
|
|
||||||
#dbSlaves:
|
|
||||||
# -
|
|
||||||
# host:
|
|
||||||
# port:
|
|
||||||
# db:
|
|
||||||
# user:
|
|
||||||
# pass:
|
|
||||||
# -
|
|
||||||
# host:
|
|
||||||
# port:
|
|
||||||
# db:
|
|
||||||
# user:
|
|
||||||
# pass:
|
|
||||||
|
|
||||||
# ┌─────────────────────┐
|
|
||||||
#───┘ Redis configuration └─────────────────────────────────────
|
|
||||||
|
|
||||||
redis:
|
|
||||||
host: redis
|
|
||||||
port: 6379
|
|
||||||
#family: 0 # 0=Both, 4=IPv4, 6=IPv6
|
|
||||||
#pass: example-pass
|
|
||||||
#prefix: example-prefix
|
|
||||||
#db: 1
|
|
||||||
|
|
||||||
#redisForPubsub:
|
|
||||||
# host: redis
|
|
||||||
# port: 6379
|
|
||||||
# #family: 0 # 0=Both, 4=IPv4, 6=IPv6
|
|
||||||
# #pass: example-pass
|
|
||||||
# #prefix: example-prefix
|
|
||||||
# #db: 1
|
|
||||||
|
|
||||||
#redisForJobQueue:
|
|
||||||
# host: redis
|
|
||||||
# port: 6379
|
|
||||||
# #family: 0 # 0=Both, 4=IPv4, 6=IPv6
|
|
||||||
# #pass: example-pass
|
|
||||||
# #prefix: example-prefix
|
|
||||||
# #db: 1
|
|
||||||
|
|
||||||
#redisForTimelines:
|
|
||||||
# host: redis
|
|
||||||
# port: 6379
|
|
||||||
# #family: 0 # 0=Both, 4=IPv4, 6=IPv6
|
|
||||||
# #pass: example-pass
|
|
||||||
# #prefix: example-prefix
|
|
||||||
# #db: 1
|
|
||||||
|
|
||||||
#redisForReactions:
|
|
||||||
# host: redis
|
|
||||||
# port: 6379
|
|
||||||
# #family: 0 # 0=Both, 4=IPv4, 6=IPv6
|
|
||||||
# #pass: example-pass
|
|
||||||
# #prefix: example-prefix
|
|
||||||
# #db: 1
|
|
||||||
|
|
||||||
# ┌───────────────────────────┐
|
|
||||||
#───┘ MeiliSearch configuration └─────────────────────────────
|
|
||||||
|
|
||||||
#meilisearch:
|
|
||||||
# host: meilisearch
|
|
||||||
# port: 7700
|
|
||||||
# apiKey: ''
|
|
||||||
# ssl: true
|
|
||||||
# index: ''
|
|
||||||
|
|
||||||
# ┌───────────────┐
|
|
||||||
#───┘ ID generation └───────────────────────────────────────────
|
|
||||||
|
|
||||||
# You can select the ID generation method.
|
|
||||||
# You don't usually need to change this setting, but you can
|
|
||||||
# change it according to your preferences.
|
|
||||||
|
|
||||||
# Available methods:
|
|
||||||
# aid ... Short, Millisecond accuracy
|
|
||||||
# aidx ... Millisecond accuracy
|
|
||||||
# meid ... Similar to ObjectID, Millisecond accuracy
|
|
||||||
# ulid ... Millisecond accuracy
|
|
||||||
# objectid ... This is left for backward compatibility
|
|
||||||
|
|
||||||
# ONCE YOU HAVE STARTED THE INSTANCE, DO NOT CHANGE THE
|
|
||||||
# ID SETTINGS AFTER THAT!
|
|
||||||
|
|
||||||
id: 'aidx'
|
|
||||||
|
|
||||||
# ┌────────────────┐
|
|
||||||
#───┘ Error tracking └──────────────────────────────────────────
|
|
||||||
|
|
||||||
# Sentry is available for error tracking.
|
|
||||||
# See the Sentry documentation for more details on options.
|
|
||||||
|
|
||||||
#sentryForBackend:
|
|
||||||
# enableNodeProfiling: true
|
|
||||||
# options:
|
|
||||||
# dsn: 'https://examplePublicKey@o0.ingest.sentry.io/0'
|
|
||||||
|
|
||||||
#sentryForFrontend:
|
|
||||||
# options:
|
|
||||||
# dsn: 'https://examplePublicKey@o0.ingest.sentry.io/0'
|
|
||||||
|
|
||||||
# ┌─────────────────────┐
|
|
||||||
#───┘ Other configuration └─────────────────────────────────────
|
|
||||||
|
|
||||||
# Whether disable HSTS
|
|
||||||
#disableHsts: true
|
|
||||||
|
|
||||||
# Number of worker processes
|
|
||||||
#clusterLimit: 1
|
|
||||||
|
|
||||||
# Job concurrency per worker
|
|
||||||
# deliverJobConcurrency: 128
|
|
||||||
# inboxJobConcurrency: 16
|
|
||||||
|
|
||||||
# Job rate limiter
|
|
||||||
# deliverJobPerSec: 128
|
|
||||||
# inboxJobPerSec: 32
|
|
||||||
|
|
||||||
# Job attempts
|
|
||||||
# deliverJobMaxAttempts: 12
|
|
||||||
# inboxJobMaxAttempts: 8
|
|
||||||
|
|
||||||
# IP address family used for outgoing request (ipv4, ipv6 or dual)
|
|
||||||
#outgoingAddressFamily: ipv4
|
|
||||||
|
|
||||||
# Proxy for HTTP/HTTPS
|
|
||||||
#proxy: http://127.0.0.1:3128
|
|
||||||
|
|
||||||
proxyBypassHosts:
|
|
||||||
- api.deepl.com
|
|
||||||
- api-free.deepl.com
|
|
||||||
- www.recaptcha.net
|
|
||||||
- hcaptcha.com
|
|
||||||
- challenges.cloudflare.com
|
|
||||||
|
|
||||||
# Proxy for SMTP/SMTPS
|
|
||||||
#proxySmtp: http://127.0.0.1:3128 # use HTTP/1.1 CONNECT
|
|
||||||
#proxySmtp: socks4://127.0.0.1:1080 # use SOCKS4
|
|
||||||
#proxySmtp: socks5://127.0.0.1:1080 # use SOCKS5
|
|
||||||
|
|
||||||
# Media Proxy
|
|
||||||
#mediaProxy: https://example.com/proxy
|
|
||||||
|
|
||||||
# Proxy remote files (default: true)
|
|
||||||
proxyRemoteFiles: true
|
|
||||||
|
|
||||||
# Sign to ActivityPub GET request (default: true)
|
|
||||||
signToActivityPubGet: true
|
|
||||||
|
|
||||||
allowedPrivateNetworks: [
|
|
||||||
'127.0.0.1/32'
|
|
||||||
]
|
|
||||||
|
|
||||||
# Upload or download file size limits (bytes)
|
|
||||||
#maxFileSize: 262144000
|
|
@ -1,11 +1,4 @@
|
|||||||
# misskey settings
|
|
||||||
# MISSKEY_URL=https://example.tld/
|
|
||||||
|
|
||||||
# db settings
|
# db settings
|
||||||
POSTGRES_PASSWORD=example-misskey-pass
|
POSTGRES_PASSWORD=example-misskey-pass
|
||||||
# DATABASE_PASSWORD=${POSTGRES_PASSWORD}
|
|
||||||
POSTGRES_USER=example-misskey-user
|
POSTGRES_USER=example-misskey-user
|
||||||
# DATABASE_USER=${POSTGRES_USER}
|
|
||||||
POSTGRES_DB=misskey
|
POSTGRES_DB=misskey
|
||||||
# DATABASE_DB=${POSTGRES_DB}
|
|
||||||
DATABASE_URL="postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@db:5432/${POSTGRES_DB}"
|
|
||||||
|
@ -1,221 +0,0 @@
|
|||||||
#━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
||||||
# Misskey configuration
|
|
||||||
#━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
||||||
|
|
||||||
# ┌─────┐
|
|
||||||
#───┘ URL └─────────────────────────────────────────────────────
|
|
||||||
|
|
||||||
# Final accessible URL seen by a user.
|
|
||||||
# You can set url from an environment variable instead.
|
|
||||||
url: https://example.tld/
|
|
||||||
|
|
||||||
# ONCE YOU HAVE STARTED THE INSTANCE, DO NOT CHANGE THE
|
|
||||||
# URL SETTINGS AFTER THAT!
|
|
||||||
|
|
||||||
# ┌───────────────────────┐
|
|
||||||
#───┘ Port and TLS settings └───────────────────────────────────
|
|
||||||
|
|
||||||
#
|
|
||||||
# Misskey requires a reverse proxy to support HTTPS connections.
|
|
||||||
#
|
|
||||||
# +----- https://example.tld/ ------------+
|
|
||||||
# +------+ |+-------------+ +----------------+|
|
|
||||||
# | User | ---> || Proxy (443) | ---> | Misskey (3000) ||
|
|
||||||
# +------+ |+-------------+ +----------------+|
|
|
||||||
# +---------------------------------------+
|
|
||||||
#
|
|
||||||
# You need to set up a reverse proxy. (e.g. nginx)
|
|
||||||
# An encrypted connection with HTTPS is highly recommended
|
|
||||||
# because tokens may be transferred in GET requests.
|
|
||||||
|
|
||||||
# The port that your Misskey server should listen on.
|
|
||||||
port: 3000
|
|
||||||
|
|
||||||
# ┌──────────────────────────┐
|
|
||||||
#───┘ PostgreSQL configuration └────────────────────────────────
|
|
||||||
|
|
||||||
db:
|
|
||||||
host: db
|
|
||||||
port: 5432
|
|
||||||
|
|
||||||
# Database name
|
|
||||||
# You can set db from an environment variable instead.
|
|
||||||
db: misskey
|
|
||||||
|
|
||||||
# Auth
|
|
||||||
# You can set user and pass from environment variables instead.
|
|
||||||
user: example-misskey-user
|
|
||||||
pass: example-misskey-pass
|
|
||||||
|
|
||||||
# Whether disable Caching queries
|
|
||||||
#disableCache: true
|
|
||||||
|
|
||||||
# Extra Connection options
|
|
||||||
#extra:
|
|
||||||
# ssl: true
|
|
||||||
|
|
||||||
dbReplications: false
|
|
||||||
|
|
||||||
# You can configure any number of replicas here
|
|
||||||
#dbSlaves:
|
|
||||||
# -
|
|
||||||
# host:
|
|
||||||
# port:
|
|
||||||
# db:
|
|
||||||
# user:
|
|
||||||
# pass:
|
|
||||||
# -
|
|
||||||
# host:
|
|
||||||
# port:
|
|
||||||
# db:
|
|
||||||
# user:
|
|
||||||
# pass:
|
|
||||||
|
|
||||||
# ┌─────────────────────┐
|
|
||||||
#───┘ Redis configuration └─────────────────────────────────────
|
|
||||||
|
|
||||||
redis:
|
|
||||||
host: redis
|
|
||||||
port: 6379
|
|
||||||
#family: 0 # 0=Both, 4=IPv4, 6=IPv6
|
|
||||||
#pass: example-pass
|
|
||||||
#prefix: example-prefix
|
|
||||||
#db: 1
|
|
||||||
|
|
||||||
#redisForPubsub:
|
|
||||||
# host: redis
|
|
||||||
# port: 6379
|
|
||||||
# #family: 0 # 0=Both, 4=IPv4, 6=IPv6
|
|
||||||
# #pass: example-pass
|
|
||||||
# #prefix: example-prefix
|
|
||||||
# #db: 1
|
|
||||||
|
|
||||||
#redisForJobQueue:
|
|
||||||
# host: redis
|
|
||||||
# port: 6379
|
|
||||||
# #family: 0 # 0=Both, 4=IPv4, 6=IPv6
|
|
||||||
# #pass: example-pass
|
|
||||||
# #prefix: example-prefix
|
|
||||||
# #db: 1
|
|
||||||
|
|
||||||
#redisForTimelines:
|
|
||||||
# host: redis
|
|
||||||
# port: 6379
|
|
||||||
# #family: 0 # 0=Both, 4=IPv4, 6=IPv6
|
|
||||||
# #pass: example-pass
|
|
||||||
# #prefix: example-prefix
|
|
||||||
# #db: 1
|
|
||||||
|
|
||||||
#redisForReactions:
|
|
||||||
# host: redis
|
|
||||||
# port: 6379
|
|
||||||
# #family: 0 # 0=Both, 4=IPv4, 6=IPv6
|
|
||||||
# #pass: example-pass
|
|
||||||
# #prefix: example-prefix
|
|
||||||
# #db: 1
|
|
||||||
|
|
||||||
# ┌───────────────────────────┐
|
|
||||||
#───┘ MeiliSearch configuration └─────────────────────────────
|
|
||||||
|
|
||||||
# You can set scope to local (default value) or global
|
|
||||||
# (include notes from remote).
|
|
||||||
|
|
||||||
#meilisearch:
|
|
||||||
# host: meilisearch
|
|
||||||
# port: 7700
|
|
||||||
# apiKey: ''
|
|
||||||
# ssl: true
|
|
||||||
# index: ''
|
|
||||||
# scope: local
|
|
||||||
|
|
||||||
# ┌───────────────┐
|
|
||||||
#───┘ ID generation └───────────────────────────────────────────
|
|
||||||
|
|
||||||
# You can select the ID generation method.
|
|
||||||
# You don't usually need to change this setting, but you can
|
|
||||||
# change it according to your preferences.
|
|
||||||
|
|
||||||
# Available methods:
|
|
||||||
# aid ... Short, Millisecond accuracy
|
|
||||||
# aidx ... Millisecond accuracy
|
|
||||||
# meid ... Similar to ObjectID, Millisecond accuracy
|
|
||||||
# ulid ... Millisecond accuracy
|
|
||||||
# objectid ... This is left for backward compatibility
|
|
||||||
|
|
||||||
# ONCE YOU HAVE STARTED THE INSTANCE, DO NOT CHANGE THE
|
|
||||||
# ID SETTINGS AFTER THAT!
|
|
||||||
|
|
||||||
id: 'aidx'
|
|
||||||
|
|
||||||
# ┌────────────────┐
|
|
||||||
#───┘ Error tracking └──────────────────────────────────────────
|
|
||||||
|
|
||||||
# Sentry is available for error tracking.
|
|
||||||
# See the Sentry documentation for more details on options.
|
|
||||||
|
|
||||||
#sentryForBackend:
|
|
||||||
# enableNodeProfiling: true
|
|
||||||
# options:
|
|
||||||
# dsn: 'https://examplePublicKey@o0.ingest.sentry.io/0'
|
|
||||||
|
|
||||||
#sentryForFrontend:
|
|
||||||
# options:
|
|
||||||
# dsn: 'https://examplePublicKey@o0.ingest.sentry.io/0'
|
|
||||||
|
|
||||||
# ┌─────────────────────┐
|
|
||||||
#───┘ Other configuration └─────────────────────────────────────
|
|
||||||
|
|
||||||
# Whether disable HSTS
|
|
||||||
#disableHsts: true
|
|
||||||
|
|
||||||
# Number of worker processes
|
|
||||||
#clusterLimit: 1
|
|
||||||
|
|
||||||
# Job concurrency per worker
|
|
||||||
# deliverJobConcurrency: 128
|
|
||||||
# inboxJobConcurrency: 16
|
|
||||||
|
|
||||||
# Job rate limiter
|
|
||||||
# deliverJobPerSec: 128
|
|
||||||
# inboxJobPerSec: 32
|
|
||||||
|
|
||||||
# Job attempts
|
|
||||||
# deliverJobMaxAttempts: 12
|
|
||||||
# inboxJobMaxAttempts: 8
|
|
||||||
|
|
||||||
# IP address family used for outgoing request (ipv4, ipv6 or dual)
|
|
||||||
#outgoingAddressFamily: ipv4
|
|
||||||
|
|
||||||
# Proxy for HTTP/HTTPS
|
|
||||||
#proxy: http://127.0.0.1:3128
|
|
||||||
|
|
||||||
proxyBypassHosts:
|
|
||||||
- api.deepl.com
|
|
||||||
- api-free.deepl.com
|
|
||||||
- www.recaptcha.net
|
|
||||||
- hcaptcha.com
|
|
||||||
- challenges.cloudflare.com
|
|
||||||
|
|
||||||
# Proxy for SMTP/SMTPS
|
|
||||||
#proxySmtp: http://127.0.0.1:3128 # use HTTP/1.1 CONNECT
|
|
||||||
#proxySmtp: socks4://127.0.0.1:1080 # use SOCKS4
|
|
||||||
#proxySmtp: socks5://127.0.0.1:1080 # use SOCKS5
|
|
||||||
|
|
||||||
# Media Proxy
|
|
||||||
#mediaProxy: https://example.com/proxy
|
|
||||||
|
|
||||||
# Proxy remote files (default: true)
|
|
||||||
proxyRemoteFiles: true
|
|
||||||
|
|
||||||
# Sign to ActivityPub GET request (default: true)
|
|
||||||
signToActivityPubGet: true
|
|
||||||
|
|
||||||
# For security reasons, uploading attachments from the intranet is prohibited,
|
|
||||||
# but exceptions can be made from the following settings. Default value is "undefined".
|
|
||||||
# Read changelog to learn more (Improvements of 12.90.0 (2021/09/04)).
|
|
||||||
#allowedPrivateNetworks: [
|
|
||||||
# '127.0.0.1/32'
|
|
||||||
#]
|
|
||||||
|
|
||||||
# Upload or download file size limits (bytes)
|
|
||||||
#maxFileSize: 262144000
|
|
@ -2,77 +2,6 @@
|
|||||||
# Misskey configuration
|
# Misskey configuration
|
||||||
#━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
#━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||||
|
|
||||||
# ┌──────────────────────────────┐
|
|
||||||
#───┘ a boring but important thing └────────────────────────────
|
|
||||||
|
|
||||||
#
|
|
||||||
# First of all, let me tell you a story that may possibly be
|
|
||||||
# boring to you and possibly important to you.
|
|
||||||
#
|
|
||||||
# Misskey is licensed under the AGPLv3 license. This license is
|
|
||||||
# known to be often misunderstood. Please read the following
|
|
||||||
# instructions carefully and select the appropriate option so
|
|
||||||
# that you do not negligently cause a license violation.
|
|
||||||
#
|
|
||||||
|
|
||||||
# --------
|
|
||||||
# Option 1: If you host Misskey AS-IS (without any changes to
|
|
||||||
# the source code. forks are not included).
|
|
||||||
#
|
|
||||||
# Step 1: Congratulations! You don't need to do anything.
|
|
||||||
|
|
||||||
# --------
|
|
||||||
# Option 2: If you have made changes to the source code (forks
|
|
||||||
# are included) and publish a Git repository of source
|
|
||||||
# code. There should be no access restrictions on
|
|
||||||
# this repository. Strictly speaking, it doesn't have
|
|
||||||
# to be a Git repository, but you'll probably use Git!
|
|
||||||
#
|
|
||||||
# Step 1: Build and run the Misskey server first.
|
|
||||||
# Step 2: Open <https://your.misskey.example/admin/settings> in
|
|
||||||
# your browser with the administrator account.
|
|
||||||
# Step 3: Enter the URL of your Git repository in the
|
|
||||||
# "Repository URL" field.
|
|
||||||
|
|
||||||
# --------
|
|
||||||
# Option 3: If neither of the above applies to you.
|
|
||||||
# (In this case, the source code should be published
|
|
||||||
# on the Misskey interface. IT IS NOT ENOUGH TO
|
|
||||||
# DISCLOSE THE SOURCE CODE WHEN A USER REQUESTS IT BY
|
|
||||||
# E-MAIL OR OTHER MEANS. If you are not satisfied
|
|
||||||
# with this, it is recommended that you read the
|
|
||||||
# license again carefully. Anyway, enabling this
|
|
||||||
# option will automatically generate and publish a
|
|
||||||
# tarball at build time, protecting you from
|
|
||||||
# inadvertent license violations. (There is no legal
|
|
||||||
# guarantee, of course.) The tarball will generated
|
|
||||||
# from the root directory of your codebase. So it is
|
|
||||||
# also recommended to check <built/tarball> directory
|
|
||||||
# once after building and before activating the server
|
|
||||||
# to avoid ACCIDENTAL LEAKING OF SENSITIVE INFORMATION.
|
|
||||||
# To prevent certain files from being included in the
|
|
||||||
# tarball, add a glob pattern after line 15 in
|
|
||||||
# <scripts/tarball.mjs>. DO NOT FORGET TO BUILD AFTER
|
|
||||||
# ENABLING THIS OPTION!)
|
|
||||||
#
|
|
||||||
# Step 1: Uncomment the following line.
|
|
||||||
#
|
|
||||||
# publishTarballInsteadOfProvideRepositoryUrl: true
|
|
||||||
|
|
||||||
# ┌────────────────────────┐
|
|
||||||
#───┘ Initial Setup Password └─────────────────────────────────────────────────────
|
|
||||||
|
|
||||||
# Password to initiate setting up admin account.
|
|
||||||
# It will not be used after the initial setup is complete.
|
|
||||||
#
|
|
||||||
# Be sure to change this when you set up Misskey via the Internet.
|
|
||||||
#
|
|
||||||
# The provider of the service who sets up Misskey on behalf of the customer should
|
|
||||||
# set this value to something unique when generating the Misskey config file,
|
|
||||||
# and provide it to the customer.
|
|
||||||
#
|
|
||||||
# setupPassword: example_password_please_change_this_or_you_will_get_hacked
|
|
||||||
|
|
||||||
# ┌─────┐
|
# ┌─────┐
|
||||||
#───┘ URL └─────────────────────────────────────────────────────
|
#───┘ URL └─────────────────────────────────────────────────────
|
||||||
|
|
||||||
@ -101,10 +30,6 @@ url: https://example.tld/
|
|||||||
# The port that your Misskey server should listen on.
|
# The port that your Misskey server should listen on.
|
||||||
port: 3000
|
port: 3000
|
||||||
|
|
||||||
# You can also use UNIX domain socket.
|
|
||||||
# socket: /path/to/misskey.sock
|
|
||||||
# chmodSocket: '777'
|
|
||||||
|
|
||||||
# ┌──────────────────────────┐
|
# ┌──────────────────────────┐
|
||||||
#───┘ PostgreSQL configuration └────────────────────────────────
|
#───┘ PostgreSQL configuration └────────────────────────────────
|
||||||
|
|
||||||
@ -126,89 +51,25 @@ db:
|
|||||||
#extra:
|
#extra:
|
||||||
# ssl: true
|
# ssl: true
|
||||||
|
|
||||||
dbReplications: false
|
|
||||||
|
|
||||||
# You can configure any number of replicas here
|
|
||||||
#dbSlaves:
|
|
||||||
# -
|
|
||||||
# host:
|
|
||||||
# port:
|
|
||||||
# db:
|
|
||||||
# user:
|
|
||||||
# pass:
|
|
||||||
# -
|
|
||||||
# host:
|
|
||||||
# port:
|
|
||||||
# db:
|
|
||||||
# user:
|
|
||||||
# pass:
|
|
||||||
|
|
||||||
# ┌─────────────────────┐
|
# ┌─────────────────────┐
|
||||||
#───┘ Redis configuration └─────────────────────────────────────
|
#───┘ Redis configuration └─────────────────────────────────────
|
||||||
|
|
||||||
redis:
|
redis:
|
||||||
host: localhost
|
host: localhost
|
||||||
port: 6379
|
port: 6379
|
||||||
#family: 0 # 0=Both, 4=IPv4, 6=IPv6
|
|
||||||
#pass: example-pass
|
#pass: example-pass
|
||||||
#prefix: example-prefix
|
#prefix: example-prefix
|
||||||
#db: 1
|
#db: 1
|
||||||
# You can specify more ioredis options...
|
|
||||||
#username: example-username
|
|
||||||
|
|
||||||
#redisForPubsub:
|
# ┌─────────────────────────────┐
|
||||||
|
#───┘ Elasticsearch configuration └─────────────────────────────
|
||||||
|
|
||||||
|
#elasticsearch:
|
||||||
# host: localhost
|
# host: localhost
|
||||||
# port: 6379
|
# port: 9200
|
||||||
# #family: 0 # 0=Both, 4=IPv4, 6=IPv6
|
# ssl: false
|
||||||
# #pass: example-pass
|
# user:
|
||||||
# #prefix: example-prefix
|
# pass:
|
||||||
# #db: 1
|
|
||||||
# # You can specify more ioredis options...
|
|
||||||
# #username: example-username
|
|
||||||
|
|
||||||
#redisForJobQueue:
|
|
||||||
# host: localhost
|
|
||||||
# port: 6379
|
|
||||||
# #family: 0 # 0=Both, 4=IPv4, 6=IPv6
|
|
||||||
# #pass: example-pass
|
|
||||||
# #prefix: example-prefix
|
|
||||||
# #db: 1
|
|
||||||
# # You can specify more ioredis options...
|
|
||||||
# #username: example-username
|
|
||||||
|
|
||||||
#redisForTimelines:
|
|
||||||
# host: localhost
|
|
||||||
# port: 6379
|
|
||||||
# #family: 0 # 0=Both, 4=IPv4, 6=IPv6
|
|
||||||
# #pass: example-pass
|
|
||||||
# #prefix: example-prefix
|
|
||||||
# #db: 1
|
|
||||||
# # You can specify more ioredis options...
|
|
||||||
# #username: example-username
|
|
||||||
|
|
||||||
#redisForReactions:
|
|
||||||
# host: localhost
|
|
||||||
# port: 6379
|
|
||||||
# #family: 0 # 0=Both, 4=IPv4, 6=IPv6
|
|
||||||
# #pass: example-pass
|
|
||||||
# #prefix: example-prefix
|
|
||||||
# #db: 1
|
|
||||||
# # You can specify more ioredis options...
|
|
||||||
# #username: example-username
|
|
||||||
|
|
||||||
# ┌───────────────────────────┐
|
|
||||||
#───┘ MeiliSearch configuration └─────────────────────────────
|
|
||||||
|
|
||||||
# You can set scope to local (default value) or global
|
|
||||||
# (include notes from remote).
|
|
||||||
|
|
||||||
#meilisearch:
|
|
||||||
# host: localhost
|
|
||||||
# port: 7700
|
|
||||||
# apiKey: ''
|
|
||||||
# ssl: true
|
|
||||||
# index: ''
|
|
||||||
# scope: local
|
|
||||||
|
|
||||||
# ┌───────────────┐
|
# ┌───────────────┐
|
||||||
#───┘ ID generation └───────────────────────────────────────────
|
#───┘ ID generation └───────────────────────────────────────────
|
||||||
@ -219,7 +80,6 @@ redis:
|
|||||||
|
|
||||||
# Available methods:
|
# Available methods:
|
||||||
# aid ... Short, Millisecond accuracy
|
# aid ... Short, Millisecond accuracy
|
||||||
# aidx ... Millisecond accuracy
|
|
||||||
# meid ... Similar to ObjectID, Millisecond accuracy
|
# meid ... Similar to ObjectID, Millisecond accuracy
|
||||||
# ulid ... Millisecond accuracy
|
# ulid ... Millisecond accuracy
|
||||||
# objectid ... This is left for backward compatibility
|
# objectid ... This is left for backward compatibility
|
||||||
@ -227,22 +87,7 @@ redis:
|
|||||||
# ONCE YOU HAVE STARTED THE INSTANCE, DO NOT CHANGE THE
|
# ONCE YOU HAVE STARTED THE INSTANCE, DO NOT CHANGE THE
|
||||||
# ID SETTINGS AFTER THAT!
|
# ID SETTINGS AFTER THAT!
|
||||||
|
|
||||||
id: 'aidx'
|
id: 'aid'
|
||||||
|
|
||||||
# ┌────────────────┐
|
|
||||||
#───┘ Error tracking └──────────────────────────────────────────
|
|
||||||
|
|
||||||
# Sentry is available for error tracking.
|
|
||||||
# See the Sentry documentation for more details on options.
|
|
||||||
|
|
||||||
#sentryForBackend:
|
|
||||||
# enableNodeProfiling: true
|
|
||||||
# options:
|
|
||||||
# dsn: 'https://examplePublicKey@o0.ingest.sentry.io/0'
|
|
||||||
|
|
||||||
#sentryForFrontend:
|
|
||||||
# options:
|
|
||||||
# dsn: 'https://examplePublicKey@o0.ingest.sentry.io/0'
|
|
||||||
|
|
||||||
# ┌─────────────────────┐
|
# ┌─────────────────────┐
|
||||||
#───┘ Other configuration └─────────────────────────────────────
|
#───┘ Other configuration └─────────────────────────────────────
|
||||||
@ -256,34 +101,30 @@ id: 'aidx'
|
|||||||
# Job concurrency per worker
|
# Job concurrency per worker
|
||||||
# deliverJobConcurrency: 128
|
# deliverJobConcurrency: 128
|
||||||
# inboxJobConcurrency: 16
|
# inboxJobConcurrency: 16
|
||||||
#relationshipJobConcurrency: 16
|
|
||||||
# What's relationshipJob?:
|
|
||||||
# Follow, unfollow, block and unblock(ings) while following-imports, etc. or account migrations.
|
|
||||||
|
|
||||||
# Job rate limiter
|
# Job rate limiter
|
||||||
# deliverJobPerSec: 128
|
# deliverJobPerSec: 128
|
||||||
#inboxJobPerSec: 32
|
# inboxJobPerSec: 16
|
||||||
#relationshipJobPerSec: 64
|
|
||||||
|
|
||||||
# Job attempts
|
# Job attempts
|
||||||
# deliverJobMaxAttempts: 12
|
# deliverJobMaxAttempts: 12
|
||||||
# inboxJobMaxAttempts: 8
|
# inboxJobMaxAttempts: 8
|
||||||
|
|
||||||
# Local address used for outgoing requests
|
|
||||||
#outgoingAddress: 127.0.0.1
|
|
||||||
|
|
||||||
# IP address family used for outgoing request (ipv4, ipv6 or dual)
|
# IP address family used for outgoing request (ipv4, ipv6 or dual)
|
||||||
#outgoingAddressFamily: ipv4
|
#outgoingAddressFamily: ipv4
|
||||||
|
|
||||||
|
# Syslog option
|
||||||
|
#syslog:
|
||||||
|
# host: localhost
|
||||||
|
# port: 514
|
||||||
|
|
||||||
# Proxy for HTTP/HTTPS
|
# Proxy for HTTP/HTTPS
|
||||||
#proxy: http://127.0.0.1:3128
|
#proxy: http://127.0.0.1:3128
|
||||||
|
|
||||||
proxyBypassHosts:
|
#proxyBypassHosts: [
|
||||||
- api.deepl.com
|
# 'example.com',
|
||||||
- api-free.deepl.com
|
# '192.0.2.8'
|
||||||
- www.recaptcha.net
|
#]
|
||||||
- hcaptcha.com
|
|
||||||
- challenges.cloudflare.com
|
|
||||||
|
|
||||||
# Proxy for SMTP/SMTPS
|
# Proxy for SMTP/SMTPS
|
||||||
#proxySmtp: http://127.0.0.1:3128 # use HTTP/1.1 CONNECT
|
#proxySmtp: http://127.0.0.1:3128 # use HTTP/1.1 CONNECT
|
||||||
@ -291,33 +132,17 @@ proxyBypassHosts:
|
|||||||
#proxySmtp: socks5://127.0.0.1:1080 # use SOCKS5
|
#proxySmtp: socks5://127.0.0.1:1080 # use SOCKS5
|
||||||
|
|
||||||
# Media Proxy
|
# Media Proxy
|
||||||
# Reference Implementation: https://github.com/misskey-dev/media-proxy
|
|
||||||
# * Deliver a common cache between instances
|
|
||||||
# * Perform image compression (on a different server resource than the main process)
|
|
||||||
#mediaProxy: https://example.com/proxy
|
#mediaProxy: https://example.com/proxy
|
||||||
|
|
||||||
# Proxy remote files (default: true)
|
# Proxy remote files (default: false)
|
||||||
# Proxy remote files by this instance or mediaProxy to prevent remote files from running in remote domains.
|
#proxyRemoteFiles: true
|
||||||
proxyRemoteFiles: true
|
|
||||||
|
|
||||||
# Movie Thumbnail Generation URL
|
# Sign to ActivityPub GET request (default: false)
|
||||||
# There is no reference implementation.
|
#signToActivityPubGet: true
|
||||||
# For example, Misskey will point to the following URL:
|
|
||||||
# https://example.com/thumbnail.webp?thumbnail=1&url=https%3A%2F%2Fstorage.example.com%2Fpath%2Fto%2Fvideo.mp4
|
|
||||||
#videoThumbnailGenerator: https://example.com
|
|
||||||
|
|
||||||
# Sign to ActivityPub GET request (default: true)
|
|
||||||
signToActivityPubGet: true
|
|
||||||
|
|
||||||
# For security reasons, uploading attachments from the intranet is prohibited,
|
|
||||||
# but exceptions can be made from the following settings. Default value is "undefined".
|
|
||||||
# Read changelog to learn more (Improvements of 12.90.0 (2021/09/04)).
|
|
||||||
#allowedPrivateNetworks: [
|
#allowedPrivateNetworks: [
|
||||||
# '127.0.0.1/32'
|
# '127.0.0.1/32'
|
||||||
#]
|
#]
|
||||||
|
|
||||||
# Upload or download file size limits (bytes)
|
# Upload or download file size limits (bytes)
|
||||||
#maxFileSize: 262144000
|
#maxFileSize: 262144000
|
||||||
|
|
||||||
# PID File of master process
|
|
||||||
#pidFile: /tmp/misskey.pid
|
|
||||||
|
@ -1 +0,0 @@
|
|||||||
FROM mcr.microsoft.com/devcontainers/javascript-node:0-18
|
|
@ -1,53 +0,0 @@
|
|||||||
services:
|
|
||||||
app:
|
|
||||||
build:
|
|
||||||
context: .
|
|
||||||
dockerfile: Dockerfile
|
|
||||||
|
|
||||||
volumes:
|
|
||||||
- ../:/workspace:cached
|
|
||||||
- node_modules:/workspace/node_modules
|
|
||||||
|
|
||||||
command: sleep infinity
|
|
||||||
|
|
||||||
networks:
|
|
||||||
- internal_network
|
|
||||||
- external_network
|
|
||||||
|
|
||||||
redis:
|
|
||||||
restart: unless-stopped
|
|
||||||
image: redis:7-alpine
|
|
||||||
networks:
|
|
||||||
- internal_network
|
|
||||||
volumes:
|
|
||||||
- redis-data:/data
|
|
||||||
healthcheck:
|
|
||||||
test: "redis-cli ping"
|
|
||||||
interval: 5s
|
|
||||||
retries: 20
|
|
||||||
|
|
||||||
db:
|
|
||||||
restart: unless-stopped
|
|
||||||
image: postgres:15-alpine
|
|
||||||
networks:
|
|
||||||
- internal_network
|
|
||||||
environment:
|
|
||||||
POSTGRES_USER: postgres
|
|
||||||
POSTGRES_PASSWORD: postgres
|
|
||||||
POSTGRES_DB: misskey
|
|
||||||
volumes:
|
|
||||||
- postgres-data:/var/lib/postgresql/data
|
|
||||||
healthcheck:
|
|
||||||
test: "pg_isready -U $$POSTGRES_USER -d $$POSTGRES_DB"
|
|
||||||
interval: 5s
|
|
||||||
retries: 20
|
|
||||||
|
|
||||||
volumes:
|
|
||||||
postgres-data:
|
|
||||||
redis-data:
|
|
||||||
node_modules:
|
|
||||||
|
|
||||||
networks:
|
|
||||||
internal_network:
|
|
||||||
internal: true
|
|
||||||
external_network:
|
|
@ -1,26 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "Misskey",
|
|
||||||
"dockerComposeFile": "compose.yml",
|
|
||||||
"service": "app",
|
|
||||||
"workspaceFolder": "/workspace",
|
|
||||||
"features": {
|
|
||||||
"ghcr.io/devcontainers/features/node:1": {
|
|
||||||
"version": "20.16.0"
|
|
||||||
},
|
|
||||||
"ghcr.io/devcontainers-contrib/features/corepack:1": {}
|
|
||||||
},
|
|
||||||
"forwardPorts": [3000],
|
|
||||||
"postCreateCommand": "/bin/bash .devcontainer/init.sh",
|
|
||||||
"customizations": {
|
|
||||||
"vscode": {
|
|
||||||
"extensions": [
|
|
||||||
"editorconfig.editorconfig",
|
|
||||||
"dbaeumer.vscode-eslint",
|
|
||||||
"Vue.volar",
|
|
||||||
"Orta.vscode-jest",
|
|
||||||
"dbaeumer.vscode-eslint",
|
|
||||||
"mrmlnc.vscode-json5"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,211 +0,0 @@
|
|||||||
#━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
||||||
# Misskey configuration
|
|
||||||
#━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
||||||
|
|
||||||
# ┌─────┐
|
|
||||||
#───┘ URL └─────────────────────────────────────────────────────
|
|
||||||
|
|
||||||
# Final accessible URL seen by a user.
|
|
||||||
url: http://127.0.0.1:3000/
|
|
||||||
|
|
||||||
# ONCE YOU HAVE STARTED THE INSTANCE, DO NOT CHANGE THE
|
|
||||||
# URL SETTINGS AFTER THAT!
|
|
||||||
|
|
||||||
# ┌───────────────────────┐
|
|
||||||
#───┘ Port and TLS settings └───────────────────────────────────
|
|
||||||
|
|
||||||
#
|
|
||||||
# Misskey requires a reverse proxy to support HTTPS connections.
|
|
||||||
#
|
|
||||||
# +----- https://example.tld/ ------------+
|
|
||||||
# +------+ |+-------------+ +----------------+|
|
|
||||||
# | User | ---> || Proxy (443) | ---> | Misskey (3000) ||
|
|
||||||
# +------+ |+-------------+ +----------------+|
|
|
||||||
# +---------------------------------------+
|
|
||||||
#
|
|
||||||
# You need to set up a reverse proxy. (e.g. nginx)
|
|
||||||
# An encrypted connection with HTTPS is highly recommended
|
|
||||||
# because tokens may be transferred in GET requests.
|
|
||||||
|
|
||||||
# The port that your Misskey server should listen on.
|
|
||||||
port: 3000
|
|
||||||
|
|
||||||
# ┌──────────────────────────┐
|
|
||||||
#───┘ PostgreSQL configuration └────────────────────────────────
|
|
||||||
|
|
||||||
db:
|
|
||||||
host: db
|
|
||||||
port: 5432
|
|
||||||
|
|
||||||
# Database name
|
|
||||||
db: misskey
|
|
||||||
|
|
||||||
# Auth
|
|
||||||
user: postgres
|
|
||||||
pass: postgres
|
|
||||||
|
|
||||||
# Whether disable Caching queries
|
|
||||||
#disableCache: true
|
|
||||||
|
|
||||||
# Extra Connection options
|
|
||||||
#extra:
|
|
||||||
# ssl: true
|
|
||||||
|
|
||||||
dbReplications: false
|
|
||||||
|
|
||||||
# You can configure any number of replicas here
|
|
||||||
#dbSlaves:
|
|
||||||
# -
|
|
||||||
# host:
|
|
||||||
# port:
|
|
||||||
# db:
|
|
||||||
# user:
|
|
||||||
# pass:
|
|
||||||
# -
|
|
||||||
# host:
|
|
||||||
# port:
|
|
||||||
# db:
|
|
||||||
# user:
|
|
||||||
# pass:
|
|
||||||
|
|
||||||
# ┌─────────────────────┐
|
|
||||||
#───┘ Redis configuration └─────────────────────────────────────
|
|
||||||
|
|
||||||
redis:
|
|
||||||
host: redis
|
|
||||||
port: 6379
|
|
||||||
#family: 0 # 0=Both, 4=IPv4, 6=IPv6
|
|
||||||
#pass: example-pass
|
|
||||||
#prefix: example-prefix
|
|
||||||
#db: 1
|
|
||||||
|
|
||||||
#redisForPubsub:
|
|
||||||
# host: redis
|
|
||||||
# port: 6379
|
|
||||||
# #family: 0 # 0=Both, 4=IPv4, 6=IPv6
|
|
||||||
# #pass: example-pass
|
|
||||||
# #prefix: example-prefix
|
|
||||||
# #db: 1
|
|
||||||
|
|
||||||
#redisForJobQueue:
|
|
||||||
# host: redis
|
|
||||||
# port: 6379
|
|
||||||
# #family: 0 # 0=Both, 4=IPv4, 6=IPv6
|
|
||||||
# #pass: example-pass
|
|
||||||
# #prefix: example-prefix
|
|
||||||
# #db: 1
|
|
||||||
|
|
||||||
#redisForTimelines:
|
|
||||||
# host: redis
|
|
||||||
# port: 6379
|
|
||||||
# #family: 0 # 0=Both, 4=IPv4, 6=IPv6
|
|
||||||
# #pass: example-pass
|
|
||||||
# #prefix: example-prefix
|
|
||||||
# #db: 1
|
|
||||||
|
|
||||||
#redisForReactions:
|
|
||||||
# host: redis
|
|
||||||
# port: 6379
|
|
||||||
# #family: 0 # 0=Both, 4=IPv4, 6=IPv6
|
|
||||||
# #pass: example-pass
|
|
||||||
# #prefix: example-prefix
|
|
||||||
# #db: 1
|
|
||||||
|
|
||||||
# ┌───────────────────────────┐
|
|
||||||
#───┘ MeiliSearch configuration └─────────────────────────────
|
|
||||||
|
|
||||||
#meilisearch:
|
|
||||||
# host: meilisearch
|
|
||||||
# port: 7700
|
|
||||||
# apiKey: ''
|
|
||||||
# ssl: true
|
|
||||||
# index: ''
|
|
||||||
|
|
||||||
# ┌───────────────┐
|
|
||||||
#───┘ ID generation └───────────────────────────────────────────
|
|
||||||
|
|
||||||
# You can select the ID generation method.
|
|
||||||
# You don't usually need to change this setting, but you can
|
|
||||||
# change it according to your preferences.
|
|
||||||
|
|
||||||
# Available methods:
|
|
||||||
# aid ... Short, Millisecond accuracy
|
|
||||||
# aidx ... Millisecond accuracy
|
|
||||||
# meid ... Similar to ObjectID, Millisecond accuracy
|
|
||||||
# ulid ... Millisecond accuracy
|
|
||||||
# objectid ... This is left for backward compatibility
|
|
||||||
|
|
||||||
# ONCE YOU HAVE STARTED THE INSTANCE, DO NOT CHANGE THE
|
|
||||||
# ID SETTINGS AFTER THAT!
|
|
||||||
|
|
||||||
id: 'aidx'
|
|
||||||
|
|
||||||
# ┌────────────────┐
|
|
||||||
#───┘ Error tracking └──────────────────────────────────────────
|
|
||||||
|
|
||||||
# Sentry is available for error tracking.
|
|
||||||
# See the Sentry documentation for more details on options.
|
|
||||||
|
|
||||||
#sentryForBackend:
|
|
||||||
# enableNodeProfiling: true
|
|
||||||
# options:
|
|
||||||
# dsn: 'https://examplePublicKey@o0.ingest.sentry.io/0'
|
|
||||||
|
|
||||||
#sentryForFrontend:
|
|
||||||
# options:
|
|
||||||
# dsn: 'https://examplePublicKey@o0.ingest.sentry.io/0'
|
|
||||||
|
|
||||||
# ┌─────────────────────┐
|
|
||||||
#───┘ Other configuration └─────────────────────────────────────
|
|
||||||
|
|
||||||
# Whether disable HSTS
|
|
||||||
#disableHsts: true
|
|
||||||
|
|
||||||
# Number of worker processes
|
|
||||||
#clusterLimit: 1
|
|
||||||
|
|
||||||
# Job concurrency per worker
|
|
||||||
# deliverJobConcurrency: 128
|
|
||||||
# inboxJobConcurrency: 16
|
|
||||||
|
|
||||||
# Job rate limiter
|
|
||||||
# deliverJobPerSec: 128
|
|
||||||
# inboxJobPerSec: 32
|
|
||||||
|
|
||||||
# Job attempts
|
|
||||||
# deliverJobMaxAttempts: 12
|
|
||||||
# inboxJobMaxAttempts: 8
|
|
||||||
|
|
||||||
# IP address family used for outgoing request (ipv4, ipv6 or dual)
|
|
||||||
#outgoingAddressFamily: ipv4
|
|
||||||
|
|
||||||
# Proxy for HTTP/HTTPS
|
|
||||||
#proxy: http://127.0.0.1:3128
|
|
||||||
|
|
||||||
proxyBypassHosts:
|
|
||||||
- api.deepl.com
|
|
||||||
- api-free.deepl.com
|
|
||||||
- www.recaptcha.net
|
|
||||||
- hcaptcha.com
|
|
||||||
- challenges.cloudflare.com
|
|
||||||
|
|
||||||
# Proxy for SMTP/SMTPS
|
|
||||||
#proxySmtp: http://127.0.0.1:3128 # use HTTP/1.1 CONNECT
|
|
||||||
#proxySmtp: socks4://127.0.0.1:1080 # use SOCKS4
|
|
||||||
#proxySmtp: socks5://127.0.0.1:1080 # use SOCKS5
|
|
||||||
|
|
||||||
# Media Proxy
|
|
||||||
#mediaProxy: https://example.com/proxy
|
|
||||||
|
|
||||||
# Proxy remote files (default: true)
|
|
||||||
proxyRemoteFiles: true
|
|
||||||
|
|
||||||
# Sign to ActivityPub GET request (default: true)
|
|
||||||
signToActivityPubGet: true
|
|
||||||
|
|
||||||
allowedPrivateNetworks: [
|
|
||||||
'127.0.0.1/32'
|
|
||||||
]
|
|
||||||
|
|
||||||
# Upload or download file size limits (bytes)
|
|
||||||
#maxFileSize: 262144000
|
|
@ -1,17 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
set -xe
|
|
||||||
|
|
||||||
sudo chown node node_modules
|
|
||||||
sudo apt-get update
|
|
||||||
sudo apt-get -y install libgtk2.0-0 libgtk-3-0 libgbm-dev libnotify-dev libnss3 libxss1 libasound2 libxtst6 xauth xvfb
|
|
||||||
git config --global --add safe.directory /workspace
|
|
||||||
git submodule update --init
|
|
||||||
corepack install
|
|
||||||
corepack enable
|
|
||||||
pnpm config set store-dir /home/node/.local/share/pnpm/store
|
|
||||||
pnpm install --frozen-lockfile
|
|
||||||
cp .devcontainer/devcontainer.yml .config/default.yml
|
|
||||||
pnpm build
|
|
||||||
pnpm migrate
|
|
||||||
pnpm exec cypress install
|
|
@ -7,24 +7,9 @@ Dockerfile
|
|||||||
build/
|
build/
|
||||||
built/
|
built/
|
||||||
db/
|
db/
|
||||||
.devcontainer/compose.yml
|
docker-compose.yml
|
||||||
|
elasticsearch/
|
||||||
node_modules/
|
node_modules/
|
||||||
packages/*/node_modules
|
|
||||||
redis/
|
redis/
|
||||||
files/
|
files/
|
||||||
fluent-emojis/
|
misskey-assets/
|
||||||
.pnp.*
|
|
||||||
|
|
||||||
# .yarn関連
|
|
||||||
.yarn/*
|
|
||||||
!.yarn/patches
|
|
||||||
!.yarn/plugins
|
|
||||||
!.yarn/releases
|
|
||||||
!.yarn/sdks
|
|
||||||
!.yarn/versions
|
|
||||||
|
|
||||||
.pnpm-store
|
|
||||||
|
|
||||||
.idea/
|
|
||||||
packages/*/.vscode/
|
|
||||||
packages/backend/test/compose.yml
|
|
||||||
|
@ -1,3 +0,0 @@
|
|||||||
DKL-DI-0005
|
|
||||||
DKL-DI-0006
|
|
||||||
DKL-LI-0003
|
|
@ -5,11 +5,6 @@ indent_style = tab
|
|||||||
indent_size = 2
|
indent_size = 2
|
||||||
charset = utf-8
|
charset = utf-8
|
||||||
insert_final_newline = true
|
insert_final_newline = true
|
||||||
end_of_line = lf
|
|
||||||
trim_trailing_whitespace = true
|
|
||||||
|
|
||||||
[*.md]
|
[*.yml]
|
||||||
trim_trailing_whitespace = false
|
|
||||||
|
|
||||||
[*.{yml,yaml}]
|
|
||||||
indent_style = space
|
indent_style = space
|
||||||
|
1
.gitattributes
vendored
1
.gitattributes
vendored
@ -5,4 +5,3 @@
|
|||||||
*.glb -diff -text
|
*.glb -diff -text
|
||||||
*.blend -diff -text
|
*.blend -diff -text
|
||||||
*.afdesign -diff -text
|
*.afdesign -diff -text
|
||||||
* text=auto eol=lf
|
|
||||||
|
3
.github/FUNDING.yml
vendored
Normal file
3
.github/FUNDING.yml
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
# These are supported funding model platforms
|
||||||
|
|
||||||
|
patreon: syuilo
|
42
.github/ISSUE_TEMPLATE/01_bug-report.md
vendored
Normal file
42
.github/ISSUE_TEMPLATE/01_bug-report.md
vendored
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
---
|
||||||
|
name: 🐛 Bug Report
|
||||||
|
about: Create a report to help us improve
|
||||||
|
title: ''
|
||||||
|
labels: ⚠️bug?
|
||||||
|
assignees: ''
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Thanks for reporting!
|
||||||
|
First, in order to avoid duplicate Issues, please search to see if the problem you found has already been reported.
|
||||||
|
-->
|
||||||
|
|
||||||
|
## 💡 Summary
|
||||||
|
|
||||||
|
<!-- Tell us what the bug is -->
|
||||||
|
|
||||||
|
## 🥰 Expected Behavior
|
||||||
|
|
||||||
|
<!--- Tell us what should happen -->
|
||||||
|
|
||||||
|
## 🤬 Actual Behavior
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Tell us what happens instead of the expected behavior.
|
||||||
|
Please include errors from the developer console and/or server log files if you have access to them.
|
||||||
|
-->
|
||||||
|
|
||||||
|
## 📝 Steps to Reproduce
|
||||||
|
|
||||||
|
1.
|
||||||
|
2.
|
||||||
|
3.
|
||||||
|
|
||||||
|
## 📌 Environment
|
||||||
|
|
||||||
|
<!-- Tell us where on the platform it happens -->
|
||||||
|
|
||||||
|
Misskey version:
|
||||||
|
Your OS:
|
||||||
|
Your browser:
|
97
.github/ISSUE_TEMPLATE/01_bug-report.yml
vendored
97
.github/ISSUE_TEMPLATE/01_bug-report.yml
vendored
@ -1,97 +0,0 @@
|
|||||||
name: 🐛 Bug Report
|
|
||||||
description: Create a report to help us improve
|
|
||||||
labels: ["⚠️bug?"]
|
|
||||||
|
|
||||||
body:
|
|
||||||
- type: markdown
|
|
||||||
attributes:
|
|
||||||
value: |
|
|
||||||
Thanks for reporting!
|
|
||||||
First, in order to avoid duplicate Issues, please search to see if the problem you found has already been reported.
|
|
||||||
Also, If you are NOT owner/admin of server, PLEASE DONT REPORT SERVER SPECIFIC ISSUES TO HERE! (e.g. feature XXX is not working in misskey.example) Please try with another misskey servers, and if your issue is only reproducible with specific server, contact your server's owner/admin first.
|
|
||||||
|
|
||||||
- type: textarea
|
|
||||||
attributes:
|
|
||||||
label: 💡 Summary
|
|
||||||
description: Tell us what the bug is
|
|
||||||
validations:
|
|
||||||
required: true
|
|
||||||
|
|
||||||
- type: textarea
|
|
||||||
attributes:
|
|
||||||
label: 🥰 Expected Behavior
|
|
||||||
description: Tell us what should happen
|
|
||||||
validations:
|
|
||||||
required: true
|
|
||||||
|
|
||||||
- type: textarea
|
|
||||||
attributes:
|
|
||||||
label: 🤬 Actual Behavior
|
|
||||||
description: |
|
|
||||||
Tell us what happens instead of the expected behavior.
|
|
||||||
Please include errors from the developer console and/or server log files if you have access to them.
|
|
||||||
validations:
|
|
||||||
required: true
|
|
||||||
|
|
||||||
- type: textarea
|
|
||||||
attributes:
|
|
||||||
label: 📝 Steps to Reproduce
|
|
||||||
placeholder: |
|
|
||||||
1.
|
|
||||||
2.
|
|
||||||
3.
|
|
||||||
validations:
|
|
||||||
required: false
|
|
||||||
|
|
||||||
- type: textarea
|
|
||||||
attributes:
|
|
||||||
label: 💻 Frontend Environment
|
|
||||||
description: |
|
|
||||||
Tell us where on the platform it happens
|
|
||||||
DO NOT WRITE "latest". Please provide the specific version.
|
|
||||||
|
|
||||||
Examples:
|
|
||||||
* Model and OS of the device(s): MacBook Pro (14inch, 2021), macOS Ventura 13.4
|
|
||||||
* Browser: Chrome 113.0.5672.126
|
|
||||||
* Server URL: misskey.example.com
|
|
||||||
* Misskey: 2024.x.x
|
|
||||||
value: |
|
|
||||||
* Model and OS of the device(s):
|
|
||||||
* Browser:
|
|
||||||
* Server URL:
|
|
||||||
* Misskey:
|
|
||||||
render: markdown
|
|
||||||
validations:
|
|
||||||
required: false
|
|
||||||
|
|
||||||
- type: textarea
|
|
||||||
attributes:
|
|
||||||
label: 🛰 Backend Environment (for server admin)
|
|
||||||
description: |
|
|
||||||
Tell us where on the platform it happens
|
|
||||||
DO NOT WRITE "latest". Please provide the specific version.
|
|
||||||
If you are using a managed service, put that after the version.
|
|
||||||
|
|
||||||
Examples:
|
|
||||||
* Installation Method or Hosting Service: docker compose, k8s/docker, systemd, "Misskey install shell script", development environment
|
|
||||||
* Misskey: 2024.x.x
|
|
||||||
* Node: 20.x.x
|
|
||||||
* PostgreSQL: 15.x.x
|
|
||||||
* Redis: 7.x.x
|
|
||||||
* OS and Architecture: Ubuntu 24.04.2 LTS aarch64
|
|
||||||
value: |
|
|
||||||
* Installation Method or Hosting Service:
|
|
||||||
* Misskey:
|
|
||||||
* Node:
|
|
||||||
* PostgreSQL:
|
|
||||||
* Redis:
|
|
||||||
* OS and Architecture:
|
|
||||||
render: markdown
|
|
||||||
validations:
|
|
||||||
required: false
|
|
||||||
|
|
||||||
- type: checkboxes
|
|
||||||
attributes:
|
|
||||||
label: Do you want to address this bug yourself?
|
|
||||||
options:
|
|
||||||
- label: Yes, I will patch the bug myself and send a pull request
|
|
12
.github/ISSUE_TEMPLATE/02_feature-request.md
vendored
Normal file
12
.github/ISSUE_TEMPLATE/02_feature-request.md
vendored
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
---
|
||||||
|
name: ✨ Feature Request
|
||||||
|
about: Suggest an idea for this project
|
||||||
|
title: ''
|
||||||
|
labels: ✨Feature
|
||||||
|
assignees: ''
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Summary
|
||||||
|
|
||||||
|
<!-- Tell us what the suggestion is -->
|
22
.github/ISSUE_TEMPLATE/02_feature-request.yml
vendored
22
.github/ISSUE_TEMPLATE/02_feature-request.yml
vendored
@ -1,22 +0,0 @@
|
|||||||
name: ✨ Feature Request
|
|
||||||
description: Suggest an idea for this project
|
|
||||||
labels: ["✨Feature"]
|
|
||||||
|
|
||||||
body:
|
|
||||||
- type: textarea
|
|
||||||
attributes:
|
|
||||||
label: Summary
|
|
||||||
description: Tell us what the suggestion is
|
|
||||||
validations:
|
|
||||||
required: true
|
|
||||||
- type: textarea
|
|
||||||
attributes:
|
|
||||||
label: Purpose
|
|
||||||
description: Describe the specific problem or need you think this feature will solve, and who it will help.
|
|
||||||
validations:
|
|
||||||
required: true
|
|
||||||
- type: checkboxes
|
|
||||||
attributes:
|
|
||||||
label: Do you want to implement this feature yourself?
|
|
||||||
options:
|
|
||||||
- label: Yes, I will implement this by myself and send a pull request
|
|
7
.github/ISSUE_TEMPLATE/config.yml
vendored
7
.github/ISSUE_TEMPLATE/config.yml
vendored
@ -1,8 +1,7 @@
|
|||||||
contact_links:
|
contact_links:
|
||||||
|
- name: 👪 Misskey Forum
|
||||||
|
url: https://forum.misskey.io/
|
||||||
|
about: Ask questions and share knowledge
|
||||||
- name: 💬 Misskey official Discord
|
- name: 💬 Misskey official Discord
|
||||||
url: https://discord.gg/Wp8gVStHW3
|
url: https://discord.gg/Wp8gVStHW3
|
||||||
about: Chat freely about Misskey
|
about: Chat freely about Misskey
|
||||||
# 仮
|
|
||||||
- name: 💬 Start discussion
|
|
||||||
url: https://github.com/misskey-dev/misskey/discussions
|
|
||||||
about: The official forum to join conversation and ask question
|
|
||||||
|
17
.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
17
.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
<!-- ℹ お読みください / README
|
||||||
|
PRありがとうございます! PRを作成する前に、コントリビューションガイドをご確認ください:
|
||||||
|
Thank you for your PR! Before creating a PR, please check the contribution guide:
|
||||||
|
https://github.com/misskey-dev/misskey/blob/develop/CONTRIBUTING.md
|
||||||
|
-->
|
||||||
|
|
||||||
|
# What
|
||||||
|
<!-- このPRで何をしたのか? どう変わるのか? -->
|
||||||
|
<!-- What did you do with this PR? How will it change things? -->
|
||||||
|
|
||||||
|
# Why
|
||||||
|
<!-- なぜそうするのか? どういう意図なのか? 何が困っているのか? -->
|
||||||
|
<!-- Why do you do it? What are your intentions? What is the problem? -->
|
||||||
|
|
||||||
|
# Additional info (optional)
|
||||||
|
<!-- テスト観点など -->
|
||||||
|
<!-- Test perspective, etc -->
|
23
.github/PULL_REQUEST_TEMPLATE/01_bug.md
vendored
23
.github/PULL_REQUEST_TEMPLATE/01_bug.md
vendored
@ -1,23 +0,0 @@
|
|||||||
<!-- ℹ お読みください / README
|
|
||||||
PRありがとうございます! PRを作成する前に、コントリビューションガイドをご確認ください:
|
|
||||||
Thank you for your PR! Before creating a PR, please check the contribution guide:
|
|
||||||
https://github.com/misskey-dev/misskey/blob/develop/CONTRIBUTING.md
|
|
||||||
-->
|
|
||||||
|
|
||||||
## What
|
|
||||||
<!-- このPRで何をしたのか? どう変わるのか? -->
|
|
||||||
<!-- What did you do with this PR? How will it change things? -->
|
|
||||||
|
|
||||||
## Why
|
|
||||||
<!-- なぜそうするのか? どういう意図なのか? 何が困っているのか? -->
|
|
||||||
<!-- Why do you do it? What are your intentions? What is the problem? -->
|
|
||||||
|
|
||||||
## Additional info (optional)
|
|
||||||
<!-- テスト観点など -->
|
|
||||||
<!-- Test perspective, etc -->
|
|
||||||
|
|
||||||
## Checklist
|
|
||||||
- [ ] Read the [contribution guide](https://github.com/misskey-dev/misskey/blob/develop/CONTRIBUTING.md)
|
|
||||||
- [ ] Test working in a local environment
|
|
||||||
- [ ] (If needed) Update CHANGELOG.md
|
|
||||||
- [ ] (If possible) Add tests
|
|
23
.github/PULL_REQUEST_TEMPLATE/02_enhance.md
vendored
23
.github/PULL_REQUEST_TEMPLATE/02_enhance.md
vendored
@ -1,23 +0,0 @@
|
|||||||
<!-- ℹ お読みください / README
|
|
||||||
PRありがとうございます! PRを作成する前に、コントリビューションガイドをご確認ください:
|
|
||||||
Thank you for your PR! Before creating a PR, please check the contribution guide:
|
|
||||||
https://github.com/misskey-dev/misskey/blob/develop/CONTRIBUTING.md
|
|
||||||
-->
|
|
||||||
|
|
||||||
## What
|
|
||||||
<!-- このPRで何をしたのか? どう変わるのか? -->
|
|
||||||
<!-- What did you do with this PR? How will it change things? -->
|
|
||||||
|
|
||||||
## Why
|
|
||||||
<!-- なぜそうするのか? どういう意図なのか? 何が困っているのか? -->
|
|
||||||
<!-- Why do you do it? What are your intentions? What is the problem? -->
|
|
||||||
|
|
||||||
## Additional info (optional)
|
|
||||||
<!-- テスト観点など -->
|
|
||||||
<!-- Test perspective, etc -->
|
|
||||||
|
|
||||||
## Checklist
|
|
||||||
- [ ] Read the [contribution guide](https://github.com/misskey-dev/misskey/blob/develop/CONTRIBUTING.md)
|
|
||||||
- [ ] Test working in a local environment
|
|
||||||
- [ ] (If needed) Update CHANGELOG.md
|
|
||||||
- [ ] (If possible) Add tests
|
|
20
.github/PULL_REQUEST_TEMPLATE/03_release.md
vendored
20
.github/PULL_REQUEST_TEMPLATE/03_release.md
vendored
@ -1,20 +0,0 @@
|
|||||||
## Summary
|
|
||||||
This is a release PR.
|
|
||||||
|
|
||||||
For more information on the release instructions, please see:
|
|
||||||
https://github.com/misskey-dev/misskey/blob/develop/CONTRIBUTING.md#release
|
|
||||||
|
|
||||||
## For reviewers
|
|
||||||
- CHANGELOGに抜け漏れは無いか
|
|
||||||
- バージョンの上げ方は適切か
|
|
||||||
- 他にこのリリースに含めなければならない変更は無いか
|
|
||||||
- 全体的な変更内容を俯瞰し問題は無いか
|
|
||||||
- レビューされていないコミットがある場合は、それが問題ないか
|
|
||||||
- 最終的な動作確認を行い問題は無いか
|
|
||||||
|
|
||||||
などを確認し、リリースする準備が整っていると思われる場合は approve してください。
|
|
||||||
|
|
||||||
## Checklist
|
|
||||||
- [ ] package.jsonのバージョンが正しく更新されている
|
|
||||||
- [ ] CHANGELOGが過不足無く更新されている
|
|
||||||
- [ ] CIが全て通っている
|
|
48
.github/dependabot.yml
vendored
48
.github/dependabot.yml
vendored
@ -5,44 +5,18 @@
|
|||||||
|
|
||||||
version: 2
|
version: 2
|
||||||
updates:
|
updates:
|
||||||
- package-ecosystem: github-actions
|
|
||||||
directory: "/"
|
|
||||||
schedule:
|
|
||||||
interval: daily
|
|
||||||
open-pull-requests-limit: 100
|
|
||||||
|
|
||||||
# Add only the root, not each workspace item
|
|
||||||
# https://github.com/dependabot/dependabot-core/issues/4993#issuecomment-1289133027
|
|
||||||
- package-ecosystem: npm
|
- package-ecosystem: npm
|
||||||
directory: "/"
|
directory: "/"
|
||||||
schedule:
|
schedule:
|
||||||
interval: daily
|
interval: daily
|
||||||
open-pull-requests-limit: 10
|
open-pull-requests-limit: 0
|
||||||
# List dependencies required to be updated together, sharing the same version numbers.
|
- package-ecosystem: npm
|
||||||
# Those who simply have the common owner (e.g. @fastify) don't need to be listed.
|
directory: "/packages/backend"
|
||||||
groups:
|
schedule:
|
||||||
aws-sdk:
|
interval: daily
|
||||||
patterns:
|
open-pull-requests-limit: 0
|
||||||
- "@aws-sdk/*"
|
- package-ecosystem: npm
|
||||||
bull-board:
|
directory: "/packages/client"
|
||||||
patterns:
|
schedule:
|
||||||
- "@bull-board/*"
|
interval: daily
|
||||||
nestjs:
|
open-pull-requests-limit: 0
|
||||||
patterns:
|
|
||||||
- "@nestjs/*"
|
|
||||||
slacc:
|
|
||||||
patterns:
|
|
||||||
- "slacc-*"
|
|
||||||
storybook:
|
|
||||||
patterns:
|
|
||||||
- "storybook*"
|
|
||||||
- "@storybook/*"
|
|
||||||
swc-core:
|
|
||||||
patterns:
|
|
||||||
- "@swc/core*"
|
|
||||||
typescript-eslint:
|
|
||||||
patterns:
|
|
||||||
- "@typescript-eslint/*"
|
|
||||||
tensorflow:
|
|
||||||
patterns:
|
|
||||||
- "@tensorflow/*"
|
|
||||||
|
40
.github/labeler.yml
vendored
40
.github/labeler.yml
vendored
@ -1,34 +1,12 @@
|
|||||||
'packages/backend':
|
'⚙️Server':
|
||||||
- any:
|
- packages/backend/**/*
|
||||||
- changed-files:
|
|
||||||
- any-glob-to-any-file: ['packages/backend/**/*']
|
|
||||||
|
|
||||||
'packages/backend:test':
|
'🖥️Client':
|
||||||
- any:
|
- packages/client/**/*
|
||||||
- changed-files:
|
|
||||||
- any-glob-to-any-file: ['packages/backend/test/**/*']
|
|
||||||
|
|
||||||
'packages/frontend':
|
'🧪Test':
|
||||||
- any:
|
- cypress/**/*
|
||||||
- changed-files:
|
- packages/backend/test/**/*
|
||||||
- any-glob-to-any-file: ['packages/frontend/**/*']
|
|
||||||
|
|
||||||
'packages/frontend:test':
|
'‼️ wrong locales':
|
||||||
- any:
|
- any: ['locales/*.yml', '!locales/ja-JP.yml']
|
||||||
- changed-files:
|
|
||||||
- any-glob-to-any-file: ['cypress/**/*']
|
|
||||||
|
|
||||||
'packages/sw':
|
|
||||||
- any:
|
|
||||||
- changed-files:
|
|
||||||
- any-glob-to-any-file: ['packages/sw/**/*']
|
|
||||||
|
|
||||||
'packages/misskey-js':
|
|
||||||
- any:
|
|
||||||
- changed-files:
|
|
||||||
- any-glob-to-any-file: ['packages/misskey-js/**/*']
|
|
||||||
|
|
||||||
'packages/misskey-js:test':
|
|
||||||
- any:
|
|
||||||
- changed-files:
|
|
||||||
- any-glob-to-any-file: ['packages/misskey-js/test/**/*', 'packages/misskey-js/test-d/**/*']
|
|
||||||
|
8
.github/misskey/test.yml
vendored
8
.github/misskey/test.yml
vendored
@ -1,17 +1,15 @@
|
|||||||
url: 'http://misskey.local'
|
url: 'http://misskey.local'
|
||||||
|
|
||||||
setupPassword: example_password_please_change_this_or_you_will_get_hacked
|
|
||||||
|
|
||||||
# ローカルでテストするときにポートを被らないようにするためデフォルトのものとは変える(以下同じ)
|
# ローカルでテストするときにポートを被らないようにするためデフォルトのものとは変える(以下同じ)
|
||||||
port: 61812
|
port: 61812
|
||||||
|
|
||||||
db:
|
db:
|
||||||
host: 127.0.0.1
|
host: localhost
|
||||||
port: 54312
|
port: 54312
|
||||||
db: test-misskey
|
db: test-misskey
|
||||||
user: postgres
|
user: postgres
|
||||||
pass: ''
|
pass: ''
|
||||||
redis:
|
redis:
|
||||||
host: 127.0.0.1
|
host: localhost
|
||||||
port: 56312
|
port: 56312
|
||||||
id: aidx
|
id: aid
|
||||||
|
24
.github/pull_request_template.md
vendored
24
.github/pull_request_template.md
vendored
@ -1,24 +0,0 @@
|
|||||||
<!-- ℹ お読みください / README
|
|
||||||
PRありがとうございます! PRを作成する前に、コントリビューションガイドをご確認ください:
|
|
||||||
Thank you for your PR! Before creating a PR, please check the contribution guide:
|
|
||||||
https://github.com/misskey-dev/misskey/blob/develop/CONTRIBUTING.md
|
|
||||||
-->
|
|
||||||
|
|
||||||
## What
|
|
||||||
<!-- このPRで何をしたのか? どう変わるのか? -->
|
|
||||||
<!-- What did you do with this PR? How will it change things? -->
|
|
||||||
|
|
||||||
## Why
|
|
||||||
<!-- なぜそうするのか? どういう意図なのか? 何が困っているのか? -->
|
|
||||||
<!-- Why do you do it? What are your intentions? What is the problem? -->
|
|
||||||
|
|
||||||
## Additional info (optional)
|
|
||||||
<!-- テスト観点など -->
|
|
||||||
<!-- Test perspective, etc -->
|
|
||||||
|
|
||||||
## Checklist
|
|
||||||
- [ ] Read the [contribution guide](https://github.com/misskey-dev/misskey/blob/develop/CONTRIBUTING.md)
|
|
||||||
- [ ] Test working in a local environment
|
|
||||||
- [ ] (If needed) Add story of storybook
|
|
||||||
- [ ] (If needed) Update CHANGELOG.md
|
|
||||||
- [ ] (If possible) Add tests
|
|
43
.github/workflows/api-misskey-js.yml
vendored
43
.github/workflows/api-misskey-js.yml
vendored
@ -1,43 +0,0 @@
|
|||||||
name: API report (misskey.js)
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
paths:
|
|
||||||
- packages/misskey-js/**
|
|
||||||
- .github/workflows/api-misskey-js.yml
|
|
||||||
pull_request:
|
|
||||||
paths:
|
|
||||||
- packages/misskey-js/**
|
|
||||||
- .github/workflows/api-misskey-js.yml
|
|
||||||
jobs:
|
|
||||||
report:
|
|
||||||
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@v4.1.1
|
|
||||||
|
|
||||||
- run: corepack enable
|
|
||||||
|
|
||||||
- name: Setup Node.js
|
|
||||||
uses: actions/setup-node@v4.0.4
|
|
||||||
with:
|
|
||||||
node-version-file: '.node-version'
|
|
||||||
cache: 'pnpm'
|
|
||||||
|
|
||||||
- name: Install dependencies
|
|
||||||
run: pnpm i --frozen-lockfile
|
|
||||||
|
|
||||||
- name: Build
|
|
||||||
run: pnpm --filter misskey-js build
|
|
||||||
|
|
||||||
- name: Check files
|
|
||||||
run: ls packages/misskey-js/built
|
|
||||||
|
|
||||||
- name: API report
|
|
||||||
run: pnpm --filter misskey-js api-prod
|
|
||||||
|
|
||||||
- name: Show report
|
|
||||||
if: always()
|
|
||||||
run: cat packages/misskey-js/temp/misskey-js.api.md
|
|
43
.github/workflows/changelog-check.yml
vendored
43
.github/workflows/changelog-check.yml
vendored
@ -1,43 +0,0 @@
|
|||||||
name: Check the description in CHANGELOG.md
|
|
||||||
|
|
||||||
on:
|
|
||||||
pull_request:
|
|
||||||
branches:
|
|
||||||
- master
|
|
||||||
- develop
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
check-changelog:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: Checkout head
|
|
||||||
uses: actions/checkout@v4.1.1
|
|
||||||
- name: Setup Node.js
|
|
||||||
uses: actions/setup-node@v4.0.4
|
|
||||||
with:
|
|
||||||
node-version-file: '.node-version'
|
|
||||||
|
|
||||||
- name: Checkout base
|
|
||||||
run: |
|
|
||||||
mkdir _base
|
|
||||||
cp -r .git _base/.git
|
|
||||||
cd _base
|
|
||||||
git fetch --depth 1 origin ${{ github.base_ref }}
|
|
||||||
git checkout origin/${{ github.base_ref }} CHANGELOG.md
|
|
||||||
|
|
||||||
- name: Copy to Checker directory for CHANGELOG-base.md
|
|
||||||
run: cp _base/CHANGELOG.md scripts/changelog-checker/CHANGELOG-base.md
|
|
||||||
- name: Copy to Checker directory for CHANGELOG-head.md
|
|
||||||
run: cp CHANGELOG.md scripts/changelog-checker/CHANGELOG-head.md
|
|
||||||
- name: diff
|
|
||||||
continue-on-error: true
|
|
||||||
run: diff -u CHANGELOG-base.md CHANGELOG-head.md
|
|
||||||
working-directory: scripts/changelog-checker
|
|
||||||
|
|
||||||
- name: Setup Checker
|
|
||||||
run: npm install
|
|
||||||
working-directory: scripts/changelog-checker
|
|
||||||
- name: Run Checker
|
|
||||||
run: npm run run
|
|
||||||
working-directory: scripts/changelog-checker
|
|
139
.github/workflows/check-misskey-js-autogen.yml
vendored
139
.github/workflows/check-misskey-js-autogen.yml
vendored
@ -1,139 +0,0 @@
|
|||||||
name: Check Misskey JS autogen
|
|
||||||
|
|
||||||
on:
|
|
||||||
pull_request_target:
|
|
||||||
branches:
|
|
||||||
- master
|
|
||||||
- develop
|
|
||||||
- improve-misskey-js-autogen-check
|
|
||||||
paths:
|
|
||||||
- packages/backend/**
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
# pull_request_target safety: permissions: read-all, and there are no secrets used in this job
|
|
||||||
generate-misskey-js:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
permissions:
|
|
||||||
contents: read
|
|
||||||
if: ${{ github.event.pull_request.mergeable == null || github.event.pull_request.mergeable == true }}
|
|
||||||
steps:
|
|
||||||
- name: checkout
|
|
||||||
uses: actions/checkout@v4.1.1
|
|
||||||
with:
|
|
||||||
submodules: true
|
|
||||||
persist-credentials: false
|
|
||||||
ref: refs/pull/${{ github.event.pull_request.number }}/merge
|
|
||||||
|
|
||||||
- name: setup pnpm
|
|
||||||
uses: pnpm/action-setup@v4
|
|
||||||
|
|
||||||
- name: setup node
|
|
||||||
id: setup-node
|
|
||||||
uses: actions/setup-node@v4.0.4
|
|
||||||
with:
|
|
||||||
node-version-file: '.node-version'
|
|
||||||
cache: pnpm
|
|
||||||
|
|
||||||
- name: install dependencies
|
|
||||||
run: pnpm i --frozen-lockfile
|
|
||||||
|
|
||||||
# generate api.json
|
|
||||||
- name: Copy Config
|
|
||||||
run: cp .config/example.yml .config/default.yml
|
|
||||||
- name: Build
|
|
||||||
run: pnpm build
|
|
||||||
- name: Generate API JSON
|
|
||||||
run: pnpm --filter backend generate-api-json
|
|
||||||
|
|
||||||
# build misskey js
|
|
||||||
- name: Build misskey-js
|
|
||||||
run: |-
|
|
||||||
cp packages/backend/built/api.json packages/misskey-js/generator/api.json
|
|
||||||
pnpm run --filter misskey-js-type-generator generate
|
|
||||||
|
|
||||||
# packages/misskey-js/generator/built/autogen
|
|
||||||
- name: Upload Generated
|
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: generated-misskey-js
|
|
||||||
path: packages/misskey-js/generator/built/autogen
|
|
||||||
|
|
||||||
# pull_request_target safety: permissions: read-all, and no user codes are executed
|
|
||||||
get-actual-misskey-js:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
permissions:
|
|
||||||
contents: read
|
|
||||||
if: ${{ github.event.pull_request.mergeable == null || github.event.pull_request.mergeable == true }}
|
|
||||||
steps:
|
|
||||||
- name: checkout
|
|
||||||
uses: actions/checkout@v4.1.1
|
|
||||||
with:
|
|
||||||
submodules: true
|
|
||||||
persist-credentials: false
|
|
||||||
ref: refs/pull/${{ github.event.pull_request.number }}/merge
|
|
||||||
|
|
||||||
- name: Upload From Merged
|
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: actual-misskey-js
|
|
||||||
path: packages/misskey-js/src/autogen
|
|
||||||
|
|
||||||
# pull_request_target safety: nothing is cloned from repository
|
|
||||||
comment-misskey-js-autogen:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
needs: [generate-misskey-js, get-actual-misskey-js]
|
|
||||||
permissions:
|
|
||||||
pull-requests: write
|
|
||||||
steps:
|
|
||||||
- name: download generated-misskey-js
|
|
||||||
uses: actions/download-artifact@v4
|
|
||||||
with:
|
|
||||||
name: generated-misskey-js
|
|
||||||
path: misskey-js-generated
|
|
||||||
|
|
||||||
- name: download actual-misskey-js
|
|
||||||
uses: actions/download-artifact@v4
|
|
||||||
with:
|
|
||||||
name: actual-misskey-js
|
|
||||||
path: misskey-js-actual
|
|
||||||
|
|
||||||
- name: check misskey-js changes
|
|
||||||
id: check-changes
|
|
||||||
run: |
|
|
||||||
diff -r -u --label=generated --label=on-tree ./misskey-js-generated ./misskey-js-actual > misskey-js.diff || true
|
|
||||||
|
|
||||||
if [ -s misskey-js.diff ]; then
|
|
||||||
echo "changes=true" >> $GITHUB_OUTPUT
|
|
||||||
else
|
|
||||||
echo "changes=false" >> $GITHUB_OUTPUT
|
|
||||||
fi
|
|
||||||
|
|
||||||
- name: Print full diff
|
|
||||||
run: cat ./misskey-js.diff
|
|
||||||
|
|
||||||
- name: send message
|
|
||||||
if: steps.check-changes.outputs.changes == 'true'
|
|
||||||
uses: thollander/actions-comment-pull-request@v2
|
|
||||||
with:
|
|
||||||
comment_tag: check-misskey-js-autogen
|
|
||||||
message: |-
|
|
||||||
Thank you for sending us a great Pull Request! 👍
|
|
||||||
Please regenerate misskey-js type definitions! 🙏
|
|
||||||
|
|
||||||
example:
|
|
||||||
```sh
|
|
||||||
pnpm run build-misskey-js-with-types
|
|
||||||
```
|
|
||||||
|
|
||||||
- name: send message
|
|
||||||
if: steps.check-changes.outputs.changes == 'false'
|
|
||||||
uses: thollander/actions-comment-pull-request@v2
|
|
||||||
with:
|
|
||||||
comment_tag: check-misskey-js-autogen
|
|
||||||
mode: delete
|
|
||||||
message: "Thank you!"
|
|
||||||
create_if_not_exists: false
|
|
||||||
|
|
||||||
- name: Make failure if changes are detected
|
|
||||||
if: steps.check-changes.outputs.changes == 'true'
|
|
||||||
run: exit 1
|
|
29
.github/workflows/check-misskey-js-version.yml
vendored
29
.github/workflows/check-misskey-js-version.yml
vendored
@ -1,29 +0,0 @@
|
|||||||
name: Check Misskey JS version
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches: [ develop ]
|
|
||||||
paths:
|
|
||||||
- packages/misskey-js/package.json
|
|
||||||
- package.json
|
|
||||||
- .github/workflows/check-misskey-js-version.yml
|
|
||||||
pull_request:
|
|
||||||
branches: [ develop ]
|
|
||||||
paths:
|
|
||||||
- packages/misskey-js/package.json
|
|
||||||
- package.json
|
|
||||||
- .github/workflows/check-misskey-js-version.yml
|
|
||||||
jobs:
|
|
||||||
check-version:
|
|
||||||
# ルートの package.json と packages/misskey-js/package.json のバージョンが一致しているかを確認する
|
|
||||||
name: Check version
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@v4.1.1
|
|
||||||
- name: Check version
|
|
||||||
run: |
|
|
||||||
if [ "$(jq -r '.version' package.json)" != "$(jq -r '.version' packages/misskey-js/package.json)" ]; then
|
|
||||||
echo "Version mismatch!"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
79
.github/workflows/check-spdx-license-id.yml
vendored
79
.github/workflows/check-spdx-license-id.yml
vendored
@ -1,79 +0,0 @@
|
|||||||
name: Check SPDX-License-Identifier
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- master
|
|
||||||
- develop
|
|
||||||
pull_request:
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
check-spdx-license-id:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@v4.1.1
|
|
||||||
- name: Check
|
|
||||||
run: |
|
|
||||||
counter=0
|
|
||||||
|
|
||||||
search() {
|
|
||||||
local directory="$1"
|
|
||||||
find "$directory" -type f \
|
|
||||||
'(' \
|
|
||||||
-name "*.cjs" -and -not -name '*.config.cjs' -o \
|
|
||||||
-name "*.html" -o \
|
|
||||||
-name "*.js" -and -not -name '*.config.js' -o \
|
|
||||||
-name "*.mjs" -and -not -name '*.config.mjs' -o \
|
|
||||||
-name "*.scss" -o \
|
|
||||||
-name "*.ts" -and -not -name '*.config.ts' -o \
|
|
||||||
-name "*.vue" \
|
|
||||||
')' -and \
|
|
||||||
-not -name '*eslint*'
|
|
||||||
}
|
|
||||||
|
|
||||||
check() {
|
|
||||||
local file="$1"
|
|
||||||
if ! (
|
|
||||||
grep -q "SPDX-FileCopyrightText: syuilo and misskey-project" "$file" ||
|
|
||||||
grep -q "SPDX-License-Identifier: AGPL-3.0-only" "$file"
|
|
||||||
); then
|
|
||||||
echo "Missing: $file"
|
|
||||||
((counter++))
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
directories=(
|
|
||||||
"cypress/e2e"
|
|
||||||
"packages/backend/migration"
|
|
||||||
"packages/backend/src"
|
|
||||||
"packages/backend/test"
|
|
||||||
"packages/frontend-shared/@types"
|
|
||||||
"packages/frontend-shared/js"
|
|
||||||
"packages/frontend/.storybook"
|
|
||||||
"packages/frontend/@types"
|
|
||||||
"packages/frontend/lib"
|
|
||||||
"packages/frontend/public"
|
|
||||||
"packages/frontend/src"
|
|
||||||
"packages/frontend/test"
|
|
||||||
"packages/frontend-embed/@types"
|
|
||||||
"packages/frontend-embed/src"
|
|
||||||
"packages/misskey-bubble-game/src"
|
|
||||||
"packages/misskey-reversi/src"
|
|
||||||
"packages/sw/src"
|
|
||||||
"scripts"
|
|
||||||
)
|
|
||||||
|
|
||||||
for directory in "${directories[@]}"; do
|
|
||||||
for file in $(search $directory); do
|
|
||||||
check "$file"
|
|
||||||
done
|
|
||||||
done
|
|
||||||
|
|
||||||
if [ $counter -gt 0 ]; then
|
|
||||||
echo "SPDX-License-Identifier is missing in $counter files."
|
|
||||||
exit 1
|
|
||||||
else
|
|
||||||
echo "SPDX-License-Identifier is certainly described in all target files!"
|
|
||||||
exit 0
|
|
||||||
fi
|
|
18
.github/workflows/check_copyright_year.yml
vendored
18
.github/workflows/check_copyright_year.yml
vendored
@ -1,18 +0,0 @@
|
|||||||
name: Check copyright year
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- master
|
|
||||||
- develop
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
check_copyright_year:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4.1.1
|
|
||||||
- run: |
|
|
||||||
if [ "$(grep Copyright COPYING | sed -e 's/.*2014-\([0-9]*\) .*/\1/g')" -ne "$(date +%Y)" ]; then
|
|
||||||
echo "Please change copyright year!"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
84
.github/workflows/deploy-test-environment.yml
vendored
84
.github/workflows/deploy-test-environment.yml
vendored
@ -1,84 +0,0 @@
|
|||||||
name: deploy-test-environment
|
|
||||||
|
|
||||||
on:
|
|
||||||
issue_comment:
|
|
||||||
types: [created]
|
|
||||||
workflow_dispatch:
|
|
||||||
inputs:
|
|
||||||
repository:
|
|
||||||
description: 'Repository to deploy (optional, use the repository where this workflow is stored by default)'
|
|
||||||
required: false
|
|
||||||
default: ''
|
|
||||||
branch_or_hash:
|
|
||||||
description: 'Branch or Commit hash to deploy (optional, use the branch where this workflow is stored by default)'
|
|
||||||
required: false
|
|
||||||
default: ''
|
|
||||||
wait_time:
|
|
||||||
description: 'Time to wait in seconds (optional, 1800 seconds by default)'
|
|
||||||
required: false
|
|
||||||
default: ''
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
get-pr-ref:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
if: github.event_name == 'issue_comment' && github.event.issue.pull_request && startsWith(github.event.comment.body, '/preview')
|
|
||||||
outputs:
|
|
||||||
is-allowed-user: ${{ steps.check-allowed-users.outputs.is-allowed-user }}
|
|
||||||
pr-ref: ${{ steps.get-ref.outputs.pr-ref }}
|
|
||||||
wait_time: ${{ steps.get-wait-time.outputs.wait_time }}
|
|
||||||
steps:
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@v4.1.1
|
|
||||||
|
|
||||||
- name: Check allowed users
|
|
||||||
id: check-allowed-users
|
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
ORG_ID: ${{ github.repository_owner_id }}
|
|
||||||
COMMENT_AUTHOR: ${{ github.event.comment.user.login }}
|
|
||||||
run: |
|
|
||||||
MEMBERSHIP_STATUS=$(curl -s -H "Authorization: Bearer $GITHUB_TOKEN" \
|
|
||||||
-H "Accept: application/vnd.github+json" \
|
|
||||||
-H "X-GitHub-Api-Version: 2022-11-28" \
|
|
||||||
"https://api.github.com/organizations/$ORG_ID/public_members/$COMMENT_AUTHOR" \
|
|
||||||
-o /dev/null -w '%{http_code}\n' -s)
|
|
||||||
if [ "$MEMBERSHIP_STATUS" -eq 204 ]; then
|
|
||||||
echo "is-allowed-user=true" > $GITHUB_OUTPUT
|
|
||||||
else
|
|
||||||
echo "is-allowed-user=false" > $GITHUB_OUTPUT
|
|
||||||
fi
|
|
||||||
|
|
||||||
- name: Get PR ref
|
|
||||||
id: get-ref
|
|
||||||
run: |
|
|
||||||
PR_REF="refs/pull/${{ github.event.issue.number }}/head"
|
|
||||||
echo "pr-ref=$PR_REF" >> $GITHUB_OUTPUT
|
|
||||||
|
|
||||||
- name: Extract wait time
|
|
||||||
id: get-wait-time
|
|
||||||
env:
|
|
||||||
COMMENT_BODY: ${{ github.event.comment.body }}
|
|
||||||
run: |
|
|
||||||
WAIT_TIME=$(echo "$COMMENT_BODY" | grep -oP '(?<=/preview\s)\d+' || echo "1800")
|
|
||||||
echo "wait_time=$WAIT_TIME" > $GITHUB_OUTPUT
|
|
||||||
|
|
||||||
deploy-test-environment-pr-comment:
|
|
||||||
needs: get-pr-ref
|
|
||||||
if: needs.get-pr-ref.outputs.is-allowed-user == 'true'
|
|
||||||
uses: joinmisskey/misskey-tga/.github/workflows/deploy-test-environment.yml@main
|
|
||||||
with:
|
|
||||||
repository: ${{ github.repository }}
|
|
||||||
branch_or_hash: ${{ needs.get-pr-ref.outputs.pr-ref }}
|
|
||||||
wait_time: ${{ needs.get-pr-ref.outputs.wait_time }}
|
|
||||||
secrets:
|
|
||||||
DISCORD_WEBHOOK_URL: ${{ secrets.DISCORD_WEBHOOK_URL }}
|
|
||||||
|
|
||||||
deploy-test-environment-wd:
|
|
||||||
if: github.event_name == 'workflow_dispatch'
|
|
||||||
uses: joinmisskey/misskey-tga/.github/workflows/deploy-test-environment.yml@main
|
|
||||||
with:
|
|
||||||
repository: ${{ inputs.repository || github.repository }}
|
|
||||||
branch_or_hash: ${{ inputs.branch_or_hash || github.ref_name }}
|
|
||||||
wait_time: ${{ inputs.wait_time || '1800' }}
|
|
||||||
secrets:
|
|
||||||
DISCORD_WEBHOOK_URL: ${{ secrets.DISCORD_WEBHOOK_URL }}
|
|
81
.github/workflows/docker-develop.yml
vendored
81
.github/workflows/docker-develop.yml
vendored
@ -6,83 +6,28 @@ on:
|
|||||||
- develop
|
- develop
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
env:
|
|
||||||
REGISTRY_IMAGE: laoxong/misskey
|
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
# see https://docs.docker.com/build/ci/github-actions/multi-platform/#distribute-build-across-multiple-runners
|
push_to_registry:
|
||||||
build:
|
name: Push Docker image to Docker Hub
|
||||||
name: Build
|
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
matrix:
|
|
||||||
platform:
|
|
||||||
- linux/amd64
|
|
||||||
- linux/arm64
|
|
||||||
if: github.repository == 'laoxong/misskey'
|
|
||||||
steps:
|
steps:
|
||||||
- name: Prepare
|
|
||||||
run: |
|
|
||||||
platform=${{ matrix.platform }}
|
|
||||||
echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV
|
|
||||||
- name: Check out the repo
|
- name: Check out the repo
|
||||||
uses: actions/checkout@v4.1.1
|
uses: actions/checkout@v2
|
||||||
- name: Set up Docker Buildx
|
- name: Docker meta
|
||||||
uses: docker/setup-buildx-action@v3
|
id: meta
|
||||||
|
uses: docker/metadata-action@v3
|
||||||
|
with:
|
||||||
|
images: misskey/misskey
|
||||||
- name: Log in to Docker Hub
|
- name: Log in to Docker Hub
|
||||||
uses: docker/login-action@v3
|
uses: docker/login-action@v1
|
||||||
with:
|
with:
|
||||||
username: ${{ secrets.DOCKER_USERNAME }}
|
username: ${{ secrets.DOCKER_USERNAME }}
|
||||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||||
- name: Build and push by digest
|
- name: Build and Push to Docker Hub
|
||||||
id: build
|
uses: docker/build-push-action@v2
|
||||||
uses: docker/build-push-action@v6
|
|
||||||
with:
|
with:
|
||||||
context: .
|
context: .
|
||||||
push: true
|
push: true
|
||||||
platforms: ${{ matrix.platform }}
|
tags: misskey/misskey:develop
|
||||||
provenance: false
|
|
||||||
labels: develop
|
labels: develop
|
||||||
cache-from: type=gha
|
|
||||||
cache-to: type=gha,mode=max
|
|
||||||
outputs: type=image,name=${{ env.REGISTRY_IMAGE }},push-by-digest=true,name-canonical=true,push=true
|
|
||||||
- name: Export digest
|
|
||||||
run: |
|
|
||||||
mkdir -p /tmp/digests
|
|
||||||
digest="${{ steps.build.outputs.digest }}"
|
|
||||||
touch "/tmp/digests/${digest#sha256:}"
|
|
||||||
- name: Upload digest
|
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: digests-${{ env.PLATFORM_PAIR }}
|
|
||||||
path: /tmp/digests/*
|
|
||||||
if-no-files-found: error
|
|
||||||
retention-days: 1
|
|
||||||
|
|
||||||
merge:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
needs:
|
|
||||||
- build
|
|
||||||
steps:
|
|
||||||
- name: Download digests
|
|
||||||
uses: actions/download-artifact@v4
|
|
||||||
with:
|
|
||||||
path: /tmp/digests
|
|
||||||
pattern: digests-*
|
|
||||||
merge-multiple: true
|
|
||||||
- name: Set up Docker Buildx
|
|
||||||
uses: docker/setup-buildx-action@v3
|
|
||||||
- name: Login to Docker Hub
|
|
||||||
uses: docker/login-action@v3
|
|
||||||
with:
|
|
||||||
username: ${{ secrets.DOCKER_USERNAME }}
|
|
||||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
|
||||||
- name: Create manifest list and push
|
|
||||||
working-directory: /tmp/digests
|
|
||||||
run: |
|
|
||||||
docker buildx imagetools create --tag ${{ env.REGISTRY_IMAGE }}:develop \
|
|
||||||
$(printf '${{ env.REGISTRY_IMAGE }}@sha256:%s ' *)
|
|
||||||
- name: Inspect image
|
|
||||||
run: |
|
|
||||||
docker buildx imagetools inspect ${{ env.REGISTRY_IMAGE }}:develop
|
|
||||||
|
91
.github/workflows/docker.yml
vendored
91
.github/workflows/docker.yml
vendored
@ -5,101 +5,28 @@ on:
|
|||||||
types: [published]
|
types: [published]
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
env:
|
|
||||||
REGISTRY_IMAGE: laoxong/misskey
|
|
||||||
TAGS: |
|
|
||||||
type=edge
|
|
||||||
type=ref,event=pr
|
|
||||||
type=ref,event=branch
|
|
||||||
type=semver,pattern={{version}}
|
|
||||||
type=semver,pattern={{major}}.{{minor}}
|
|
||||||
type=semver,pattern={{major}}
|
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
# see https://docs.docker.com/build/ci/github-actions/multi-platform/#distribute-build-across-multiple-runners
|
push_to_registry:
|
||||||
build:
|
name: Push Docker image to Docker Hub
|
||||||
name: Build
|
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
matrix:
|
|
||||||
platform:
|
|
||||||
- linux/amd64
|
|
||||||
# - linux/arm64
|
|
||||||
steps:
|
steps:
|
||||||
- name: Prepare
|
|
||||||
run: |
|
|
||||||
platform=${{ matrix.platform }}
|
|
||||||
echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV
|
|
||||||
- name: Check out the repo
|
- name: Check out the repo
|
||||||
uses: actions/checkout@v4.1.1
|
uses: actions/checkout@v2
|
||||||
- name: Set up Docker Buildx
|
|
||||||
uses: docker/setup-buildx-action@v3
|
|
||||||
- name: Docker meta
|
- name: Docker meta
|
||||||
id: meta
|
id: meta
|
||||||
uses: docker/metadata-action@v5
|
uses: docker/metadata-action@v3
|
||||||
with:
|
with:
|
||||||
images: ${{ env.REGISTRY_IMAGE }}
|
images: misskey/misskey
|
||||||
tags: ${{ env.TAGS }}
|
|
||||||
- name: Log in to Docker Hub
|
- name: Log in to Docker Hub
|
||||||
uses: docker/login-action@v3
|
uses: docker/login-action@v1
|
||||||
with:
|
with:
|
||||||
username: ${{ secrets.DOCKER_USERNAME }}
|
username: ${{ secrets.DOCKER_USERNAME }}
|
||||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||||
- name: Build and Push to Docker Hub
|
- name: Build and Push to Docker Hub
|
||||||
id: build
|
uses: docker/build-push-action@v2
|
||||||
uses: docker/build-push-action@v6
|
|
||||||
with:
|
with:
|
||||||
context: .
|
context: .
|
||||||
push: true
|
push: true
|
||||||
platforms: ${{ matrix.platform }}
|
tags: ${{ steps.meta.outputs.tags }}
|
||||||
provenance: false
|
|
||||||
labels: ${{ steps.meta.outputs.labels }}
|
labels: ${{ steps.meta.outputs.labels }}
|
||||||
cache-from: type=gha
|
|
||||||
cache-to: type=gha,mode=max
|
|
||||||
outputs: type=image,name=${{ env.REGISTRY_IMAGE }},push-by-digest=true,name-canonical=true,push=true
|
|
||||||
- name: Export digest
|
|
||||||
run: |
|
|
||||||
mkdir -p /tmp/digests
|
|
||||||
digest="${{ steps.build.outputs.digest }}"
|
|
||||||
touch "/tmp/digests/${digest#sha256:}"
|
|
||||||
- name: Upload digest
|
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: digests-${{ env.PLATFORM_PAIR }}
|
|
||||||
path: /tmp/digests/*
|
|
||||||
if-no-files-found: error
|
|
||||||
retention-days: 1
|
|
||||||
|
|
||||||
merge:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
needs:
|
|
||||||
- build
|
|
||||||
steps:
|
|
||||||
- name: Download digests
|
|
||||||
uses: actions/download-artifact@v4
|
|
||||||
with:
|
|
||||||
path: /tmp/digests
|
|
||||||
pattern: digests-*
|
|
||||||
merge-multiple: true
|
|
||||||
- name: Set up Docker Buildx
|
|
||||||
uses: docker/setup-buildx-action@v3
|
|
||||||
- name: Docker meta
|
|
||||||
id: meta
|
|
||||||
uses: docker/metadata-action@v5
|
|
||||||
with:
|
|
||||||
images: ${{ env.REGISTRY_IMAGE }}
|
|
||||||
tags: ${{ env.TAGS }}
|
|
||||||
- name: Login to Docker Hub
|
|
||||||
uses: docker/login-action@v3
|
|
||||||
with:
|
|
||||||
username: ${{ secrets.DOCKER_USERNAME }}
|
|
||||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
|
||||||
- name: Create manifest list and push
|
|
||||||
working-directory: /tmp/digests
|
|
||||||
run: |
|
|
||||||
docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \
|
|
||||||
$(printf '${{ env.REGISTRY_IMAGE }}@sha256:%s ' *)
|
|
||||||
- name: Inspect image
|
|
||||||
run: |
|
|
||||||
docker buildx imagetools inspect ${{ env.REGISTRY_IMAGE }}:${{ steps.meta.outputs.version }}
|
|
||||||
|
32
.github/workflows/dockle.yml
vendored
32
.github/workflows/dockle.yml
vendored
@ -1,32 +0,0 @@
|
|||||||
---
|
|
||||||
name: Dockle
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- master
|
|
||||||
- develop
|
|
||||||
pull_request:
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
dockle:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
env:
|
|
||||||
DOCKER_CONTENT_TRUST: 1
|
|
||||||
DOCKLE_VERSION: 0.4.14
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4.1.1
|
|
||||||
- name: Download and install dockle v${{ env.DOCKLE_VERSION }}
|
|
||||||
run: |
|
|
||||||
curl -L -o dockle.deb "https://github.com/goodwithtech/dockle/releases/download/v${DOCKLE_VERSION}/dockle_${DOCKLE_VERSION}_Linux-64bit.deb"
|
|
||||||
sudo dpkg -i dockle.deb
|
|
||||||
- run: |
|
|
||||||
cp .config/docker_example.env .config/docker.env
|
|
||||||
cp ./compose_example.yml ./compose.yml
|
|
||||||
- run: |
|
|
||||||
docker compose up -d web
|
|
||||||
docker tag "$(docker compose images web | awk 'OFS=":" {print $4}' | tail -n +2)" misskey-web:latest
|
|
||||||
- run: |
|
|
||||||
cmd="dockle --exit-code 1 misskey-web:latest ${image_name}"
|
|
||||||
echo "> ${cmd}"
|
|
||||||
eval "${cmd}"
|
|
69
.github/workflows/get-api-diff.yml
vendored
69
.github/workflows/get-api-diff.yml
vendored
@ -1,69 +0,0 @@
|
|||||||
# this name is used in report-api-diff.yml so be careful when change name
|
|
||||||
name: Get api.json from Misskey
|
|
||||||
|
|
||||||
on:
|
|
||||||
pull_request:
|
|
||||||
branches:
|
|
||||||
- master
|
|
||||||
- develop
|
|
||||||
paths:
|
|
||||||
- packages/backend/**
|
|
||||||
- .github/workflows/get-api-diff.yml
|
|
||||||
jobs:
|
|
||||||
get-from-misskey:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
permissions:
|
|
||||||
contents: read
|
|
||||||
|
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
node-version: [20.16.0]
|
|
||||||
api-json-name: [api-base.json, api-head.json]
|
|
||||||
include:
|
|
||||||
- api-json-name: api-base.json
|
|
||||||
ref: ${{ github.base_ref }}
|
|
||||||
- api-json-name: api-head.json
|
|
||||||
ref: refs/pull/${{ github.event.number }}/merge
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4.1.1
|
|
||||||
with:
|
|
||||||
ref: ${{ matrix.ref }}
|
|
||||||
submodules: true
|
|
||||||
- name: Install pnpm
|
|
||||||
uses: pnpm/action-setup@v4
|
|
||||||
- name: Use Node.js ${{ matrix.node-version }}
|
|
||||||
uses: actions/setup-node@v4.0.4
|
|
||||||
with:
|
|
||||||
node-version: ${{ matrix.node-version }}
|
|
||||||
cache: 'pnpm'
|
|
||||||
- run: corepack enable
|
|
||||||
- run: pnpm i --frozen-lockfile
|
|
||||||
- name: Check pnpm-lock.yaml
|
|
||||||
run: git diff --exit-code pnpm-lock.yaml
|
|
||||||
- name: Copy Configure
|
|
||||||
run: cp .config/example.yml .config/default.yml
|
|
||||||
- name: Build
|
|
||||||
run: pnpm build
|
|
||||||
- name: Generate API JSON
|
|
||||||
run: pnpm --filter backend generate-api-json
|
|
||||||
- name: Copy API.json
|
|
||||||
run: cp packages/backend/built/api.json ${{ matrix.api-json-name }}
|
|
||||||
- name: Upload Artifact
|
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: api-artifact-${{ matrix.api-json-name }}
|
|
||||||
path: ${{ matrix.api-json-name }}
|
|
||||||
|
|
||||||
save-pr-number:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- name: Save PR number
|
|
||||||
env:
|
|
||||||
PR_NUMBER: ${{ github.event.number }}
|
|
||||||
run: |
|
|
||||||
echo "$PR_NUMBER" > ./pr_number
|
|
||||||
- uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: api-artifact-pr-number
|
|
||||||
path: pr_number
|
|
2
.github/workflows/labeler.yml
vendored
2
.github/workflows/labeler.yml
vendored
@ -11,6 +11,6 @@ jobs:
|
|||||||
pull-requests: write
|
pull-requests: write
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/labeler@v5
|
- uses: actions/labeler@v4
|
||||||
with:
|
with:
|
||||||
repo-token: "${{ secrets.GITHUB_TOKEN }}"
|
repo-token: "${{ secrets.GITHUB_TOKEN }}"
|
||||||
|
110
.github/workflows/lint.yml
vendored
110
.github/workflows/lint.yml
vendored
@ -5,107 +5,35 @@ on:
|
|||||||
branches:
|
branches:
|
||||||
- master
|
- master
|
||||||
- develop
|
- develop
|
||||||
paths:
|
|
||||||
- packages/backend/**
|
|
||||||
- packages/frontend/**
|
|
||||||
- packages/frontend-shared/**
|
|
||||||
- packages/frontend-embed/**
|
|
||||||
- packages/sw/**
|
|
||||||
- packages/misskey-js/**
|
|
||||||
- packages/misskey-bubble-game/**
|
|
||||||
- packages/misskey-reversi/**
|
|
||||||
- packages/shared/eslint.config.js
|
|
||||||
- .github/workflows/lint.yml
|
|
||||||
pull_request:
|
pull_request:
|
||||||
paths:
|
|
||||||
- packages/backend/**
|
|
||||||
- packages/frontend/**
|
|
||||||
- packages/frontend-shared/**
|
|
||||||
- packages/frontend-embed/**
|
|
||||||
- packages/sw/**
|
|
||||||
- packages/misskey-js/**
|
|
||||||
- packages/misskey-bubble-game/**
|
|
||||||
- packages/misskey-reversi/**
|
|
||||||
- packages/shared/eslint.config.js
|
|
||||||
- .github/workflows/lint.yml
|
|
||||||
jobs:
|
jobs:
|
||||||
pnpm_install:
|
backend:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4.1.1
|
- uses: actions/checkout@v2
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
|
||||||
submodules: true
|
submodules: true
|
||||||
- uses: pnpm/action-setup@v4
|
- uses: actions/setup-node@v3
|
||||||
- uses: actions/setup-node@v4.0.4
|
|
||||||
with:
|
with:
|
||||||
node-version-file: '.node-version'
|
node-version: 18.x
|
||||||
cache: 'pnpm'
|
cache: 'yarn'
|
||||||
- run: corepack enable
|
cache-dependency-path: |
|
||||||
- run: pnpm i --frozen-lockfile
|
packages/backend/yarn.lock
|
||||||
|
- run: yarn install
|
||||||
|
- run: yarn --cwd ./packages/backend lint
|
||||||
|
|
||||||
lint:
|
client:
|
||||||
needs: [pnpm_install]
|
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
continue-on-error: true
|
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
workspace:
|
|
||||||
- backend
|
|
||||||
- frontend
|
|
||||||
- frontend-shared
|
|
||||||
- frontend-embed
|
|
||||||
- sw
|
|
||||||
- misskey-js
|
|
||||||
- misskey-bubble-game
|
|
||||||
- misskey-reversi
|
|
||||||
env:
|
|
||||||
eslint-cache-version: v1
|
|
||||||
eslint-cache-path: ${{ github.workspace }}/node_modules/.cache/eslint-${{ matrix.workspace }}
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4.1.1
|
- uses: actions/checkout@v2
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
|
||||||
submodules: true
|
submodules: true
|
||||||
- uses: pnpm/action-setup@v4
|
- uses: actions/setup-node@v3
|
||||||
- uses: actions/setup-node@v4.0.4
|
|
||||||
with:
|
with:
|
||||||
node-version-file: '.node-version'
|
node-version: 18.x
|
||||||
cache: 'pnpm'
|
cache: 'yarn'
|
||||||
- run: corepack enable
|
cache-dependency-path: |
|
||||||
- run: pnpm i --frozen-lockfile
|
packages/client/yarn.lock
|
||||||
- name: Restore eslint cache
|
- run: yarn install
|
||||||
uses: actions/cache@v4.1.0
|
- run: yarn --cwd ./packages/client lint
|
||||||
with:
|
|
||||||
path: ${{ env.eslint-cache-path }}
|
|
||||||
key: eslint-${{ env.eslint-cache-version }}-${{ matrix.workspace }}-${{ hashFiles('**/pnpm-lock.yaml') }}-${{ github.ref_name }}-${{ github.sha }}
|
|
||||||
restore-keys: eslint-${{ env.eslint-cache-version }}-${{ matrix.workspace }}-${{ hashFiles('**/pnpm-lock.yaml') }}-
|
|
||||||
- run: pnpm --filter ${{ matrix.workspace }} run eslint --cache --cache-location ${{ env.eslint-cache-path }} --cache-strategy content
|
|
||||||
|
|
||||||
typecheck:
|
|
||||||
needs: [pnpm_install]
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
continue-on-error: true
|
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
workspace:
|
|
||||||
- backend
|
|
||||||
- sw
|
|
||||||
- misskey-js
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4.1.1
|
|
||||||
with:
|
|
||||||
fetch-depth: 0
|
|
||||||
submodules: true
|
|
||||||
- uses: pnpm/action-setup@v4
|
|
||||||
- uses: actions/setup-node@v4.0.4
|
|
||||||
with:
|
|
||||||
node-version-file: '.node-version'
|
|
||||||
cache: 'pnpm'
|
|
||||||
- run: corepack enable
|
|
||||||
- run: pnpm i --frozen-lockfile
|
|
||||||
- run: pnpm --filter misskey-js run build
|
|
||||||
if: ${{ matrix.workspace == 'backend' || matrix.workspace == 'sw' }}
|
|
||||||
- run: pnpm --filter misskey-reversi run build
|
|
||||||
if: ${{ matrix.workspace == 'backend' }}
|
|
||||||
- run: pnpm --filter ${{ matrix.workspace }} run typecheck
|
|
||||||
|
28
.github/workflows/locale.yml
vendored
28
.github/workflows/locale.yml
vendored
@ -1,28 +0,0 @@
|
|||||||
name: Lint
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
paths:
|
|
||||||
- locales/**
|
|
||||||
- .github/workflows/locale.yml
|
|
||||||
pull_request:
|
|
||||||
paths:
|
|
||||||
- locales/**
|
|
||||||
- .github/workflows/locale.yml
|
|
||||||
jobs:
|
|
||||||
locale_verify:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
continue-on-error: true
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4.1.1
|
|
||||||
with:
|
|
||||||
fetch-depth: 0
|
|
||||||
submodules: true
|
|
||||||
- uses: pnpm/action-setup@v4
|
|
||||||
- uses: actions/setup-node@v4.0.4
|
|
||||||
with:
|
|
||||||
node-version-file: '.node-version'
|
|
||||||
cache: 'pnpm'
|
|
||||||
- run: corepack enable
|
|
||||||
- run: pnpm i --frozen-lockfile
|
|
||||||
- run: cd locales && node verify.js
|
|
4
.github/workflows/ok-to-test.yml
vendored
4
.github/workflows/ok-to-test.yml
vendored
@ -17,13 +17,13 @@ jobs:
|
|||||||
# See app.yml for an example app manifest
|
# See app.yml for an example app manifest
|
||||||
- name: Generate token
|
- name: Generate token
|
||||||
id: generate_token
|
id: generate_token
|
||||||
uses: tibdex/github-app-token@v2
|
uses: tibdex/github-app-token@v1
|
||||||
with:
|
with:
|
||||||
app_id: ${{ secrets.DEPLOYBOT_APP_ID }}
|
app_id: ${{ secrets.DEPLOYBOT_APP_ID }}
|
||||||
private_key: ${{ secrets.DEPLOYBOT_PRIVATE_KEY }}
|
private_key: ${{ secrets.DEPLOYBOT_PRIVATE_KEY }}
|
||||||
|
|
||||||
- name: Slash Command Dispatch
|
- name: Slash Command Dispatch
|
||||||
uses: peter-evans/slash-command-dispatch@v4
|
uses: peter-evans/slash-command-dispatch@v1
|
||||||
env:
|
env:
|
||||||
TOKEN: ${{ steps.generate_token.outputs.token }}
|
TOKEN: ${{ steps.generate_token.outputs.token }}
|
||||||
with:
|
with:
|
||||||
|
42
.github/workflows/on-release-created.yml
vendored
42
.github/workflows/on-release-created.yml
vendored
@ -1,42 +0,0 @@
|
|||||||
name: On Release Created (Publish misskey-js)
|
|
||||||
|
|
||||||
on:
|
|
||||||
release:
|
|
||||||
types: [created]
|
|
||||||
|
|
||||||
workflow_dispatch:
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
publish-misskey-js:
|
|
||||||
name: Publish misskey-js
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
permissions:
|
|
||||||
contents: read
|
|
||||||
id-token: write
|
|
||||||
|
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
node-version: [20.16.0]
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4.1.1
|
|
||||||
with:
|
|
||||||
submodules: true
|
|
||||||
- name: Install pnpm
|
|
||||||
uses: pnpm/action-setup@v4
|
|
||||||
- name: Use Node.js ${{ matrix.node-version }}
|
|
||||||
uses: actions/setup-node@v4.0.4
|
|
||||||
with:
|
|
||||||
node-version: ${{ matrix.node-version }}
|
|
||||||
cache: 'pnpm'
|
|
||||||
registry-url: 'https://registry.npmjs.org'
|
|
||||||
- name: Publish package
|
|
||||||
run: |
|
|
||||||
corepack enable
|
|
||||||
pnpm i --frozen-lockfile
|
|
||||||
pnpm build
|
|
||||||
pnpm --filter misskey-js publish --access public --no-git-checks --provenance
|
|
||||||
env:
|
|
||||||
NODE_AUTH_TOKEN: ${{ secrets.NODE_AUTH_TOKEN }}
|
|
||||||
NPM_TOKEN: ${{ secrets.NODE_AUTH_TOKEN }}
|
|
11
.github/workflows/pr-preview-deploy.yml
vendored
11
.github/workflows/pr-preview-deploy.yml
vendored
@ -1,5 +1,7 @@
|
|||||||
# Run secret-dependent integration tests only after /deploy approval
|
# Run secret-dependent integration tests only after /deploy approval
|
||||||
on:
|
on:
|
||||||
|
pull_request:
|
||||||
|
types: [opened, reopened, synchronize]
|
||||||
repository_dispatch:
|
repository_dispatch:
|
||||||
types: [deploy-command]
|
types: [deploy-command]
|
||||||
|
|
||||||
@ -10,10 +12,11 @@ jobs:
|
|||||||
deploy-preview-environment:
|
deploy-preview-environment:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
if:
|
if:
|
||||||
|
github.event_name == 'repository_dispatch' &&
|
||||||
github.event.client_payload.slash_command.sha != '' &&
|
github.event.client_payload.slash_command.sha != '' &&
|
||||||
contains(github.event.client_payload.pull_request.head.sha, github.event.client_payload.slash_command.sha)
|
contains(github.event.client_payload.pull_request.head.sha, github.event.client_payload.slash_command.sha)
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/github-script@v7.0.1
|
- uses: actions/github-script@v5
|
||||||
id: check-id
|
id: check-id
|
||||||
env:
|
env:
|
||||||
number: ${{ github.event.client_payload.pull_request.number }}
|
number: ${{ github.event.client_payload.pull_request.number }}
|
||||||
@ -37,7 +40,7 @@ jobs:
|
|||||||
|
|
||||||
return check[0].id;
|
return check[0].id;
|
||||||
|
|
||||||
- uses: actions/github-script@v7.0.1
|
- uses: actions/github-script@v5
|
||||||
env:
|
env:
|
||||||
check_id: ${{ steps.check-id.outputs.result }}
|
check_id: ${{ steps.check-id.outputs.result }}
|
||||||
details_url: ${{ github.server_url }}/${{ github.repository }}/runs/${{ github.run_id }}
|
details_url: ${{ github.server_url }}/${{ github.repository }}/runs/${{ github.run_id }}
|
||||||
@ -53,7 +56,7 @@ jobs:
|
|||||||
|
|
||||||
# Check out merge commit
|
# Check out merge commit
|
||||||
- name: Fork based /deploy checkout
|
- name: Fork based /deploy checkout
|
||||||
uses: actions/checkout@v4.1.1
|
uses: actions/checkout@v2
|
||||||
with:
|
with:
|
||||||
ref: 'refs/pull/${{ github.event.client_payload.pull_request.number }}/merge'
|
ref: 'refs/pull/${{ github.event.client_payload.pull_request.number }}/merge'
|
||||||
|
|
||||||
@ -72,7 +75,7 @@ jobs:
|
|||||||
timeout: 15m
|
timeout: 15m
|
||||||
|
|
||||||
# Update check run called "integration-fork"
|
# Update check run called "integration-fork"
|
||||||
- uses: actions/github-script@v7.0.1
|
- uses: actions/github-script@v5
|
||||||
id: update-check-run
|
id: update-check-run
|
||||||
if: ${{ always() }}
|
if: ${{ always() }}
|
||||||
env:
|
env:
|
||||||
|
33
.github/workflows/pr-preview-destroy.yml
vendored
33
.github/workflows/pr-preview-destroy.yml
vendored
@ -10,45 +10,12 @@ jobs:
|
|||||||
destroy-preview-environment:
|
destroy-preview-environment:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/github-script@v7.0.1
|
|
||||||
id: check-conclusion
|
|
||||||
env:
|
|
||||||
number: ${{ github.event.number }}
|
|
||||||
with:
|
|
||||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
result-encoding: string
|
|
||||||
script: |
|
|
||||||
const { data: pull } = await github.rest.pulls.get({
|
|
||||||
...context.repo,
|
|
||||||
pull_number: process.env.number
|
|
||||||
});
|
|
||||||
const ref = pull.head.sha;
|
|
||||||
|
|
||||||
const { data: checks } = await github.rest.checks.listForRef({
|
|
||||||
...context.repo,
|
|
||||||
ref
|
|
||||||
});
|
|
||||||
|
|
||||||
const check = checks.check_runs.filter(c => c.name === 'deploy-preview-environment');
|
|
||||||
|
|
||||||
if (check.length === 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const { data: result } = await github.rest.checks.get({
|
|
||||||
...context.repo,
|
|
||||||
check_run_id: check[0].id,
|
|
||||||
});
|
|
||||||
|
|
||||||
return result.conclusion;
|
|
||||||
- name: Context
|
- name: Context
|
||||||
if: steps.check-conclusion.outputs.result == 'success'
|
|
||||||
uses: okteto/context@latest
|
uses: okteto/context@latest
|
||||||
with:
|
with:
|
||||||
token: ${{ secrets.OKTETO_TOKEN }}
|
token: ${{ secrets.OKTETO_TOKEN }}
|
||||||
|
|
||||||
- name: Destroy preview environment
|
- name: Destroy preview environment
|
||||||
if: steps.check-conclusion.outputs.result == 'success'
|
|
||||||
uses: okteto/destroy-preview@latest
|
uses: okteto/destroy-preview@latest
|
||||||
with:
|
with:
|
||||||
name: pr-${{ github.event.number }}-syuilo
|
name: pr-${{ github.event.number }}-syuilo
|
||||||
|
48
.github/workflows/release-edit-with-push.yml
vendored
48
.github/workflows/release-edit-with-push.yml
vendored
@ -1,48 +0,0 @@
|
|||||||
name: "Release Manager: sync changelog with PR"
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- develop
|
|
||||||
paths:
|
|
||||||
- 'CHANGELOG.md'
|
|
||||||
|
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
|
|
||||||
permissions:
|
|
||||||
contents: write
|
|
||||||
issues: write
|
|
||||||
pull-requests: write
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
edit:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
# headが$GITHUB_REF_NAME, baseが$STABLE_BRANCHかつopenのPRを1つ取得
|
|
||||||
- name: Get PR
|
|
||||||
run: |
|
|
||||||
echo "pr_number=$(gh pr list --limit 1 --search "head:$GITHUB_REF_NAME base:$STABLE_BRANCH is:open" --json number --jq '.[] | .number')" >> $GITHUB_OUTPUT
|
|
||||||
id: get_pr
|
|
||||||
env:
|
|
||||||
STABLE_BRANCH: ${{ vars.STABLE_BRANCH }}
|
|
||||||
- name: Get target version
|
|
||||||
if: steps.get_pr.outputs.pr_number != ''
|
|
||||||
uses: misskey-dev/release-manager-actions/.github/actions/get-target-version@v2
|
|
||||||
id: v
|
|
||||||
# CHANGELOG.mdの内容を取得
|
|
||||||
- name: Get changelog
|
|
||||||
if: steps.get_pr.outputs.pr_number != ''
|
|
||||||
uses: misskey-dev/release-manager-actions/.github/actions/get-changelog@v2
|
|
||||||
with:
|
|
||||||
version: ${{ steps.v.outputs.target_version }}
|
|
||||||
id: changelog
|
|
||||||
# PRのnotesを更新
|
|
||||||
- name: Update PR
|
|
||||||
if: steps.get_pr.outputs.pr_number != ''
|
|
||||||
run: |
|
|
||||||
gh pr edit "$PR_NUMBER" --body "$CHANGELOG"
|
|
||||||
env:
|
|
||||||
PR_NUMBER: ${{ steps.get_pr.outputs.pr_number }}
|
|
||||||
CHANGELOG: ${{ steps.changelog.outputs.changelog }}
|
|
135
.github/workflows/release-with-dispatch.yml
vendored
135
.github/workflows/release-with-dispatch.yml
vendored
@ -1,135 +0,0 @@
|
|||||||
name: "Release Manager [Dispatch]"
|
|
||||||
|
|
||||||
on:
|
|
||||||
workflow_dispatch:
|
|
||||||
inputs:
|
|
||||||
## Specify the type of the next release.
|
|
||||||
#version_increment_type:
|
|
||||||
# type: choice
|
|
||||||
# description: 'VERSION INCREMENT TYPE'
|
|
||||||
# default: 'patch'
|
|
||||||
# required: false
|
|
||||||
# options:
|
|
||||||
# - 'major'
|
|
||||||
# - 'minor'
|
|
||||||
# - 'patch'
|
|
||||||
merge:
|
|
||||||
type: boolean
|
|
||||||
description: 'MERGE RELEASE BRANCH TO MAIN'
|
|
||||||
default: false
|
|
||||||
start-rc:
|
|
||||||
type: boolean
|
|
||||||
description: 'Start Release Candidate'
|
|
||||||
default: false
|
|
||||||
|
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
|
|
||||||
permissions:
|
|
||||||
contents: write
|
|
||||||
issues: write
|
|
||||||
pull-requests: write
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
get-pr:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
outputs:
|
|
||||||
pr_number: ${{ steps.get_pr.outputs.pr_number }}
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
# headが$GITHUB_REF_NAME, baseが$STABLE_BRANCHかつopenのPRを1つ取得
|
|
||||||
- name: Get PRs
|
|
||||||
run: |
|
|
||||||
echo "pr_number=$(gh pr list --limit 1 --search "head:$GITHUB_REF_NAME base:$STABLE_BRANCH is:open" --json number --jq '.[] | .number')" >> $GITHUB_OUTPUT
|
|
||||||
id: get_pr
|
|
||||||
env:
|
|
||||||
STABLE_BRANCH: ${{ vars.STABLE_BRANCH }}
|
|
||||||
|
|
||||||
merge:
|
|
||||||
uses: misskey-dev/release-manager-actions/.github/workflows/merge.yml@v2
|
|
||||||
needs: get-pr
|
|
||||||
if: ${{ needs.get-pr.outputs.pr_number != '' && inputs.merge == true }}
|
|
||||||
with:
|
|
||||||
pr_number: ${{ needs.get-pr.outputs.pr_number }}
|
|
||||||
user: 'github-actions[bot]'
|
|
||||||
package_jsons_to_rewrite: ${{ vars.PACKAGE_JSONS_TO_REWRITE }}
|
|
||||||
# Text to prepend to the changelog
|
|
||||||
# The first line must be `## Unreleased`
|
|
||||||
changes_template: |
|
|
||||||
## Unreleased
|
|
||||||
|
|
||||||
### General
|
|
||||||
-
|
|
||||||
|
|
||||||
### Client
|
|
||||||
-
|
|
||||||
|
|
||||||
### Server
|
|
||||||
-
|
|
||||||
|
|
||||||
use_external_app_to_release: ${{ vars.USE_RELEASE_APP == 'true' }}
|
|
||||||
indent: ${{ vars.INDENT }}
|
|
||||||
secrets:
|
|
||||||
RELEASE_APP_ID: ${{ secrets.RELEASE_APP_ID }}
|
|
||||||
RELEASE_APP_PRIVATE_KEY: ${{ secrets.RELEASE_APP_PRIVATE_KEY }}
|
|
||||||
|
|
||||||
create-prerelease:
|
|
||||||
uses: misskey-dev/release-manager-actions/.github/workflows/create-prerelease.yml@v2
|
|
||||||
needs: get-pr
|
|
||||||
if: ${{ needs.get-pr.outputs.pr_number != '' && inputs.merge != true }}
|
|
||||||
with:
|
|
||||||
pr_number: ${{ needs.get-pr.outputs.pr_number }}
|
|
||||||
user: 'github-actions[bot]'
|
|
||||||
package_jsons_to_rewrite: ${{ vars.PACKAGE_JSONS_TO_REWRITE }}
|
|
||||||
use_external_app_to_release: ${{ vars.USE_RELEASE_APP == 'true' }}
|
|
||||||
indent: ${{ vars.INDENT }}
|
|
||||||
draft_prerelease_channel: alpha
|
|
||||||
ready_start_prerelease_channel: beta
|
|
||||||
prerelease_channel: ${{ inputs.start-rc && 'rc' || '' }}
|
|
||||||
secrets:
|
|
||||||
RELEASE_APP_ID: ${{ secrets.RELEASE_APP_ID }}
|
|
||||||
RELEASE_APP_PRIVATE_KEY: ${{ secrets.RELEASE_APP_PRIVATE_KEY }}
|
|
||||||
|
|
||||||
create-target:
|
|
||||||
uses: misskey-dev/release-manager-actions/.github/workflows/create-target.yml@v2
|
|
||||||
needs: get-pr
|
|
||||||
if: ${{ needs.get-pr.outputs.pr_number == '' }}
|
|
||||||
with:
|
|
||||||
user: 'github-actions[bot]'
|
|
||||||
# The script for version increment.
|
|
||||||
# process.env.CURRENT_VERSION: The current version.
|
|
||||||
#
|
|
||||||
# Misskey calender versioning (yyyy.MM.patch) example
|
|
||||||
version_increment_script: |
|
|
||||||
const now = new Date();
|
|
||||||
const year = now.toLocaleDateString('en-US', { year: 'numeric', timeZone: 'Asia/Tokyo' });
|
|
||||||
const month = now.toLocaleDateString('en-US', { month: 'numeric', timeZone: 'Asia/Tokyo' });
|
|
||||||
const [major, minor, _patch] = process.env.CURRENT_VERSION.split('.');
|
|
||||||
const patch = Number(_patch.split('-')[0]);
|
|
||||||
if (Number.isNaN(patch)) {
|
|
||||||
console.error('Invalid patch version', year, month, process.env.CURRENT_VERSION, major, minor, _patch);
|
|
||||||
throw new Error('Invalid patch version');
|
|
||||||
}
|
|
||||||
if (year !== major || month !== minor) {
|
|
||||||
return `${year}.${month}.0`;
|
|
||||||
} else {
|
|
||||||
return `${major}.${minor}.${patch + 1}`;
|
|
||||||
}
|
|
||||||
##Semver example
|
|
||||||
#version_increment_script: |
|
|
||||||
# const [major, minor, patch] = process.env.CURRENT_VERSION.split('.');
|
|
||||||
# if ("${{ inputs.version_increment_type }}" === "major") {
|
|
||||||
# return `${Number(major) + 1}.0.0`;
|
|
||||||
# } else if ("${{ inputs.version_increment_type }}" === "minor") {
|
|
||||||
# return `${major}.${Number(minor) + 1}.0`;
|
|
||||||
# } else {
|
|
||||||
# return `${major}.${minor}.${Number(patch) + 1}`;
|
|
||||||
# }
|
|
||||||
package_jsons_to_rewrite: ${{ vars.PACKAGE_JSONS_TO_REWRITE }}
|
|
||||||
use_external_app_to_release: ${{ vars.USE_RELEASE_APP == 'true' }}
|
|
||||||
indent: ${{ vars.INDENT }}
|
|
||||||
stable_branch: ${{ vars.STABLE_BRANCH }}
|
|
||||||
draft_prerelease_channel: alpha
|
|
||||||
secrets:
|
|
||||||
RELEASE_APP_ID: ${{ secrets.RELEASE_APP_ID }}
|
|
||||||
RELEASE_APP_PRIVATE_KEY: ${{ secrets.RELEASE_APP_PRIVATE_KEY }}
|
|
46
.github/workflows/release-with-ready.yml
vendored
46
.github/workflows/release-with-ready.yml
vendored
@ -1,46 +0,0 @@
|
|||||||
name: "Release Manager: release RC when ready for review"
|
|
||||||
|
|
||||||
on:
|
|
||||||
pull_request:
|
|
||||||
types: [ready_for_review]
|
|
||||||
|
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
|
|
||||||
permissions:
|
|
||||||
contents: write
|
|
||||||
issues: write
|
|
||||||
pull-requests: write
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
check:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
outputs:
|
|
||||||
head: ${{ steps.get_pr.outputs.head }}
|
|
||||||
base: ${{ steps.get_pr.outputs.base }}
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
# PR情報を取得
|
|
||||||
- name: Get PR
|
|
||||||
run: |
|
|
||||||
pr_json=$(gh pr view "$PR_NUMBER" --json isDraft,headRefName,baseRefName)
|
|
||||||
echo "head=$(echo $pr_json | jq -r '.headRefName')" >> $GITHUB_OUTPUT
|
|
||||||
echo "base=$(echo $pr_json | jq -r '.baseRefName')" >> $GITHUB_OUTPUT
|
|
||||||
id: get_pr
|
|
||||||
env:
|
|
||||||
PR_NUMBER: ${{ github.event.pull_request.number }}
|
|
||||||
release:
|
|
||||||
uses: misskey-dev/release-manager-actions/.github/workflows/create-prerelease.yml@v2
|
|
||||||
needs: check
|
|
||||||
if: needs.check.outputs.head == github.event.repository.default_branch && needs.check.outputs.base == vars.STABLE_BRANCH
|
|
||||||
with:
|
|
||||||
pr_number: ${{ github.event.pull_request.number }}
|
|
||||||
user: 'github-actions[bot]'
|
|
||||||
package_jsons_to_rewrite: ${{ vars.PACKAGE_JSONS_TO_REWRITE }}
|
|
||||||
use_external_app_to_release: ${{ vars.USE_RELEASE_APP == 'true' }}
|
|
||||||
indent: ${{ vars.INDENT }}
|
|
||||||
draft_prerelease_channel: alpha
|
|
||||||
ready_start_prerelease_channel: beta
|
|
||||||
secrets:
|
|
||||||
RELEASE_APP_ID: ${{ secrets.RELEASE_APP_ID }}
|
|
||||||
RELEASE_APP_PRIVATE_KEY: ${{ secrets.RELEASE_APP_PRIVATE_KEY }}
|
|
104
.github/workflows/report-api-diff.yml
vendored
104
.github/workflows/report-api-diff.yml
vendored
@ -1,104 +0,0 @@
|
|||||||
name: Report API Diff
|
|
||||||
|
|
||||||
on:
|
|
||||||
workflow_run:
|
|
||||||
types: [completed]
|
|
||||||
workflows:
|
|
||||||
- Get api.json from Misskey # get-api-diff.yml
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
compare-diff:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
if: ${{ github.event.workflow_run.conclusion == 'success' }}
|
|
||||||
permissions:
|
|
||||||
pull-requests: write
|
|
||||||
|
|
||||||
# api-artifact
|
|
||||||
steps:
|
|
||||||
- name: Download artifact
|
|
||||||
uses: actions/github-script@v7.0.1
|
|
||||||
with:
|
|
||||||
script: |
|
|
||||||
const fs = require('fs');
|
|
||||||
let allArtifacts = await github.rest.actions.listWorkflowRunArtifacts({
|
|
||||||
owner: context.repo.owner,
|
|
||||||
repo: context.repo.repo,
|
|
||||||
run_id: context.payload.workflow_run.id,
|
|
||||||
});
|
|
||||||
let matchArtifacts = allArtifacts.data.artifacts.filter((artifact) => {
|
|
||||||
return artifact.name.startsWith("api-artifact-") || artifact.name == "api-artifact"
|
|
||||||
});
|
|
||||||
await Promise.all(matchArtifacts.map(async (artifact) => {
|
|
||||||
let download = await github.rest.actions.downloadArtifact({
|
|
||||||
owner: context.repo.owner,
|
|
||||||
repo: context.repo.repo,
|
|
||||||
artifact_id: artifact.id,
|
|
||||||
archive_format: 'zip',
|
|
||||||
});
|
|
||||||
await fs.promises.writeFile(`${process.env.GITHUB_WORKSPACE}/${artifact.name}.zip`, Buffer.from(download.data));
|
|
||||||
}));
|
|
||||||
- name: Extract all artifacts
|
|
||||||
run: |
|
|
||||||
find . -mindepth 1 -maxdepth 1 -type f -name '*.zip' -exec unzip {} -d artifacts ';'
|
|
||||||
ls -la
|
|
||||||
- name: Load PR Number
|
|
||||||
id: load-pr-num
|
|
||||||
run: echo "pr-number=$(cat artifacts/pr_number)" >> "$GITHUB_OUTPUT"
|
|
||||||
|
|
||||||
- name: Output base
|
|
||||||
run: cat ./artifacts/api-base.json
|
|
||||||
- name: Output head
|
|
||||||
run: cat ./artifacts/api-head.json
|
|
||||||
- name: Arrange json files
|
|
||||||
run: |
|
|
||||||
jq '.' ./artifacts/api-base.json > ./api-base.json
|
|
||||||
jq '.' ./artifacts/api-head.json > ./api-head.json
|
|
||||||
- name: Get diff of 2 files
|
|
||||||
run: diff -u --label=base --label=head ./api-base.json ./api-head.json | cat > api.json.diff
|
|
||||||
- name: Get full diff
|
|
||||||
run: diff --label=base --label=head --new-line-format='+%L' --old-line-format='-%L' --unchanged-line-format=' %L' ./api-base.json ./api-head.json | cat > api-full.json.diff
|
|
||||||
- name: Echo full diff
|
|
||||||
run: cat ./api-full.json.diff
|
|
||||||
- name: Upload full diff to Artifact
|
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: api-artifact
|
|
||||||
path: |
|
|
||||||
api-full.json.diff
|
|
||||||
api-base.json
|
|
||||||
api-head.json
|
|
||||||
- id: out-diff
|
|
||||||
name: Build diff Comment
|
|
||||||
run: |
|
|
||||||
HEADER="このPRによるapi.jsonの差分"
|
|
||||||
FOOTER="[Get diff files from Workflow Page](https://github.com/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID})"
|
|
||||||
DIFF_BYTES="$(stat ./api.json.diff -c '%s' | tr -d '\n')"
|
|
||||||
|
|
||||||
echo "$HEADER" > ./output.md
|
|
||||||
|
|
||||||
if (( "$DIFF_BYTES" <= 1 )); then
|
|
||||||
echo '差分はありません。' >> ./output.md
|
|
||||||
else
|
|
||||||
echo '<details>' >> ./output.md
|
|
||||||
echo '<summary>差分はこちら</summary>' >> ./output.md
|
|
||||||
echo >> ./output.md
|
|
||||||
echo '```diff' >> ./output.md
|
|
||||||
cat ./api.json.diff >> ./output.md
|
|
||||||
echo '```' >> ./output.md
|
|
||||||
echo '</details>' >> .output.md
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "$FOOTER" >> ./output.md
|
|
||||||
- uses: thollander/actions-comment-pull-request@v2
|
|
||||||
with:
|
|
||||||
pr_number: ${{ steps.load-pr-num.outputs.pr-number }}
|
|
||||||
comment_tag: show_diff
|
|
||||||
filePath: ./output.md
|
|
||||||
- name: Tell error to PR
|
|
||||||
uses: thollander/actions-comment-pull-request@v2
|
|
||||||
if: failure() && steps.load-pr-num.outputs.pr-number
|
|
||||||
with:
|
|
||||||
pr_number: ${{ steps.load-pr-num.outputs.pr-number }}
|
|
||||||
comment_tag: show_diff_error
|
|
||||||
message: |
|
|
||||||
api.jsonの差分作成中にエラーが発生しました。詳細は[Workflowのログ](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }})を確認してください。
|
|
116
.github/workflows/storybook.yml
vendored
116
.github/workflows/storybook.yml
vendored
@ -1,116 +0,0 @@
|
|||||||
name: Storybook
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- master
|
|
||||||
- develop
|
|
||||||
- dev/storybook8 # for testing
|
|
||||||
pull_request_target:
|
|
||||||
branches-ignore:
|
|
||||||
# Since pull requests targets master mostly is the "develop" branch.
|
|
||||||
# Storybook CI is checked on the "push" event of "develop" branch so it would cause a duplicate build.
|
|
||||||
# This is a waste of chromatic build quota, so we don't run storybook CI on pull requests targets master.
|
|
||||||
- master
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
env:
|
|
||||||
NODE_OPTIONS: "--max_old_space_size=7168"
|
|
||||||
if: github.repository == 'misskey-dev/misskey'
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4.1.1
|
|
||||||
if: github.event_name != 'pull_request_target'
|
|
||||||
with:
|
|
||||||
fetch-depth: 0
|
|
||||||
submodules: true
|
|
||||||
- uses: actions/checkout@v4.1.1
|
|
||||||
if: github.event_name == 'pull_request_target'
|
|
||||||
with:
|
|
||||||
fetch-depth: 0
|
|
||||||
submodules: true
|
|
||||||
ref: "refs/pull/${{ github.event.number }}/merge"
|
|
||||||
- name: Checkout actual HEAD
|
|
||||||
if: github.event_name == 'pull_request_target'
|
|
||||||
id: rev
|
|
||||||
run: |
|
|
||||||
echo "base=$(git rev-list --parents -n1 HEAD | cut -d" " -f2)" >> $GITHUB_OUTPUT
|
|
||||||
git checkout $(git rev-list --parents -n1 HEAD | cut -d" " -f3)
|
|
||||||
- name: Install pnpm
|
|
||||||
uses: pnpm/action-setup@v4
|
|
||||||
- name: Use Node.js 20.x
|
|
||||||
uses: actions/setup-node@v4.0.4
|
|
||||||
with:
|
|
||||||
node-version-file: '.node-version'
|
|
||||||
cache: 'pnpm'
|
|
||||||
- run: corepack enable
|
|
||||||
- run: pnpm i --frozen-lockfile
|
|
||||||
- name: Check pnpm-lock.yaml
|
|
||||||
run: git diff --exit-code pnpm-lock.yaml
|
|
||||||
- name: Build misskey-js
|
|
||||||
run: pnpm --filter misskey-js build
|
|
||||||
- name: Build storybook
|
|
||||||
run: pnpm --filter frontend build-storybook
|
|
||||||
- name: Publish to Chromatic
|
|
||||||
if: github.event_name != 'pull_request_target' && github.ref == 'refs/heads/master'
|
|
||||||
run: pnpm --filter frontend chromatic --exit-once-uploaded -d storybook-static
|
|
||||||
env:
|
|
||||||
CHROMATIC_PROJECT_TOKEN: ${{ secrets.CHROMATIC_PROJECT_TOKEN }}
|
|
||||||
- name: Publish to Chromatic
|
|
||||||
if: github.event_name != 'pull_request_target' && github.ref != 'refs/heads/master'
|
|
||||||
id: chromatic_push
|
|
||||||
run: |
|
|
||||||
DIFF="${{ github.event.before }} HEAD"
|
|
||||||
if [ "$DIFF" = "0000000000000000000000000000000000000000 HEAD" ]; then
|
|
||||||
DIFF="HEAD"
|
|
||||||
fi
|
|
||||||
CHROMATIC_PARAMETER="$(node packages/frontend/.storybook/changes.js $(git diff-tree --no-commit-id --name-only -r $(echo "$DIFF") | xargs))"
|
|
||||||
if [ "$CHROMATIC_PARAMETER" = " --skip" ]; then
|
|
||||||
echo "skip=true" >> $GITHUB_OUTPUT
|
|
||||||
fi
|
|
||||||
if pnpm --filter frontend chromatic -d storybook-static $(echo "$CHROMATIC_PARAMETER"); then
|
|
||||||
echo "success=true" >> $GITHUB_OUTPUT
|
|
||||||
else
|
|
||||||
echo "success=false" >> $GITHUB_OUTPUT
|
|
||||||
fi
|
|
||||||
env:
|
|
||||||
CHROMATIC_PROJECT_TOKEN: ${{ secrets.CHROMATIC_PROJECT_TOKEN }}
|
|
||||||
- name: Publish to Chromatic
|
|
||||||
if: github.event_name == 'pull_request_target'
|
|
||||||
id: chromatic_pull_request
|
|
||||||
run: |
|
|
||||||
DIFF="${{ steps.rev.outputs.base }} HEAD"
|
|
||||||
if [ "$DIFF" = "0000000000000000000000000000000000000000 HEAD" ]; then
|
|
||||||
DIFF="HEAD"
|
|
||||||
fi
|
|
||||||
CHROMATIC_PARAMETER="$(node packages/frontend/.storybook/changes.js $(git diff-tree --no-commit-id --name-only -r $(echo "$DIFF") | xargs))"
|
|
||||||
if [ "$CHROMATIC_PARAMETER" = " --skip" ]; then
|
|
||||||
echo "skip=true" >> $GITHUB_OUTPUT
|
|
||||||
fi
|
|
||||||
BRANCH="${{ github.event.pull_request.head.user.login }}:$HEAD_REF"
|
|
||||||
if [ "$BRANCH" = "misskey-dev:$HEAD_REF" ]; then
|
|
||||||
BRANCH="$HEAD_REF"
|
|
||||||
fi
|
|
||||||
pnpm --filter frontend chromatic --exit-once-uploaded -d storybook-static --branch-name "$BRANCH" $(echo "$CHROMATIC_PARAMETER")
|
|
||||||
env:
|
|
||||||
HEAD_REF: ${{ github.event.pull_request.head.ref }}
|
|
||||||
CHROMATIC_PROJECT_TOKEN: ${{ secrets.CHROMATIC_PROJECT_TOKEN }}
|
|
||||||
- name: Notify that Chromatic detects changes
|
|
||||||
uses: actions/github-script@v7.0.1
|
|
||||||
if: github.event_name != 'pull_request_target' && steps.chromatic_push.outputs.success == 'false'
|
|
||||||
with:
|
|
||||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
script: |
|
|
||||||
github.rest.repos.createCommitComment({
|
|
||||||
owner: context.repo.owner,
|
|
||||||
repo: context.repo.repo,
|
|
||||||
commit_sha: context.sha,
|
|
||||||
body: 'Chromatic detects changes. Please [review the changes on Chromatic](https://www.chromatic.com/builds?appId=6428f7d7b962f0b79f97d6e4).'
|
|
||||||
})
|
|
||||||
- name: Upload Artifacts
|
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: storybook
|
|
||||||
path: packages/frontend/storybook-static
|
|
114
.github/workflows/test-backend.yml
vendored
114
.github/workflows/test-backend.yml
vendored
@ -1,114 +0,0 @@
|
|||||||
name: Test (backend)
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- master
|
|
||||||
- develop
|
|
||||||
paths:
|
|
||||||
- packages/backend/**
|
|
||||||
# for permissions
|
|
||||||
- packages/misskey-js/**
|
|
||||||
- .github/workflows/test-backend.yml
|
|
||||||
pull_request:
|
|
||||||
paths:
|
|
||||||
- packages/backend/**
|
|
||||||
# for permissions
|
|
||||||
- packages/misskey-js/**
|
|
||||||
- .github/workflows/test-backend.yml
|
|
||||||
jobs:
|
|
||||||
unit:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
node-version: [20.16.0]
|
|
||||||
|
|
||||||
services:
|
|
||||||
postgres:
|
|
||||||
image: postgres:15
|
|
||||||
ports:
|
|
||||||
- 54312:5432
|
|
||||||
env:
|
|
||||||
POSTGRES_DB: test-misskey
|
|
||||||
POSTGRES_HOST_AUTH_METHOD: trust
|
|
||||||
redis:
|
|
||||||
image: redis:7
|
|
||||||
ports:
|
|
||||||
- 56312:6379
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4.1.1
|
|
||||||
with:
|
|
||||||
submodules: true
|
|
||||||
- name: Install pnpm
|
|
||||||
uses: pnpm/action-setup@v4
|
|
||||||
- name: Install FFmpeg
|
|
||||||
uses: FedericoCarboni/setup-ffmpeg@v3
|
|
||||||
- name: Use Node.js ${{ matrix.node-version }}
|
|
||||||
uses: actions/setup-node@v4.0.4
|
|
||||||
with:
|
|
||||||
node-version: ${{ matrix.node-version }}
|
|
||||||
cache: 'pnpm'
|
|
||||||
- run: corepack enable
|
|
||||||
- run: pnpm i --frozen-lockfile
|
|
||||||
- name: Check pnpm-lock.yaml
|
|
||||||
run: git diff --exit-code pnpm-lock.yaml
|
|
||||||
- name: Copy Configure
|
|
||||||
run: cp .github/misskey/test.yml .config
|
|
||||||
- name: Build
|
|
||||||
run: pnpm build
|
|
||||||
- name: Test
|
|
||||||
run: pnpm --filter backend test-and-coverage
|
|
||||||
- name: Upload to Codecov
|
|
||||||
uses: codecov/codecov-action@v4
|
|
||||||
with:
|
|
||||||
token: ${{ secrets.CODECOV_TOKEN }}
|
|
||||||
files: ./packages/backend/coverage/coverage-final.json
|
|
||||||
|
|
||||||
e2e:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
node-version: [20.16.0]
|
|
||||||
|
|
||||||
services:
|
|
||||||
postgres:
|
|
||||||
image: postgres:15
|
|
||||||
ports:
|
|
||||||
- 54312:5432
|
|
||||||
env:
|
|
||||||
POSTGRES_DB: test-misskey
|
|
||||||
POSTGRES_HOST_AUTH_METHOD: trust
|
|
||||||
redis:
|
|
||||||
image: redis:7
|
|
||||||
ports:
|
|
||||||
- 56312:6379
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4.1.1
|
|
||||||
with:
|
|
||||||
submodules: true
|
|
||||||
- name: Install pnpm
|
|
||||||
uses: pnpm/action-setup@v4
|
|
||||||
- name: Use Node.js ${{ matrix.node-version }}
|
|
||||||
uses: actions/setup-node@v4.0.4
|
|
||||||
with:
|
|
||||||
node-version: ${{ matrix.node-version }}
|
|
||||||
cache: 'pnpm'
|
|
||||||
- run: corepack enable
|
|
||||||
- run: pnpm i --frozen-lockfile
|
|
||||||
- name: Check pnpm-lock.yaml
|
|
||||||
run: git diff --exit-code pnpm-lock.yaml
|
|
||||||
- name: Copy Configure
|
|
||||||
run: cp .github/misskey/test.yml .config
|
|
||||||
- name: Build
|
|
||||||
run: pnpm build
|
|
||||||
- name: Test
|
|
||||||
run: pnpm --filter backend test-and-coverage:e2e
|
|
||||||
- name: Upload to Codecov
|
|
||||||
uses: codecov/codecov-action@v4
|
|
||||||
with:
|
|
||||||
token: ${{ secrets.CODECOV_TOKEN }}
|
|
||||||
files: ./packages/backend/coverage/coverage-final.json
|
|
128
.github/workflows/test-frontend.yml
vendored
128
.github/workflows/test-frontend.yml
vendored
@ -1,128 +0,0 @@
|
|||||||
name: Test (frontend)
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- master
|
|
||||||
- develop
|
|
||||||
paths:
|
|
||||||
- packages/frontend/**
|
|
||||||
# for permissions
|
|
||||||
- packages/misskey-js/**
|
|
||||||
# for e2e
|
|
||||||
- packages/backend/**
|
|
||||||
- .github/workflows/test-frontend.yml
|
|
||||||
pull_request:
|
|
||||||
paths:
|
|
||||||
- packages/frontend/**
|
|
||||||
# for permissions
|
|
||||||
- packages/misskey-js/**
|
|
||||||
# for e2e
|
|
||||||
- packages/backend/**
|
|
||||||
- .github/workflows/test-frontend.yml
|
|
||||||
jobs:
|
|
||||||
vitest:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
node-version: [20.16.0]
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4.1.1
|
|
||||||
with:
|
|
||||||
submodules: true
|
|
||||||
- name: Install pnpm
|
|
||||||
uses: pnpm/action-setup@v4
|
|
||||||
- name: Use Node.js ${{ matrix.node-version }}
|
|
||||||
uses: actions/setup-node@v4.0.4
|
|
||||||
with:
|
|
||||||
node-version: ${{ matrix.node-version }}
|
|
||||||
cache: 'pnpm'
|
|
||||||
- run: corepack enable
|
|
||||||
- run: pnpm i --frozen-lockfile
|
|
||||||
- name: Check pnpm-lock.yaml
|
|
||||||
run: git diff --exit-code pnpm-lock.yaml
|
|
||||||
- name: Copy Configure
|
|
||||||
run: cp .github/misskey/test.yml .config
|
|
||||||
- name: Build
|
|
||||||
run: pnpm build
|
|
||||||
- name: Test
|
|
||||||
run: pnpm --filter frontend test-and-coverage
|
|
||||||
- name: Upload Coverage
|
|
||||||
uses: codecov/codecov-action@v4
|
|
||||||
with:
|
|
||||||
token: ${{ secrets.CODECOV_TOKEN }}
|
|
||||||
files: ./packages/frontend/coverage/coverage-final.json
|
|
||||||
|
|
||||||
e2e:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
matrix:
|
|
||||||
node-version: [20.16.0]
|
|
||||||
browser: [chrome]
|
|
||||||
|
|
||||||
services:
|
|
||||||
postgres:
|
|
||||||
image: postgres:15
|
|
||||||
ports:
|
|
||||||
- 54312:5432
|
|
||||||
env:
|
|
||||||
POSTGRES_DB: test-misskey
|
|
||||||
POSTGRES_HOST_AUTH_METHOD: trust
|
|
||||||
redis:
|
|
||||||
image: redis:7
|
|
||||||
ports:
|
|
||||||
- 56312:6379
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4.1.1
|
|
||||||
with:
|
|
||||||
submodules: true
|
|
||||||
# https://github.com/cypress-io/cypress-docker-images/issues/150
|
|
||||||
#- name: Install mplayer for FireFox
|
|
||||||
# run: sudo apt install mplayer -y
|
|
||||||
# if: ${{ matrix.browser == 'firefox' }}
|
|
||||||
#- uses: browser-actions/setup-firefox@latest
|
|
||||||
# if: ${{ matrix.browser == 'firefox' }}
|
|
||||||
- name: Install pnpm
|
|
||||||
uses: pnpm/action-setup@v4
|
|
||||||
- name: Use Node.js ${{ matrix.node-version }}
|
|
||||||
uses: actions/setup-node@v4.0.4
|
|
||||||
with:
|
|
||||||
node-version: ${{ matrix.node-version }}
|
|
||||||
cache: 'pnpm'
|
|
||||||
- run: corepack enable
|
|
||||||
- run: pnpm i --frozen-lockfile
|
|
||||||
- name: Copy Configure
|
|
||||||
run: cp .github/misskey/test.yml .config
|
|
||||||
- name: Build
|
|
||||||
run: pnpm build
|
|
||||||
# https://github.com/cypress-io/cypress/issues/4351#issuecomment-559489091
|
|
||||||
- name: ALSA Env
|
|
||||||
run: echo -e 'pcm.!default {\n type hw\n card 0\n}\n\nctl.!default {\n type hw\n card 0\n}' > ~/.asoundrc
|
|
||||||
# XXX: This tries reinstalling Cypress if the binary is not cached
|
|
||||||
# Remove this when the cache issue is fixed
|
|
||||||
- name: Cypress install
|
|
||||||
run: pnpm exec cypress install
|
|
||||||
- name: Cypress run
|
|
||||||
uses: cypress-io/github-action@v6
|
|
||||||
timeout-minutes: 15
|
|
||||||
with:
|
|
||||||
install: false
|
|
||||||
start: pnpm start:test
|
|
||||||
wait-on: 'http://localhost:61812'
|
|
||||||
headed: true
|
|
||||||
browser: ${{ matrix.browser }}
|
|
||||||
- uses: actions/upload-artifact@v4
|
|
||||||
if: failure()
|
|
||||||
with:
|
|
||||||
name: ${{ matrix.browser }}-cypress-screenshots
|
|
||||||
path: cypress/screenshots
|
|
||||||
- uses: actions/upload-artifact@v4
|
|
||||||
if: always()
|
|
||||||
with:
|
|
||||||
name: ${{ matrix.browser }}-cypress-videos
|
|
||||||
path: cypress/videos
|
|
57
.github/workflows/test-misskey-js.yml
vendored
57
.github/workflows/test-misskey-js.yml
vendored
@ -1,57 +0,0 @@
|
|||||||
# This workflow will do a clean install of node dependencies, build the source code and run tests across different versions of node
|
|
||||||
# For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions
|
|
||||||
|
|
||||||
name: Test (misskey.js)
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches: [ develop ]
|
|
||||||
paths:
|
|
||||||
- packages/misskey-js/**
|
|
||||||
- .github/workflows/test-misskey-js.yml
|
|
||||||
pull_request:
|
|
||||||
branches: [ develop ]
|
|
||||||
paths:
|
|
||||||
- packages/misskey-js/**
|
|
||||||
- .github/workflows/test-misskey-js.yml
|
|
||||||
jobs:
|
|
||||||
test:
|
|
||||||
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
node-version: [20.16.0]
|
|
||||||
# See supported Node.js release schedule at https://nodejs.org/en/about/releases/
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@v4.1.1
|
|
||||||
|
|
||||||
- run: corepack enable
|
|
||||||
|
|
||||||
- name: Setup Node.js ${{ matrix.node-version }}
|
|
||||||
uses: actions/setup-node@v4.0.4
|
|
||||||
with:
|
|
||||||
node-version: ${{ matrix.node-version }}
|
|
||||||
cache: 'pnpm'
|
|
||||||
|
|
||||||
- name: Install dependencies
|
|
||||||
run: pnpm i --frozen-lockfile
|
|
||||||
|
|
||||||
- name: Check pnpm-lock.yaml
|
|
||||||
run: git diff --exit-code pnpm-lock.yaml
|
|
||||||
|
|
||||||
- name: Build
|
|
||||||
run: pnpm --filter misskey-js build
|
|
||||||
|
|
||||||
- name: Test
|
|
||||||
run: pnpm --filter misskey-js test
|
|
||||||
env:
|
|
||||||
CI: true
|
|
||||||
|
|
||||||
- name: Upload Coverage
|
|
||||||
uses: codecov/codecov-action@v4
|
|
||||||
with:
|
|
||||||
token: ${{ secrets.CODECOV_TOKEN }}
|
|
||||||
files: ./packages/misskey-js/coverage/coverage-final.json
|
|
39
.github/workflows/test-production.yml
vendored
39
.github/workflows/test-production.yml
vendored
@ -1,39 +0,0 @@
|
|||||||
name: Test (production install and build)
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- master
|
|
||||||
- develop
|
|
||||||
pull_request:
|
|
||||||
|
|
||||||
env:
|
|
||||||
NODE_ENV: production
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
production:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
node-version: [20.16.0]
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4.1.1
|
|
||||||
with:
|
|
||||||
submodules: true
|
|
||||||
- name: Install pnpm
|
|
||||||
uses: pnpm/action-setup@v4
|
|
||||||
- name: Use Node.js ${{ matrix.node-version }}
|
|
||||||
uses: actions/setup-node@v4.0.4
|
|
||||||
with:
|
|
||||||
node-version: ${{ matrix.node-version }}
|
|
||||||
cache: 'pnpm'
|
|
||||||
- run: corepack enable
|
|
||||||
- run: pnpm i --frozen-lockfile
|
|
||||||
- name: Check pnpm-lock.yaml
|
|
||||||
run: git diff --exit-code pnpm-lock.yaml
|
|
||||||
- name: Copy Configure
|
|
||||||
run: cp .github/misskey/test.yml .config/default.yml
|
|
||||||
- name: Build
|
|
||||||
run: pnpm build
|
|
122
.github/workflows/test.yml
vendored
Normal file
122
.github/workflows/test.yml
vendored
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
name: Test
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
- develop
|
||||||
|
pull_request:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
mocha:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
node-version: [18.x]
|
||||||
|
|
||||||
|
services:
|
||||||
|
postgres:
|
||||||
|
image: postgres:13
|
||||||
|
ports:
|
||||||
|
- 54312:5432
|
||||||
|
env:
|
||||||
|
POSTGRES_DB: test-misskey
|
||||||
|
POSTGRES_HOST_AUTH_METHOD: trust
|
||||||
|
redis:
|
||||||
|
image: redis:6
|
||||||
|
ports:
|
||||||
|
- 56312:6379
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
with:
|
||||||
|
submodules: true
|
||||||
|
- name: Use Node.js ${{ matrix.node-version }}
|
||||||
|
uses: actions/setup-node@v3
|
||||||
|
with:
|
||||||
|
node-version: ${{ matrix.node-version }}
|
||||||
|
cache: 'yarn'
|
||||||
|
cache-dependency-path: |
|
||||||
|
packages/backend/yarn.lock
|
||||||
|
packages/client/yarn.lock
|
||||||
|
- name: Install dependencies
|
||||||
|
run: yarn install
|
||||||
|
- name: Check yarn.lock
|
||||||
|
run: git diff --exit-code yarn.lock
|
||||||
|
- name: Copy Configure
|
||||||
|
run: cp .github/misskey/test.yml .config
|
||||||
|
- name: Build
|
||||||
|
run: yarn build
|
||||||
|
- name: Test
|
||||||
|
run: yarn mocha
|
||||||
|
|
||||||
|
e2e:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
node-version: [18.x]
|
||||||
|
browser: [chrome]
|
||||||
|
|
||||||
|
services:
|
||||||
|
postgres:
|
||||||
|
image: postgres:13
|
||||||
|
ports:
|
||||||
|
- 54312:5432
|
||||||
|
env:
|
||||||
|
POSTGRES_DB: test-misskey
|
||||||
|
POSTGRES_HOST_AUTH_METHOD: trust
|
||||||
|
redis:
|
||||||
|
image: redis:6
|
||||||
|
ports:
|
||||||
|
- 56312:6379
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
with:
|
||||||
|
submodules: true
|
||||||
|
# https://github.com/cypress-io/cypress-docker-images/issues/150
|
||||||
|
#- name: Install mplayer for FireFox
|
||||||
|
# run: sudo apt install mplayer -y
|
||||||
|
# if: ${{ matrix.browser == 'firefox' }}
|
||||||
|
#- uses: browser-actions/setup-firefox@latest
|
||||||
|
# if: ${{ matrix.browser == 'firefox' }}
|
||||||
|
- name: Use Node.js ${{ matrix.node-version }}
|
||||||
|
uses: actions/setup-node@v3
|
||||||
|
with:
|
||||||
|
node-version: ${{ matrix.node-version }}
|
||||||
|
cache: 'yarn'
|
||||||
|
cache-dependency-path: |
|
||||||
|
packages/backend/yarn.lock
|
||||||
|
packages/client/yarn.lock
|
||||||
|
- name: Install dependencies
|
||||||
|
run: yarn install
|
||||||
|
- name: Check yarn.lock
|
||||||
|
run: git diff --exit-code yarn.lock
|
||||||
|
- name: Copy Configure
|
||||||
|
run: cp .github/misskey/test.yml .config
|
||||||
|
- name: Build
|
||||||
|
run: yarn build
|
||||||
|
# https://github.com/cypress-io/cypress/issues/4351#issuecomment-559489091
|
||||||
|
- name: ALSA Env
|
||||||
|
run: echo -e 'pcm.!default {\n type hw\n card 0\n}\n\nctl.!default {\n type hw\n card 0\n}' > ~/.asoundrc
|
||||||
|
- name: Cypress run
|
||||||
|
uses: cypress-io/github-action@v4
|
||||||
|
with:
|
||||||
|
install: false
|
||||||
|
start: npm run start:test
|
||||||
|
wait-on: 'http://localhost:61812'
|
||||||
|
headless: false
|
||||||
|
browser: ${{ matrix.browser }}
|
||||||
|
- uses: actions/upload-artifact@v2
|
||||||
|
if: failure()
|
||||||
|
with:
|
||||||
|
name: ${{ matrix.browser }}-cypress-screenshots
|
||||||
|
path: cypress/screenshots
|
||||||
|
- uses: actions/upload-artifact@v2
|
||||||
|
if: always()
|
||||||
|
with:
|
||||||
|
name: ${{ matrix.browser }}-cypress-videos
|
||||||
|
path: cypress/videos
|
45
.github/workflows/validate-api-json.yml
vendored
45
.github/workflows/validate-api-json.yml
vendored
@ -1,45 +0,0 @@
|
|||||||
name: Test (backend)
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- master
|
|
||||||
- develop
|
|
||||||
paths:
|
|
||||||
- packages/backend/**
|
|
||||||
- .github/workflows/validate-api-json.yml
|
|
||||||
pull_request:
|
|
||||||
paths:
|
|
||||||
- packages/backend/**
|
|
||||||
- .github/workflows/validate-api-json.yml
|
|
||||||
jobs:
|
|
||||||
validate-api-json:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
node-version: [20.16.0]
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4.1.1
|
|
||||||
with:
|
|
||||||
submodules: true
|
|
||||||
- name: Install pnpm
|
|
||||||
uses: pnpm/action-setup@v4
|
|
||||||
- name: Use Node.js ${{ matrix.node-version }}
|
|
||||||
uses: actions/setup-node@v4.0.4
|
|
||||||
with:
|
|
||||||
node-version: ${{ matrix.node-version }}
|
|
||||||
cache: 'pnpm'
|
|
||||||
- name: Install Redocly CLI
|
|
||||||
run: npm i -g @redocly/cli
|
|
||||||
- run: corepack enable
|
|
||||||
- run: pnpm i --frozen-lockfile
|
|
||||||
- name: Check pnpm-lock.yaml
|
|
||||||
run: git diff --exit-code pnpm-lock.yaml
|
|
||||||
- name: Copy Configure
|
|
||||||
run: cp .config/example.yml .config/default.yml
|
|
||||||
- name: Build and generate
|
|
||||||
run: pnpm build && pnpm --filter backend generate-api-json
|
|
||||||
- name: Validation
|
|
||||||
run: npx @redocly/cli lint --extends=minimal ./packages/backend/built/api.json
|
|
40
.gitignore
vendored
40
.gitignore
vendored
@ -9,47 +9,22 @@
|
|||||||
node_modules
|
node_modules
|
||||||
report.*.json
|
report.*.json
|
||||||
|
|
||||||
# Yarn
|
|
||||||
.yarn/*
|
|
||||||
!.yarn/patches
|
|
||||||
!.yarn/plugins
|
|
||||||
!.yarn/releases
|
|
||||||
!.yarn/sdks
|
|
||||||
!.yarn/versions
|
|
||||||
packages/frontend/.yarn/cache
|
|
||||||
packages/backend/.yarn/cache
|
|
||||||
packages/sw/.yarn/cache
|
|
||||||
|
|
||||||
# pnpm
|
|
||||||
.pnpm-store
|
|
||||||
|
|
||||||
# Cypress
|
# Cypress
|
||||||
cypress/screenshots
|
cypress/screenshots
|
||||||
cypress/videos
|
cypress/videos
|
||||||
|
|
||||||
# Coverage
|
|
||||||
coverage
|
|
||||||
|
|
||||||
# config
|
# config
|
||||||
/.config/*
|
/.config/*
|
||||||
!/.config/example.yml
|
!/.config/example.yml
|
||||||
!/.config/docker_example.yml
|
|
||||||
!/.config/docker_example.env
|
!/.config/docker_example.env
|
||||||
!/.config/cypress-devcontainer.yml
|
|
||||||
docker-compose.yml
|
|
||||||
compose.yml
|
|
||||||
.devcontainer/compose.yml
|
|
||||||
!/.devcontainer/compose.yml
|
|
||||||
|
|
||||||
# misskey
|
# misskey
|
||||||
/build
|
/build
|
||||||
built
|
built
|
||||||
built-test
|
|
||||||
js-built
|
|
||||||
/data
|
/data
|
||||||
/.cache-loader
|
/.cache-loader
|
||||||
/db
|
/db
|
||||||
/meili_data
|
/elasticsearch
|
||||||
npm-debug.log
|
npm-debug.log
|
||||||
*.pem
|
*.pem
|
||||||
run.bat
|
run.bat
|
||||||
@ -60,14 +35,6 @@ api-docs.json
|
|||||||
.DS_Store
|
.DS_Store
|
||||||
/files
|
/files
|
||||||
ormconfig.json
|
ormconfig.json
|
||||||
temp
|
|
||||||
/packages/frontend/src/**/*.stories.ts
|
|
||||||
tsdoc-metadata.json
|
|
||||||
misskey-assets
|
|
||||||
|
|
||||||
# Vite temporary files
|
|
||||||
vite.config.js.timestamp-*
|
|
||||||
vite.config.ts.timestamp-*
|
|
||||||
|
|
||||||
# blender backups
|
# blender backups
|
||||||
*.blend1
|
*.blend1
|
||||||
@ -75,8 +42,3 @@ vite.config.ts.timestamp-*
|
|||||||
*.blend3
|
*.blend3
|
||||||
*.blend4
|
*.blend4
|
||||||
*.blend5
|
*.blend5
|
||||||
|
|
||||||
# VSCode addon
|
|
||||||
.favorites.json
|
|
||||||
|
|
||||||
/dump.rdb
|
|
||||||
|
6
.gitmodules
vendored
6
.gitmodules
vendored
@ -1,3 +1,3 @@
|
|||||||
[submodule "fluent-emojis"]
|
[submodule "misskey-assets"]
|
||||||
path = fluent-emojis
|
path = misskey-assets
|
||||||
url = https://github.com/misskey-dev/emojis.git
|
url = https://github.com/misskey-dev/assets.git
|
||||||
|
@ -1 +1 @@
|
|||||||
20.16.0
|
v16.15.0
|
||||||
|
4
.vscode/extensions.json
vendored
4
.vscode/extensions.json
vendored
@ -1,9 +1,9 @@
|
|||||||
{
|
{
|
||||||
"recommendations": [
|
"recommendations": [
|
||||||
"editorconfig.editorconfig",
|
"editorconfig.editorconfig",
|
||||||
|
"eg2.vscode-npm-script",
|
||||||
"dbaeumer.vscode-eslint",
|
"dbaeumer.vscode-eslint",
|
||||||
"Vue.volar",
|
"Vue.volar",
|
||||||
"Orta.vscode-jest",
|
"Vue.vscode-typescript-vue-plugin"
|
||||||
"mrmlnc.vscode-json5"
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
15
.vscode/settings.json
vendored
15
.vscode/settings.json
vendored
@ -1,15 +0,0 @@
|
|||||||
{
|
|
||||||
"search.exclude": {
|
|
||||||
"**/node_modules": true
|
|
||||||
},
|
|
||||||
"typescript.tsdk": "node_modules/typescript/lib",
|
|
||||||
"files.associations": {
|
|
||||||
"*.test.ts": "typescript"
|
|
||||||
},
|
|
||||||
"jest.jestCommandLine": "pnpm run jest",
|
|
||||||
"jest.runMode": "on-demand",
|
|
||||||
"editor.codeActionsOnSave": {
|
|
||||||
"source.fixAll": "explicit"
|
|
||||||
},
|
|
||||||
"editor.formatOnSave": false
|
|
||||||
}
|
|
2104
CHANGELOG.md
2104
CHANGELOG.md
File diff suppressed because it is too large
Load Diff
@ -2,131 +2,45 @@
|
|||||||
|
|
||||||
## Our Pledge
|
## Our Pledge
|
||||||
|
|
||||||
We as members, contributors, and leaders pledge to make participation in our
|
In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
|
||||||
community a harassment-free experience for everyone, regardless of age, body
|
|
||||||
size, visible or invisible disability, ethnicity, sex characteristics, gender
|
|
||||||
identity and expression, level of experience, education, socio-economic status,
|
|
||||||
nationality, personal appearance, race, caste, color, religion, or sexual
|
|
||||||
identity and orientation.
|
|
||||||
|
|
||||||
We pledge to act and interact in ways that contribute to an open, welcoming,
|
|
||||||
diverse, inclusive, and healthy community.
|
|
||||||
|
|
||||||
## Our Standards
|
## Our Standards
|
||||||
|
|
||||||
Examples of behavior that contributes to a positive environment for our
|
Examples of behavior that contributes to creating a positive environment include:
|
||||||
community include:
|
|
||||||
|
|
||||||
* Demonstrating empathy and kindness toward other people
|
* Using welcoming and inclusive language
|
||||||
* Being respectful of differing opinions, viewpoints, and experiences
|
* Being respectful of differing viewpoints and experiences
|
||||||
* Giving and gracefully accepting constructive feedback
|
* Gracefully accepting constructive criticism
|
||||||
* Accepting responsibility and apologizing to those affected by our mistakes,
|
* Focusing on what is best for the community
|
||||||
and learning from the experience
|
* Showing empathy towards other community members
|
||||||
* Focusing on what is best not just for us as individuals, but for the overall
|
|
||||||
community
|
|
||||||
|
|
||||||
Examples of unacceptable behavior include:
|
Examples of unacceptable behavior by participants include:
|
||||||
|
|
||||||
* The use of sexualized language or imagery, and sexual attention or advances of
|
* The use of sexualized language or imagery and unwelcome sexual attention or advances
|
||||||
any kind
|
* Trolling, insulting/derogatory comments, and personal or political attacks
|
||||||
* Trolling, insulting or derogatory comments, and personal or political attacks
|
|
||||||
* Public or private harassment
|
* Public or private harassment
|
||||||
* Publishing others' private information, such as a physical or email address,
|
* Publishing others' private information, such as a physical or electronic address, without explicit permission
|
||||||
without their explicit permission
|
* Other conduct which could reasonably be considered inappropriate in a professional setting
|
||||||
* Other conduct which could reasonably be considered inappropriate in a
|
|
||||||
professional setting
|
|
||||||
|
|
||||||
## Enforcement Responsibilities
|
## Our Responsibilities
|
||||||
|
|
||||||
Community leaders are responsible for clarifying and enforcing our standards of
|
Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
|
||||||
acceptable behavior and will take appropriate and fair corrective action in
|
|
||||||
response to any behavior that they deem inappropriate, threatening, offensive,
|
|
||||||
or harmful.
|
|
||||||
|
|
||||||
Community leaders have the right and responsibility to remove, edit, or reject
|
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
|
||||||
comments, commits, code, wiki edits, issues, and other contributions that are
|
|
||||||
not aligned to this Code of Conduct, and will communicate reasons for moderation
|
|
||||||
decisions when appropriate.
|
|
||||||
|
|
||||||
## Scope
|
## Scope
|
||||||
|
|
||||||
This Code of Conduct applies within all community spaces, and also applies when
|
This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
|
||||||
an individual is officially representing the community in public spaces.
|
|
||||||
Examples of representing our community include using an official e-mail address,
|
|
||||||
posting via an official social media account, or acting as an appointed
|
|
||||||
representative at an online or offline event.
|
|
||||||
|
|
||||||
## Enforcement
|
## Enforcement
|
||||||
|
|
||||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at syuilotan@yahoo.co.jp. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
|
||||||
reported to the community leaders responsible for enforcement at
|
|
||||||
<syuilotan@yahoo.co.jp>.
|
|
||||||
All complaints will be reviewed and investigated promptly and fairly.
|
|
||||||
|
|
||||||
All community leaders are obligated to respect the privacy and security of the
|
Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
|
||||||
reporter of any incident.
|
|
||||||
|
|
||||||
## Enforcement Guidelines
|
|
||||||
|
|
||||||
Community leaders will follow these Community Impact Guidelines in determining
|
|
||||||
the consequences for any action they deem in violation of this Code of Conduct:
|
|
||||||
|
|
||||||
### 1. Correction
|
|
||||||
|
|
||||||
**Community Impact**: Use of inappropriate language or other behavior deemed
|
|
||||||
unprofessional or unwelcome in the community.
|
|
||||||
|
|
||||||
**Consequence**: A private, written warning from community leaders, providing
|
|
||||||
clarity around the nature of the violation and an explanation of why the
|
|
||||||
behavior was inappropriate. A public apology may be requested.
|
|
||||||
|
|
||||||
### 2. Warning
|
|
||||||
|
|
||||||
**Community Impact**: A violation through a single incident or series of
|
|
||||||
actions.
|
|
||||||
|
|
||||||
**Consequence**: A warning with consequences for continued behavior. No
|
|
||||||
interaction with the people involved, including unsolicited interaction with
|
|
||||||
those enforcing the Code of Conduct, for a specified period of time. This
|
|
||||||
includes avoiding interactions in community spaces as well as external channels
|
|
||||||
like social media. Violating these terms may lead to a temporary or permanent
|
|
||||||
ban.
|
|
||||||
|
|
||||||
### 3. Temporary Ban
|
|
||||||
|
|
||||||
**Community Impact**: A serious violation of community standards, including
|
|
||||||
sustained inappropriate behavior.
|
|
||||||
|
|
||||||
**Consequence**: A temporary ban from any sort of interaction or public
|
|
||||||
communication with the community for a specified period of time. No public or
|
|
||||||
private interaction with the people involved, including unsolicited interaction
|
|
||||||
with those enforcing the Code of Conduct, is allowed during this period.
|
|
||||||
Violating these terms may lead to a permanent ban.
|
|
||||||
|
|
||||||
### 4. Permanent Ban
|
|
||||||
|
|
||||||
**Community Impact**: Demonstrating a pattern of violation of community
|
|
||||||
standards, including sustained inappropriate behavior, harassment of an
|
|
||||||
individual, or aggression toward or disparagement of classes of individuals.
|
|
||||||
|
|
||||||
**Consequence**: A permanent ban from any sort of public interaction within the
|
|
||||||
community.
|
|
||||||
|
|
||||||
## Attribution
|
## Attribution
|
||||||
|
|
||||||
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
|
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]
|
||||||
version 2.1, available at
|
|
||||||
[https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1].
|
|
||||||
|
|
||||||
Community Impact Guidelines were inspired by
|
[homepage]: http://contributor-covenant.org
|
||||||
[Mozilla's code of conduct enforcement ladder][Mozilla CoC].
|
[version]: http://contributor-covenant.org/version/1/4/
|
||||||
|
|
||||||
For answers to common questions about this code of conduct, see the FAQ at
|
|
||||||
[https://www.contributor-covenant.org/faq][FAQ]. Translations are available at
|
|
||||||
[https://www.contributor-covenant.org/translations][translations].
|
|
||||||
|
|
||||||
[homepage]: https://www.contributor-covenant.org
|
|
||||||
[v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html
|
|
||||||
[Mozilla CoC]: https://github.com/mozilla/diversity
|
|
||||||
[FAQ]: https://www.contributor-covenant.org/faq
|
|
||||||
[translations]: https://www.contributor-covenant.org/translations
|
|
||||||
|
391
CONTRIBUTING.md
391
CONTRIBUTING.md
@ -1,7 +1,7 @@
|
|||||||
# Contribution guide
|
# Contribution guide
|
||||||
We're glad you're interested in contributing Misskey! In this document you will find the information you need to contribute to the project.
|
We're glad you're interested in contributing Misskey! In this document you will find the information you need to contribute to the project.
|
||||||
|
|
||||||
> [!NOTE]
|
> **Note**
|
||||||
> This project uses Japanese as its major language, **but you do not need to translate and write the Issues/PRs in Japanese.**
|
> This project uses Japanese as its major language, **but you do not need to translate and write the Issues/PRs in Japanese.**
|
||||||
> Also, you might receive comments on your Issue/PR in Japanese, but you do not need to reply to them in Japanese as well.\
|
> Also, you might receive comments on your Issue/PR in Japanese, but you do not need to reply to them in Japanese as well.\
|
||||||
> The accuracy of machine translation into Japanese is not high, so it will be easier for us to understand if you write it in the original language.
|
> The accuracy of machine translation into Japanese is not high, so it will be easier for us to understand if you write it in the original language.
|
||||||
@ -15,33 +15,18 @@ Before creating an issue, please check the following:
|
|||||||
- To avoid duplication, please search for similar issues before creating a new issue.
|
- To avoid duplication, please search for similar issues before creating a new issue.
|
||||||
- Do not use Issues to ask questions or troubleshooting.
|
- Do not use Issues to ask questions or troubleshooting.
|
||||||
- Issues should only be used to feature requests, suggestions, and bug tracking.
|
- Issues should only be used to feature requests, suggestions, and bug tracking.
|
||||||
- Please ask questions or troubleshooting in [GitHub Discussions](https://github.com/misskey-dev/misskey/discussions) or [Discord](https://discord.gg/Wp8gVStHW3).
|
- Please ask questions or troubleshooting in the [Misskey Forum](https://forum.misskey.io/) or [Discord](https://discord.gg/Wp8gVStHW3).
|
||||||
|
|
||||||
> [!WARNING]
|
> **Warning**
|
||||||
> Do not close issues that are about to be resolved. It should remain open until a commit that actually resolves it is merged.
|
> Do not close issues that are about to be resolved. It should remain open until a commit that actually resolves it is merged.
|
||||||
|
|
||||||
### Recommended discussing before implementation
|
## Before implementation
|
||||||
We welcome your proposal.
|
|
||||||
|
|
||||||
When you want to add a feature or fix a bug, **first have the design and policy reviewed in an Issue** (if it is not there, please make one). Without this step, there is a high possibility that the PR will not be merged even if it is implemented.
|
When you want to add a feature or fix a bug, **first have the design and policy reviewed in an Issue** (if it is not there, please make one). Without this step, there is a high possibility that the PR will not be merged even if it is implemented.
|
||||||
|
|
||||||
At this point, you also need to clarify the goals of the PR you will create, and make sure that the other members of the team are aware of them.
|
At this point, you also need to clarify the goals of the PR you will create, and make sure that the other members of the team are aware of them.
|
||||||
PRs that do not have a clear set of do's and don'ts tend to be bloated and difficult to review.
|
PRs that do not have a clear set of do's and don'ts tend to be bloated and difficult to review.
|
||||||
|
|
||||||
Also, when you start implementation, assign yourself to the Issue (if you cannot do it yourself, ask Committer to assign you).
|
Also, when you start implementation, assign yourself to the Issue (if you cannot do it yourself, ask another member to assign you). By expressing your intention to work the Issue, you can prevent conflicts in the work.
|
||||||
By expressing your intention to work on the Issue, you can prevent conflicts in the work.
|
|
||||||
|
|
||||||
To the Committers: you should not assign someone on it before the Final Decision.
|
|
||||||
|
|
||||||
### How issues are triaged
|
|
||||||
|
|
||||||
The Committers may:
|
|
||||||
* close an issue that is not reproducible on latest stable release,
|
|
||||||
* merge an issue into another issue,
|
|
||||||
* split an issue into multiple issues,
|
|
||||||
* or re-open that has been closed for some reason which is not applicable anymore.
|
|
||||||
|
|
||||||
@syuilo reserves the Final Decision rights including whether the project will implement feature and how to implement, these rights are not always exercised.
|
|
||||||
|
|
||||||
## Well-known branches
|
## Well-known branches
|
||||||
- **`master`** branch is tracking the latest release and used for production purposes.
|
- **`master`** branch is tracking the latest release and used for production purposes.
|
||||||
@ -59,7 +44,7 @@ Thank you for your PR! Before creating a PR, please check the following:
|
|||||||
- Check if there are any documents that need to be created or updated due to this change.
|
- Check if there are any documents that need to be created or updated due to this change.
|
||||||
- If you have added a feature or fixed a bug, please add a test case if possible.
|
- If you have added a feature or fixed a bug, please add a test case if possible.
|
||||||
- Please make sure that tests and Lint are passed in advance.
|
- Please make sure that tests and Lint are passed in advance.
|
||||||
- You can run it with `pnpm test` and `pnpm lint`. [See more info](#testing)
|
- You can run it with `npm run test` and `npm run lint`. [See more info](#testing)
|
||||||
- If this PR includes UI changes, please attach a screenshot in the text.
|
- If this PR includes UI changes, please attach a screenshot in the text.
|
||||||
|
|
||||||
Thanks for your cooperation 🤗
|
Thanks for your cooperation 🤗
|
||||||
@ -89,27 +74,22 @@ The `/deploy` command by issue comment can be used to deploy the contents of a P
|
|||||||
An actual domain will be assigned so you can test the federation.
|
An actual domain will be assigned so you can test the federation.
|
||||||
|
|
||||||
## Merge
|
## Merge
|
||||||
|
For now, basically only @syuilo has the authority to merge PRs into develop because he is most familiar with the codebase.
|
||||||
|
However, minor fixes, refactoring, and urgent changes may be merged at the discretion of a contributor.
|
||||||
|
|
||||||
## Release
|
## Release
|
||||||
### Release Instructions
|
### Release Instructions
|
||||||
1. Commit version changes in the `develop` branch ([package.json](package.json))
|
1. Commit version changes in the `develop` branch ([package.json](https://github.com/misskey-dev/misskey/blob/develop/package.json))
|
||||||
2. Create a release PR.
|
2. Create a release PR.
|
||||||
- Into `master` from `develop` branch.
|
- Into `master` from `develop` branch.
|
||||||
- The title must be in the format `Release: x.y.z`.
|
- The title must be in the format `Release: x.y.z`.
|
||||||
- `x.y.z` is the new version you are trying to release.
|
- `x.y.z` is the new version you are trying to release.
|
||||||
3. Deploy and perform a simple QA check. Also verify that the tests passed.
|
3. Deploy and perform a simple QA check. Also verify that the tests passed.
|
||||||
4. Merge it. (Do not squash commit)
|
4. Merge it.
|
||||||
5. Create a [release of GitHub](https://github.com/misskey-dev/misskey/releases)
|
5. Create a [release of GitHub](https://github.com/misskey-dev/misskey/releases)
|
||||||
- The target branch must be `master`
|
- The target branch must be `master`
|
||||||
- The tag name must be the version
|
- The tag name must be the version
|
||||||
|
|
||||||
> [!NOTE]
|
|
||||||
> Why this instruction is necessary:
|
|
||||||
> - To perform final QA checks
|
|
||||||
> - To distribute responsibility
|
|
||||||
> - To check direct commits to develop
|
|
||||||
> - To celebrate the release together 🎉
|
|
||||||
|
|
||||||
## Localization (l10n)
|
## Localization (l10n)
|
||||||
Misskey uses [Crowdin](https://crowdin.com/project/misskey) for localization management.
|
Misskey uses [Crowdin](https://crowdin.com/project/misskey) for localization management.
|
||||||
You can improve our translations with your Crowdin account.
|
You can improve our translations with your Crowdin account.
|
||||||
@ -121,97 +101,37 @@ If your language is not listed in Crowdin, please open an issue.
|
|||||||
![Crowdin](https://d322cqt584bo4o.cloudfront.net/misskey/localized.svg)
|
![Crowdin](https://d322cqt584bo4o.cloudfront.net/misskey/localized.svg)
|
||||||
|
|
||||||
## Development
|
## Development
|
||||||
### Setup
|
During development, it is useful to use the `npm run dev` command.
|
||||||
Before developing, you have to set up environment. Misskey requires Redis, PostgreSQL, and FFmpeg.
|
This command monitors the server-side and client-side source files and automatically builds them if they are modified.
|
||||||
|
In addition, it will also automatically start the Misskey server process.
|
||||||
You would want to install Meilisearch to experiment related features. Technically, meilisearch is not strict requirement, but some features and tests require it.
|
|
||||||
|
|
||||||
There are a few ways to proceed.
|
|
||||||
|
|
||||||
#### Use system-wide software
|
|
||||||
You could install them in system-wide (such as from package manager).
|
|
||||||
|
|
||||||
#### Use `docker compose`
|
|
||||||
You could obtain middleware container by typing `docker compose -f $PROJECT_ROOT/compose.local-db.yml up -d`.
|
|
||||||
|
|
||||||
#### Use Devcontainer
|
|
||||||
Devcontainer also has necessary setting. This method can be done by connecting from VSCode.
|
|
||||||
|
|
||||||
Instead of running `pnpm` locally, you can use Dev Container to set up your development environment.
|
|
||||||
To use Dev Container, open the project directory on VSCode with Dev Containers installed.
|
|
||||||
**Note:** If you are using Windows, please clone the repository with WSL. Using Git for Windows will result in broken files due to the difference in how newlines are handled.
|
|
||||||
|
|
||||||
It will run the following command automatically inside the container.
|
|
||||||
``` bash
|
|
||||||
git submodule update --init
|
|
||||||
pnpm install --frozen-lockfile
|
|
||||||
cp .devcontainer/devcontainer.yml .config/default.yml
|
|
||||||
pnpm build
|
|
||||||
pnpm migrate
|
|
||||||
```
|
|
||||||
|
|
||||||
After finishing the migration, you can proceed.
|
|
||||||
|
|
||||||
### Start developing
|
|
||||||
During development, it is useful to use the
|
|
||||||
```
|
|
||||||
pnpm dev
|
|
||||||
```
|
|
||||||
command.
|
|
||||||
|
|
||||||
- Server-side source files and automatically builds them if they are modified. Automatically start the server process(es).
|
|
||||||
- Vite HMR (just the `vite` command) is available. The behavior may be different from production.
|
|
||||||
- Service Worker is watched by esbuild.
|
|
||||||
- The front end can be viewed by accessing `http://localhost:5173`.
|
|
||||||
- The backend listens on the port configured with `port` in .config/default.yml.
|
|
||||||
If you have not changed it from the default, it will be "http://localhost:3000".
|
|
||||||
If "port" in .config/default.yml is set to something other than 3000, you need to change the proxy settings in packages/frontend/vite.config.local-dev.ts.
|
|
||||||
|
|
||||||
### `MK_DEV_PREFER=backend pnpm dev`
|
|
||||||
pnpm dev has another mode with `MK_DEV_PREFER=backend`.
|
|
||||||
|
|
||||||
```
|
|
||||||
MK_DEV_PREFER=backend pnpm dev
|
|
||||||
```
|
|
||||||
|
|
||||||
- This mode is closer to the production environment than the default mode.
|
|
||||||
- Vite runs behind the backend (the backend will proxy Vite at /vite).
|
|
||||||
- You can see Misskey by accessing `http://localhost:3000` (Replace `3000` with the port configured with `port` in .config/default.yml).
|
|
||||||
- To change the port of Vite, specify with `VITE_PORT` environment variable.
|
|
||||||
- HMR may not work in some environments such as Windows.
|
|
||||||
|
|
||||||
## Testing
|
## Testing
|
||||||
- Test codes are located in [`/packages/backend/test`](/packages/backend/test).
|
- Test codes are located in [`/test`](/test).
|
||||||
|
|
||||||
### Run test
|
### Run test
|
||||||
Create a config file.
|
Create a config file.
|
||||||
```
|
```
|
||||||
cp .github/misskey/test.yml .config/
|
cp test/test.yml .config/
|
||||||
```
|
```
|
||||||
Prepare DB/Redis for testing.
|
Prepare DB/Redis for testing.
|
||||||
```
|
```
|
||||||
docker compose -f packages/backend/test/compose.yml up
|
docker-compose -f test/docker-compose.yml up
|
||||||
```
|
```
|
||||||
Alternatively, prepare an empty (data can be erased) DB and edit `.config/test.yml`.
|
Alternatively, prepare an empty (data can be erased) DB and edit `.config/test.yml`.
|
||||||
|
|
||||||
Run all test.
|
Run all test.
|
||||||
```
|
```
|
||||||
pnpm test
|
npm run test
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Run specify test
|
#### Run specify test
|
||||||
```
|
```
|
||||||
pnpm jest -- foo.ts
|
npx cross-env TS_NODE_FILES=true TS_NODE_TRANSPILE_ONLY=true TS_NODE_PROJECT="./test/tsconfig.json" npx mocha test/foo.ts --require ts-node/register
|
||||||
```
|
```
|
||||||
|
|
||||||
### e2e tests
|
### e2e tests
|
||||||
TODO
|
TODO
|
||||||
|
|
||||||
## Environment Variable
|
|
||||||
|
|
||||||
- `MISSKEY_CONFIG_YML`: Specify the file path of config.yml instead of default.yml (e.g. `2nd.yml`).
|
|
||||||
- `MISSKEY_WEBFINGER_USE_HTTP`: If it's set true, WebFinger requests will be http instead of https, useful for testing federation between servers in localhost. NEVER USE IN PRODUCTION.
|
|
||||||
|
|
||||||
## Continuous integration
|
## Continuous integration
|
||||||
Misskey uses GitHub Actions for executing automated tests.
|
Misskey uses GitHub Actions for executing automated tests.
|
||||||
Configuration files are located in [`/.github/workflows`](/.github/workflows).
|
Configuration files are located in [`/.github/workflows`](/.github/workflows).
|
||||||
@ -222,227 +142,10 @@ Misskey uses Vue(v3) as its front-end framework.
|
|||||||
- **When creating a new component, please use the Composition API (with [setup sugar](https://v3.vuejs.org/api/sfc-script-setup.html) and [ref sugar](https://github.com/vuejs/rfcs/discussions/369)) instead of the Options API.**
|
- **When creating a new component, please use the Composition API (with [setup sugar](https://v3.vuejs.org/api/sfc-script-setup.html) and [ref sugar](https://github.com/vuejs/rfcs/discussions/369)) instead of the Options API.**
|
||||||
- Some of the existing components are implemented in the Options API, but it is an old implementation. Refactors that migrate those components to the Composition API are also welcome.
|
- Some of the existing components are implemented in the Options API, but it is an old implementation. Refactors that migrate those components to the Composition API are also welcome.
|
||||||
|
|
||||||
## nirax
|
|
||||||
niraxは、Misskeyで使用しているオリジナルのフロントエンドルーティングシステムです。
|
|
||||||
**vue-routerから影響を多大に受けているので、まずはvue-routerについて学ぶことをお勧めします。**
|
|
||||||
|
|
||||||
### ルート定義
|
|
||||||
ルート定義は、以下の形式のオブジェクトの配列です。
|
|
||||||
|
|
||||||
```ts
|
|
||||||
{
|
|
||||||
name?: string;
|
|
||||||
path: string;
|
|
||||||
component: Component;
|
|
||||||
query?: Record<string, string>;
|
|
||||||
loginRequired?: boolean;
|
|
||||||
hash?: string;
|
|
||||||
globalCacheKey?: string;
|
|
||||||
children?: RouteDef[];
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
> [!WARNING]
|
|
||||||
> 現状、ルートは定義された順に評価されます。
|
|
||||||
> たとえば、`/foo/:id`ルート定義の次に`/foo/bar`ルート定義がされていた場合、後者がマッチすることはありません。
|
|
||||||
|
|
||||||
### 複数のルーター
|
|
||||||
vue-routerとの最大の違いは、niraxは複数のルーターが存在することを許可している点です。
|
|
||||||
これにより、アプリ内ウィンドウでブラウザとは個別にルーティングすることなどが可能になります。
|
|
||||||
|
|
||||||
## Storybook
|
|
||||||
|
|
||||||
Misskey uses [Storybook](https://storybook.js.org/) for UI development.
|
|
||||||
|
|
||||||
### Setup & Run
|
|
||||||
|
|
||||||
#### Setup
|
|
||||||
|
|
||||||
```bash
|
|
||||||
pnpm --filter misskey-js build
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Run
|
|
||||||
|
|
||||||
```bash
|
|
||||||
pnpm --filter frontend storybook-dev
|
|
||||||
```
|
|
||||||
|
|
||||||
### Usage
|
|
||||||
|
|
||||||
When you create a new component (in this example, `MyComponent.vue`), the story file (`MyComponent.stories.ts`) will be automatically generated by the `.storybook/generate.js` script.
|
|
||||||
You can override the default story by creating a impl story file (`MyComponent.stories.impl.ts`).
|
|
||||||
|
|
||||||
```ts
|
|
||||||
/* eslint-disable @typescript-eslint/explicit-function-return-type */
|
|
||||||
import { StoryObj } from '@storybook/vue3';
|
|
||||||
import MyComponent from './MyComponent.vue';
|
|
||||||
export const Default = {
|
|
||||||
render(args) {
|
|
||||||
return {
|
|
||||||
components: {
|
|
||||||
MyComponent,
|
|
||||||
},
|
|
||||||
setup() {
|
|
||||||
return {
|
|
||||||
args,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
props() {
|
|
||||||
return {
|
|
||||||
...this.args,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
},
|
|
||||||
template: '<MyComponent v-bind="props" />',
|
|
||||||
};
|
|
||||||
},
|
|
||||||
args: {
|
|
||||||
foo: 'bar',
|
|
||||||
},
|
|
||||||
parameters: {
|
|
||||||
layout: 'centered',
|
|
||||||
},
|
|
||||||
} satisfies StoryObj<typeof MyComponent>;
|
|
||||||
```
|
|
||||||
|
|
||||||
If you want to opt-out from the automatic generation, create a `MyComponent.stories.impl.ts` file and add the following line to the file.
|
|
||||||
|
|
||||||
```ts
|
|
||||||
import MyComponent from './MyComponent.vue';
|
|
||||||
void MyComponent;
|
|
||||||
```
|
|
||||||
|
|
||||||
You can override the component meta by creating a meta story file (`MyComponent.stories.meta.ts`).
|
|
||||||
|
|
||||||
```ts
|
|
||||||
export const argTypes = {
|
|
||||||
scale: {
|
|
||||||
control: {
|
|
||||||
type: 'range',
|
|
||||||
min: 1,
|
|
||||||
max: 4,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
```
|
|
||||||
|
|
||||||
Also, you can use msw to mock API requests in the storybook. Creating a `MyComponent.stories.msw.ts` file to define the mock handlers.
|
|
||||||
|
|
||||||
```ts
|
|
||||||
import { HttpResponse, http } from 'msw';
|
|
||||||
export const handlers = [
|
|
||||||
http.post('/api/notes/timeline', ({ request }) => {
|
|
||||||
return HttpResponse.json([]);
|
|
||||||
}),
|
|
||||||
];
|
|
||||||
```
|
|
||||||
|
|
||||||
Don't forget to re-run the `.storybook/generate.js` script after adding, editing, or removing the above files.
|
|
||||||
|
|
||||||
## Nest
|
|
||||||
|
|
||||||
### Nest Service Circular dependency / Nestでサービスの循環参照でエラーが起きた場合
|
|
||||||
|
|
||||||
#### forwardRef
|
|
||||||
まずは簡単に`forwardRef`を試してみる
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
export class FooService {
|
|
||||||
constructor(
|
|
||||||
@Inject(forwardRef(() => BarService))
|
|
||||||
private barService: BarService
|
|
||||||
) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
#### OnModuleInit
|
|
||||||
できなければ`OnModuleInit`を使う
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
import { Injectable, OnModuleInit } from '@nestjs/common';
|
|
||||||
import { ModuleRef } from '@nestjs/core';
|
|
||||||
import { BarService } from '@/core/BarService';
|
|
||||||
|
|
||||||
@Injectable()
|
|
||||||
export class FooService implements OnModuleInit {
|
|
||||||
private barService: BarService // constructorから移動してくる
|
|
||||||
|
|
||||||
constructor(
|
|
||||||
private moduleRef: ModuleRef,
|
|
||||||
) {
|
|
||||||
}
|
|
||||||
|
|
||||||
async onModuleInit() {
|
|
||||||
this.barService = this.moduleRef.get(BarService.name);
|
|
||||||
}
|
|
||||||
|
|
||||||
public async niceMethod() {
|
|
||||||
return await this.barService.incredibleMethod({ hoge: 'fuga' });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
##### Service Unit Test
|
|
||||||
テストで`onModuleInit`を呼び出す必要がある
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
// import ...
|
|
||||||
|
|
||||||
describe('test', () => {
|
|
||||||
let app: TestingModule;
|
|
||||||
let fooService: FooService; // for test case
|
|
||||||
let barService: BarService; // for test case
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
|
||||||
app = await Test.createTestingModule({
|
|
||||||
imports: ...,
|
|
||||||
providers: [
|
|
||||||
FooService,
|
|
||||||
{ // mockする (mockは必須ではないかもしれない)
|
|
||||||
provide: BarService,
|
|
||||||
useFactory: () => ({
|
|
||||||
incredibleMethod: jest.fn(),
|
|
||||||
}),
|
|
||||||
},
|
|
||||||
{ // Provideにする
|
|
||||||
provide: BarService.name,
|
|
||||||
useExisting: BarService,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
})
|
|
||||||
.useMocker(...
|
|
||||||
.compile();
|
|
||||||
|
|
||||||
fooService = app.get<FooService>(FooService);
|
|
||||||
barService = app.get<BarService>(BarService) as jest.Mocked<BarService>;
|
|
||||||
|
|
||||||
// onModuleInitを実行する
|
|
||||||
await fooService.onModuleInit();
|
|
||||||
});
|
|
||||||
|
|
||||||
test('nice', () => {
|
|
||||||
await fooService.niceMethod();
|
|
||||||
|
|
||||||
expect(barService.incredibleMethod).toHaveBeenCalled();
|
|
||||||
expect(barService.incredibleMethod.mock.lastCall![0])
|
|
||||||
.toEqual({ hoge: 'fuga' });
|
|
||||||
});
|
|
||||||
})
|
|
||||||
```
|
|
||||||
|
|
||||||
## Notes
|
## Notes
|
||||||
|
### How to resolve conflictions occurred at yarn.lock?
|
||||||
|
|
||||||
### Misskeyのドメイン固有の概念は`Mi`をprefixする
|
Just execute `yarn` to fix it.
|
||||||
例えばGoogleが自社サービスをMap、Earth、DriveではなくGoogle Map、Google Earth、Google Driveのように命名するのと同じ
|
|
||||||
コード上でMisskeyのドメイン固有の概念には`Mi`をprefixすることで、他のドメインの同様の概念と区別できるほか、名前の衝突を防ぐ。
|
|
||||||
ただし、文脈上Misskeyのものを指すことが明らかであり、名前の衝突の恐れがない場合は、一時的なローカル変数に限って`Mi`を省略してもよい。
|
|
||||||
|
|
||||||
### How to resolve conflictions occurred at pnpm-lock.yaml?
|
|
||||||
|
|
||||||
Just execute `pnpm` to fix it.
|
|
||||||
|
|
||||||
### INSERTするときにはsaveではなくinsertを使用する
|
### INSERTするときにはsaveではなくinsertを使用する
|
||||||
#6441
|
#6441
|
||||||
@ -521,41 +224,19 @@ SQLでは配列のインデックスは**1始まり**。
|
|||||||
### null IN
|
### null IN
|
||||||
nullが含まれる可能性のあるカラムにINするときは、そのままだとおかしくなるのでORなどでnullのハンドリングをしよう。
|
nullが含まれる可能性のあるカラムにINするときは、そのままだとおかしくなるのでORなどでnullのハンドリングをしよう。
|
||||||
|
|
||||||
### enumの削除は気をつける
|
### `undefined`にご用心
|
||||||
enumの列挙の内容の削除は、その値をもつレコードを全て削除しないといけない
|
MongoDBの時とは違い、findOneでレコードを取得する時に対象レコードが存在しない場合 **`undefined`** が返ってくるので注意。
|
||||||
|
MongoDBは`null`で返してきてたので、その感覚で`if (x === null)`とか書くとバグる。代わりに`if (x == null)`と書いてください
|
||||||
削除が重たかったり不可能だったりする場合は、削除しないでおく
|
|
||||||
|
|
||||||
### Migration作成方法
|
### Migration作成方法
|
||||||
packages/backendで:
|
packages/backendで:
|
||||||
```sh
|
```sh
|
||||||
pnpm dlx typeorm migration:generate -d ormconfig.js -o <migration name>
|
npx typeorm migration:generate -d ormconfig.js -o <migration name>
|
||||||
```
|
```
|
||||||
|
|
||||||
- 生成後、ファイルをmigration下に移してください
|
- 生成後、ファイルをmigration下に移してください
|
||||||
- 作成されたスクリプトは不必要な変更を含むため除去してください
|
- 作成されたスクリプトは不必要な変更を含むため除去してください
|
||||||
|
|
||||||
### JSON SchemaのobjectでanyOfを使うとき
|
|
||||||
JSON Schemaで、objectに対してanyOfを使う場合、anyOfの中でpropertiesを定義しないこと。
|
|
||||||
バリデーションが効かないため。(SchemaTypeもそのように作られており、objectのanyOf内のpropertiesは捨てられます)
|
|
||||||
https://github.com/misskey-dev/misskey/pull/10082
|
|
||||||
|
|
||||||
テキストhogeおよびfugaについて、片方を必須としつつ両方の指定もありうる場合:
|
|
||||||
|
|
||||||
```ts
|
|
||||||
export const paramDef = {
|
|
||||||
type: 'object',
|
|
||||||
properties: {
|
|
||||||
hoge: { type: 'string', minLength: 1 },
|
|
||||||
fuga: { type: 'string', minLength: 1 },
|
|
||||||
},
|
|
||||||
anyOf: [
|
|
||||||
{ required: ['hoge'] },
|
|
||||||
{ required: ['fuga'] },
|
|
||||||
],
|
|
||||||
} as const;
|
|
||||||
```
|
|
||||||
|
|
||||||
### コネクションには`markRaw`せよ
|
### コネクションには`markRaw`せよ
|
||||||
**Vueのコンポーネントのdataオプションとして**misskey.jsのコネクションを設定するとき、必ず`markRaw`でラップしてください。インスタンスが不必要にリアクティブ化されることで、misskey.js内の処理で不具合が発生するとともに、パフォーマンス上の問題にも繋がる。なお、Composition APIを使う場合はこの限りではない(リアクティブ化はマニュアルなため)。
|
**Vueのコンポーネントのdataオプションとして**misskey.jsのコネクションを設定するとき、必ず`markRaw`でラップしてください。インスタンスが不必要にリアクティブ化されることで、misskey.js内の処理で不具合が発生するとともに、パフォーマンス上の問題にも繋がる。なお、Composition APIを使う場合はこの限りではない(リアクティブ化はマニュアルなため)。
|
||||||
|
|
||||||
@ -569,27 +250,3 @@ marginはそのコンポーネントを使う側が設定する
|
|||||||
## その他
|
## その他
|
||||||
### HTMLのクラス名で follow という単語は使わない
|
### HTMLのクラス名で follow という単語は使わない
|
||||||
広告ブロッカーで誤ってブロックされる
|
広告ブロッカーで誤ってブロックされる
|
||||||
|
|
||||||
### indexというファイル名を使うな
|
|
||||||
ESMではディレクトリインポートは廃止されているのと、ディレクトリインポートせずともファイル名が index だと何故か一部のライブラリ?でディレクトリインポートだと見做されてエラーになる
|
|
||||||
|
|
||||||
## CSS Recipe
|
|
||||||
|
|
||||||
### Lighten CSS vars
|
|
||||||
|
|
||||||
``` css
|
|
||||||
color: hsl(from var(--accent) h s calc(l + 10));
|
|
||||||
```
|
|
||||||
|
|
||||||
### Darken CSS vars
|
|
||||||
|
|
||||||
``` css
|
|
||||||
color: hsl(from var(--accent) h s calc(l - 10));
|
|
||||||
```
|
|
||||||
|
|
||||||
### Add alpha to CSS vars
|
|
||||||
|
|
||||||
``` css
|
|
||||||
color: color(from var(--accent) srgb r g b / 0.5);
|
|
||||||
```
|
|
||||||
|
|
||||||
|
6
COPYING
6
COPYING
@ -1,5 +1,5 @@
|
|||||||
Unless otherwise stated this repository is
|
Unless otherwise stated this repository is
|
||||||
Copyright © 2014-2024 syuilo and contributors
|
Copyright © 2014-2020 syuilo and contributers
|
||||||
|
|
||||||
And is distributed under The GNU Affero General Public License Version 3, you should have received a copy of the license file as LICENSE.
|
And is distributed under The GNU Affero General Public License Version 3, you should have received a copy of the license file as LICENSE.
|
||||||
|
|
||||||
@ -13,7 +13,3 @@ https://github.com/muan/emojilib/blob/master/LICENSE
|
|||||||
RsaSignature2017 implementation by Transmute Industries Inc
|
RsaSignature2017 implementation by Transmute Industries Inc
|
||||||
License: MIT
|
License: MIT
|
||||||
https://github.com/transmute-industries/RsaSignature2017/blob/master/LICENSE
|
https://github.com/transmute-industries/RsaSignature2017/blob/master/LICENSE
|
||||||
|
|
||||||
Machine learning model for sensitive images by Infinite Red, Inc.
|
|
||||||
License: MIT
|
|
||||||
https://github.com/infinitered/nsfwjs/blob/master/LICENSE
|
|
||||||
|
116
Dockerfile
116
Dockerfile
@ -1,108 +1,36 @@
|
|||||||
# syntax = docker/dockerfile:1.4
|
FROM node:18.0.0-alpine3.15 AS base
|
||||||
|
|
||||||
ARG NODE_VERSION=20.16.0-bullseye
|
|
||||||
|
|
||||||
# build assets & compile TypeScript
|
|
||||||
|
|
||||||
FROM --platform=$BUILDPLATFORM node:${NODE_VERSION} AS native-builder
|
|
||||||
|
|
||||||
RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
|
|
||||||
--mount=type=cache,target=/var/lib/apt,sharing=locked \
|
|
||||||
rm -f /etc/apt/apt.conf.d/docker-clean \
|
|
||||||
; echo 'Binary::apt::APT::Keep-Downloaded-Packages "true";' > /etc/apt/apt.conf.d/keep-cache \
|
|
||||||
&& apt-get update \
|
|
||||||
&& apt-get install -yqq --no-install-recommends \
|
|
||||||
build-essential
|
|
||||||
|
|
||||||
RUN corepack enable
|
|
||||||
|
|
||||||
WORKDIR /misskey
|
|
||||||
|
|
||||||
COPY --link ["pnpm-lock.yaml", "pnpm-workspace.yaml", "package.json", "./"]
|
|
||||||
COPY --link ["scripts", "./scripts"]
|
|
||||||
COPY --link ["packages/backend/package.json", "./packages/backend/"]
|
|
||||||
COPY --link ["packages/frontend-shared/package.json", "./packages/frontend-shared/"]
|
|
||||||
COPY --link ["packages/frontend/package.json", "./packages/frontend/"]
|
|
||||||
COPY --link ["packages/frontend-embed/package.json", "./packages/frontend-embed/"]
|
|
||||||
COPY --link ["packages/sw/package.json", "./packages/sw/"]
|
|
||||||
COPY --link ["packages/misskey-js/package.json", "./packages/misskey-js/"]
|
|
||||||
COPY --link ["packages/misskey-reversi/package.json", "./packages/misskey-reversi/"]
|
|
||||||
COPY --link ["packages/misskey-bubble-game/package.json", "./packages/misskey-bubble-game/"]
|
|
||||||
|
|
||||||
ARG NODE_ENV=production
|
ARG NODE_ENV=production
|
||||||
|
|
||||||
RUN --mount=type=cache,target=/root/.local/share/pnpm/store,sharing=locked \
|
|
||||||
pnpm i --frozen-lockfile --aggregate-output
|
|
||||||
|
|
||||||
COPY --link . ./
|
|
||||||
|
|
||||||
RUN git submodule update --init
|
|
||||||
RUN pnpm build
|
|
||||||
RUN rm -rf .git/
|
|
||||||
|
|
||||||
# build native dependencies for target platform
|
|
||||||
|
|
||||||
FROM --platform=$TARGETPLATFORM node:${NODE_VERSION} AS target-builder
|
|
||||||
|
|
||||||
RUN apt-get update \
|
|
||||||
&& apt-get install -yqq --no-install-recommends \
|
|
||||||
build-essential
|
|
||||||
|
|
||||||
RUN corepack enable
|
|
||||||
|
|
||||||
WORKDIR /misskey
|
WORKDIR /misskey
|
||||||
|
|
||||||
COPY --link ["pnpm-lock.yaml", "pnpm-workspace.yaml", "package.json", "./"]
|
ENV BUILD_DEPS autoconf automake file g++ gcc libc-dev libtool make nasm pkgconfig python3 zlib-dev git
|
||||||
COPY --link ["scripts", "./scripts"]
|
|
||||||
COPY --link ["packages/backend/package.json", "./packages/backend/"]
|
|
||||||
COPY --link ["packages/misskey-js/package.json", "./packages/misskey-js/"]
|
|
||||||
COPY --link ["packages/misskey-reversi/package.json", "./packages/misskey-reversi/"]
|
|
||||||
COPY --link ["packages/misskey-bubble-game/package.json", "./packages/misskey-bubble-game/"]
|
|
||||||
|
|
||||||
ARG NODE_ENV=production
|
FROM base AS builder
|
||||||
|
|
||||||
RUN --mount=type=cache,target=/root/.local/share/pnpm/store,sharing=locked \
|
COPY . ./
|
||||||
pnpm i --frozen-lockfile --aggregate-output
|
|
||||||
|
|
||||||
FROM --platform=$TARGETPLATFORM node:${NODE_VERSION}-slim AS runner
|
RUN apk add --no-cache $BUILD_DEPS && \
|
||||||
|
git submodule update --init && \
|
||||||
|
yarn install && \
|
||||||
|
yarn build && \
|
||||||
|
rm -rf .git
|
||||||
|
|
||||||
ARG UID="991"
|
FROM base AS runner
|
||||||
ARG GID="991"
|
|
||||||
|
|
||||||
RUN apt-get update \
|
RUN apk add --no-cache \
|
||||||
&& apt-get install -y --no-install-recommends \
|
ffmpeg \
|
||||||
ffmpeg tini curl libjemalloc-dev libjemalloc2 \
|
tini
|
||||||
&& ln -s /usr/lib/$(uname -m)-linux-gnu/libjemalloc.so.2 /usr/local/lib/libjemalloc.so \
|
|
||||||
&& corepack enable \
|
|
||||||
&& groupadd -g "${GID}" misskey \
|
|
||||||
&& useradd -l -u "${UID}" -g "${GID}" -m -d /misskey misskey \
|
|
||||||
&& find / -type d -path /sys -prune -o -type d -path /proc -prune -o -type f -perm /u+s -ignore_readdir_race -exec chmod u-s {} \; \
|
|
||||||
&& find / -type d -path /sys -prune -o -type d -path /proc -prune -o -type f -perm /g+s -ignore_readdir_race -exec chmod g-s {} \; \
|
|
||||||
&& apt-get clean \
|
|
||||||
&& rm -rf /var/lib/apt/lists
|
|
||||||
|
|
||||||
USER misskey
|
ENTRYPOINT ["/sbin/tini", "--"]
|
||||||
WORKDIR /misskey
|
|
||||||
|
|
||||||
# add package.json to add pnpm
|
COPY --from=builder /misskey/node_modules ./node_modules
|
||||||
COPY --chown=misskey:misskey ./package.json ./package.json
|
COPY --from=builder /misskey/built ./built
|
||||||
RUN corepack install
|
COPY --from=builder /misskey/packages/backend/node_modules ./packages/backend/node_modules
|
||||||
|
COPY --from=builder /misskey/packages/backend/built ./packages/backend/built
|
||||||
|
COPY --from=builder /misskey/packages/client/node_modules ./packages/client/node_modules
|
||||||
|
COPY . ./
|
||||||
|
|
||||||
COPY --chown=misskey:misskey --from=target-builder /misskey/node_modules ./node_modules
|
|
||||||
COPY --chown=misskey:misskey --from=target-builder /misskey/packages/backend/node_modules ./packages/backend/node_modules
|
|
||||||
COPY --chown=misskey:misskey --from=target-builder /misskey/packages/misskey-js/node_modules ./packages/misskey-js/node_modules
|
|
||||||
COPY --chown=misskey:misskey --from=target-builder /misskey/packages/misskey-reversi/node_modules ./packages/misskey-reversi/node_modules
|
|
||||||
COPY --chown=misskey:misskey --from=target-builder /misskey/packages/misskey-bubble-game/node_modules ./packages/misskey-bubble-game/node_modules
|
|
||||||
COPY --chown=misskey:misskey --from=native-builder /misskey/built ./built
|
|
||||||
COPY --chown=misskey:misskey --from=native-builder /misskey/packages/misskey-js/built ./packages/misskey-js/built
|
|
||||||
COPY --chown=misskey:misskey --from=native-builder /misskey/packages/misskey-reversi/built ./packages/misskey-reversi/built
|
|
||||||
COPY --chown=misskey:misskey --from=native-builder /misskey/packages/misskey-bubble-game/built ./packages/misskey-bubble-game/built
|
|
||||||
COPY --chown=misskey:misskey --from=native-builder /misskey/packages/backend/built ./packages/backend/built
|
|
||||||
COPY --chown=misskey:misskey --from=native-builder /misskey/fluent-emojis /misskey/fluent-emojis
|
|
||||||
COPY --chown=misskey:misskey . ./
|
|
||||||
|
|
||||||
ENV LD_PRELOAD=/usr/local/lib/libjemalloc.so
|
|
||||||
ENV NODE_ENV=production
|
ENV NODE_ENV=production
|
||||||
HEALTHCHECK --interval=5s --retries=20 CMD ["/bin/bash", "/misskey/healthcheck.sh"]
|
CMD ["npm", "run", "migrateandstart"]
|
||||||
ENTRYPOINT ["/usr/bin/tini", "--"]
|
|
||||||
CMD ["pnpm", "run", "migrateandstart"]
|
|
||||||
|
48
README.md
48
README.md
@ -1,18 +1,16 @@
|
|||||||
<div align="center">
|
<div align="center">
|
||||||
<a href="https://misskey-hub.net">
|
<a href="https://misskey-hub.net">
|
||||||
<img src="./assets/title_float.svg" alt="Misskey logo" style="border-radius:50%" width="300"/>
|
<img src="./assets/title_float.svg" alt="Misskey logo" style="border-radius:50%" width="400"/>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
**🌎 **Misskey** is an open source, federated social media platform that's free forever! 🚀**
|
**🌎 **[Misskey](https://misskey-hub.net/)** is an open source, decentralized social media platform that's free forever! 🚀**
|
||||||
|
|
||||||
[Learn more](https://misskey-hub.net/)
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
<a href="https://misskey-hub.net/servers/">
|
<a href="https://misskey-hub.net/instances.html">
|
||||||
<img src="https://custom-icon-badges.herokuapp.com/badge/find_an-instance-acea31?logoColor=acea31&style=for-the-badge&logo=misskey&labelColor=363B40" alt="find an instance"/></a>
|
<img src="https://custom-icon-badges.herokuapp.com/badge/find_an-instance-acea31?logoColor=acea31&style=for-the-badge&logo=misskey&labelColor=363B40" alt="find an instance"/></a>
|
||||||
|
|
||||||
<a href="https://misskey-hub.net/docs/for-admin/install/guides/">
|
<a href="https://misskey-hub.net/docs/install.html">
|
||||||
<img src="https://custom-icon-badges.herokuapp.com/badge/create_an-instance-FBD53C?logoColor=FBD53C&style=for-the-badge&logo=server&labelColor=363B40" alt="create an instance"/></a>
|
<img src="https://custom-icon-badges.herokuapp.com/badge/create_an-instance-FBD53C?logoColor=FBD53C&style=for-the-badge&logo=server&labelColor=363B40" alt="create an instance"/></a>
|
||||||
|
|
||||||
<a href="./CONTRIBUTING.md">
|
<a href="./CONTRIBUTING.md">
|
||||||
@ -24,26 +22,36 @@
|
|||||||
<a href="https://www.patreon.com/syuilo">
|
<a href="https://www.patreon.com/syuilo">
|
||||||
<img src="https://custom-icon-badges.herokuapp.com/badge/become_a-patron-F96854?logoColor=F96854&style=for-the-badge&logo=patreon&labelColor=363B40" alt="become a patron"/></a>
|
<img src="https://custom-icon-badges.herokuapp.com/badge/become_a-patron-F96854?logoColor=F96854&style=for-the-badge&logo=patreon&labelColor=363B40" alt="become a patron"/></a>
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
## Thanks
|
<div>
|
||||||
|
|
||||||
<a href="https://sentry.io/"><img src="https://github.com/misskey-dev/misskey/assets/4439005/98576556-222f-467a-94be-e98dbda1d852" height="30" alt="Sentry" /></a>
|
<a href="https://xn--931a.moe/"><img src="https://github.com/misskey-dev/misskey/blob/develop/assets/ai.png?raw=true" align="right" height="320px"/></a>
|
||||||
|
|
||||||
Thanks to [Sentry](https://sentry.io/) for providing the error tracking platform that helps us catch unexpected errors.
|
## ✨ Features
|
||||||
|
- **ActivityPub support**\
|
||||||
|
Not on Misskey? No problem! Not only can Misskey instances talk to each other, but you can make friends with people on other networks like Mastodon and Pixelfed!
|
||||||
|
- **Reactions**\
|
||||||
|
You can add emoji reactions to any post! No longer are you bound by a like button, show everyone exactly how you feel with the tap of a button.
|
||||||
|
- **Drive**\
|
||||||
|
With Misskey's built in drive, you get cloud storage right in your social media, where you can upload any files, make folders, and find media from posts you've made!
|
||||||
|
- **Rich Web UI**\
|
||||||
|
Misskey has a rich and easy to use Web UI!
|
||||||
|
It is highly customizable, from changing the layout and adding widgets to making custom themes.
|
||||||
|
Furthermore, plugins can be created using AiScript, an original programming language.
|
||||||
|
- And much more...
|
||||||
|
|
||||||
<a href="https://www.chromatic.com/"><img src="https://user-images.githubusercontent.com/321738/84662277-e3db4f80-af1b-11ea-88f5-91d67a5e59f6.png" height="30" alt="Chromatic" /></a>
|
</div>
|
||||||
|
|
||||||
Thanks to [Chromatic](https://www.chromatic.com/) for providing the visual testing platform that helps us review UI changes and catch visual regressions.
|
<div style="clear: both;"></div>
|
||||||
|
|
||||||
<a href="https://about.codecov.io/for/open-source/"><img src="https://about.codecov.io/wp-content/themes/codecov/assets/brand/sentry-cobranding/logos/codecov-by-sentry-logo.svg" height="30" alt="Codecov" /></a>
|
## Documentation
|
||||||
|
|
||||||
Thanks to [Codecov](https://about.codecov.io/for/open-source/) for providing the code coverage platform that helps us improve our test coverage.
|
Misskey Documentation can be found at [Misskey Hub](https://misskey-hub.net/), some of the links and graphics above also lead to specific portions of it.
|
||||||
|
|
||||||
<a href="https://crowdin.com/"><img src="https://user-images.githubusercontent.com/20679825/230709597-1299a011-171a-4294-a91e-355a9b37c672.svg" height="30" alt="Crowdin" /></a>
|
## Sponsors
|
||||||
|
<div align="center">
|
||||||
Thanks to [Crowdin](https://crowdin.com/) for providing the localization platform that helps us translate Misskey into many languages.
|
<a class="rss3" title="RSS3" href="https://rss3.io/" target="_blank"><img src="https://rss3.mypinata.cloud/ipfs/QmUG6H3Z7D5P511shn7sB4CPmpjH5uZWu4m5mWX7U3Gqbu" alt="RSS3" height="60"></a>
|
||||||
|
</div>
|
||||||
<a href="https://hub.docker.com/"><img src="https://user-images.githubusercontent.com/20679825/230148221-f8e73a32-a49b-47c3-9029-9a15c3824f92.png" height="30" alt="Docker" /></a>
|
|
||||||
|
|
||||||
Thanks to [Docker](https://hub.docker.com/) for providing the container platform that helps us run Misskey in production.
|
|
||||||
|
18
ROADMAP.md
18
ROADMAP.md
@ -5,25 +5,21 @@ Also, the later tasks are more indefinite and are subject to change as developme
|
|||||||
## (1) Improve maintainability \<current phase\>
|
## (1) Improve maintainability \<current phase\>
|
||||||
This is the phase we are at now. We need to make a high-maintenance environment that can withstand future development.
|
This is the phase we are at now. We need to make a high-maintenance environment that can withstand future development.
|
||||||
|
|
||||||
- ~~Make the number of type errors zero (backend)~~ → Done ✔️
|
- Make the number of type errors zero (backend)
|
||||||
- Make the number of type errors zero (frontend)
|
- Probably need to switch some libraries to others that make it difficult to reduce type errors
|
||||||
|
- e.g. koa to fastify https://github.com/misskey-dev/misskey/issues/7537
|
||||||
- Improve CI
|
- Improve CI
|
||||||
- ~~Fix tests~~ → Done ✔️
|
- Fix tests
|
||||||
|
- mocha, jest, etc. do not support the combination of `TypeScript + ESM + Path alias`, and the tests currently do not work.
|
||||||
- Fix random test failures - https://github.com/misskey-dev/misskey/issues/7985 and https://github.com/misskey-dev/misskey/issues/7986
|
- Fix random test failures - https://github.com/misskey-dev/misskey/issues/7985 and https://github.com/misskey-dev/misskey/issues/7986
|
||||||
- Add more tests
|
- Add more tests
|
||||||
- ~~May need to implement a mechanism that allows for DI~~ → Done ✔️
|
- May need to implement a mechanism that allows for DI
|
||||||
- https://github.com/misskey-dev/misskey/pull/9085
|
|
||||||
- ~~Measure coverage~~ → Done ✔️
|
|
||||||
- https://github.com/misskey-dev/misskey/pull/9081
|
|
||||||
- Improve documentation
|
- Improve documentation
|
||||||
- Refactoring
|
|
||||||
- Extract the logic of each endpoint definition into a service and just call it
|
|
||||||
|
|
||||||
## (2) Improve functionality
|
## (2) Improve functionality
|
||||||
Once Phase 1 is complete and an environment conducive to the development of a stable system is in place, the implementation of new functions can begin gradually.
|
Once Phase 1 is complete and an environment conducive to the development of a stable system is in place, the implementation of new functions can begin gradually.
|
||||||
|
|
||||||
- Improve features for moderation
|
- OAuth2 support https://github.com/misskey-dev/misskey/issues/8262
|
||||||
- ~~OAuth2 support https://github.com/misskey-dev/misskey/issues/8262~~ → Done ✔️
|
|
||||||
- GraphQL support?
|
- GraphQL support?
|
||||||
|
|
||||||
## (3) Improve scalability
|
## (3) Improve scalability
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
# Reporting Security Issues
|
# Reporting Security Issues
|
||||||
|
|
||||||
If you discover a security issue in Misskey, please report it by **[this form](https://github.com/misskey-dev/misskey/security/advisories/new)**.
|
If you discover a security issue in Misskey, please report it by sending an
|
||||||
|
email to [syuilotan@yahoo.co.jp](mailto:syuilotan@yahoo.co.jp).
|
||||||
|
|
||||||
This will allow us to assess the risk, and make a fix available before we add a
|
This will allow us to assess the risk, and make a fix available before we add a
|
||||||
bug report to the GitHub repository.
|
bug report to the GitHub repository.
|
||||||
|
Binary file not shown.
Before Width: | Height: | Size: 41 KiB |
@ -1,4 +1,3 @@
|
|||||||
apiVersion: v2
|
apiVersion: v2
|
||||||
name: misskey
|
name: misskey
|
||||||
version: 0.0.0
|
version: 0.0.0
|
||||||
description: This chart is created for the purpose of previewing Pull Requests. Do not use this for production use.
|
|
||||||
|
@ -72,75 +72,25 @@ db:
|
|||||||
#extra:
|
#extra:
|
||||||
# ssl: true
|
# ssl: true
|
||||||
|
|
||||||
dbReplications: false
|
|
||||||
|
|
||||||
# You can configure any number of replicas here
|
|
||||||
#dbSlaves:
|
|
||||||
# -
|
|
||||||
# host:
|
|
||||||
# port:
|
|
||||||
# db:
|
|
||||||
# user:
|
|
||||||
# pass:
|
|
||||||
# -
|
|
||||||
# host:
|
|
||||||
# port:
|
|
||||||
# db:
|
|
||||||
# user:
|
|
||||||
# pass:
|
|
||||||
|
|
||||||
# ┌─────────────────────┐
|
# ┌─────────────────────┐
|
||||||
#───┘ Redis configuration └─────────────────────────────────────
|
#───┘ Redis configuration └─────────────────────────────────────
|
||||||
|
|
||||||
redis:
|
redis:
|
||||||
host: localhost
|
host: localhost
|
||||||
port: 6379
|
port: 6379
|
||||||
#family: 0 # 0=Both, 4=IPv4, 6=IPv6
|
|
||||||
#pass: example-pass
|
#pass: example-pass
|
||||||
#prefix: example-prefix
|
#prefix: example-prefix
|
||||||
#db: 1
|
#db: 1
|
||||||
|
|
||||||
#redisForPubsub:
|
# ┌─────────────────────────────┐
|
||||||
|
#───┘ Elasticsearch configuration └─────────────────────────────
|
||||||
|
|
||||||
|
#elasticsearch:
|
||||||
# host: localhost
|
# host: localhost
|
||||||
# port: 6379
|
# port: 9200
|
||||||
# #family: 0 # 0=Both, 4=IPv4, 6=IPv6
|
# ssl: false
|
||||||
# #pass: example-pass
|
# user:
|
||||||
# #prefix: example-prefix
|
# pass:
|
||||||
# #db: 1
|
|
||||||
|
|
||||||
#redisForJobQueue:
|
|
||||||
# host: localhost
|
|
||||||
# port: 6379
|
|
||||||
# #family: 0 # 0=Both, 4=IPv4, 6=IPv6
|
|
||||||
# #pass: example-pass
|
|
||||||
# #prefix: example-prefix
|
|
||||||
# #db: 1
|
|
||||||
|
|
||||||
#redisForTimelines:
|
|
||||||
# host: redis
|
|
||||||
# port: 6379
|
|
||||||
# #family: 0 # 0=Both, 4=IPv4, 6=IPv6
|
|
||||||
# #pass: example-pass
|
|
||||||
# #prefix: example-prefix
|
|
||||||
# #db: 1
|
|
||||||
|
|
||||||
#redisForReactions:
|
|
||||||
# host: redis
|
|
||||||
# port: 6379
|
|
||||||
# #family: 0 # 0=Both, 4=IPv4, 6=IPv6
|
|
||||||
# #pass: example-pass
|
|
||||||
# #prefix: example-prefix
|
|
||||||
# #db: 1
|
|
||||||
|
|
||||||
# ┌───────────────────────────┐
|
|
||||||
#───┘ MeiliSearch configuration └─────────────────────────────
|
|
||||||
|
|
||||||
#meilisearch:
|
|
||||||
# host: localhost
|
|
||||||
# port: 7700
|
|
||||||
# apiKey: ''
|
|
||||||
# ssl: true
|
|
||||||
# index: ''
|
|
||||||
|
|
||||||
# ┌───────────────┐
|
# ┌───────────────┐
|
||||||
#───┘ ID generation └───────────────────────────────────────────
|
#───┘ ID generation └───────────────────────────────────────────
|
||||||
@ -151,7 +101,6 @@ redis:
|
|||||||
|
|
||||||
# Available methods:
|
# Available methods:
|
||||||
# aid ... Short, Millisecond accuracy
|
# aid ... Short, Millisecond accuracy
|
||||||
# aidx ... Millisecond accuracy
|
|
||||||
# meid ... Similar to ObjectID, Millisecond accuracy
|
# meid ... Similar to ObjectID, Millisecond accuracy
|
||||||
# ulid ... Millisecond accuracy
|
# ulid ... Millisecond accuracy
|
||||||
# objectid ... This is left for backward compatibility
|
# objectid ... This is left for backward compatibility
|
||||||
@ -159,23 +108,7 @@ redis:
|
|||||||
# ONCE YOU HAVE STARTED THE INSTANCE, DO NOT CHANGE THE
|
# ONCE YOU HAVE STARTED THE INSTANCE, DO NOT CHANGE THE
|
||||||
# ID SETTINGS AFTER THAT!
|
# ID SETTINGS AFTER THAT!
|
||||||
|
|
||||||
id: "aidx"
|
id: "aid"
|
||||||
|
|
||||||
# ┌────────────────┐
|
|
||||||
#───┘ Error tracking └──────────────────────────────────────────
|
|
||||||
|
|
||||||
# Sentry is available for error tracking.
|
|
||||||
# See the Sentry documentation for more details on options.
|
|
||||||
|
|
||||||
#sentryForBackend:
|
|
||||||
# enableNodeProfiling: true
|
|
||||||
# options:
|
|
||||||
# dsn: 'https://examplePublicKey@o0.ingest.sentry.io/0'
|
|
||||||
|
|
||||||
#sentryForFrontend:
|
|
||||||
# options:
|
|
||||||
# dsn: 'https://examplePublicKey@o0.ingest.sentry.io/0'
|
|
||||||
|
|
||||||
# ┌─────────────────────┐
|
# ┌─────────────────────┐
|
||||||
#───┘ Other configuration └─────────────────────────────────────
|
#───┘ Other configuration └─────────────────────────────────────
|
||||||
|
|
||||||
@ -191,7 +124,7 @@ id: "aidx"
|
|||||||
|
|
||||||
# Job rate limiter
|
# Job rate limiter
|
||||||
# deliverJobPerSec: 128
|
# deliverJobPerSec: 128
|
||||||
# inboxJobPerSec: 32
|
# inboxJobPerSec: 16
|
||||||
|
|
||||||
# Job attempts
|
# Job attempts
|
||||||
# deliverJobMaxAttempts: 12
|
# deliverJobMaxAttempts: 12
|
||||||
@ -200,6 +133,11 @@ id: "aidx"
|
|||||||
# IP address family used for outgoing request (ipv4, ipv6 or dual)
|
# IP address family used for outgoing request (ipv4, ipv6 or dual)
|
||||||
#outgoingAddressFamily: ipv4
|
#outgoingAddressFamily: ipv4
|
||||||
|
|
||||||
|
# Syslog option
|
||||||
|
#syslog:
|
||||||
|
# host: localhost
|
||||||
|
# port: 514
|
||||||
|
|
||||||
# Proxy for HTTP/HTTPS
|
# Proxy for HTTP/HTTPS
|
||||||
#proxy: http://127.0.0.1:3128
|
#proxy: http://127.0.0.1:3128
|
||||||
|
|
||||||
@ -216,8 +154,8 @@ id: "aidx"
|
|||||||
# Media Proxy
|
# Media Proxy
|
||||||
#mediaProxy: https://example.com/proxy
|
#mediaProxy: https://example.com/proxy
|
||||||
|
|
||||||
# Sign to ActivityPub GET request (default: true)
|
# Sign to ActivityPub GET request (default: false)
|
||||||
signToActivityPubGet: true
|
#signToActivityPubGet: true
|
||||||
|
|
||||||
#allowedPrivateNetworks: [
|
#allowedPrivateNetworks: [
|
||||||
# '127.0.0.1/32'
|
# '127.0.0.1/32'
|
||||||
|
@ -27,7 +27,7 @@ spec:
|
|||||||
ports:
|
ports:
|
||||||
- containerPort: 3000
|
- containerPort: 3000
|
||||||
- name: postgres
|
- name: postgres
|
||||||
image: postgres:15-alpine
|
image: postgres:14-alpine
|
||||||
env:
|
env:
|
||||||
- name: POSTGRES_USER
|
- name: POSTGRES_USER
|
||||||
value: "example-misskey-user"
|
value: "example-misskey-user"
|
||||||
@ -38,7 +38,7 @@ spec:
|
|||||||
ports:
|
ports:
|
||||||
- containerPort: 5432
|
- containerPort: 5432
|
||||||
- name: redis
|
- name: redis
|
||||||
image: redis:7-alpine
|
image: redis:alpine
|
||||||
ports:
|
ports:
|
||||||
- containerPort: 6379
|
- containerPort: 6379
|
||||||
volumes:
|
volumes:
|
||||||
|
@ -1,4 +0,0 @@
|
|||||||
coverage:
|
|
||||||
status:
|
|
||||||
project: false
|
|
||||||
patch: false
|
|
@ -1,40 +0,0 @@
|
|||||||
# このconfigは、 dockerでMisskey本体を起動せず、 redisとpostgresql などだけを起動します
|
|
||||||
|
|
||||||
services:
|
|
||||||
redis:
|
|
||||||
restart: always
|
|
||||||
image: redis:7-alpine
|
|
||||||
ports:
|
|
||||||
- "6379:6379"
|
|
||||||
volumes:
|
|
||||||
- ./redis:/data
|
|
||||||
healthcheck:
|
|
||||||
test: "redis-cli ping"
|
|
||||||
interval: 5s
|
|
||||||
retries: 20
|
|
||||||
|
|
||||||
db:
|
|
||||||
restart: always
|
|
||||||
image: postgres:15-alpine
|
|
||||||
ports:
|
|
||||||
- "5432:5432"
|
|
||||||
env_file:
|
|
||||||
- .config/docker.env
|
|
||||||
volumes:
|
|
||||||
- ./db:/var/lib/postgresql/data
|
|
||||||
healthcheck:
|
|
||||||
test: "pg_isready -U $$POSTGRES_USER -d $$POSTGRES_DB"
|
|
||||||
interval: 5s
|
|
||||||
retries: 20
|
|
||||||
|
|
||||||
# meilisearch:
|
|
||||||
# restart: always
|
|
||||||
# image: getmeili/meilisearch:v1.3.4
|
|
||||||
# environment:
|
|
||||||
# - MEILI_NO_ANALYTICS=true
|
|
||||||
# - MEILI_ENV=production
|
|
||||||
# env_file:
|
|
||||||
# - .config/meilisearch.env
|
|
||||||
# volumes:
|
|
||||||
# - ./meili_data:/meili_data
|
|
||||||
|
|
@ -1,98 +0,0 @@
|
|||||||
services:
|
|
||||||
web:
|
|
||||||
build: .
|
|
||||||
restart: always
|
|
||||||
links:
|
|
||||||
- db
|
|
||||||
- redis
|
|
||||||
# - mcaptcha
|
|
||||||
# - meilisearch
|
|
||||||
depends_on:
|
|
||||||
db:
|
|
||||||
condition: service_healthy
|
|
||||||
redis:
|
|
||||||
condition: service_healthy
|
|
||||||
ports:
|
|
||||||
- "3000:3000"
|
|
||||||
networks:
|
|
||||||
- internal_network
|
|
||||||
- external_network
|
|
||||||
# env_file:
|
|
||||||
# - .config/docker.env
|
|
||||||
volumes:
|
|
||||||
- ./files:/misskey/files
|
|
||||||
- ./.config:/misskey/.config:ro
|
|
||||||
|
|
||||||
redis:
|
|
||||||
restart: always
|
|
||||||
image: redis:7-alpine
|
|
||||||
networks:
|
|
||||||
- internal_network
|
|
||||||
volumes:
|
|
||||||
- ./redis:/data
|
|
||||||
healthcheck:
|
|
||||||
test: "redis-cli ping"
|
|
||||||
interval: 5s
|
|
||||||
retries: 20
|
|
||||||
|
|
||||||
db:
|
|
||||||
restart: always
|
|
||||||
image: postgres:15-alpine
|
|
||||||
networks:
|
|
||||||
- internal_network
|
|
||||||
env_file:
|
|
||||||
- .config/docker.env
|
|
||||||
volumes:
|
|
||||||
- ./db:/var/lib/postgresql/data
|
|
||||||
healthcheck:
|
|
||||||
test: "pg_isready -U $$POSTGRES_USER -d $$POSTGRES_DB"
|
|
||||||
interval: 5s
|
|
||||||
retries: 20
|
|
||||||
|
|
||||||
# mcaptcha:
|
|
||||||
# restart: always
|
|
||||||
# image: mcaptcha/mcaptcha:latest
|
|
||||||
# networks:
|
|
||||||
# internal_network:
|
|
||||||
# external_network:
|
|
||||||
# aliases:
|
|
||||||
# - localhost
|
|
||||||
# ports:
|
|
||||||
# - 7493:7493
|
|
||||||
# env_file:
|
|
||||||
# - .config/docker.env
|
|
||||||
# environment:
|
|
||||||
# PORT: 7493
|
|
||||||
# MCAPTCHA_redis_URL: "redis://mcaptcha_redis/"
|
|
||||||
# depends_on:
|
|
||||||
# db:
|
|
||||||
# condition: service_healthy
|
|
||||||
# mcaptcha_redis:
|
|
||||||
# condition: service_healthy
|
|
||||||
#
|
|
||||||
# mcaptcha_redis:
|
|
||||||
# image: mcaptcha/cache:latest
|
|
||||||
# networks:
|
|
||||||
# - internal_network
|
|
||||||
# healthcheck:
|
|
||||||
# test: "redis-cli ping"
|
|
||||||
# interval: 5s
|
|
||||||
# retries: 20
|
|
||||||
|
|
||||||
# meilisearch:
|
|
||||||
# restart: always
|
|
||||||
# image: getmeili/meilisearch:v1.3.4
|
|
||||||
# environment:
|
|
||||||
# - MEILI_NO_ANALYTICS=true
|
|
||||||
# - MEILI_ENV=production
|
|
||||||
# env_file:
|
|
||||||
# - .config/meilisearch.env
|
|
||||||
# networks:
|
|
||||||
# - internal_network
|
|
||||||
# volumes:
|
|
||||||
# - ./meili_data:/meili_data
|
|
||||||
|
|
||||||
networks:
|
|
||||||
internal_network:
|
|
||||||
internal: true
|
|
||||||
external_network:
|
|
149
cypress/e2e/basic.cy.js
Normal file
149
cypress/e2e/basic.cy.js
Normal file
@ -0,0 +1,149 @@
|
|||||||
|
describe('Before setup instance', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
cy.resetState();
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
// テスト終了直前にページ遷移するようなテストケース(例えばアカウント作成)だと、たぶんCypressのバグでブラウザの内容が次のテストケースに引き継がれてしまう(例えばアカウントが作成し終わった段階からテストが始まる)。
|
||||||
|
// waitを入れることでそれを防止できる
|
||||||
|
cy.wait(1000);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('successfully loads', () => {
|
||||||
|
cy.visit('/');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('setup instance', () => {
|
||||||
|
cy.visit('/');
|
||||||
|
|
||||||
|
cy.intercept('POST', '/api/admin/accounts/create').as('signup');
|
||||||
|
|
||||||
|
cy.get('[data-cy-admin-username] input').type('admin');
|
||||||
|
cy.get('[data-cy-admin-password] input').type('admin1234');
|
||||||
|
cy.get('[data-cy-admin-ok]').click();
|
||||||
|
|
||||||
|
// なぜか動かない
|
||||||
|
//cy.wait('@signup').should('have.property', 'response.statusCode');
|
||||||
|
cy.wait('@signup');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('After setup instance', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
cy.resetState();
|
||||||
|
|
||||||
|
// インスタンス初期セットアップ
|
||||||
|
cy.registerUser('admin', 'pass', true);
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
// テスト終了直前にページ遷移するようなテストケース(例えばアカウント作成)だと、たぶんCypressのバグでブラウザの内容が次のテストケースに引き継がれてしまう(例えばアカウントが作成し終わった段階からテストが始まる)。
|
||||||
|
// waitを入れることでそれを防止できる
|
||||||
|
cy.wait(1000);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('successfully loads', () => {
|
||||||
|
cy.visit('/');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('signup', () => {
|
||||||
|
cy.visit('/');
|
||||||
|
|
||||||
|
cy.intercept('POST', '/api/signup').as('signup');
|
||||||
|
|
||||||
|
cy.get('[data-cy-signup]').click();
|
||||||
|
cy.get('[data-cy-signup-username] input').type('alice');
|
||||||
|
cy.get('[data-cy-signup-password] input').type('alice1234');
|
||||||
|
cy.get('[data-cy-signup-password-retype] input').type('alice1234');
|
||||||
|
cy.get('[data-cy-signup-submit]').click();
|
||||||
|
|
||||||
|
cy.wait('@signup');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('After user signup', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
cy.resetState();
|
||||||
|
|
||||||
|
// インスタンス初期セットアップ
|
||||||
|
cy.registerUser('admin', 'pass', true);
|
||||||
|
|
||||||
|
// ユーザー作成
|
||||||
|
cy.registerUser('alice', 'alice1234');
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
// テスト終了直前にページ遷移するようなテストケース(例えばアカウント作成)だと、たぶんCypressのバグでブラウザの内容が次のテストケースに引き継がれてしまう(例えばアカウントが作成し終わった段階からテストが始まる)。
|
||||||
|
// waitを入れることでそれを防止できる
|
||||||
|
cy.wait(1000);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('successfully loads', () => {
|
||||||
|
cy.visit('/');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('signin', () => {
|
||||||
|
cy.visit('/');
|
||||||
|
|
||||||
|
cy.intercept('POST', '/api/signin').as('signin');
|
||||||
|
|
||||||
|
cy.get('[data-cy-signin]').click();
|
||||||
|
cy.get('[data-cy-signin-username] input').type('alice');
|
||||||
|
// Enterキーでサインインできるかの確認も兼ねる
|
||||||
|
cy.get('[data-cy-signin-password] input').type('alice1234{enter}');
|
||||||
|
|
||||||
|
cy.wait('@signin');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('suspend', function() {
|
||||||
|
cy.request('POST', '/api/admin/suspend-user', {
|
||||||
|
i: this.admin.token,
|
||||||
|
userId: this.alice.id,
|
||||||
|
});
|
||||||
|
|
||||||
|
cy.visit('/');
|
||||||
|
|
||||||
|
cy.get('[data-cy-signin]').click();
|
||||||
|
cy.get('[data-cy-signin-username] input').type('alice');
|
||||||
|
cy.get('[data-cy-signin-password] input').type('alice1234{enter}');
|
||||||
|
|
||||||
|
// TODO: cypressにブラウザの言語指定できる機能が実装され次第英語のみテストするようにする
|
||||||
|
cy.contains(/アカウントが凍結されています|This account has been suspended due to/gi);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('After user singed in', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
cy.resetState();
|
||||||
|
|
||||||
|
// インスタンス初期セットアップ
|
||||||
|
cy.registerUser('admin', 'pass', true);
|
||||||
|
|
||||||
|
// ユーザー作成
|
||||||
|
cy.registerUser('alice', 'alice1234');
|
||||||
|
|
||||||
|
cy.login('alice', 'alice1234');
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
// テスト終了直前にページ遷移するようなテストケース(例えばアカウント作成)だと、たぶんCypressのバグでブラウザの内容が次のテストケースに引き継がれてしまう(例えばアカウントが作成し終わった段階からテストが始まる)。
|
||||||
|
// waitを入れることでそれを防止できる
|
||||||
|
cy.wait(1000);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('successfully loads', () => {
|
||||||
|
cy.get('[data-cy-open-post-form]').should('be.visible');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('note', () => {
|
||||||
|
cy.get('[data-cy-open-post-form]').click();
|
||||||
|
cy.get('[data-cy-post-form-text]').type('Hello, Misskey!');
|
||||||
|
cy.get('[data-cy-open-post-form-submit]').click();
|
||||||
|
|
||||||
|
cy.contains('Hello, Misskey!');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// TODO: 投稿フォームの公開範囲指定のテスト
|
||||||
|
// TODO: 投稿フォームのファイル添付のテスト
|
||||||
|
// TODO: 投稿フォームのハッシュタグ保持フィールドのテスト
|
@ -1,255 +0,0 @@
|
|||||||
/*
|
|
||||||
* SPDX-FileCopyrightText: syuilo and misskey-project
|
|
||||||
* SPDX-License-Identifier: AGPL-3.0-only
|
|
||||||
*/
|
|
||||||
|
|
||||||
describe('Before setup instance', () => {
|
|
||||||
beforeEach(() => {
|
|
||||||
cy.resetState();
|
|
||||||
});
|
|
||||||
|
|
||||||
afterEach(() => {
|
|
||||||
// テスト終了直前にページ遷移するようなテストケース(例えばアカウント作成)だと、たぶんCypressのバグでブラウザの内容が次のテストケースに引き継がれてしまう(例えばアカウントが作成し終わった段階からテストが始まる)。
|
|
||||||
// waitを入れることでそれを防止できる
|
|
||||||
cy.wait(1000);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('successfully loads', () => {
|
|
||||||
cy.visitHome();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('setup instance', () => {
|
|
||||||
cy.visitHome();
|
|
||||||
|
|
||||||
cy.intercept('POST', '/api/admin/accounts/create').as('signup');
|
|
||||||
|
|
||||||
cy.get('[data-cy-admin-initial-password] input').type('example_password_please_change_this_or_you_will_get_hacked');
|
|
||||||
cy.get('[data-cy-admin-username] input').type('admin');
|
|
||||||
cy.get('[data-cy-admin-password] input').type('admin1234');
|
|
||||||
cy.get('[data-cy-admin-ok]').click();
|
|
||||||
|
|
||||||
// なぜか動かない
|
|
||||||
//cy.wait('@signup').should('have.property', 'response.statusCode');
|
|
||||||
cy.wait('@signup');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('After setup instance', () => {
|
|
||||||
beforeEach(() => {
|
|
||||||
cy.resetState();
|
|
||||||
|
|
||||||
// インスタンス初期セットアップ
|
|
||||||
cy.registerUser('admin', 'pass', true);
|
|
||||||
});
|
|
||||||
|
|
||||||
afterEach(() => {
|
|
||||||
// テスト終了直前にページ遷移するようなテストケース(例えばアカウント作成)だと、たぶんCypressのバグでブラウザの内容が次のテストケースに引き継がれてしまう(例えばアカウントが作成し終わった段階からテストが始まる)。
|
|
||||||
// waitを入れることでそれを防止できる
|
|
||||||
cy.wait(1000);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('successfully loads', () => {
|
|
||||||
cy.visitHome();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('signup', () => {
|
|
||||||
cy.visitHome();
|
|
||||||
|
|
||||||
cy.intercept('POST', '/api/signup').as('signup');
|
|
||||||
|
|
||||||
cy.get('[data-cy-signup]').click();
|
|
||||||
cy.get('[data-cy-signup-rules-continue]').should('be.disabled');
|
|
||||||
cy.get('[data-cy-signup-rules-notes-agree] [data-cy-switch-toggle]').click();
|
|
||||||
cy.get('[data-cy-modal-dialog-ok]').click();
|
|
||||||
cy.get('[data-cy-signup-rules-continue]').should('not.be.disabled');
|
|
||||||
cy.get('[data-cy-signup-rules-continue]').click();
|
|
||||||
|
|
||||||
cy.get('[data-cy-signup-submit]').should('be.disabled');
|
|
||||||
cy.get('[data-cy-signup-username] input').type('alice');
|
|
||||||
cy.get('[data-cy-signup-submit]').should('be.disabled');
|
|
||||||
cy.get('[data-cy-signup-password] input').type('alice1234');
|
|
||||||
cy.get('[data-cy-signup-submit]').should('be.disabled');
|
|
||||||
cy.get('[data-cy-signup-password-retype] input').type('alice1234');
|
|
||||||
cy.get('[data-cy-signup-submit]').should('not.be.disabled');
|
|
||||||
cy.get('[data-cy-signup-submit]').click();
|
|
||||||
|
|
||||||
cy.wait('@signup');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('signup with duplicated username', () => {
|
|
||||||
cy.registerUser('alice', 'alice1234');
|
|
||||||
|
|
||||||
cy.visitHome();
|
|
||||||
|
|
||||||
// ユーザー名が重複している場合の挙動確認
|
|
||||||
cy.get('[data-cy-signup]').click();
|
|
||||||
cy.get('[data-cy-signup-rules-continue]').should('be.disabled');
|
|
||||||
cy.get('[data-cy-signup-rules-notes-agree] [data-cy-switch-toggle]').click();
|
|
||||||
cy.get('[data-cy-modal-dialog-ok]').click();
|
|
||||||
cy.get('[data-cy-signup-rules-continue]').should('not.be.disabled');
|
|
||||||
cy.get('[data-cy-signup-rules-continue]').click();
|
|
||||||
|
|
||||||
cy.get('[data-cy-signup-username] input').type('alice');
|
|
||||||
cy.get('[data-cy-signup-password] input').type('alice1234');
|
|
||||||
cy.get('[data-cy-signup-password-retype] input').type('alice1234');
|
|
||||||
cy.get('[data-cy-signup-submit]').should('be.disabled');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('After user signup', () => {
|
|
||||||
beforeEach(() => {
|
|
||||||
cy.resetState();
|
|
||||||
|
|
||||||
// インスタンス初期セットアップ
|
|
||||||
cy.registerUser('admin', 'pass', true);
|
|
||||||
|
|
||||||
// ユーザー作成
|
|
||||||
cy.registerUser('alice', 'alice1234');
|
|
||||||
});
|
|
||||||
|
|
||||||
afterEach(() => {
|
|
||||||
// テスト終了直前にページ遷移するようなテストケース(例えばアカウント作成)だと、たぶんCypressのバグでブラウザの内容が次のテストケースに引き継がれてしまう(例えばアカウントが作成し終わった段階からテストが始まる)。
|
|
||||||
// waitを入れることでそれを防止できる
|
|
||||||
cy.wait(1000);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('successfully loads', () => {
|
|
||||||
cy.visitHome();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('signin', () => {
|
|
||||||
cy.visitHome();
|
|
||||||
|
|
||||||
cy.intercept('POST', '/api/signin-flow').as('signin');
|
|
||||||
|
|
||||||
cy.get('[data-cy-signin]').click();
|
|
||||||
|
|
||||||
cy.get('[data-cy-signin-page-input]').should('be.visible', { timeout: 1000 });
|
|
||||||
// Enterキーで続行できるかの確認も兼ねる
|
|
||||||
cy.get('[data-cy-signin-username] input').type('alice{enter}');
|
|
||||||
|
|
||||||
cy.get('[data-cy-signin-page-password]').should('be.visible', { timeout: 10000 });
|
|
||||||
// Enterキーで続行できるかの確認も兼ねる
|
|
||||||
cy.get('[data-cy-signin-password] input').type('alice1234{enter}');
|
|
||||||
|
|
||||||
cy.wait('@signin');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('suspend', function() {
|
|
||||||
cy.request('POST', '/api/admin/suspend-user', {
|
|
||||||
i: this.admin.token,
|
|
||||||
userId: this.alice.id,
|
|
||||||
});
|
|
||||||
|
|
||||||
cy.visitHome();
|
|
||||||
|
|
||||||
cy.get('[data-cy-signin]').click();
|
|
||||||
|
|
||||||
cy.get('[data-cy-signin-page-input]').should('be.visible', { timeout: 1000 });
|
|
||||||
cy.get('[data-cy-signin-username] input').type('alice{enter}');
|
|
||||||
|
|
||||||
// TODO: cypressにブラウザの言語指定できる機能が実装され次第英語のみテストするようにする
|
|
||||||
cy.contains(/アカウントが凍結されています|This account has been suspended due to/gi);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('After user signed in', () => {
|
|
||||||
beforeEach(() => {
|
|
||||||
cy.resetState();
|
|
||||||
|
|
||||||
// インスタンス初期セットアップ
|
|
||||||
cy.registerUser('admin', 'pass', true);
|
|
||||||
|
|
||||||
// ユーザー作成
|
|
||||||
cy.registerUser('alice', 'alice1234');
|
|
||||||
|
|
||||||
cy.login('alice', 'alice1234');
|
|
||||||
});
|
|
||||||
|
|
||||||
afterEach(() => {
|
|
||||||
// テスト終了直前にページ遷移するようなテストケース(例えばアカウント作成)だと、たぶんCypressのバグでブラウザの内容が次のテストケースに引き継がれてしまう(例えばアカウントが作成し終わった段階からテストが始まる)。
|
|
||||||
// waitを入れることでそれを防止できる
|
|
||||||
cy.wait(1000);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('successfully loads', () => {
|
|
||||||
// 表示に時間がかかるのでデフォルト秒数だとタイムアウトする
|
|
||||||
cy.get('[data-cy-user-setup-continue]', { timeout: 30000 }).should('be.visible');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('account setup wizard', () => {
|
|
||||||
// 表示に時間がかかるのでデフォルト秒数だとタイムアウトする
|
|
||||||
cy.get('[data-cy-user-setup-continue]', { timeout: 30000 }).click();
|
|
||||||
|
|
||||||
cy.get('[data-cy-user-setup-user-name] input').type('ありす');
|
|
||||||
cy.get('[data-cy-user-setup-user-description] textarea').type('ほげ');
|
|
||||||
// TODO: アイコン設定テスト
|
|
||||||
|
|
||||||
cy.get('[data-cy-user-setup-continue]').click();
|
|
||||||
|
|
||||||
// プライバシー設定
|
|
||||||
|
|
||||||
cy.get('[data-cy-user-setup-continue]').click();
|
|
||||||
|
|
||||||
// フォローはスキップ
|
|
||||||
|
|
||||||
cy.get('[data-cy-user-setup-continue]').click();
|
|
||||||
|
|
||||||
// プッシュ通知設定はスキップ
|
|
||||||
|
|
||||||
cy.get('[data-cy-user-setup-continue]').click();
|
|
||||||
|
|
||||||
cy.get('[data-cy-user-setup-continue]').click();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('After user setup', () => {
|
|
||||||
beforeEach(() => {
|
|
||||||
cy.resetState();
|
|
||||||
|
|
||||||
// インスタンス初期セットアップ
|
|
||||||
cy.registerUser('admin', 'pass', true);
|
|
||||||
|
|
||||||
// ユーザー作成
|
|
||||||
cy.registerUser('alice', 'alice1234');
|
|
||||||
|
|
||||||
cy.login('alice', 'alice1234');
|
|
||||||
|
|
||||||
// アカウント初期設定ウィザード
|
|
||||||
// 表示に時間がかかるのでデフォルト秒数だとタイムアウトする
|
|
||||||
cy.get('[data-cy-user-setup] [data-cy-modal-window-close]', { timeout: 30000 }).click();
|
|
||||||
cy.get('[data-cy-modal-dialog-ok]').click();
|
|
||||||
});
|
|
||||||
|
|
||||||
afterEach(() => {
|
|
||||||
// テスト終了直前にページ遷移するようなテストケース(例えばアカウント作成)だと、たぶんCypressのバグでブラウザの内容が次のテストケースに引き継がれてしまう(例えばアカウントが作成し終わった段階からテストが始まる)。
|
|
||||||
// waitを入れることでそれを防止できる
|
|
||||||
cy.wait(1000);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('note', () => {
|
|
||||||
cy.get('[data-cy-open-post-form]').should('be.visible');
|
|
||||||
cy.get('[data-cy-open-post-form]').click();
|
|
||||||
cy.get('[data-cy-post-form-text]').type('Hello, Misskey!');
|
|
||||||
cy.get('[data-cy-open-post-form-submit]').click();
|
|
||||||
|
|
||||||
cy.contains('Hello, Misskey!');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('open note form with hotkey', () => {
|
|
||||||
// Wait until the page loads
|
|
||||||
cy.get('[data-cy-open-post-form]').should('be.visible');
|
|
||||||
// Use trigger() to give different `code` to test if hotkeys also work on non-QWERTY keyboards.
|
|
||||||
cy.document().trigger("keydown", { eventConstructor: 'KeyboardEvent', key: "n", code: "KeyL" });
|
|
||||||
// See if the form is opened
|
|
||||||
cy.get('[data-cy-post-form-text]').should('be.visible');
|
|
||||||
// Close it
|
|
||||||
cy.focused().trigger("keydown", { eventConstructor: 'KeyboardEvent', key: "Escape", code: "Escape" });
|
|
||||||
// See if the form is closed
|
|
||||||
cy.get('[data-cy-post-form-text]').should('not.be.visible');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
// TODO: 投稿フォームの公開範囲指定のテスト
|
|
||||||
// TODO: 投稿フォームのファイル添付のテスト
|
|
||||||
// TODO: 投稿フォームのハッシュタグ保持フィールドのテスト
|
|
@ -1,35 +0,0 @@
|
|||||||
/*
|
|
||||||
* SPDX-FileCopyrightText: syuilo and misskey-project
|
|
||||||
* SPDX-License-Identifier: AGPL-3.0-only
|
|
||||||
*/
|
|
||||||
|
|
||||||
describe('Router transition', () => {
|
|
||||||
describe('Redirect', () => {
|
|
||||||
// サーバの初期化。ルートのテストに関しては各describeごとに1度だけ実行で十分だと思う(使いまわした方が早い)
|
|
||||||
before(() => {
|
|
||||||
cy.resetState();
|
|
||||||
|
|
||||||
// インスタンス初期セットアップ
|
|
||||||
cy.registerUser('admin', 'pass', true);
|
|
||||||
|
|
||||||
// ユーザー作成
|
|
||||||
cy.registerUser('alice', 'alice1234');
|
|
||||||
|
|
||||||
cy.login('alice', 'alice1234');
|
|
||||||
|
|
||||||
// アカウント初期設定ウィザード
|
|
||||||
// 表示に時間がかかるのでデフォルト秒数だとタイムアウトする
|
|
||||||
cy.get('[data-cy-user-setup] [data-cy-modal-window-close]', { timeout: 30000 }).click();
|
|
||||||
cy.wait(500);
|
|
||||||
cy.get('[data-cy-modal-dialog-ok]').click();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('redirect to user profile', () => {
|
|
||||||
// テストのためだけに用意されたリダイレクト用ルートに飛ぶ
|
|
||||||
cy.visit('/redirect-test');
|
|
||||||
|
|
||||||
// プロフィールページのURLであることを確認する
|
|
||||||
cy.url().should('include', '/@alice')
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
65
cypress/e2e/widgets.cy.js
Normal file
65
cypress/e2e/widgets.cy.js
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
describe('After user signed in', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
cy.resetState();
|
||||||
|
cy.viewport('macbook-16');
|
||||||
|
|
||||||
|
// インスタンス初期セットアップ
|
||||||
|
cy.registerUser('admin', 'pass', true);
|
||||||
|
|
||||||
|
// ユーザー作成
|
||||||
|
cy.registerUser('alice', 'alice1234');
|
||||||
|
|
||||||
|
cy.login('alice', 'alice1234');
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
// テスト終了直前にページ遷移するようなテストケース(例えばアカウント作成)だと、たぶんCypressのバグでブラウザの内容が次のテストケースに引き継がれてしまう(例えばアカウントが作成し終わった段階からテストが始まる)。
|
||||||
|
// waitを入れることでそれを防止できる
|
||||||
|
cy.wait(1000);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('widget edit toggle is visible', () => {
|
||||||
|
cy.get('.mk-widget-edit').should('be.visible');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('widget select should be visible in edit mode', () => {
|
||||||
|
cy.get('.mk-widget-edit').click();
|
||||||
|
cy.get('.mk-widget-select').should('be.visible');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('first widget should be removed', () => {
|
||||||
|
cy.get('.mk-widget-edit').click();
|
||||||
|
cy.get('.customize-container:first-child .remove._button').click();
|
||||||
|
cy.get('.customize-container').should('have.length', 2);
|
||||||
|
});
|
||||||
|
|
||||||
|
function buildWidgetTest(widgetName) {
|
||||||
|
it(`${widgetName} widget should get added`, () => {
|
||||||
|
cy.get('.mk-widget-edit').click();
|
||||||
|
cy.get('.mk-widget-select select').select(widgetName, { force: true });
|
||||||
|
cy.get('.bg._modalBg.transparent').click({ multiple: true, force: true });
|
||||||
|
cy.get('.mk-widget-add').click({ force: true });
|
||||||
|
cy.get(`.mkw-${widgetName}`).should('exist');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
buildWidgetTest('memo');
|
||||||
|
buildWidgetTest('notifications');
|
||||||
|
buildWidgetTest('timeline');
|
||||||
|
buildWidgetTest('calendar');
|
||||||
|
buildWidgetTest('rss');
|
||||||
|
buildWidgetTest('trends');
|
||||||
|
buildWidgetTest('clock');
|
||||||
|
buildWidgetTest('activity');
|
||||||
|
buildWidgetTest('photos');
|
||||||
|
buildWidgetTest('digitalClock');
|
||||||
|
buildWidgetTest('federation');
|
||||||
|
buildWidgetTest('postForm');
|
||||||
|
buildWidgetTest('slideshow');
|
||||||
|
buildWidgetTest('serverMetric');
|
||||||
|
buildWidgetTest('onlineUsers');
|
||||||
|
buildWidgetTest('jobQueue');
|
||||||
|
buildWidgetTest('button');
|
||||||
|
buildWidgetTest('aiscript');
|
||||||
|
buildWidgetTest('aichan');
|
||||||
|
});
|
@ -1,76 +0,0 @@
|
|||||||
/*
|
|
||||||
* SPDX-FileCopyrightText: syuilo and misskey-project
|
|
||||||
* SPDX-License-Identifier: AGPL-3.0-only
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* flaky
|
|
||||||
describe('After user signed in', () => {
|
|
||||||
beforeEach(() => {
|
|
||||||
cy.resetState();
|
|
||||||
cy.viewport('macbook-16');
|
|
||||||
|
|
||||||
// インスタンス初期セットアップ
|
|
||||||
cy.registerUser('admin', 'pass', true);
|
|
||||||
|
|
||||||
// ユーザー作成
|
|
||||||
cy.registerUser('alice', 'alice1234');
|
|
||||||
|
|
||||||
cy.login('alice', 'alice1234');
|
|
||||||
|
|
||||||
// アカウント初期設定ウィザード
|
|
||||||
cy.get('[data-cy-user-setup] [data-cy-modal-window-close]').click();
|
|
||||||
cy.get('[data-cy-modal-dialog-ok]').click();
|
|
||||||
});
|
|
||||||
|
|
||||||
afterEach(() => {
|
|
||||||
// テスト終了直前にページ遷移するようなテストケース(例えばアカウント作成)だと、たぶんCypressのバグでブラウザの内容が次のテストケースに引き継がれてしまう(例えばアカウントが作成し終わった段階からテストが始まる)。
|
|
||||||
// waitを入れることでそれを防止できる
|
|
||||||
cy.wait(1000);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('widget edit toggle is visible', () => {
|
|
||||||
cy.get('[data-cy-widget-edit]').should('be.visible');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('widget select should be visible in edit mode', () => {
|
|
||||||
cy.get('[data-cy-widget-edit]').click();
|
|
||||||
cy.get('[data-cy-widget-select]').should('be.visible');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('first widget should be removed', () => {
|
|
||||||
cy.get('[data-cy-widget-edit]').click();
|
|
||||||
cy.get('[data-cy-customize-container]:first-child [data-cy-customize-container-remove]._button').click();
|
|
||||||
cy.get('[data-cy-customize-container]').should('have.length', 2);
|
|
||||||
});
|
|
||||||
|
|
||||||
function buildWidgetTest(widgetName) {
|
|
||||||
it(`${widgetName} widget should get added`, () => {
|
|
||||||
cy.get('[data-cy-widget-edit]').click();
|
|
||||||
cy.get('[data-cy-widget-select] select').select(widgetName, { force: true });
|
|
||||||
cy.get('[data-cy-bg]._modalBg[data-cy-transparent]').click({ multiple: true, force: true });
|
|
||||||
cy.get('[data-cy-widget-add]').click({ force: true });
|
|
||||||
cy.get(`[data-cy-mkw-${widgetName}]`).should('exist');
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
buildWidgetTest('memo');
|
|
||||||
buildWidgetTest('notifications');
|
|
||||||
buildWidgetTest('timeline');
|
|
||||||
buildWidgetTest('calendar');
|
|
||||||
buildWidgetTest('rss');
|
|
||||||
buildWidgetTest('trends');
|
|
||||||
buildWidgetTest('clock');
|
|
||||||
buildWidgetTest('activity');
|
|
||||||
buildWidgetTest('photos');
|
|
||||||
buildWidgetTest('digitalClock');
|
|
||||||
buildWidgetTest('federation');
|
|
||||||
buildWidgetTest('postForm');
|
|
||||||
buildWidgetTest('slideshow');
|
|
||||||
buildWidgetTest('serverMetric');
|
|
||||||
buildWidgetTest('onlineUsers');
|
|
||||||
buildWidgetTest('jobQueue');
|
|
||||||
buildWidgetTest('button');
|
|
||||||
buildWidgetTest('aiscript');
|
|
||||||
buildWidgetTest('aichan');
|
|
||||||
});
|
|
||||||
*/
|
|
55
cypress/support/commands.js
Normal file
55
cypress/support/commands.js
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
// ***********************************************
|
||||||
|
// This example commands.js shows you how to
|
||||||
|
// create various custom commands and overwrite
|
||||||
|
// existing commands.
|
||||||
|
//
|
||||||
|
// For more comprehensive examples of custom
|
||||||
|
// commands please read more here:
|
||||||
|
// https://on.cypress.io/custom-commands
|
||||||
|
// ***********************************************
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// -- This is a parent command --
|
||||||
|
// Cypress.Commands.add('login', (email, password) => { ... })
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// -- This is a child command --
|
||||||
|
// Cypress.Commands.add('drag', { prevSubject: 'element'}, (subject, options) => { ... })
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// -- This is a dual command --
|
||||||
|
// Cypress.Commands.add('dismiss', { prevSubject: 'optional'}, (subject, options) => { ... })
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// -- This will overwrite an existing command --
|
||||||
|
// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... })
|
||||||
|
|
||||||
|
Cypress.Commands.add('resetState', () => {
|
||||||
|
cy.window(win => {
|
||||||
|
win.indexedDB.deleteDatabase('keyval-store');
|
||||||
|
});
|
||||||
|
cy.request('POST', '/api/reset-db').as('reset');
|
||||||
|
cy.get('@reset').its('status').should('equal', 204);
|
||||||
|
cy.reload(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
Cypress.Commands.add('registerUser', (username, password, isAdmin = false) => {
|
||||||
|
const route = isAdmin ? '/api/admin/accounts/create' : '/api/signup';
|
||||||
|
|
||||||
|
cy.request('POST', route, {
|
||||||
|
username: username,
|
||||||
|
password: password,
|
||||||
|
}).its('body').as(username);
|
||||||
|
});
|
||||||
|
|
||||||
|
Cypress.Commands.add('login', (username, password) => {
|
||||||
|
cy.visit('/');
|
||||||
|
|
||||||
|
cy.intercept('POST', '/api/signin').as('signin');
|
||||||
|
|
||||||
|
cy.get('[data-cy-signin]').click();
|
||||||
|
cy.get('[data-cy-signin-username] input').type(username);
|
||||||
|
cy.get('[data-cy-signin-password] input').type(`${password}{enter}`);
|
||||||
|
|
||||||
|
cy.wait('@signin').as('signedIn');
|
||||||
|
});
|
@ -1,67 +0,0 @@
|
|||||||
// ***********************************************
|
|
||||||
// This example commands.js shows you how to
|
|
||||||
// create various custom commands and overwrite
|
|
||||||
// existing commands.
|
|
||||||
//
|
|
||||||
// For more comprehensive examples of custom
|
|
||||||
// commands please read more here:
|
|
||||||
// https://on.cypress.io/custom-commands
|
|
||||||
// ***********************************************
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// -- This is a parent command --
|
|
||||||
// Cypress.Commands.add('login', (email, password) => { ... })
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// -- This is a child command --
|
|
||||||
// Cypress.Commands.add('drag', { prevSubject: 'element'}, (subject, options) => { ... })
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// -- This is a dual command --
|
|
||||||
// Cypress.Commands.add('dismiss', { prevSubject: 'optional'}, (subject, options) => { ... })
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// -- This will overwrite an existing command --
|
|
||||||
// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... })
|
|
||||||
|
|
||||||
Cypress.Commands.add('visitHome', () => {
|
|
||||||
cy.visit('/');
|
|
||||||
cy.get('button', { timeout: 30000 }).should('be.visible');
|
|
||||||
})
|
|
||||||
|
|
||||||
Cypress.Commands.add('resetState', () => {
|
|
||||||
// iframe.contentWindow.indexedDB.deleteDatabase() がchromeのバグで使用できないため、indexedDBを無効化している。
|
|
||||||
// see https://github.com/misskey-dev/misskey/issues/13605#issuecomment-2053652123
|
|
||||||
/*
|
|
||||||
cy.window().then(win => {
|
|
||||||
win.indexedDB.deleteDatabase('keyval-store');
|
|
||||||
});
|
|
||||||
*/
|
|
||||||
cy.request('POST', '/api/reset-db', {}).as('reset');
|
|
||||||
cy.get('@reset').its('status').should('equal', 204);
|
|
||||||
cy.reload(true);
|
|
||||||
});
|
|
||||||
|
|
||||||
Cypress.Commands.add('registerUser', (username, password, isAdmin = false) => {
|
|
||||||
const route = isAdmin ? '/api/admin/accounts/create' : '/api/signup';
|
|
||||||
|
|
||||||
cy.request('POST', route, {
|
|
||||||
username: username,
|
|
||||||
password: password,
|
|
||||||
...(isAdmin ? { setupPassword: 'example_password_please_change_this_or_you_will_get_hacked' } : {}),
|
|
||||||
}).its('body').as(username);
|
|
||||||
});
|
|
||||||
|
|
||||||
Cypress.Commands.add('login', (username, password) => {
|
|
||||||
cy.visitHome();
|
|
||||||
|
|
||||||
cy.intercept('POST', '/api/signin-flow').as('signin');
|
|
||||||
|
|
||||||
cy.get('[data-cy-signin]').click();
|
|
||||||
cy.get('[data-cy-signin-page-input]').should('be.visible', { timeout: 1000 });
|
|
||||||
cy.get('[data-cy-signin-username] input').type(`${username}{enter}`);
|
|
||||||
cy.get('[data-cy-signin-page-password]').should('be.visible', { timeout: 10000 });
|
|
||||||
cy.get('[data-cy-signin-password] input').type(`${password}{enter}`);
|
|
||||||
|
|
||||||
cy.wait('@signin').as('signedIn');
|
|
||||||
});
|
|
32
cypress/support/e2e.js
Normal file
32
cypress/support/e2e.js
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
// ***********************************************************
|
||||||
|
// This example support/index.js is processed and
|
||||||
|
// loaded automatically before your test files.
|
||||||
|
//
|
||||||
|
// This is a great place to put global configuration and
|
||||||
|
// behavior that modifies Cypress.
|
||||||
|
//
|
||||||
|
// You can change the location of this file or turn off
|
||||||
|
// automatically serving support files with the
|
||||||
|
// 'supportFile' configuration option.
|
||||||
|
//
|
||||||
|
// You can read more here:
|
||||||
|
// https://on.cypress.io/configuration
|
||||||
|
// ***********************************************************
|
||||||
|
|
||||||
|
// Import commands.js using ES2015 syntax:
|
||||||
|
import './commands'
|
||||||
|
|
||||||
|
// Alternatively you can use CommonJS syntax:
|
||||||
|
// require('./commands')
|
||||||
|
|
||||||
|
Cypress.on('uncaught:exception', (err, runnable) => {
|
||||||
|
if ([
|
||||||
|
// Chrome
|
||||||
|
'ResizeObserver loop limit exceeded',
|
||||||
|
|
||||||
|
// Firefox
|
||||||
|
'ResizeObserver loop completed with undelivered notifications',
|
||||||
|
].some(msg => err.message.includes(msg))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
@ -1,34 +0,0 @@
|
|||||||
// ***********************************************************
|
|
||||||
// This example support/index.js is processed and
|
|
||||||
// loaded automatically before your test files.
|
|
||||||
//
|
|
||||||
// This is a great place to put global configuration and
|
|
||||||
// behavior that modifies Cypress.
|
|
||||||
//
|
|
||||||
// You can change the location of this file or turn off
|
|
||||||
// automatically serving support files with the
|
|
||||||
// 'supportFile' configuration option.
|
|
||||||
//
|
|
||||||
// You can read more here:
|
|
||||||
// https://on.cypress.io/configuration
|
|
||||||
// ***********************************************************
|
|
||||||
|
|
||||||
// Import commands.js using ES2015 syntax:
|
|
||||||
import './commands'
|
|
||||||
|
|
||||||
// Alternatively you can use CommonJS syntax:
|
|
||||||
// require('./commands')
|
|
||||||
|
|
||||||
Cypress.on('uncaught:exception', (err, runnable) => {
|
|
||||||
if ([
|
|
||||||
'The source image cannot be decoded',
|
|
||||||
|
|
||||||
// Chrome
|
|
||||||
'ResizeObserver loop limit exceeded',
|
|
||||||
|
|
||||||
// Firefox
|
|
||||||
'ResizeObserver loop completed with undelivered notifications',
|
|
||||||
].some(msg => err.message.includes(msg))) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
});
|
|
@ -1,19 +0,0 @@
|
|||||||
declare global {
|
|
||||||
namespace Cypress {
|
|
||||||
interface Chainable {
|
|
||||||
login(username: string, password: string): Chainable<void>;
|
|
||||||
|
|
||||||
registerUser(
|
|
||||||
username: string,
|
|
||||||
password: string,
|
|
||||||
isAdmin?: boolean
|
|
||||||
): Chainable<void>;
|
|
||||||
|
|
||||||
resetState(): Chainable<void>;
|
|
||||||
|
|
||||||
visitHome(): Chainable<void>;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export {}
|
|
@ -1,8 +0,0 @@
|
|||||||
{
|
|
||||||
"compilerOptions": {
|
|
||||||
"lib": ["dom", "es5"],
|
|
||||||
"target": "es5",
|
|
||||||
"types": ["cypress", "node"]
|
|
||||||
},
|
|
||||||
"include": ["./**/*.ts"]
|
|
||||||
}
|
|
52
docker-compose.yml
Normal file
52
docker-compose.yml
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
version: "3"
|
||||||
|
|
||||||
|
services:
|
||||||
|
web:
|
||||||
|
build: .
|
||||||
|
restart: always
|
||||||
|
links:
|
||||||
|
- db
|
||||||
|
- redis
|
||||||
|
# - es
|
||||||
|
ports:
|
||||||
|
- "3000:3000"
|
||||||
|
networks:
|
||||||
|
- internal_network
|
||||||
|
- external_network
|
||||||
|
volumes:
|
||||||
|
- ./files:/misskey/files
|
||||||
|
- ./.config:/misskey/.config:ro
|
||||||
|
|
||||||
|
redis:
|
||||||
|
restart: always
|
||||||
|
image: redis:4.0-alpine
|
||||||
|
networks:
|
||||||
|
- internal_network
|
||||||
|
volumes:
|
||||||
|
- ./redis:/data
|
||||||
|
|
||||||
|
db:
|
||||||
|
restart: always
|
||||||
|
image: postgres:12.2-alpine
|
||||||
|
networks:
|
||||||
|
- internal_network
|
||||||
|
env_file:
|
||||||
|
- .config/docker.env
|
||||||
|
volumes:
|
||||||
|
- ./db:/var/lib/postgresql/data
|
||||||
|
|
||||||
|
# es:
|
||||||
|
# restart: always
|
||||||
|
# image: docker.elastic.co/elasticsearch/elasticsearch-oss:6.4.2
|
||||||
|
# environment:
|
||||||
|
# - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
|
||||||
|
# - "TAKE_FILE_OWNERSHIP=111"
|
||||||
|
# networks:
|
||||||
|
# - internal_network
|
||||||
|
# volumes:
|
||||||
|
# - ./elasticsearch:/usr/share/elasticsearch/data
|
||||||
|
|
||||||
|
networks:
|
||||||
|
internal_network:
|
||||||
|
internal: true
|
||||||
|
external_network:
|
25
docs/DONATORS.md
Normal file
25
docs/DONATORS.md
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
DONATORS
|
||||||
|
========
|
||||||
|
The list of people who have sent donation for Misskey.
|
||||||
|
|
||||||
|
(In random order, honorific titles are omitted.)
|
||||||
|
|
||||||
|
* らふぁ
|
||||||
|
* 俺様
|
||||||
|
* なぎうり
|
||||||
|
* スルメ https://surume.tk/
|
||||||
|
* 藍
|
||||||
|
* 音船 https://otofune.me/
|
||||||
|
* aqz https://misskey.xyz/aqz
|
||||||
|
* kotodu "虚無創作中"
|
||||||
|
* Maya Minatsuki
|
||||||
|
* Knzk https://knzk.me/@Knzk
|
||||||
|
* ねじりわさび https://knzk.me/@y
|
||||||
|
* NCLS https://knzk.me/@imncls]
|
||||||
|
* こじま @skoji@sandbox.skoji.jp
|
||||||
|
|
||||||
|
:heart: Thanks for donating, guys!
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
If your name is missing, please contact us!
|
@ -1 +0,0 @@
|
|||||||
Subproject commit cae981eb4c5189ea9ea3230e83b876a5068df7d1
|
|
65
gulpfile.js
Normal file
65
gulpfile.js
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
/**
|
||||||
|
* Gulp tasks
|
||||||
|
*/
|
||||||
|
|
||||||
|
const fs = require('fs');
|
||||||
|
const gulp = require('gulp');
|
||||||
|
const replace = require('gulp-replace');
|
||||||
|
const terser = require('gulp-terser');
|
||||||
|
const cssnano = require('gulp-cssnano');
|
||||||
|
|
||||||
|
const locales = require('./locales');
|
||||||
|
const meta = require('./package.json');
|
||||||
|
|
||||||
|
gulp.task('copy:backend:views', () =>
|
||||||
|
gulp.src('./packages/backend/src/server/web/views/**/*').pipe(gulp.dest('./packages/backend/built/server/web/views'))
|
||||||
|
);
|
||||||
|
|
||||||
|
gulp.task('copy:client:fonts', () =>
|
||||||
|
gulp.src('./packages/client/node_modules/three/examples/fonts/**/*').pipe(gulp.dest('./built/_client_dist_/fonts/'))
|
||||||
|
);
|
||||||
|
|
||||||
|
gulp.task('copy:client:fontawesome', () =>
|
||||||
|
gulp.src('./packages/client/node_modules/@fortawesome/fontawesome-free/**/*').pipe(gulp.dest('./built/_client_dist_/fontawesome/'))
|
||||||
|
);
|
||||||
|
|
||||||
|
gulp.task('copy:client:locales', cb => {
|
||||||
|
fs.mkdirSync('./built/_client_dist_/locales', { recursive: true });
|
||||||
|
|
||||||
|
const v = { '_version_': meta.version };
|
||||||
|
|
||||||
|
for (const [lang, locale] of Object.entries(locales)) {
|
||||||
|
fs.writeFileSync(`./built/_client_dist_/locales/${lang}.${meta.version}.json`, JSON.stringify({ ...locale, ...v }), 'utf-8');
|
||||||
|
}
|
||||||
|
|
||||||
|
cb();
|
||||||
|
});
|
||||||
|
|
||||||
|
gulp.task('build:backend:script', () => {
|
||||||
|
return gulp.src(['./packages/backend/src/server/web/boot.js', './packages/backend/src/server/web/bios.js', './packages/backend/src/server/web/cli.js'])
|
||||||
|
.pipe(replace('LANGS', JSON.stringify(Object.keys(locales))))
|
||||||
|
.pipe(terser({
|
||||||
|
toplevel: true
|
||||||
|
}))
|
||||||
|
.pipe(gulp.dest('./packages/backend/built/server/web/'));
|
||||||
|
});
|
||||||
|
|
||||||
|
gulp.task('build:backend:style', () => {
|
||||||
|
return gulp.src(['./packages/backend/src/server/web/style.css', './packages/backend/src/server/web/bios.css', './packages/backend/src/server/web/cli.css'])
|
||||||
|
.pipe(cssnano({
|
||||||
|
zindex: false
|
||||||
|
}))
|
||||||
|
.pipe(gulp.dest('./packages/backend/built/server/web/'));
|
||||||
|
});
|
||||||
|
|
||||||
|
gulp.task('build', gulp.parallel(
|
||||||
|
'copy:client:locales', 'copy:backend:views', 'build:backend:script', 'build:backend:style', 'copy:client:fonts', 'copy:client:fontawesome'
|
||||||
|
));
|
||||||
|
|
||||||
|
gulp.task('default', gulp.task('build'));
|
||||||
|
|
||||||
|
gulp.task('watch', () => {
|
||||||
|
gulp.watch([
|
||||||
|
'./packages/*/src/**/*',
|
||||||
|
], { ignoreInitial: false }, gulp.task('build'));
|
||||||
|
});
|
@ -1,7 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
# SPDX-FileCopyrightText: syuilo and misskey-project
|
|
||||||
# SPDX-License-Identifier: AGPL-3.0-only
|
|
||||||
|
|
||||||
PORT=$(grep '^port:' /misskey/.config/default.yml | awk 'NR==1{print $2; exit}')
|
|
||||||
curl -Sfso/dev/null "http://localhost:${PORT}/healthz"
|
|
@ -1,54 +0,0 @@
|
|||||||
/*
|
|
||||||
* SPDX-FileCopyrightText: syuilo and misskey-project
|
|
||||||
* SPDX-License-Identifier: AGPL-3.0-only
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* eslint-disable @typescript-eslint/explicit-function-return-type */
|
|
||||||
import { action } from '@storybook/addon-actions';
|
|
||||||
import { StoryObj } from '@storybook/vue3';
|
|
||||||
import { HttpResponse, http } from 'msw';
|
|
||||||
import { abuseUserReport } from '../packages/frontend/.storybook/fakes.js';
|
|
||||||
import { commonHandlers } from '../packages/frontend/.storybook/mocks.js';
|
|
||||||
import MkAbuseReport from './MkAbuseReport.vue';
|
|
||||||
export const Default = {
|
|
||||||
render(args) {
|
|
||||||
return {
|
|
||||||
components: {
|
|
||||||
MkAbuseReport,
|
|
||||||
},
|
|
||||||
setup() {
|
|
||||||
return {
|
|
||||||
args,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
props() {
|
|
||||||
return {
|
|
||||||
...this.args,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
events() {
|
|
||||||
return {
|
|
||||||
resolved: action('resolved'),
|
|
||||||
};
|
|
||||||
},
|
|
||||||
},
|
|
||||||
template: '<MkAbuseReport v-bind="props" v-on="events" />',
|
|
||||||
};
|
|
||||||
},
|
|
||||||
args: {
|
|
||||||
report: abuseUserReport(),
|
|
||||||
},
|
|
||||||
parameters: {
|
|
||||||
layout: 'fullscreen',
|
|
||||||
msw: {
|
|
||||||
handlers: [
|
|
||||||
...commonHandlers,
|
|
||||||
http.post('/api/admin/resolve-abuse-user-report', async ({ request }) => {
|
|
||||||
action('POST /api/admin/resolve-abuse-user-report')(await request.json());
|
|
||||||
return HttpResponse.json({});
|
|
||||||
}),
|
|
||||||
],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
} satisfies StoryObj<typeof MkAbuseReport>;
|
|
@ -1,41 +0,0 @@
|
|||||||
<!--
|
|
||||||
SPDX-FileCopyrightText: syuilo and misskey-project
|
|
||||||
SPDX-License-Identifier: AGPL-3.0-only
|
|
||||||
-->
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<div :class="[$style.root]">
|
|
||||||
<div :inert="disabled" :class="[{ [$style.disabled]: disabled }]">
|
|
||||||
<slot></slot>
|
|
||||||
</div>
|
|
||||||
<div v-if="disabled" :class="[$style.cover]"></div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script lang="ts" setup>
|
|
||||||
defineProps<{
|
|
||||||
disabled?: boolean;
|
|
||||||
}>();
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" module>
|
|
||||||
.root {
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
|
||||||
.disabled {
|
|
||||||
opacity: 0.7;
|
|
||||||
}
|
|
||||||
|
|
||||||
.cover {
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
cursor: not-allowed;
|
|
||||||
--color: color(from var(--error) srgb r g b / 0.25);
|
|
||||||
background-size: auto auto;
|
|
||||||
background-image: repeating-linear-gradient(135deg, transparent, transparent 10px, var(--color) 4px, var(--color) 14px);
|
|
||||||
}
|
|
||||||
</style>
|
|
@ -1 +0,0 @@
|
|||||||
使われなくなったけど消すのは勿体ない(将来使えるかもしれない)コードを入れておくとこ
|
|
File diff suppressed because it is too large
Load Diff
@ -2,7 +2,6 @@
|
|||||||
_lang_: "বাংলা"
|
_lang_: "বাংলা"
|
||||||
headlineMisskey: "নোট ব্যাবহার করে সংযুক্ত নেটওয়ার্ক"
|
headlineMisskey: "নোট ব্যাবহার করে সংযুক্ত নেটওয়ার্ক"
|
||||||
introMisskey: "স্বাগতম! মিসকি একটি ওপেন সোর্স, ডিসেন্ট্রালাইজড মাইক্রোব্লগিং পরিষেবা। \n\"নোট\" তৈরির মাধ্যমে যা ঘটছে তা সবার সাথে শেয়ার করুন 📡\n\"রিঅ্যাকশন\" গুলির মাধ্যমে যেকোনো নোট সম্পর্কে আপনার অনুভূতি ব্যাক্ত করতে পারেন 👍\nএকটি নতুন দুনিয়া ঘুরে দেখুন 🚀\n"
|
introMisskey: "স্বাগতম! মিসকি একটি ওপেন সোর্স, ডিসেন্ট্রালাইজড মাইক্রোব্লগিং পরিষেবা। \n\"নোট\" তৈরির মাধ্যমে যা ঘটছে তা সবার সাথে শেয়ার করুন 📡\n\"রিঅ্যাকশন\" গুলির মাধ্যমে যেকোনো নোট সম্পর্কে আপনার অনুভূতি ব্যাক্ত করতে পারেন 👍\nএকটি নতুন দুনিয়া ঘুরে দেখুন 🚀\n"
|
||||||
poweredByMisskeyDescription: "{name} হল ওপেন সোর্স প্ল্যাটফর্ম <b>Misskey</b>-এর সার্ভারগুলির একটি৷"
|
|
||||||
monthAndDay: "{day}/{month}"
|
monthAndDay: "{day}/{month}"
|
||||||
search: "খুঁজুন"
|
search: "খুঁজুন"
|
||||||
notifications: "বিজ্ঞপ্তি"
|
notifications: "বিজ্ঞপ্তি"
|
||||||
@ -13,14 +12,12 @@ fetchingAsApObject: "ফেডিভার্স থেকে খবর আন
|
|||||||
ok: "ঠিক"
|
ok: "ঠিক"
|
||||||
gotIt: "বুঝেছি"
|
gotIt: "বুঝেছি"
|
||||||
cancel: "বাতিল"
|
cancel: "বাতিল"
|
||||||
noThankYou: "না, ধন্যবাদ"
|
|
||||||
enterUsername: "ইউজারনেম লিখুন"
|
enterUsername: "ইউজারনেম লিখুন"
|
||||||
renotedBy: "{user} রিনোট করেছেন"
|
renotedBy: "{user} রিনোট করেছেন"
|
||||||
noNotes: "কোন নোট নেই"
|
noNotes: "কোন নোট নেই"
|
||||||
noNotifications: "কোনো বিজ্ঞপ্তি নেই"
|
noNotifications: "কোনো বিজ্ঞপ্তি নেই"
|
||||||
instance: "ইন্সট্যান্স"
|
instance: "ইন্সট্যান্স"
|
||||||
settings: "সেটিংস"
|
settings: "সেটিংস"
|
||||||
notificationSettings: "বিজ্ঞপ্তির সেটিংস"
|
|
||||||
basicSettings: "সাধারণ সেটিংস"
|
basicSettings: "সাধারণ সেটিংস"
|
||||||
otherSettings: "অন্যান্য সেটিংস"
|
otherSettings: "অন্যান্য সেটিংস"
|
||||||
openInWindow: "নতুন উইন্ডোতে খুলা"
|
openInWindow: "নতুন উইন্ডোতে খুলা"
|
||||||
@ -45,25 +42,16 @@ pin: "পিন করা"
|
|||||||
unpin: "পিন সরান"
|
unpin: "পিন সরান"
|
||||||
copyContent: "বিষয়বস্তু কপি করুন"
|
copyContent: "বিষয়বস্তু কপি করুন"
|
||||||
copyLink: "লিঙ্ক কপি করুন"
|
copyLink: "লিঙ্ক কপি করুন"
|
||||||
copyLinkRenote: "রিনোট লিঙ্ক কপি করুন"
|
|
||||||
delete: "মুছুন"
|
delete: "মুছুন"
|
||||||
deleteAndEdit: "মুছুন এবং সম্পাদনা করুন"
|
deleteAndEdit: "মুছুন এবং সম্পাদনা করুন"
|
||||||
deleteAndEditConfirm: "আপনি কি এই নোটটি মুছে এটি সম্পাদনা করার বিষয়ে নিশ্চিত? আপনি এটির সমস্ত রিঅ্যাকশন, রিনোট এবং জবাব হারাবেন।"
|
deleteAndEditConfirm: "আপনি কি এই নোটটি মুছে এটি সম্পাদনা করার বিষয়ে নিশ্চিত? আপনি এটির সমস্ত রিঅ্যাকশন, রিনোট এবং জবাব হারাবেন।"
|
||||||
addToList: "লিস্ট এ যোগ করুন"
|
addToList: "লিস্ট এ যোগ করুন"
|
||||||
addToAntenna: "অ্যান্টেনা এ যোগ করুন"
|
|
||||||
sendMessage: "একটি বার্তা পাঠান"
|
sendMessage: "একটি বার্তা পাঠান"
|
||||||
copyRSS: "RSS কপি করুন"
|
|
||||||
copyUsername: "ব্যবহারকারীর নাম কপি করুন"
|
copyUsername: "ব্যবহারকারীর নাম কপি করুন"
|
||||||
copyUserId: "ব্যবহারকারীর ID কপি করুন"
|
|
||||||
copyNoteId: "নোটের ID কপি করুন"
|
|
||||||
copyFileId: "ফাইল ID কপি করুন"
|
|
||||||
copyFolderId: "ফোল্ডার ID কপি করুন"
|
|
||||||
copyProfileUrl: "প্রোফাইল URL কপি করুন"
|
|
||||||
searchUser: "ব্যবহারকারী খুঁজুন..."
|
searchUser: "ব্যবহারকারী খুঁজুন..."
|
||||||
reply: "জবাব"
|
reply: "জবাব"
|
||||||
loadMore: "আরও দেখুন"
|
loadMore: "আরও দেখুন"
|
||||||
showMore: "আরও দেখুন"
|
showMore: "আরও দেখুন"
|
||||||
showLess: "বন্ধ"
|
|
||||||
youGotNewFollower: "আপনাকে অনুসরণ করছে"
|
youGotNewFollower: "আপনাকে অনুসরণ করছে"
|
||||||
receiveFollowRequest: "অনুসরণ করার জন্য অনুরোধ পাওয়া গেছে"
|
receiveFollowRequest: "অনুসরণ করার জন্য অনুরোধ পাওয়া গেছে"
|
||||||
followRequestAccepted: "অনুসরণ করার অনুরোধ গৃহীত হয়েছে"
|
followRequestAccepted: "অনুসরণ করার অনুরোধ গৃহীত হয়েছে"
|
||||||
@ -111,8 +99,6 @@ renoted: "রিনোট করা হয়েছে"
|
|||||||
cantRenote: "এই নোটটি রিনোট করা যাবে না।"
|
cantRenote: "এই নোটটি রিনোট করা যাবে না।"
|
||||||
cantReRenote: "রিনোটকে রিনোট করা যাবে না।"
|
cantReRenote: "রিনোটকে রিনোট করা যাবে না।"
|
||||||
quote: "উদ্ধৃতি"
|
quote: "উদ্ধৃতি"
|
||||||
inChannelRenote: "চ্যানেলে রিনোট"
|
|
||||||
inChannelQuote: "চ্যানেলে উদ্ধৃতি"
|
|
||||||
pinnedNote: "পিন করা নোট"
|
pinnedNote: "পিন করা নোট"
|
||||||
pinned: "পিন করা"
|
pinned: "পিন করা"
|
||||||
you: "আপনি"
|
you: "আপনি"
|
||||||
@ -120,11 +106,7 @@ clickToShow: "দেখার জন্য ক্লিক করুন"
|
|||||||
sensitive: "সংবেদনশীল বিষয়বস্তু"
|
sensitive: "সংবেদনশীল বিষয়বস্তু"
|
||||||
add: "যুক্ত করুন"
|
add: "যুক্ত করুন"
|
||||||
reaction: "প্রতিক্রিয়া"
|
reaction: "প্রতিক্রিয়া"
|
||||||
reactions: "প্রতিক্রিয়া"
|
reactionSetting: "রিঅ্যাকশন পিকারে যেসকল প্রতিক্রিয়া দেখানো হবে"
|
||||||
emojiPicker: "ইমোজি পিকার"
|
|
||||||
pinnedEmojisForReactionSettingDescription: "রিঅ্যাকশন দেয়ার সময় আপনি ইমোজিটিকে পিন করা এবং প্রদর্শিত হওয়ার জন্য সেট করতে পারেন।"
|
|
||||||
pinnedEmojisSettingDescription: "ইমোজি ইনপুট দেয়ার সময় আপনি ইমোজিটিকে পিন করা এবং প্রদর্শিত হওয়ার জন্য সেট করতে পারেন।"
|
|
||||||
emojiPickerDisplay: "পিকার ডিসপ্লে"
|
|
||||||
reactionSettingDescription2: "পুনরায় সাজাতে টেনে আনুন, মুছতে ক্লিক করুন, যোগ করতে + টিপুন।"
|
reactionSettingDescription2: "পুনরায় সাজাতে টেনে আনুন, মুছতে ক্লিক করুন, যোগ করতে + টিপুন।"
|
||||||
rememberNoteVisibility: "নোটের দৃশ্যমান্যতার সেটিংস মনে রাখুন"
|
rememberNoteVisibility: "নোটের দৃশ্যমান্যতার সেটিংস মনে রাখুন"
|
||||||
attachCancel: "অ্যাটাচমেন্ট সরান "
|
attachCancel: "অ্যাটাচমেন্ট সরান "
|
||||||
@ -181,6 +163,7 @@ annotation: "মন্তব্য"
|
|||||||
federation: "ফেডিভার্স"
|
federation: "ফেডিভার্স"
|
||||||
instances: "ইন্সট্যান্স"
|
instances: "ইন্সট্যান্স"
|
||||||
registeredAt: "যোগ দিয়েছেন"
|
registeredAt: "যোগ দিয়েছেন"
|
||||||
|
latestRequestSentAt: "শেষ রিকুয়েস্ট পাঠানো হয়েছে"
|
||||||
latestRequestReceivedAt: "শেষ রিকুয়েস্ট গৃহীত হয়েছে"
|
latestRequestReceivedAt: "শেষ রিকুয়েস্ট গৃহীত হয়েছে"
|
||||||
latestStatus: "সর্বশেষ অবস্থা"
|
latestStatus: "সর্বশেষ অবস্থা"
|
||||||
storageUsage: "স্টোরেজের ব্যাবহার"
|
storageUsage: "স্টোরেজের ব্যাবহার"
|
||||||
@ -268,12 +251,12 @@ noMoreHistory: "আর কোন ইতিহাস নেই"
|
|||||||
startMessaging: "চ্যাট শুরু করুন"
|
startMessaging: "চ্যাট শুরু করুন"
|
||||||
nUsersRead: "{n} জন পড়েছেন"
|
nUsersRead: "{n} জন পড়েছেন"
|
||||||
agreeTo: "{0} এর প্রতি আমি সম্মত"
|
agreeTo: "{0} এর প্রতি আমি সম্মত"
|
||||||
|
tos: "পরিষেবার শর্তাদি"
|
||||||
start: "শুরু করুন"
|
start: "শুরু করুন"
|
||||||
home: "মূল পাতা"
|
home: "মূল পাতা"
|
||||||
remoteUserCaution: "এই ব্যাবহারকারী রিমোট ইন্সট্যান্সের, নিম্নক্ত তথ্য অসম্পূর্ণ হতে পারে।"
|
remoteUserCaution: "এই ব্যাবহারকারী রিমোট ইন্সট্যান্সের, নিম্নক্ত তথ্য অসম্পূর্ণ হতে পারে।"
|
||||||
activity: "কার্যকলাপ"
|
activity: "কার্যকলাপ"
|
||||||
images: "ছবি"
|
images: "ছবি"
|
||||||
image: "ছবি"
|
|
||||||
birthday: "জন্মদিন"
|
birthday: "জন্মদিন"
|
||||||
yearsOld: "{age} বছর"
|
yearsOld: "{age} বছর"
|
||||||
registeredDate: "যোগদানের তারিখ"
|
registeredDate: "যোগদানের তারিখ"
|
||||||
@ -310,6 +293,7 @@ copyUrl: "URL কপি করুন"
|
|||||||
rename: "পুনঃনামকরণ"
|
rename: "পুনঃনামকরণ"
|
||||||
avatar: "প্রোফাইল ছবি"
|
avatar: "প্রোফাইল ছবি"
|
||||||
banner: "ব্যানার"
|
banner: "ব্যানার"
|
||||||
|
nsfw: "সংবেদনশীল বিষয়বস্তু"
|
||||||
whenServerDisconnected: "সার্ভারের সাথে সংযোগ বিচ্ছিন্ন হয়ে গেলে"
|
whenServerDisconnected: "সার্ভারের সাথে সংযোগ বিচ্ছিন্ন হয়ে গেলে"
|
||||||
disconnectedFromServer: "সার্ভার থেকে সংযোগ বিচ্ছিন্ন হয়েছে"
|
disconnectedFromServer: "সার্ভার থেকে সংযোগ বিচ্ছিন্ন হয়েছে"
|
||||||
reload: "আবার লোড করুন"
|
reload: "আবার লোড করুন"
|
||||||
@ -344,6 +328,7 @@ invite: "আমন্ত্রণ"
|
|||||||
driveCapacityPerLocalAccount: "প্রত্যেক স্থানীয় ব্যাবহারকারীর জন্য ড্রাইভের জায়গা"
|
driveCapacityPerLocalAccount: "প্রত্যেক স্থানীয় ব্যাবহারকারীর জন্য ড্রাইভের জায়গা"
|
||||||
driveCapacityPerRemoteAccount: "প্রত্যেক রিমোট ব্যাবহারকারীর জন্য ড্রাইভের জায়গা"
|
driveCapacityPerRemoteAccount: "প্রত্যেক রিমোট ব্যাবহারকারীর জন্য ড্রাইভের জায়গা"
|
||||||
inMb: "মেগাবাইটে লিখুন"
|
inMb: "মেগাবাইটে লিখুন"
|
||||||
|
iconUrl: "আইকনের URL (ফ্যাভিকন, ইত্যাদি)"
|
||||||
bannerUrl: "ব্যানার ছবির URL"
|
bannerUrl: "ব্যানার ছবির URL"
|
||||||
backgroundImageUrl: "পটভূমির চিত্রের URL"
|
backgroundImageUrl: "পটভূমির চিত্রের URL"
|
||||||
basicInfo: "আপনার ব্যক্তিগত তথ্য"
|
basicInfo: "আপনার ব্যক্তিগত তথ্য"
|
||||||
@ -357,14 +342,10 @@ hcaptcha: "hCaptcha"
|
|||||||
enableHcaptcha: "hCaptcha চালু করুন"
|
enableHcaptcha: "hCaptcha চালু করুন"
|
||||||
hcaptchaSiteKey: "সাইট কী"
|
hcaptchaSiteKey: "সাইট কী"
|
||||||
hcaptchaSecretKey: "সিক্রেট কী"
|
hcaptchaSecretKey: "সিক্রেট কী"
|
||||||
mcaptchaSiteKey: "সাইট কী"
|
|
||||||
mcaptchaSecretKey: "সিক্রেট কী"
|
|
||||||
recaptcha: "reCAPTCHA"
|
recaptcha: "reCAPTCHA"
|
||||||
enableRecaptcha: "reCAPTCHA চালু করুন"
|
enableRecaptcha: "reCAPTCHA চালু করুন"
|
||||||
recaptchaSiteKey: "সাইট কী"
|
recaptchaSiteKey: "সাইট কী"
|
||||||
recaptchaSecretKey: "সিক্রেট কী"
|
recaptchaSecretKey: "সিক্রেট কী"
|
||||||
turnstileSiteKey: "সাইট কী"
|
|
||||||
turnstileSecretKey: "সিক্রেট কী"
|
|
||||||
avoidMultiCaptchaConfirm: "একাধিক Captcha ব্যবহার করলে তারা পরস্পরের কাজে বাধা দিতে পারে। আপনি কি অন্যান্য Captcha নিষ্ক্রিয় করতে চান? আপনি 'বাতিল' ক্লিক করার মাধ্যমে একাধিক Captcha চালু রাখতে পারেন।"
|
avoidMultiCaptchaConfirm: "একাধিক Captcha ব্যবহার করলে তারা পরস্পরের কাজে বাধা দিতে পারে। আপনি কি অন্যান্য Captcha নিষ্ক্রিয় করতে চান? আপনি 'বাতিল' ক্লিক করার মাধ্যমে একাধিক Captcha চালু রাখতে পারেন।"
|
||||||
antennas: "অ্যান্টেনা"
|
antennas: "অ্যান্টেনা"
|
||||||
manageAntennas: "অ্যান্টেনা ব্যবস্থাপনা"
|
manageAntennas: "অ্যান্টেনা ব্যবস্থাপনা"
|
||||||
@ -398,9 +379,12 @@ about: "আপনার সম্পর্কে"
|
|||||||
aboutMisskey: "Misskey সম্পর্কে"
|
aboutMisskey: "Misskey সম্পর্কে"
|
||||||
administrator: "প্রশাসক"
|
administrator: "প্রশাসক"
|
||||||
token: "টোকেন"
|
token: "টোকেন"
|
||||||
|
twoStepAuthentication: "২-ধাপ প্রমাণীকরণ"
|
||||||
moderator: "মডারেটর"
|
moderator: "মডারেটর"
|
||||||
nUsersMentioned: "{n} জনকে উল্লেখ করা হয়েছে"
|
nUsersMentioned: "{n} জনকে উল্লেখ করা হয়েছে"
|
||||||
securityKey: "সিকিউরিটি কী"
|
securityKey: "সিকিউরিটি কী"
|
||||||
|
securityKeyName: "কী'র নাম"
|
||||||
|
registerSecurityKey: "সিকিউরিটি কী নিবন্ধন করুন"
|
||||||
lastUsed: "শেষ ব্যাবহার করা হয়েছে"
|
lastUsed: "শেষ ব্যাবহার করা হয়েছে"
|
||||||
unregister: "নিবন্ধনমুক্ত হন"
|
unregister: "নিবন্ধনমুক্ত হন"
|
||||||
passwordLessLogin: "পাসওয়ার্ড-বিহীন লগইন সেট আপ করুন"
|
passwordLessLogin: "পাসওয়ার্ড-বিহীন লগইন সেট আপ করুন"
|
||||||
@ -411,21 +395,31 @@ share: "শেয়ার"
|
|||||||
notFound: "পাওয়া যায়নি"
|
notFound: "পাওয়া যায়নি"
|
||||||
notFoundDescription: "এই URL-এর সাথে সম্পর্কিত কোনো পৃষ্ঠা নেই।"
|
notFoundDescription: "এই URL-এর সাথে সম্পর্কিত কোনো পৃষ্ঠা নেই।"
|
||||||
uploadFolder: "আপলোডের জন্য ডিফল্ট ফোল্ডার"
|
uploadFolder: "আপলোডের জন্য ডিফল্ট ফোল্ডার"
|
||||||
|
cacheClear: "ক্যাশ পরিষ্কার করুন"
|
||||||
markAsReadAllNotifications: "সমস্ত বিজ্ঞপ্তিগুলি পঠিত হিসাবে চিহ্নিত করুন"
|
markAsReadAllNotifications: "সমস্ত বিজ্ঞপ্তিগুলি পঠিত হিসাবে চিহ্নিত করুন"
|
||||||
markAsReadAllUnreadNotes: "সমস্ত নোটগুলি পঠিত হিসাবে চিহ্নিত করুন"
|
markAsReadAllUnreadNotes: "সমস্ত নোটগুলি পঠিত হিসাবে চিহ্নিত করুন"
|
||||||
markAsReadAllTalkMessages: "সমস্ত মেসেজ পঠিত হিসাবে চিহ্নিত করুন"
|
markAsReadAllTalkMessages: "সমস্ত মেসেজ পঠিত হিসাবে চিহ্নিত করুন"
|
||||||
help: "সহায়তা"
|
help: "সহায়তা"
|
||||||
inputMessageHere: "এখানে মেসেজ লিখুন"
|
inputMessageHere: "এখানে মেসেজ লিখুন"
|
||||||
close: "বন্ধ"
|
close: "বন্ধ"
|
||||||
|
group: "গ্রুপ"
|
||||||
|
groups: "গ্রুপসমূহ"
|
||||||
|
createGroup: "গ্রুপ তৈরী করুন"
|
||||||
|
ownedGroups: "আপনার গ্রুপগুলি"
|
||||||
|
joinedGroups: "যেসব গ্রুপে আপনি আছেন"
|
||||||
invites: "আমন্ত্রণ"
|
invites: "আমন্ত্রণ"
|
||||||
|
groupName: "গ্রুপের নাম"
|
||||||
members: "সদস্যবৃন্দ"
|
members: "সদস্যবৃন্দ"
|
||||||
transfer: "হস্তান্তর"
|
transfer: "হস্তান্তর"
|
||||||
|
messagingWithUser: "প্রাইভেট চ্যাট"
|
||||||
|
messagingWithGroup: "গ্রুপ চ্যাট"
|
||||||
title: "শিরোনাম"
|
title: "শিরোনাম"
|
||||||
text: "পাঠ্য"
|
text: "পাঠ্য"
|
||||||
enable: "সক্রিয়"
|
enable: "সক্রিয়"
|
||||||
next: "পরবর্তী"
|
next: "পরবর্তী"
|
||||||
retype: "পুনঃ প্রবেশ"
|
retype: "পুনঃ প্রবেশ"
|
||||||
noteOf: "{user} এর নোট"
|
noteOf: "{user} এর নোট"
|
||||||
|
inviteToGroup: "গ্রুপে আমন্ত্রণ জানান"
|
||||||
quoteAttached: "উদ্ধৃত"
|
quoteAttached: "উদ্ধৃত"
|
||||||
quoteQuestion: "উদ্ধৃতি হিসাবে সংযুক্ত করবেন?"
|
quoteQuestion: "উদ্ধৃতি হিসাবে সংযুক্ত করবেন?"
|
||||||
noMessagesYet: "কোন মেসেজ নেই"
|
noMessagesYet: "কোন মেসেজ নেই"
|
||||||
@ -447,12 +441,19 @@ passwordMatched: "মিলেছে"
|
|||||||
passwordNotMatched: "মিলেনি"
|
passwordNotMatched: "মিলেনি"
|
||||||
signinWith: "{x} এর সাহায্যে সাইন ইন করুন"
|
signinWith: "{x} এর সাহায্যে সাইন ইন করুন"
|
||||||
signinFailed: "লগ ইন করা যায়নি। আপনার ব্যবহারকারীর নাম এবং পাসওয়ার্ড চেক করুন."
|
signinFailed: "লগ ইন করা যায়নি। আপনার ব্যবহারকারীর নাম এবং পাসওয়ার্ড চেক করুন."
|
||||||
|
tapSecurityKey: "সিকিউরিটি কী স্পর্শ করুন"
|
||||||
or: "অথবা"
|
or: "অথবা"
|
||||||
language: "ভাষা"
|
language: "ভাষা"
|
||||||
uiLanguage: "UI এর ভাষা"
|
uiLanguage: "UI এর ভাষা"
|
||||||
|
groupInvited: "আপনি একটি গ্রুপে আমন্ত্রিত হয়েছেন"
|
||||||
aboutX: "{x} সম্পর্কে"
|
aboutX: "{x} সম্পর্কে"
|
||||||
|
useOsNativeEmojis: "অপারেটিং সিস্টেমের নেটিভ ইমোজি ব্যবহার করুন"
|
||||||
|
disableDrawer: "ড্রয়ার মেনু প্রদর্শন করবেন না"
|
||||||
|
youHaveNoGroups: "আপনার কোন গ্রুপ নেই "
|
||||||
|
joinOrCreateGroup: "একটি বিদ্যমান গ্রুপের আমন্ত্রণ পান বা একটি নতুন গ্রুপ তৈরি করুন৷"
|
||||||
noHistory: "কোনো ইতিহাস নেই"
|
noHistory: "কোনো ইতিহাস নেই"
|
||||||
signinHistory: "প্রবেশ করার ইতিহাস"
|
signinHistory: "প্রবেশ করার ইতিহাস"
|
||||||
|
disableAnimatedMfm: "অ্যানিমেটেড MFM অক্ষম করুন"
|
||||||
doing: "প্রক্রিয়া করছে..."
|
doing: "প্রক্রিয়া করছে..."
|
||||||
category: "বিভাগ"
|
category: "বিভাগ"
|
||||||
tags: "ট্যাগসমূহ"
|
tags: "ট্যাগসমূহ"
|
||||||
@ -499,7 +500,6 @@ deleteAll: "সব মুছুন"
|
|||||||
showFixedPostForm: "টাইমলাইনের শীর্ষে পোস্ট করার ফর্মটি দেখান"
|
showFixedPostForm: "টাইমলাইনের শীর্ষে পোস্ট করার ফর্মটি দেখান"
|
||||||
newNoteRecived: "নতুন নোট আছে"
|
newNoteRecived: "নতুন নোট আছে"
|
||||||
sounds: "শব্দ"
|
sounds: "শব্দ"
|
||||||
sound: "শব্দ"
|
|
||||||
listen: "শুনুন"
|
listen: "শুনুন"
|
||||||
none: "কিছুই না"
|
none: "কিছুই না"
|
||||||
showInPage: "পেজে দেখান"
|
showInPage: "পেজে দেখান"
|
||||||
@ -576,6 +576,7 @@ tokenRequested: "অ্যাকাউন্টে অ্যাক্সেস
|
|||||||
pluginTokenRequestedDescription: "এই প্লাগইনটি এখানে দেওয়া অনুমুতিসমূহ ব্যাবহার করবে"
|
pluginTokenRequestedDescription: "এই প্লাগইনটি এখানে দেওয়া অনুমুতিসমূহ ব্যাবহার করবে"
|
||||||
notificationType: "বিজ্ঞপ্তির ধরন"
|
notificationType: "বিজ্ঞপ্তির ধরন"
|
||||||
edit: "সম্পাদনা"
|
edit: "সম্পাদনা"
|
||||||
|
useStarForReactionFallback: "রিঅ্যাকশনের ইমোজি না জানলে ★ ব্যবহার করুন"
|
||||||
emailServer: "ইমেইল সার্ভার"
|
emailServer: "ইমেইল সার্ভার"
|
||||||
enableEmail: "ইমেইল বিতরণ চালু করুন"
|
enableEmail: "ইমেইল বিতরণ চালু করুন"
|
||||||
emailConfigInfo: "আপনার ইমেল ঠিকানা নিশ্চিত করতে এবং আপনার পাসওয়ার্ড পুনরায় সেট করতে ব্যবহৃত হয়"
|
emailConfigInfo: "আপনার ইমেল ঠিকানা নিশ্চিত করতে এবং আপনার পাসওয়ার্ড পুনরায় সেট করতে ব্যবহৃত হয়"
|
||||||
@ -624,7 +625,10 @@ abuseReported: "আপনার অভিযোগটি দাখিল কর
|
|||||||
reporter: "অভিযোগকারী"
|
reporter: "অভিযোগকারী"
|
||||||
reporteeOrigin: "অভিযোগটির উৎস"
|
reporteeOrigin: "অভিযোগটির উৎস"
|
||||||
reporterOrigin: "অভিযোগকারীর উৎস"
|
reporterOrigin: "অভিযোগকারীর উৎস"
|
||||||
|
forwardReport: "রিমোট ইন্সত্যান্সে অভিযোগটি পাঠান"
|
||||||
|
forwardReportIsAnonymous: "আপনার তথ্য রিমোট ইন্সত্যান্সে পাঠানো হবে না এবং একটি বেনামী সিস্টেম অ্যাকাউন্ট হিসাবে প্রদর্শিত হবে।"
|
||||||
send: "পাঠান"
|
send: "পাঠান"
|
||||||
|
abuseMarkAsResolved: "অভিযোগটিকে সমাধাকৃত হিসাবে চিহ্নিত করুন"
|
||||||
openInNewTab: "নতুন ট্যাবে খুলুন"
|
openInNewTab: "নতুন ট্যাবে খুলুন"
|
||||||
openInSideView: "সাইড ভিউতে খুলুন"
|
openInSideView: "সাইড ভিউতে খুলুন"
|
||||||
defaultNavigationBehaviour: "ডিফল্ট নেভিগেশন"
|
defaultNavigationBehaviour: "ডিফল্ট নেভিগেশন"
|
||||||
@ -640,7 +644,6 @@ createNew: "নতুন"
|
|||||||
optional: "প্রয়োজনীয় নয়"
|
optional: "প্রয়োজনীয় নয়"
|
||||||
createNewClip: "নতুন ক্লিপ তৈরি করুন"
|
createNewClip: "নতুন ক্লিপ তৈরি করুন"
|
||||||
public: "সর্বজনীন"
|
public: "সর্বজনীন"
|
||||||
private: "ব্যাক্তিগত"
|
|
||||||
i18nInfo: "Misskey স্বেচ্ছাসেবকদের দ্বারা বিভিন্ন ভাষায় অনুবাদ করা হচ্ছে। আপনি {link} এ গিয়ে অনুবাদে সহযোগিতা করতে পারেন।"
|
i18nInfo: "Misskey স্বেচ্ছাসেবকদের দ্বারা বিভিন্ন ভাষায় অনুবাদ করা হচ্ছে। আপনি {link} এ গিয়ে অনুবাদে সহযোগিতা করতে পারেন।"
|
||||||
manageAccessTokens: "অ্যাক্সেস টোকেন পরিচালনা করুন"
|
manageAccessTokens: "অ্যাক্সেস টোকেন পরিচালনা করুন"
|
||||||
accountInfo: "অ্যাকাউন্টের তথ্য"
|
accountInfo: "অ্যাকাউন্টের তথ্য"
|
||||||
@ -808,11 +811,15 @@ makeReactionsPublicDescription: "আপনার পূর্ববর্তী
|
|||||||
classic: "ক্লাসিক"
|
classic: "ক্লাসিক"
|
||||||
muteThread: "থ্রেড মিউট করুন"
|
muteThread: "থ্রেড মিউট করুন"
|
||||||
unmuteThread: "থ্রেড আনমিউট করুন"
|
unmuteThread: "থ্রেড আনমিউট করুন"
|
||||||
|
ffVisibility: "অনুসরণ/অনুসরণকারীদের দৃশ্যমান্যতা"
|
||||||
|
ffVisibilityDescription: "আপনি কাকে অনুসরণ করেন এবং কে আপনাকে অনুসরণ করে, সেটা কারা দেখতে পাবে তা নির্ধারণ করে।"
|
||||||
continueThread: "আরো থ্রেড দেখুন"
|
continueThread: "আরো থ্রেড দেখুন"
|
||||||
deleteAccountConfirm: "আপনার অ্যাকাউন্ট মুছে ফেলা হবে। ঠিক আছে?"
|
deleteAccountConfirm: "আপনার অ্যাকাউন্ট মুছে ফেলা হবে। ঠিক আছে?"
|
||||||
incorrectPassword: "আপনার দেওয়া পাসওয়ার্ডটি ভুল।"
|
incorrectPassword: "আপনার দেওয়া পাসওয়ার্ডটি ভুল।"
|
||||||
voteConfirm: "\"{choice}\" এ ভোট দিতে চান?"
|
voteConfirm: "\"{choice}\" এ ভোট দিতে চান?"
|
||||||
hide: "লুকান"
|
hide: "লুকান"
|
||||||
|
leaveGroup: "গ্রুপ ছেড়ে চলে যান"
|
||||||
|
leaveGroupConfirm: "\"{name}\" গ্রুপ ছেড়ে চলে যেতে চান?"
|
||||||
useDrawerReactionPickerForMobile: "মোবাইলে রিঅ্যাকশন পিকারকে ড্রয়ারে প্রদর্শন করুন"
|
useDrawerReactionPickerForMobile: "মোবাইলে রিঅ্যাকশন পিকারকে ড্রয়ারে প্রদর্শন করুন"
|
||||||
welcomeBackWithName: "আবার স্বাগতম, {name}"
|
welcomeBackWithName: "আবার স্বাগতম, {name}"
|
||||||
clickToFinishEmailVerification: " [{ok}] ক্লিক করার মাধ্যমে আপনার ইমেল ঠিকানা নিশ্চিত করুন।"
|
clickToFinishEmailVerification: " [{ok}] ক্লিক করার মাধ্যমে আপনার ইমেল ঠিকানা নিশ্চিত করুন।"
|
||||||
@ -828,7 +835,6 @@ instanceDefaultLightTheme: "ইন্সট্যান্সের ডিফল
|
|||||||
instanceDefaultDarkTheme: "ইন্সট্যান্সের ডিফল্ট ডার্ক থিম"
|
instanceDefaultDarkTheme: "ইন্সট্যান্সের ডিফল্ট ডার্ক থিম"
|
||||||
instanceDefaultThemeDescription: "অবজেক্ট ফরম্যাটে থিম কোড লিখুন"
|
instanceDefaultThemeDescription: "অবজেক্ট ফরম্যাটে থিম কোড লিখুন"
|
||||||
mutePeriod: "মিউটের সময়কাল"
|
mutePeriod: "মিউটের সময়কাল"
|
||||||
period: "পোলের সময়সীমা"
|
|
||||||
indefinitely: "অনির্দিষ্ট"
|
indefinitely: "অনির্দিষ্ট"
|
||||||
tenMinutes: "১০ মিনিট"
|
tenMinutes: "১০ মিনিট"
|
||||||
oneHour: "১ ঘণ্টা"
|
oneHour: "১ ঘণ্টা"
|
||||||
@ -837,32 +843,6 @@ oneWeek: "এক সপ্তাহ"
|
|||||||
reflectMayTakeTime: "এটির কাজ দেখা যেতে কিছুটা সময় লাগতে পারে।"
|
reflectMayTakeTime: "এটির কাজ দেখা যেতে কিছুটা সময় লাগতে পারে।"
|
||||||
failedToFetchAccountInformation: "অ্যাকাউন্টের তথ্য উদ্ধার করা যায়নি"
|
failedToFetchAccountInformation: "অ্যাকাউন্টের তথ্য উদ্ধার করা যায়নি"
|
||||||
rateLimitExceeded: "রেট লিমিট ছাড়িয়ে গেছে "
|
rateLimitExceeded: "রেট লিমিট ছাড়িয়ে গেছে "
|
||||||
file: "ফাইলগুলি"
|
|
||||||
reverse: "উল্টান"
|
|
||||||
colored: "রঙ্গিন"
|
|
||||||
label: "লেবেল"
|
|
||||||
localOnly: "শুধুমাত্র লোকাল"
|
|
||||||
account: "অ্যাকাউন্টগুলি"
|
|
||||||
like: "পছন্দ করা"
|
|
||||||
show: "প্রদর্শন"
|
|
||||||
color: "রং"
|
|
||||||
horizontal: "পাশে"
|
|
||||||
youFollowing: "অনুসরণ করা হচ্ছে"
|
|
||||||
icon: "প্রোফাইল ছবি"
|
|
||||||
replies: "জবাব"
|
|
||||||
renotes: "রিনোট"
|
|
||||||
sourceCode: "সোর্স কোড"
|
|
||||||
flip: "উল্টান"
|
|
||||||
_delivery:
|
|
||||||
stop: "স্থগিত করা হয়েছে"
|
|
||||||
_type:
|
|
||||||
none: "প্রকাশ করা হচ্ছে"
|
|
||||||
_role:
|
|
||||||
priority: "অগ্রাধিকার"
|
|
||||||
_priority:
|
|
||||||
low: "নিম্ন"
|
|
||||||
middle: "মাঝারি"
|
|
||||||
high: "উচ্চ"
|
|
||||||
_emailUnavailable:
|
_emailUnavailable:
|
||||||
used: "এই ইমেইল ঠিকানাটি ইতোমধ্যে ব্যবহৃত হয়েছে"
|
used: "এই ইমেইল ঠিকানাটি ইতোমধ্যে ব্যবহৃত হয়েছে"
|
||||||
format: "এই ইমেল ঠিকানাটি সঠিকভাবে লিখা হয়নি"
|
format: "এই ইমেল ঠিকানাটি সঠিকভাবে লিখা হয়নি"
|
||||||
@ -887,7 +867,6 @@ _accountDelete:
|
|||||||
_ad:
|
_ad:
|
||||||
back: "পিছনে"
|
back: "পিছনে"
|
||||||
reduceFrequencyOfThisAd: "এই বিজ্ঞাপনটি কম দেখান"
|
reduceFrequencyOfThisAd: "এই বিজ্ঞাপনটি কম দেখান"
|
||||||
hide: "দেখাবেন না"
|
|
||||||
_forgotPassword:
|
_forgotPassword:
|
||||||
enterEmail: "আপনি আপনার অ্যাকাউন্টের জন্য নিবন্ধিত ইমেল ঠিকানা লিখুন. সেই ঠিকানায় একটি পাসওয়ার্ড রিসেট লিঙ্ক পাঠানো হবে।"
|
enterEmail: "আপনি আপনার অ্যাকাউন্টের জন্য নিবন্ধিত ইমেল ঠিকানা লিখুন. সেই ঠিকানায় একটি পাসওয়ার্ড রিসেট লিঙ্ক পাঠানো হবে।"
|
||||||
ifNoEmail: "আপনি যদি নিবন্ধনের সময় ই-মেইল ঠিকানা না দিয়ে থাকেন, তাহলে অনুগ্রহ করে প্রশাসকের সাথে যোগাযোগ করুন।"
|
ifNoEmail: "আপনি যদি নিবন্ধনের সময় ই-মেইল ঠিকানা না দিয়ে থাকেন, তাহলে অনুগ্রহ করে প্রশাসকের সাথে যোগাযোগ করুন।"
|
||||||
@ -906,7 +885,6 @@ _plugin:
|
|||||||
install: "প্লাগইন ইন্সটল করুন"
|
install: "প্লাগইন ইন্সটল করুন"
|
||||||
installWarn: "অবিশ্বস্ত প্লাগইন ইনস্টল করবেন না।"
|
installWarn: "অবিশ্বস্ত প্লাগইন ইনস্টল করবেন না।"
|
||||||
manage: "প্লাগইন ম্যানেজ করুন"
|
manage: "প্লাগইন ম্যানেজ করুন"
|
||||||
viewSource: "উৎস দেখুন"
|
|
||||||
_registry:
|
_registry:
|
||||||
scope: "স্কোপ"
|
scope: "স্কোপ"
|
||||||
key: "কী"
|
key: "কী"
|
||||||
@ -922,6 +900,74 @@ _aboutMisskey:
|
|||||||
donate: "Misskey তে দান করুন"
|
donate: "Misskey তে দান করুন"
|
||||||
morePatrons: "আরও অনেকে আমাদের সাহায্য করছেন। তাদের সবাইকে ধন্যবাদ 🥰"
|
morePatrons: "আরও অনেকে আমাদের সাহায্য করছেন। তাদের সবাইকে ধন্যবাদ 🥰"
|
||||||
patrons: "সমর্থনকারী"
|
patrons: "সমর্থনকারী"
|
||||||
|
_nsfw:
|
||||||
|
respect: "স্পর্শকাতর মিডিয়া লুকান"
|
||||||
|
ignore: "স্পর্শকাতর মিডিয়া লুকাবেন না"
|
||||||
|
force: "সকল মিডিয়া লুকান"
|
||||||
|
_mfm:
|
||||||
|
cheatSheet: "MFM চিটশিট"
|
||||||
|
intro: "MFM একটি মার্কআপ ভাষা যা Misskey-এর মধ্যে বিভিন্ন জায়গায় ব্যবহার করা যেতে পারে। এখানে আপনি MFM-এর সিনট্যাক্সগুলির একটি তালিকা দেখতে পারবেন।"
|
||||||
|
dummy: "মিসকি ফেডিভার্সের বিশ্বকে প্রসারিত করে"
|
||||||
|
mention: "উল্লেখ"
|
||||||
|
mentionDescription: "@ চিহ্ন + ব্যবহারকারীর নাম একটি নির্দিষ্ট ব্যবহারকারীকে নির্দেশ করতে ব্যবহার করা যায়।"
|
||||||
|
hashtag: "হ্যাশট্যাগ"
|
||||||
|
hashtagDescription: "আপনি একটি # চিহ্ন + ট্যাগ সহ একটি হ্যাশট্যাগ নির্দেশ করতে পারেন।"
|
||||||
|
url: "URL"
|
||||||
|
urlDescription: "URL দেখানো সম্ভব।"
|
||||||
|
link: "লিংক"
|
||||||
|
linkDescription: "আপনি পাঠ্যের একটি নির্দিষ্ট অংশকে URL হিসাবে দেখাতে পারেন৷"
|
||||||
|
bold: "গাঢ়"
|
||||||
|
boldDescription: "অক্ষরগুলিকে মোটাকরে প্রদর্শন করা হবে।"
|
||||||
|
small: "ছোট"
|
||||||
|
smallDescription: "লেখা ছোট এবং পাতলা করে দেখানো হবে।"
|
||||||
|
center: "সেন্টার"
|
||||||
|
centerDescription: "লেখা মাঝ বরাবর দেখানো হবে"
|
||||||
|
inlineCode: "কোড (ইনলাইন)"
|
||||||
|
inlineCodeDescription: " প্রোগ্রামের কোডের জন্য ইনলাইন সিনট্যাক্স হাইলাইটিং করা হবে"
|
||||||
|
blockCode: "কোড (ব্লক)"
|
||||||
|
blockCodeDescription: "মাল্টি-লাইন প্রোগ্রামের কোডের জন্য সিনট্যাক্স হাইলাইট করে।"
|
||||||
|
inlineMath: "গাণিতিক সূত্র (ইনলাইন)"
|
||||||
|
inlineMathDescription: "গাণিতিক সূত্র প্রদর্শন করুন (KaTeX) ইনলাইন।"
|
||||||
|
blockMath: "গাণিতিক সূত্র (ব্লক)"
|
||||||
|
blockMathDescription: "একটি ব্লকে একাধিক লাইনের গাণিতিক সূত্র প্রদর্শন করুন (KaTeX)।"
|
||||||
|
quote: "উদ্ধৃতি"
|
||||||
|
quoteDescription: "বিষয়বস্তুকে একটি উদ্ধৃতি হিসাবে দেখানো হবে।"
|
||||||
|
emoji: "স্বনির্ধারিত ইমোজিগুলি"
|
||||||
|
emojiDescription: "আপনি একটি কাস্টম ইমোজির নাম কোলনে আবদ্ধ করে কাস্টম ইমোজিটি দেখাতে পারেন৷"
|
||||||
|
search: "খুঁজুন"
|
||||||
|
searchDescription: "পূর্ব-টাইপ করা পাঠ্য সহ একটি অনুসন্ধান বাক্স প্রদর্শন করে।"
|
||||||
|
flip: "উল্টান"
|
||||||
|
flipDescription: "বিষয়বস্তু উপরে/নীচে বা বাম/ডানে উল্টান।"
|
||||||
|
jelly: "অ্যানিমেশন (জেলি)"
|
||||||
|
jellyDescription: "জেলির মত অ্যানিমেশন দেখায়।"
|
||||||
|
tada: "অ্যানিমেশন (টাডা)"
|
||||||
|
tadaDescription: "\"টাডা!\" এর মত অ্যানিমেশন দেখায়।"
|
||||||
|
jump: "অ্যানিমেশন (লাফ)"
|
||||||
|
jumpDescription: "বিষয়বস্তুতে লাফ মারার মত অ্যানিমেশন দেখায়।"
|
||||||
|
bounce: "অ্যানিমেশন (তিড়িং বিড়িং)"
|
||||||
|
bounceDescription: "তিড়িং বিড়িং করার মত অ্যানিমেশন দেখায়।"
|
||||||
|
shake: "অ্যানিমেশন (ঝাঁকি)"
|
||||||
|
shakeDescription: "ঝাঁকির মত অ্যানিমেশন দেখায়।"
|
||||||
|
twitch: "অ্যানিমেশন (মোচড়ানো)"
|
||||||
|
twitchDescription: "মোচড়ানোর মত অ্যানিমেশন দেখায়।"
|
||||||
|
spin: "অ্যানিমেশন (ঘুরা)"
|
||||||
|
spinDescription: "ঘুরার মত অ্যানিমেশন দেখায়।"
|
||||||
|
x2: "বড়"
|
||||||
|
x2Description: "বিষয়বস্তু বড় করে দেখায়।"
|
||||||
|
x3: "অনেক বড়"
|
||||||
|
x3Description: "বিষয়বস্তু আরও বড় করে দেখায়।"
|
||||||
|
x4: "অস্বাভাবিক বড়"
|
||||||
|
x4Description: "বিষয়বস্তুকে আগের থেকেও আরও বড় করে দেখায়।"
|
||||||
|
blur: "ব্লার"
|
||||||
|
blurDescription: "বিষয়বস্তুকে ব্লার করতে পারেন। আপনি এর উপর মাউস কার্সার রাখলে, এটি পরিষ্কারভাবে দেখতে পাবেন।"
|
||||||
|
font: "ফন্ট"
|
||||||
|
fontDescription: "বিষয়বস্তুকে কোন ফন্টে দেখানো হবে তা নির্ধারণ করে।"
|
||||||
|
rainbow: "রেইনবো"
|
||||||
|
rainbowDescription: "বিষয়বস্তুকে রংধনুর রং গুলিতে প্রদর্শন করে।"
|
||||||
|
sparkle: "চিক চিক"
|
||||||
|
sparkleDescription: "বিষয়বস্তুকে একটি চিকচিকে কণা প্রভাব দেয়।"
|
||||||
|
rotate: "ঘুরান"
|
||||||
|
rotateDescription: "বিষয়বস্তুকে একটি নির্দিষ্ট কোনে ঘুরায়।"
|
||||||
_instanceTicker:
|
_instanceTicker:
|
||||||
none: "দেখাবেন না"
|
none: "দেখাবেন না"
|
||||||
remote: "রিমোট ব্যাবহারকারীদের জন্য দেখান"
|
remote: "রিমোট ব্যাবহারকারীদের জন্য দেখান"
|
||||||
@ -949,6 +995,11 @@ _wordMute:
|
|||||||
muteWords: "নিঃশব্দ করা শব্দগুলি"
|
muteWords: "নিঃশব্দ করা শব্দগুলি"
|
||||||
muteWordsDescription: "স্পেস দিয়ে আলাদা করলে AND শর্ত তৈরি হবে এবং আলাদা লাইনে লিখলে OR শর্ত তৈরি হবে।"
|
muteWordsDescription: "স্পেস দিয়ে আলাদা করলে AND শর্ত তৈরি হবে এবং আলাদা লাইনে লিখলে OR শর্ত তৈরি হবে।"
|
||||||
muteWordsDescription2: "রেগুলার এক্সপ্রেশন ব্যবহার করতে স্ল্যাশ দিয়ে কীওয়ার্ডকে ঘিরে রাখুন।"
|
muteWordsDescription2: "রেগুলার এক্সপ্রেশন ব্যবহার করতে স্ল্যাশ দিয়ে কীওয়ার্ডকে ঘিরে রাখুন।"
|
||||||
|
softDescription: "টাইমলাইন থেকে নির্দিষ্ট শর্তানুযায়ী নোট লুকিয়ে রাখে।"
|
||||||
|
hardDescription: "নির্দিষ্ট শর্তানুযায়ী নোটগুলিকে টাইমলাইন থেকে বাদ দেয়। আপনি শর্ত পরিবর্তন করলেও যে নোটগুলি যোগ করা হয়নি সেগুলি বাদ দেওয়া হবে।"
|
||||||
|
soft: "নমনীয়"
|
||||||
|
hard: "কঠোর"
|
||||||
|
mutedNotes: "মিউট করা নোটগুলি"
|
||||||
_instanceMute:
|
_instanceMute:
|
||||||
instanceMuteDescription: "কনফিগার করা ইন্সট্যান্সের সব নোট এবং রিনোট মিউট করুন, মিউট করা ইন্সট্যান্সের ব্যবহারকারীদের উত্তর সহ।"
|
instanceMuteDescription: "কনফিগার করা ইন্সট্যান্সের সব নোট এবং রিনোট মিউট করুন, মিউট করা ইন্সট্যান্সের ব্যবহারকারীদের উত্তর সহ।"
|
||||||
instanceMuteDescription2: "প্রতিটিকে আলাদা লাইনে লিখুন"
|
instanceMuteDescription2: "প্রতিটিকে আলাদা লাইনে লিখুন"
|
||||||
@ -1012,6 +1063,9 @@ _theme:
|
|||||||
infoFg: "তথ্যের পাঠ্য"
|
infoFg: "তথ্যের পাঠ্য"
|
||||||
infoWarnBg: "ওয়ার্নিং এর পটভূমি"
|
infoWarnBg: "ওয়ার্নিং এর পটভূমি"
|
||||||
infoWarnFg: "ওয়ার্নিং এর পাঠ্য"
|
infoWarnFg: "ওয়ার্নিং এর পাঠ্য"
|
||||||
|
cwBg: "CW বাটনের পটভূমি"
|
||||||
|
cwFg: "CW বাটনের পাঠ্য"
|
||||||
|
cwHoverBg: "CW বাটনের পটভূমি (হভার)"
|
||||||
toastBg: "বিজ্ঞপ্তির পটভূমি"
|
toastBg: "বিজ্ঞপ্তির পটভূমি"
|
||||||
toastFg: "বিজ্ঞপ্তির পাঠ্য"
|
toastFg: "বিজ্ঞপ্তির পাঠ্য"
|
||||||
buttonBg: "বাটনের পটভূমি"
|
buttonBg: "বাটনের পটভূমি"
|
||||||
@ -1029,6 +1083,10 @@ _sfx:
|
|||||||
note: "নোটগুলি"
|
note: "নোটগুলি"
|
||||||
noteMy: "নোট (আপনার)"
|
noteMy: "নোট (আপনার)"
|
||||||
notification: "বিজ্ঞপ্তি"
|
notification: "বিজ্ঞপ্তি"
|
||||||
|
chat: "চ্যাট"
|
||||||
|
chatBg: "চ্যাট (ব্যাকগ্রাউন্ড)"
|
||||||
|
antenna: "অ্যান্টেনাগুলি"
|
||||||
|
channel: "চ্যানেলের বিজ্ঞপ্তি"
|
||||||
_ago:
|
_ago:
|
||||||
future: "ভবিষ্যৎ"
|
future: "ভবিষ্যৎ"
|
||||||
justNow: "এইমাত্র"
|
justNow: "এইমাত্র"
|
||||||
@ -1039,20 +1097,44 @@ _ago:
|
|||||||
weeksAgo: "{n} সপ্তাহ আগে"
|
weeksAgo: "{n} সপ্তাহ আগে"
|
||||||
monthsAgo: "{n} মাস আগে"
|
monthsAgo: "{n} মাস আগে"
|
||||||
yearsAgo: "{n} বছর আগে"
|
yearsAgo: "{n} বছর আগে"
|
||||||
invalid: "এখানে কিছুই নাই"
|
|
||||||
_time:
|
_time:
|
||||||
second: "সেকেন্ড"
|
second: "সেকেন্ড"
|
||||||
minute: "মিনিট"
|
minute: "মিনিট"
|
||||||
hour: "ঘণ্টা"
|
hour: "ঘণ্টা"
|
||||||
day: "দিন"
|
day: "দিন"
|
||||||
|
_tutorial:
|
||||||
|
title: "Misskey কিভাবে ব্যাবহার করবেন"
|
||||||
|
step1_1: "স্বাগতম!"
|
||||||
|
step1_2: "এই স্ক্রীনটিকে \"টাইমলাইন\" বলা হয় এবং কালানুক্রমিক ক্রমে আপনার এবং আপনি যাদের \"অনুসরণ করেন\" তাদের \"নোটগুলি\" দেখায়৷"
|
||||||
|
step1_3: "আপনি আপনার টাইমলাইনে কিছু দেখতে পাবেন না কারণ আপনি এখনও কোনো নোট পোস্ট করেননি এবং আপনি কাউকে অনুসরণ করছেন না৷"
|
||||||
|
step2_1: "নোট তৈরি করার আগে বা কাউকে অনুসরণ করার আগে প্রথমে আপনার প্রোফাইলটি সম্পূর্ণ করুন।"
|
||||||
|
step2_2: "আপনি কে তা জানা অনেক লোকের জন্য আপনার নোটগুলি দেখা এবং অনুসরণ করাকে সহজ করে তোলে৷"
|
||||||
|
step3_1: "আপনি কি সফলভাবে আপনার প্রোফাইল সেট আপ করেছেন?"
|
||||||
|
step3_2: "এখন, কিছু নোট পোস্ট করার চেষ্টা করুন। পোস্ট ফর্ম খুলতে পেন্সিল চিহ্নযুক্ত বাটনে ক্লিক করুন।"
|
||||||
|
step3_3: "বিষয়বস্তু লেখার পরে, আপনি ফর্মের উপরের ডানদিকের বাটনে ক্লিক করে পোস্ট করতে পারেন।"
|
||||||
|
step3_4: "পোস্ট করার মত কিছু মনে পরছে না? \"আমি মিসকি সেট আপ করছি\" বললে কেমন হয়?"
|
||||||
|
step4_1: "পোস্ট করেছেন?"
|
||||||
|
step4_2: "সাবাশ! এখন আপনার নোট টাইমলাইনে দেখা যাবে।"
|
||||||
|
step5_1: "এখন অন্যদেরকে অনুসরণ করে আপনার টাইমলাইনকে প্রাণবন্ত করে তুলুন।"
|
||||||
|
step5_2: "আপনি {featured}-এ জনপ্রিয় নোটগুলি দেখতে পারেন, যাতে আপনি যে ব্যক্তিকে পছন্দ করেন তাকে বেছে নিতে এবং অনুসরণ করতে পারেন, অথবা {explore}-এ জনপ্রিয় ব্যবহারকারীদের দেখতে পারেন৷"
|
||||||
|
step5_3: "একজন ব্যবহারকারীকে অনুসরণ করতে, ব্যবহারকারীর আইকনে ক্লিক করুন এবং ব্যবহারকারীর পৃষ্ঠাতে \"অনুসরণ করুন\" বাটনে ক্লিক করুন।"
|
||||||
|
step5_4: "যদি ব্যবহারকারীর নামের পাশে একটি লক আইকন থাকে তাহলে আপনার অনুসরণের অনুরোধ গ্রহণ করার জন্য তারা কিছু সময় নিতে পারে।"
|
||||||
|
step6_1: "সবকিছু ঠিক থাকলে আপনি টাইমলাইনে অন্য ব্যবহারকারীদের নোট দেখতে পাবেন।"
|
||||||
|
step6_2: "আপনি সহজেই আপনার প্রতিক্রিয়া জানাতে অন্য ব্যক্তির নোটে \"রিঅ্যাকশন\" যোগ করতে পারেন।"
|
||||||
|
step6_3: "একটি রিঅ্যাকশন যোগ করতে, নোটে \"+\" চিহ্নে ক্লিক করুন এবং আপনার পছন্দের রিঅ্যাকশন নির্বাচন করুন।"
|
||||||
|
step7_1: "অভিনন্দন! আপনি এখন Misskey-র প্রাথমিক টিউটোরিয়ালটি শেষ করেছেন।"
|
||||||
|
step7_2: "আপনি যদি Misskey সম্পর্কে আরও জানতে চান, তাহলে {help} এ দেখুন।"
|
||||||
|
step7_3: "এখন Misskey উপভোগ করুন 🚀"
|
||||||
_2fa:
|
_2fa:
|
||||||
alreadyRegistered: "আপনি ইতিমধ্যে একটি 2-ফ্যাক্টর অথেনটিকেশন ডিভাইস নিবন্ধন করেছেন৷"
|
alreadyRegistered: "আপনি ইতিমধ্যে একটি 2-ফ্যাক্টর অথেনটিকেশন ডিভাইস নিবন্ধন করেছেন৷"
|
||||||
|
registerDevice: "নতুন ডিভাইস নিবন্ধন করুন"
|
||||||
|
registerKey: "সিকিউরিটি কী নিবন্ধন করুন"
|
||||||
step1: "প্রথমে, আপনার ডিভাইসে {a} বা {b} এর মতো একটি অথেনটিকেশন অ্যাপ ইনস্টল করুন৷"
|
step1: "প্রথমে, আপনার ডিভাইসে {a} বা {b} এর মতো একটি অথেনটিকেশন অ্যাপ ইনস্টল করুন৷"
|
||||||
step2: "এরপরে, অ্যাপের সাহায্যে প্রদর্শিত QR কোডটি স্ক্যান করুন।"
|
step2: "এরপরে, অ্যাপের সাহায্যে প্রদর্শিত QR কোডটি স্ক্যান করুন।"
|
||||||
|
step2Url: "ডেস্কটপ অ্যাপে, নিম্নলিখিত URL লিখুন:"
|
||||||
step3: "অ্যাপে প্রদর্শিত টোকেনটি লিখুন এবং আপনার কাজ শেষ।"
|
step3: "অ্যাপে প্রদর্শিত টোকেনটি লিখুন এবং আপনার কাজ শেষ।"
|
||||||
step4: "আপনাকে এখন থেকে লগ ইন করার সময়, এইভাবে টোকেন লিখতে হবে।"
|
step4: "আপনাকে এখন থেকে লগ ইন করার সময়, এইভাবে টোকেন লিখতে হবে।"
|
||||||
securityKeyInfo: "আপনি একটি হার্ডওয়্যার সিকিউরিটি কী ব্যবহার করে লগ ইন করতে পারেন যা FIDO2 বা ডিভাইসের ফিঙ্গারপ্রিন্ট সেন্সর বা পিন সমর্থন করে৷"
|
securityKeyInfo: "আপনি একটি হার্ডওয়্যার সিকিউরিটি কী ব্যবহার করে লগ ইন করতে পারেন যা FIDO2 বা ডিভাইসের ফিঙ্গারপ্রিন্ট সেন্সর বা পিন সমর্থন করে৷"
|
||||||
renewTOTPCancel: "না, ধন্যবাদ"
|
|
||||||
_permissions:
|
_permissions:
|
||||||
"read:account": "অ্যাকাউন্টের তথ্য দেখুন"
|
"read:account": "অ্যাকাউন্টের তথ্য দেখুন"
|
||||||
"write:account": "অ্যাকাউন্টের তথ্য সম্পাদন করুন"
|
"write:account": "অ্যাকাউন্টের তথ্য সম্পাদন করুন"
|
||||||
@ -1098,6 +1180,7 @@ _antennaSources:
|
|||||||
homeTimeline: "আপনি অনুসরণ করছেন, এমন ব্যবহারকারীদের নোট"
|
homeTimeline: "আপনি অনুসরণ করছেন, এমন ব্যবহারকারীদের নোট"
|
||||||
users: "এক বা একাধিক নির্দিষ্ট ব্যবহারকারীর নোট"
|
users: "এক বা একাধিক নির্দিষ্ট ব্যবহারকারীর নোট"
|
||||||
userList: "নির্দিষ্ট তালিকায় নাম থাকা ব্যবহারকারীদের নোট"
|
userList: "নির্দিষ্ট তালিকায় নাম থাকা ব্যবহারকারীদের নোট"
|
||||||
|
userGroup: "নির্দিষ্ট গ্রুপে থাকা ব্যবহারকারীদের নোট"
|
||||||
_weekday:
|
_weekday:
|
||||||
sunday: "রবিবার"
|
sunday: "রবিবার"
|
||||||
monday: "সোমবার"
|
monday: "সোমবার"
|
||||||
@ -1107,8 +1190,6 @@ _weekday:
|
|||||||
friday: "শুক্রবার"
|
friday: "শুক্রবার"
|
||||||
saturday: "শনিবার"
|
saturday: "শনিবার"
|
||||||
_widgets:
|
_widgets:
|
||||||
profile: "প্রোফাইল"
|
|
||||||
instanceInfo: "ইন্সট্যান্সের তথ্য"
|
|
||||||
memo: "স্টিকি নোট"
|
memo: "স্টিকি নোট"
|
||||||
notifications: "বিজ্ঞপ্তি"
|
notifications: "বিজ্ঞপ্তি"
|
||||||
timeline: "টাইমলাইন"
|
timeline: "টাইমলাইন"
|
||||||
@ -1128,8 +1209,6 @@ _widgets:
|
|||||||
serverMetric: "সার্ভার মেট্রিক্স"
|
serverMetric: "সার্ভার মেট্রিক্স"
|
||||||
aiscript: "AiScript কনসোল"
|
aiscript: "AiScript কনসোল"
|
||||||
aichan: "আই চান"
|
aichan: "আই চান"
|
||||||
_userList:
|
|
||||||
chooseList: "লিস্ট নির্বাচন করুন"
|
|
||||||
_cw:
|
_cw:
|
||||||
hide: "লুকান"
|
hide: "লুকান"
|
||||||
show: "আরও দেখুন"
|
show: "আরও দেখুন"
|
||||||
@ -1166,6 +1245,8 @@ _visibility:
|
|||||||
followersDescription: "শুধুমাত্র আপনার অনুসরণকারীদের নিকট পোস্ট করুন"
|
followersDescription: "শুধুমাত্র আপনার অনুসরণকারীদের নিকট পোস্ট করুন"
|
||||||
specified: "ডাইরেক্ট নোট"
|
specified: "ডাইরেক্ট নোট"
|
||||||
specifiedDescription: "শুধুমাত্র নির্দিষ্ট ব্যাবহারকারীর নিকট পাঠান"
|
specifiedDescription: "শুধুমাত্র নির্দিষ্ট ব্যাবহারকারীর নিকট পাঠান"
|
||||||
|
localOnly: "শুধুমাত্র লোকাল"
|
||||||
|
localOnlyDescription: "রিমোট ব্যাবহারকারীদের নিকট দৃশ্যমান নয়"
|
||||||
_postForm:
|
_postForm:
|
||||||
replyPlaceholder: "নোটটির জবাব দিন..."
|
replyPlaceholder: "নোটটির জবাব দিন..."
|
||||||
quotePlaceholder: "নোটটিকে উদ্ধৃত করুন..."
|
quotePlaceholder: "নোটটিকে উদ্ধৃত করুন..."
|
||||||
@ -1191,7 +1272,6 @@ _profile:
|
|||||||
changeBanner: "ব্যানার পরিবর্তন করুন"
|
changeBanner: "ব্যানার পরিবর্তন করুন"
|
||||||
_exportOrImport:
|
_exportOrImport:
|
||||||
allNotes: "সকল নোট"
|
allNotes: "সকল নোট"
|
||||||
clips: "ক্লিপ"
|
|
||||||
followingList: "অনুসরণ করা হচ্ছে"
|
followingList: "অনুসরণ করা হচ্ছে"
|
||||||
muteList: "মিউট"
|
muteList: "মিউট"
|
||||||
blockingList: "ব্লক"
|
blockingList: "ব্লক"
|
||||||
@ -1229,12 +1309,6 @@ _timelines:
|
|||||||
local: "স্থানীয়"
|
local: "স্থানীয়"
|
||||||
social: "সামাজিক"
|
social: "সামাজিক"
|
||||||
global: "গ্লোবাল"
|
global: "গ্লোবাল"
|
||||||
_play:
|
|
||||||
viewSource: "উৎস দেখুন"
|
|
||||||
featured: "জনপ্রিয়"
|
|
||||||
title: "শিরোনাম"
|
|
||||||
script: "স্ক্রিপ্ট"
|
|
||||||
summary: "বর্ণনা"
|
|
||||||
_pages:
|
_pages:
|
||||||
newPage: "নতুন পৃষ্ঠা বানান"
|
newPage: "নতুন পৃষ্ঠা বানান"
|
||||||
editPage: "পৃষ্ঠাটি সম্পাদনা করুন"
|
editPage: "পৃষ্ঠাটি সম্পাদনা করুন"
|
||||||
@ -1270,6 +1344,8 @@ _pages:
|
|||||||
eyeCatchingImageRemove: "থাম্বনেইল সরান"
|
eyeCatchingImageRemove: "থাম্বনেইল সরান"
|
||||||
chooseBlock: "ব্লক যোগ করুন"
|
chooseBlock: "ব্লক যোগ করুন"
|
||||||
selectType: "ধরন নির্বাচন করুন"
|
selectType: "ধরন নির্বাচন করুন"
|
||||||
|
enterVariableName: "চলকের নাম লিখুন"
|
||||||
|
variableNameIsAlreadyUsed: "চলকের নামটি ইতিপূর্বে ব্যাবহৃত হয়েছে"
|
||||||
contentBlocks: "বিষয়বস্তু"
|
contentBlocks: "বিষয়বস্তু"
|
||||||
inputBlocks: "ইনপুট"
|
inputBlocks: "ইনপুট"
|
||||||
specialBlocks: "বিশেষ"
|
specialBlocks: "বিশেষ"
|
||||||
@ -1279,11 +1355,249 @@ _pages:
|
|||||||
section: "বিভাগ"
|
section: "বিভাগ"
|
||||||
image: "ছবি"
|
image: "ছবি"
|
||||||
button: "বাটন"
|
button: "বাটন"
|
||||||
|
if: "যদি"
|
||||||
|
_if:
|
||||||
|
variable: "চলকগুলি"
|
||||||
|
post: "নোট লিখুন"
|
||||||
|
_post:
|
||||||
|
text: "বিষয়বস্তু"
|
||||||
|
attachCanvasImage: "ক্যানভাস ছবিসহ পোস্ট করুন"
|
||||||
|
canvasId: "ক্যানভাস ID"
|
||||||
|
textInput: "টেক্সট ইনপুট"
|
||||||
|
_textInput:
|
||||||
|
name: "চলকের নাম"
|
||||||
|
text: "শিরোনাম"
|
||||||
|
default: "ডিফল্ট মান"
|
||||||
|
textareaInput: "একাধিক লাইনের টেক্সট ইনপুট"
|
||||||
|
_textareaInput:
|
||||||
|
name: "চলকের নাম"
|
||||||
|
text: "শিরোনাম"
|
||||||
|
default: "ডিফল্ট মান"
|
||||||
|
numberInput: "সংখ্যা ইনপুট"
|
||||||
|
_numberInput:
|
||||||
|
name: "চলকের নাম"
|
||||||
|
text: "শিরোনাম"
|
||||||
|
default: "ডিফল্ট মান"
|
||||||
|
canvas: "ক্যানভাস"
|
||||||
|
_canvas:
|
||||||
|
id: "ক্যানভাস ID"
|
||||||
|
width: "প্রস্থ"
|
||||||
|
height: "উচ্চতা"
|
||||||
note: "এম্বেড নোট"
|
note: "এম্বেড নোট"
|
||||||
_note:
|
_note:
|
||||||
id: "নোট ID"
|
id: "নোট ID"
|
||||||
idDescription: "আপনি এর বদলে নোটের URL পেস্ট করতে পারেন."
|
idDescription: "আপনি এর বদলে নোটের URL পেস্ট করতে পারেন."
|
||||||
detailed: "বিস্তারিত দেখুন"
|
detailed: "বিস্তারিত দেখুন"
|
||||||
|
switch: "সুইচ"
|
||||||
|
_switch:
|
||||||
|
name: "চলকের নাম"
|
||||||
|
text: "শিরোনাম"
|
||||||
|
default: "ডিফল্ট মান"
|
||||||
|
counter: "কাউন্টার"
|
||||||
|
_counter:
|
||||||
|
name: "চলকের নাম"
|
||||||
|
text: "শিরোনাম"
|
||||||
|
inc: "এভাবে মান বাড়ান"
|
||||||
|
_button:
|
||||||
|
text: "শিরোনাম"
|
||||||
|
colored: "রঙ্গিন"
|
||||||
|
action: "বাটনে ক্লিক করলে যা হবে"
|
||||||
|
_action:
|
||||||
|
dialog: "ডায়ালগ দেখান "
|
||||||
|
_dialog:
|
||||||
|
content: "বিষয়বস্তু"
|
||||||
|
resetRandom: "র্যানডম সিড রিসেট করুন"
|
||||||
|
pushEvent: "ইভেন্ট পাঠান"
|
||||||
|
_pushEvent:
|
||||||
|
event: "ইভেন্টের নাম"
|
||||||
|
message: "চালু হলে প্রদর্শনের জন্য বার্তা"
|
||||||
|
variable: "পাঠানো চলক"
|
||||||
|
no-variable: "কিছুই না"
|
||||||
|
callAiScript: "AiScript চালান"
|
||||||
|
_callAiScript:
|
||||||
|
functionName: "ফাংশনের নাম"
|
||||||
|
radioButton: "বহুনির্বাচনী"
|
||||||
|
_radioButton:
|
||||||
|
name: "চলকের নাম"
|
||||||
|
title: "শিরোনাম"
|
||||||
|
values: "বিকল্পগুলিকে আলাদা লাইনে লিখুন"
|
||||||
|
default: "ডিফল্ট মান"
|
||||||
|
script:
|
||||||
|
categories:
|
||||||
|
flow: "নিয়ন্ত্রণ"
|
||||||
|
logical: "লজিক্যাল অপারেশন"
|
||||||
|
operation: "হিসাব-নিকাশ"
|
||||||
|
comparison: "তুলনা"
|
||||||
|
random: "র্যান্ডম"
|
||||||
|
value: "মান"
|
||||||
|
fn: "ফাংশন"
|
||||||
|
text: "টেক্সট ম্যানিপুলেশন"
|
||||||
|
convert: "রুপান্তর"
|
||||||
|
list: "লিস্ট"
|
||||||
|
blocks:
|
||||||
|
text: "লেখা"
|
||||||
|
multiLineText: "লেখা (একাধিক লাইন)"
|
||||||
|
textList: "লেখার লিস্ট"
|
||||||
|
_textList:
|
||||||
|
info: "প্রতিটি এন্ট্রিকে আলাদা লাইনে লিখুন"
|
||||||
|
strLen: "লেখার দৈর্ঘ্য"
|
||||||
|
_strLen:
|
||||||
|
arg1: "লেখা"
|
||||||
|
strPick: "অক্ষর বের করে আনুন"
|
||||||
|
_strPick:
|
||||||
|
arg1: "লেখা"
|
||||||
|
arg2: "অক্ষরের অবস্থান"
|
||||||
|
strReplace: "লেখা প্রতিস্থাপন"
|
||||||
|
_strReplace:
|
||||||
|
arg1: "লেখা"
|
||||||
|
arg2: "যে লেখা প্রতিস্থাপন করা হবে"
|
||||||
|
arg3: "যা দ্বারা প্রতিস্থাপন করা হবে"
|
||||||
|
strReverse: "লেখা উল্টান"
|
||||||
|
_strReverse:
|
||||||
|
arg1: "লেখা"
|
||||||
|
join: "লেখা যুক্ত করুন"
|
||||||
|
_join:
|
||||||
|
arg1: "লিস্ট"
|
||||||
|
arg2: "বিভাজক"
|
||||||
|
add: "যোগ"
|
||||||
|
_add:
|
||||||
|
arg1: "A"
|
||||||
|
arg2: "B"
|
||||||
|
subtract: "বিয়োগ"
|
||||||
|
_subtract:
|
||||||
|
arg1: "A"
|
||||||
|
arg2: "B"
|
||||||
|
multiply: "গুন"
|
||||||
|
_multiply:
|
||||||
|
arg1: "A"
|
||||||
|
arg2: "B"
|
||||||
|
divide: "ভাগ"
|
||||||
|
_divide:
|
||||||
|
arg1: "A"
|
||||||
|
arg2: "B"
|
||||||
|
mod: "ভাগশেষ"
|
||||||
|
_mod:
|
||||||
|
arg1: "A"
|
||||||
|
arg2: "B"
|
||||||
|
round: "দশমিক রাউন্ড করুন"
|
||||||
|
_round:
|
||||||
|
arg1: "সংখ্যা"
|
||||||
|
eq: "A ও B সমান"
|
||||||
|
_eq:
|
||||||
|
arg1: "A"
|
||||||
|
arg2: "B"
|
||||||
|
notEq: "A ও B সমান না"
|
||||||
|
_notEq:
|
||||||
|
arg1: "A"
|
||||||
|
arg2: "B"
|
||||||
|
and: "A এবং B"
|
||||||
|
_and:
|
||||||
|
arg1: "A"
|
||||||
|
arg2: "B"
|
||||||
|
or: "A অথবা B"
|
||||||
|
_or:
|
||||||
|
arg1: "A"
|
||||||
|
arg2: "B"
|
||||||
|
lt: "< A , B হতে কম"
|
||||||
|
_lt:
|
||||||
|
arg1: "A"
|
||||||
|
arg2: "B"
|
||||||
|
gt: "> A , B হতে বেশী"
|
||||||
|
_gt:
|
||||||
|
arg1: "A"
|
||||||
|
arg2: "B"
|
||||||
|
ltEq: "<= A , B হতে কম বা সমান"
|
||||||
|
_ltEq:
|
||||||
|
arg1: "A"
|
||||||
|
arg2: "B"
|
||||||
|
gtEq: ">= A , B হতে বেশী বা সমান"
|
||||||
|
_gtEq:
|
||||||
|
arg1: "A"
|
||||||
|
arg2: "B"
|
||||||
|
if: "যদি"
|
||||||
|
_if:
|
||||||
|
arg1: "যদি"
|
||||||
|
arg2: "তাহলে"
|
||||||
|
arg3: "তাছাড়া"
|
||||||
|
not: "না"
|
||||||
|
_not:
|
||||||
|
arg1: "না"
|
||||||
|
random: "র্যান্ডম"
|
||||||
|
_random:
|
||||||
|
arg1: "সম্ভাব্যতা"
|
||||||
|
rannum: "র্যানডম সংখ্যা"
|
||||||
|
_rannum:
|
||||||
|
arg1: "ন্যূনতম মান"
|
||||||
|
arg2: "সর্বোচ্চ মান"
|
||||||
|
randomPick: "তালিকা থেকে দৈবচয়ন করুন"
|
||||||
|
_randomPick:
|
||||||
|
arg1: "লিস্ট"
|
||||||
|
dailyRandom: "র্যান্ডম সংখ্যা (প্রতিটি ব্যবহারকারীর জন্য প্রতিদিন পরিবর্তীত হয়)"
|
||||||
|
_dailyRandom:
|
||||||
|
arg1: "সম্ভাব্যতা"
|
||||||
|
dailyRannum: "র্যান্ডম সংখ্যা (প্রতিটি ব্যবহারকারীর জন্য প্রতিদিন পরিবর্তীত হয়)"
|
||||||
|
_dailyRannum:
|
||||||
|
arg1: "ন্যূনতম মান"
|
||||||
|
arg2: "সর্বোচ্চ মান"
|
||||||
|
dailyRandomPick: "তালিকা থেকে এলোমেলোভাবে নির্বাচন করুন (প্রতিটি ব্যবহারকারীর জন্য প্রতিদিন পরিবর্তীত হয়)"
|
||||||
|
_dailyRandomPick:
|
||||||
|
arg1: "লিস্ট"
|
||||||
|
seedRandom: "র্যানডম (সীড দ্বারা)"
|
||||||
|
_seedRandom:
|
||||||
|
arg1: "সীড"
|
||||||
|
arg2: "সম্ভাব্যতা"
|
||||||
|
seedRannum: "র্যানডম সংখ্যা (সীড দ্বারা)"
|
||||||
|
_seedRannum:
|
||||||
|
arg1: "সীড"
|
||||||
|
arg2: "ন্যূনতম মান"
|
||||||
|
arg3: "সর্বোচ্চ মান"
|
||||||
|
seedRandomPick: "তালিকা থেকে দৈবচয়ন করুন (সীড দ্বারা)"
|
||||||
|
_seedRandomPick:
|
||||||
|
arg1: "সীড"
|
||||||
|
arg2: "লিস্ট"
|
||||||
|
DRPWPM: "সম্ভাব্যতা সহ একটি তালিকা থেকে এলোমেলোভাবে নির্বাচন করুন (প্রতিটি ব্যবহারকারীর জন্য প্রতিদিন)"
|
||||||
|
_DRPWPM:
|
||||||
|
arg1: "লেখার লিস্ট"
|
||||||
|
pick: "তালিকা থেকে নির্বাচন করুন"
|
||||||
|
_pick:
|
||||||
|
arg1: "লিস্ট"
|
||||||
|
arg2: "অবস্থান"
|
||||||
|
listLen: "লিস্টের দৈর্ঘ্য পান"
|
||||||
|
_listLen:
|
||||||
|
arg1: "লিস্ট"
|
||||||
|
number: "সংখ্যা"
|
||||||
|
stringToNumber: "পাঠ্য থেকে সংখ্যা"
|
||||||
|
_stringToNumber:
|
||||||
|
arg1: "লেখা"
|
||||||
|
numberToString: "সংখ্যা থেকে পাঠ্য"
|
||||||
|
_numberToString:
|
||||||
|
arg1: "সংখ্যা"
|
||||||
|
splitStrByLine: "পাঠ্যকে লাইনে বিভক্ত করুন"
|
||||||
|
_splitStrByLine:
|
||||||
|
arg1: "লেখা"
|
||||||
|
ref: "চলক"
|
||||||
|
aiScriptVar: "AiScript চলক"
|
||||||
|
fn: "ফাংশন"
|
||||||
|
_fn:
|
||||||
|
slots: "স্লটগুলি"
|
||||||
|
slots-info: "প্রতিটি স্লটকে আলাদা লাইনে লিখুন"
|
||||||
|
arg1: "আউটপুট"
|
||||||
|
for: "for-লুপ"
|
||||||
|
_for:
|
||||||
|
arg1: "কতবার চলবে"
|
||||||
|
arg2: "অ্যাকশন"
|
||||||
|
typeError: "স্লট {slot}, {expect} ধরনের মান গ্রহণ করে, কিন্তু {actual} ধরনের মান দেওয়া হয়েছে!"
|
||||||
|
thereIsEmptySlot: "স্লট {slot} খালি!"
|
||||||
|
types:
|
||||||
|
string: "লেখা"
|
||||||
|
number: "সংখ্যা"
|
||||||
|
boolean: "ফ্ল্যাগ"
|
||||||
|
array: "লিস্ট"
|
||||||
|
stringArray: "লেখার লিস্ট"
|
||||||
|
emptySlot: "খালি স্লট"
|
||||||
|
enviromentVariables: "এনভাইরনমেন্ট ভ্যারিয়েবল"
|
||||||
|
pageVariables: "পেজের চলক"
|
||||||
|
argVariables: "ইনপুটের জায়গা"
|
||||||
_relayStatus:
|
_relayStatus:
|
||||||
requesting: "অপেক্ষমান"
|
requesting: "অপেক্ষমান"
|
||||||
accepted: "অনুমোদিত"
|
accepted: "অনুমোদিত"
|
||||||
@ -1294,9 +1608,13 @@ _notification:
|
|||||||
youGotReply: "{name} আপনাকে জবাব দিয়েছে"
|
youGotReply: "{name} আপনাকে জবাব দিয়েছে"
|
||||||
youGotQuote: "{name} আপনাকে উদ্ধৃত করেছে"
|
youGotQuote: "{name} আপনাকে উদ্ধৃত করেছে"
|
||||||
youRenoted: "{name} এর Renote"
|
youRenoted: "{name} এর Renote"
|
||||||
|
youGotPoll: "{name} আপনার পোলে ভোট দিয়েছে"
|
||||||
|
youGotMessagingMessageFromUser: "{name} আপনাকে মেসেজ করেছে"
|
||||||
|
youGotMessagingMessageFromGroup: "{name} গ্রুপে একটি নতুন মেসেজ আছে"
|
||||||
youWereFollowed: "আপনাকে অনুসরণ করছে"
|
youWereFollowed: "আপনাকে অনুসরণ করছে"
|
||||||
youReceivedFollowRequest: "অনুসরণ করার জন্য অনুরোধ পাওয়া গেছে"
|
youReceivedFollowRequest: "অনুসরণ করার জন্য অনুরোধ পাওয়া গেছে"
|
||||||
yourFollowRequestAccepted: "আপনার অনুসরণ করার অনুরোধ গৃহীত হয়েছে"
|
yourFollowRequestAccepted: "আপনার অনুসরণ করার অনুরোধ গৃহীত হয়েছে"
|
||||||
|
youWereInvitedToGroup: "আপনি একটি গ্রুপে আমন্ত্রিত হয়েছেন"
|
||||||
pollEnded: "পোলের ফলাফল দেখা যাবে"
|
pollEnded: "পোলের ফলাফল দেখা যাবে"
|
||||||
emptyPushNotificationMessage: "আপডেট করা পুশ বিজ্ঞপ্তি"
|
emptyPushNotificationMessage: "আপডেট করা পুশ বিজ্ঞপ্তি"
|
||||||
_types:
|
_types:
|
||||||
@ -1307,10 +1625,11 @@ _notification:
|
|||||||
renote: "রিনোট"
|
renote: "রিনোট"
|
||||||
quote: "উদ্ধৃতি"
|
quote: "উদ্ধৃতি"
|
||||||
reaction: "প্রতিক্রিয়া"
|
reaction: "প্রতিক্রিয়া"
|
||||||
|
pollVote: "পোলে ভোট আছে"
|
||||||
pollEnded: "পোল শেষ"
|
pollEnded: "পোল শেষ"
|
||||||
receiveFollowRequest: "প্রাপ্ত অনুসরণের অনুরোধসমূহ"
|
receiveFollowRequest: "প্রাপ্ত অনুসরণের অনুরোধসমূহ"
|
||||||
followRequestAccepted: "গৃহীত অনুসরণের অনুরোধসমূহ"
|
followRequestAccepted: "গৃহীত অনুসরণের অনুরোধসমূহ"
|
||||||
login: "প্রবেশ করুন"
|
groupInvited: "গ্রুপের আমন্ত্রনসমূহ"
|
||||||
app: "লিঙ্ক করা অ্যাপ থেকে বিজ্ঞপ্তি"
|
app: "লিঙ্ক করা অ্যাপ থেকে বিজ্ঞপ্তি"
|
||||||
_actions:
|
_actions:
|
||||||
followBack: "ফলো ব্যাক করেছে"
|
followBack: "ফলো ব্যাক করেছে"
|
||||||
@ -1319,8 +1638,9 @@ _notification:
|
|||||||
_deck:
|
_deck:
|
||||||
alwaysShowMainColumn: "সর্বদা মেইন কলাম দেখান"
|
alwaysShowMainColumn: "সর্বদা মেইন কলাম দেখান"
|
||||||
columnAlign: "কলাম সাজান"
|
columnAlign: "কলাম সাজান"
|
||||||
|
columnMargin: "কলামের মধ্যবর্তী মার্জিন"
|
||||||
|
columnHeaderHeight: "কলামের হেডারের উচ্চতা"
|
||||||
addColumn: "কলাম যুক্ত করুন"
|
addColumn: "কলাম যুক্ত করুন"
|
||||||
configureColumn: "কলাম সেটিংস"
|
|
||||||
swapLeft: "বামে সরান"
|
swapLeft: "বামে সরান"
|
||||||
swapRight: "ডানে সরান"
|
swapRight: "ডানে সরান"
|
||||||
swapUp: "উপরে উঠান"
|
swapUp: "উপরে উঠান"
|
||||||
@ -1335,18 +1655,5 @@ _deck:
|
|||||||
tl: "টাইমলাইন"
|
tl: "টাইমলাইন"
|
||||||
antenna: "অ্যান্টেনা"
|
antenna: "অ্যান্টেনা"
|
||||||
list: "লিস্ট"
|
list: "লিস্ট"
|
||||||
channel: "চ্যানেলগুলি"
|
|
||||||
mentions: "উল্লেখসমূহ"
|
mentions: "উল্লেখসমূহ"
|
||||||
direct: "ডাইরেক্ট নোটগুলি"
|
direct: "ডাইরেক্ট নোটগুলি"
|
||||||
_webhookSettings:
|
|
||||||
name: "নাম"
|
|
||||||
active: "চালু"
|
|
||||||
_abuseReport:
|
|
||||||
_notificationRecipient:
|
|
||||||
_recipientType:
|
|
||||||
mail: "ইমেইল"
|
|
||||||
_moderationLogTypes:
|
|
||||||
suspend: "স্থগিত করা"
|
|
||||||
resetPassword: "পাসওয়ার্ড রিসেট করুন"
|
|
||||||
_reversi:
|
|
||||||
total: "মোট"
|
|
||||||
|
2514
locales/ca-ES.yml
2514
locales/ca-ES.yml
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user