Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • tedomum/ttrss
  • mickge/ttrss
2 results
Show changes
Commits on Source (1582)
Showing with 636 additions and 46 deletions
ARG PROXY_REGISTRY
FROM ${PROXY_REGISTRY}alpine:3.20
EXPOSE 9000/tcp
ARG ALPINE_MIRROR
ENV SCRIPT_ROOT=/opt/tt-rss
ENV SRC_DIR=/src/tt-rss/
RUN [ ! -z ${ALPINE_MIRROR} ] && \
sed -i.bak "s#dl-cdn.alpinelinux.org#${ALPINE_MIRROR}#" /etc/apk/repositories ; \
apk add --no-cache dcron php83 php83-fpm php83-phar php83-sockets php83-pecl-apcu \
php83-pdo php83-gd php83-pgsql php83-pdo_pgsql php83-xmlwriter php83-opcache \
php83-mbstring php83-intl php83-xml php83-curl php83-simplexml \
php83-session php83-tokenizer php83-dom php83-fileinfo php83-ctype \
php83-json php83-iconv php83-pcntl php83-posix php83-zip php83-exif \
php83-openssl git postgresql-client sudo php83-pecl-xdebug rsync tzdata \
nginx envsubst && \
sed -i 's/\(memory_limit =\) 128M/\1 256M/' /etc/php83/php.ini && \
sed -i -e 's/^listen = 127.0.0.1:9000/listen = 9000/' \
-e 's/;\(clear_env\) = .*/\1 = no/i' \
-e 's/;\(pm.status_path = \/status\)/\1/i' \
-e 's/;\(pm.status_listen\) = .*/\1 = 9001/i' \
-e 's/^\(user\|group\) = .*/\1 = app/i' \
-e 's/;\(php_admin_value\[error_log\]\) = .*/\1 = \/tmp\/error.log/' \
-e 's/;\(php_admin_flag\[log_errors\]\) = .*/\1 = on/' \
/etc/php83/php-fpm.d/www.conf && \
mkdir -p /var/www ${SCRIPT_ROOT}/config.d
ARG CI_COMMIT_BRANCH
ENV CI_COMMIT_BRANCH=${CI_COMMIT_BRANCH}
ARG CI_COMMIT_SHORT_SHA
ENV CI_COMMIT_SHORT_SHA=${CI_COMMIT_SHORT_SHA}
ARG CI_COMMIT_TIMESTAMP
ENV CI_COMMIT_TIMESTAMP=${CI_COMMIT_TIMESTAMP}
ARG CI_COMMIT_SHA
ENV CI_COMMIT_SHA=${CI_COMMIT_SHA}
ADD .docker/app/startup.sh ${SCRIPT_ROOT}
ADD .docker/app/updater.sh ${SCRIPT_ROOT}
ADD .docker/app/dcron.sh ${SCRIPT_ROOT}
ADD .docker/app/nginx.sh ${SCRIPT_ROOT}
ADD .docker/app/backup.sh /etc/periodic/weekly/backup
RUN chmod 0755 ${SCRIPT_ROOT}/*.sh /etc/periodic/weekly/backup
ADD .docker/app/index.php ${SCRIPT_ROOT}
ADD .docker/app/config.docker.php ${SCRIPT_ROOT}
COPY . ${SRC_DIR}
ARG ORIGIN_REPO_EXPORT_IMPORT=https://gitlab.tt-rss.org/tt-rss/plugins/ttrss-data-migration.git
RUN git clone --depth=1 ${ORIGIN_REPO_EXPORT_IMPORT} ${SRC_DIR}/plugins.local/data_migration
ARG ORIGIN_REPO_XACCEL=https://git.tt-rss.org/fox/ttrss-nginx-xaccel.git
RUN git clone --depth=1 ${ORIGIN_REPO_XACCEL} ${SRC_DIR}/plugins.local/nginx_xaccel
ARG ORIGIN_REPO_SMTP=https://git.tt-rss.org/fox/ttrss-mailer-smtp.git
RUN git clone --depth=1 ${ORIGIN_REPO_SMTP} ${SRC_DIR}/plugins.local/mailer_smtp
ARG ORIGIN_REPO_MASTODON=https://framagit.org/framasoft/ttrss/ttrss_mastodon.git
RUN git clone --depth=1 ${ORIGIN_REPO_MASTODON} ${SRC_DIR}/plugins.local/mastodon
ARG ORIGIN_REPO_CACHE_S3=https://git.tt-rss.org/fox/ttrss-cache-s3.git
RUN git clone --depth=1 ${ORIGIN_REPO_CACHE_S3} ${SRC_DIR}/plugins.local/cache_s3
ENV OWNER_UID=1000
ENV OWNER_GID=1000
ENV PHP_WORKER_MAX_CHILDREN=5
ENV PHP_WORKER_MEMORY_LIMIT=256M
# these are applied on every startup, if set
ENV ADMIN_USER_PASS=""
# see classes/UserHelper.php ACCESS_LEVEL_*
# setting this to -2 would effectively disable built-in admin user
# unless single user mode is enabled
ENV ADMIN_USER_ACCESS_LEVEL=""
# these are applied unless user already exists
ENV AUTO_CREATE_USER=""
ENV AUTO_CREATE_USER_PASS=""
ENV AUTO_CREATE_USER_ACCESS_LEVEL="0"
ENV AUTO_CREATE_USER_ENABLE_API=""
# TODO: remove prefix from container variables not used by tt-rss itself:
#
# - TTRSS_NO_STARTUP_PLUGIN_UPDATES -> NO_STARTUP_PLUGIN_UPDATES
# - TTRSS_XDEBUG_... -> XDEBUG_...
# don't try to update local plugins on startup
ENV TTRSS_NO_STARTUP_PLUGIN_UPDATES=""
# TTRSS_XDEBUG_HOST defaults to host IP if unset
ENV TTRSS_XDEBUG_ENABLED=""
ENV TTRSS_XDEBUG_HOST=""
ENV TTRSS_XDEBUG_PORT="9000"
ENV TTRSS_DB_TYPE="pgsql"
ENV TTRSS_DB_HOST="db"
ENV TTRSS_DB_PORT="5432"
ENV TTRSS_MYSQL_CHARSET="UTF8"
ENV TTRSS_PHP_EXECUTABLE="/usr/bin/php83"
ENV TTRSS_PLUGINS="cache_s3, auth_internal, note, nginx_xaccel, mailer_smtp, data_migration"
CMD ${SCRIPT_ROOT}/startup.sh
#!/bin/sh -e
DST_DIR=/backups
KEEP_DAYS=28
APP_ROOT=/var/www/html/tt-rss
if pg_isready -h $TTRSS_DB_HOST -U $TTRSS_DB_USER; then
DST_FILE=ttrss-backup-$(date +%Y%m%d).sql.gz
echo backing up tt-rss database to $DST_DIR/$DST_FILE...
export PGPASSWORD=$TTRSS_DB_PASS
pg_dump --clean -h $TTRSS_DB_HOST -U $TTRSS_DB_USER $TTRSS_DB_NAME | gzip > $DST_DIR/$DST_FILE
DST_FILE=ttrss-backup-$(date +%Y%m%d).tar.gz
echo backing up tt-rss local directories to $DST_DIR/$DST_FILE...
tar -cz -f $DST_DIR/$DST_FILE $APP_ROOT/*.local \
$APP_ROOT/feed-icons/ \
$APP_ROOT/config.php
echo cleaning up...
find $DST_DIR -type f -name '*.gz' -mtime +$KEEP_DAYS -delete
echo done.
else
echo backup failed: database is not ready.
fi
<?php
$snippets = glob(getenv("SCRIPT_ROOT")."/config.d/*.php");
foreach ($snippets as $snippet) {
require_once $snippet;
}
#!/bin/sh
# https://github.com/dubiousjim/dcron/issues/13
set -e
/usr/sbin/crond "$@"
<?php
header("Location: /tt-rss/");
return;
#!/bin/sh -e
mkdir -p /var/www/html
ln -s /src/tt-rss /var/www/html/tt-rss
defined_envs=$(printf '${%s} ' $(env | cut -d= -f1))
envsubst "$defined_envs" </src/tt-rss/.docker/web-nginx/nginx.conf >/etc/nginx/nginx.conf
nginx -g 'daemon off;'
#!/bin/sh -e
while ! pg_isready -h $TTRSS_DB_HOST -U $TTRSS_DB_USER; do
echo waiting until $TTRSS_DB_HOST is ready...
sleep 3
done
# We don't need those here (HTTP_HOST would cause false SELF_URL_PATH check failures)
unset HTTP_PORT
unset HTTP_HOST
if ! id app >/dev/null 2>&1; then
addgroup -g $OWNER_GID app
adduser -D -h /var/www/html -G app -u $OWNER_UID app
fi
update-ca-certificates || true
DST_DIR=/var/www/html/tt-rss
[ -e $DST_DIR ] && rm -f $DST_DIR/.app_is_ready
export PGPASSWORD=$TTRSS_DB_PASS
[ ! -e /var/www/html/index.php ] && cp ${SCRIPT_ROOT}/index.php /var/www/html
if [ -z $SKIP_RSYNC_ON_STARTUP ]; then
if [ ! -d $DST_DIR ]; then
mkdir -p $DST_DIR
chown $OWNER_UID:$OWNER_GID $DST_DIR
sudo -u app rsync -a --no-owner \
$SRC_DIR/ $DST_DIR/
else
chown $OWNER_UID:$OWNER_GID $DST_DIR
sudo -u app rsync -a --no-owner --delete \
--exclude /cache \
--exclude /lock \
--exclude /feed-icons \
--exclude /plugins/af_comics/filters.local \
--exclude /templates.local \
--exclude /themes.local \
$SRC_DIR/ $DST_DIR/
sudo -u app mkdir -p $DST_DIR/plugins.local
sudo -u app rsync -a --no-owner --delete \
$SRC_DIR/plugins.local/nginx_xaccel \
$DST_DIR/plugins.local/nginx_xaccel
sudo -u app rsync -a --no-owner --delete \
$SRC_DIR/plugins.local/mastodon \
$DST_DIR/plugins.local/mastodon
sudo -u app rsync -a --no-owner --delete \
$SRC_DIR/plugins.local/mailer_smtp \
$DST_DIR/plugins.local/mailer_smtp
sudo -u app rsync -a --no-owner --delete \
$SRC_DIR/plugins.local/data_migration \
$DST_DIR/plugins.local/data_migration
sudo -u app rsync -a --no-owner --delete \
$SRC_DIR/plugins.local/cache_s3 \
$DST_DIR/plugins.local/cache_s3
fi
else
echo "warning: working copy in $DST_DIR won't be updated, make sure you know what you're doing."
fi
for d in cache lock feed-icons plugins.local themes.local templates.local cache/export cache/feeds cache/images cache/upload; do
sudo -u app mkdir -p $DST_DIR/$d
done
for d in cache lock feed-icons; do
chmod 777 $DST_DIR/$d
find $DST_DIR/$d -type f -exec chmod 666 {} \;
done
sudo -u app cp ${SCRIPT_ROOT}/config.docker.php $DST_DIR/config.php
chmod 644 $DST_DIR/config.php
chown -R $OWNER_UID:$OWNER_GID $DST_DIR \
/var/log/php83
if [ -z "$TTRSS_NO_STARTUP_PLUGIN_UPDATES" ]; then
echo updating all local plugins...
find $DST_DIR/plugins.local -mindepth 1 -maxdepth 1 -type d | while read PLUGIN; do
if [ -d $PLUGIN/.git ]; then
echo updating $PLUGIN...
cd $PLUGIN && \
sudo -u app git config core.filemode false && \
sudo -u app git config pull.rebase false && \
sudo -u app git pull origin master || echo warning: attempt to update plugin $PLUGIN failed.
fi
done
else
echo skipping local plugin updates, disabled.
fi
PSQL="psql -q -h $TTRSS_DB_HOST -U $TTRSS_DB_USER $TTRSS_DB_NAME"
$PSQL -c "create extension if not exists pg_trgm"
RESTORE_SCHEMA=${SCRIPT_ROOT}/restore-schema.sql.gz
if [ -r $RESTORE_SCHEMA ]; then
$PSQL -c "drop schema public cascade; create schema public;"
zcat $RESTORE_SCHEMA | $PSQL
fi
# this was previously generated
rm -f $DST_DIR/config.php.bak
if [ ! -z "${TTRSS_XDEBUG_ENABLED}" ]; then
if [ -z "${TTRSS_XDEBUG_HOST}" ]; then
export TTRSS_XDEBUG_HOST=$(ip ro sh 0/0 | cut -d " " -f 3)
fi
echo enabling xdebug with the following parameters:
env | grep TTRSS_XDEBUG
cat > /etc/php83/conf.d/50_xdebug.ini <<EOF
zend_extension=xdebug.so
xdebug.mode=debug
xdebug.start_with_request = yes
xdebug.client_port = ${TTRSS_XDEBUG_PORT}
xdebug.client_host = ${TTRSS_XDEBUG_HOST}
EOF
fi
sed -i.bak "s/^\(memory_limit\) = \(.*\)/\1 = ${PHP_WORKER_MEMORY_LIMIT}/" \
/etc/php83/php.ini
sed -i.bak "s/^\(pm.max_children\) = \(.*\)/\1 = ${PHP_WORKER_MAX_CHILDREN}/" \
/etc/php83/php-fpm.d/www.conf
sudo -Eu app php83 $DST_DIR/update.php --update-schema=force-yes
if [ ! -z "$ADMIN_USER_PASS" ]; then
sudo -Eu app php83 $DST_DIR/update.php --user-set-password "admin:$ADMIN_USER_PASS"
else
if sudo -Eu app php83 $DST_DIR/update.php --user-check-password "admin:password"; then
RANDOM_PASS=$(tr -dc A-Za-z0-9 </dev/urandom | head -c 16 ; echo '')
echo "*****************************************************************************"
echo "* Setting initial built-in admin user password to '$RANDOM_PASS' *"
echo "* If you want to set it manually, use ADMIN_USER_PASS environment variable. *"
echo "*****************************************************************************"
sudo -Eu app php83 $DST_DIR/update.php --user-set-password "admin:$RANDOM_PASS"
fi
fi
if [ ! -z "$ADMIN_USER_ACCESS_LEVEL" ]; then
sudo -Eu app php83 $DST_DIR/update.php --user-set-access-level "admin:$ADMIN_USER_ACCESS_LEVEL"
fi
if [ ! -z "$AUTO_CREATE_USER" ]; then
sudo -Eu app /bin/sh -c "php83 $DST_DIR/update.php --user-exists $AUTO_CREATE_USER ||
php83 $DST_DIR/update.php --force-yes --user-add \"$AUTO_CREATE_USER:$AUTO_CREATE_USER_PASS:$AUTO_CREATE_USER_ACCESS_LEVEL\""
if [ ! -z "$AUTO_CREATE_USER_ENABLE_API" ]; then
# TODO: remove || true later
sudo -Eu app /bin/sh -c "php83 $DST_DIR/update.php --user-enable-api \"$AUTO_CREATE_USER:$AUTO_CREATE_USER_ENABLE_API\"" || true
fi
fi
rm -f /tmp/error.log && mkfifo /tmp/error.log && chown app:app /tmp/error.log
(tail -q -f /tmp/error.log >> /proc/1/fd/2) &
unset ADMIN_USER_PASS
unset AUTO_CREATE_USER_PASS
touch $DST_DIR/.app_is_ready
exec /usr/sbin/php-fpm83 --nodaemonize --force-stderr
#!/bin/sh -e
# We don't need those here (HTTP_HOST would cause false SELF_URL_PATH check failures)
unset HTTP_PORT
unset HTTP_HOST
unset ADMIN_USER_PASS
unset AUTO_CREATE_USER_PASS
# wait for the app container to delete .app_is_ready and perform rsync, etc.
sleep 30
if ! id app; then
addgroup -g $OWNER_GID app
adduser -D -h /var/www/html -G app -u $OWNER_UID app
fi
while ! pg_isready -h $TTRSS_DB_HOST -U $TTRSS_DB_USER; do
echo waiting until $TTRSS_DB_HOST is ready...
sleep 3
done
sed -i.bak "s/^\(memory_limit\) = \(.*\)/\1 = ${PHP_WORKER_MEMORY_LIMIT}/" \
/etc/php83/php.ini
DST_DIR=/var/www/html/tt-rss
mkdir -p /var/www/html
rsync -a /src/tt-rss/ $DST_DIR/
mkdir -p "$DST_DIR/cache/{images,export,upload}"
chown "$OWNER_UID":"$OWNER_GID" "$DST_DIR/cache/{images,export,upload}"
while [ ! -s $DST_DIR/config.php -a -e $DST_DIR/.app_is_ready ]; do
echo waiting for app container...
sleep 3
done
sudo -E -u app /usr/bin/php83 /var/www/html/tt-rss/update_daemon2.php "$@"
ARG PROXY_REGISTRY
FROM ${PROXY_REGISTRY}nginx:alpine
HEALTHCHECK CMD curl --fail http://localhost${APP_BASE}/index.php || exit 1
COPY .docker/web-nginx/nginx.conf /etc/nginx/templates/nginx.conf.template
# By default, nginx will send the php requests to "app" server, but this server
# name can be overridden at runtime by passing an APP_UPSTREAM env var
ENV APP_UPSTREAM=${APP_UPSTREAM:-app}
# Webroot (defaults to /var/www/html)
ENV APP_WEB_ROOT=${APP_WEB_ROOT:-/var/www/html}
# Base location for tt-rss (defaults to /tt-rss)
ENV APP_BASE=${APP_BASE:-/tt-rss}
# Resolver for nginx (kube-dns.kube-system.svc.cluster.local for k8s)
ENV RESOLVER=${RESOLVER:-127.0.0.11}
# In order to make tt-rss appear on website root without /tt-rss/ set above as follows in .env:
# APP_WEB_ROOT=/var/www/html/tt-rss
# APP_BASE=
# It's necessary to set the following NGINX_ENVSUBST_OUTPUT_DIR env var to tell
# nginx to replace the env vars of /etc/nginx/templates/nginx.conf.template
# and put the result in /etc/nginx/nginx.conf (instead of /etc/nginx/conf.d/nginx.conf)
# See https://github.com/docker-library/docs/tree/master/nginx#using-environment-variables-in-nginx-configuration-new-in-119
ENV NGINX_ENVSUBST_OUTPUT_DIR=/etc/nginx
worker_processes auto;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
access_log /dev/stdout;
error_log /dev/stderr warn;
sendfile on;
index index.php;
resolver ${RESOLVER} valid=5s ipv6=on;
server {
listen [::]:80 ipv6only=on;
root ${APP_WEB_ROOT};
location ${APP_BASE}/cache {
aio threads;
internal;
}
location ${APP_BASE}/backups {
internal;
}
rewrite ${APP_BASE}/healthz ${APP_BASE}/public.php?op=healthcheck;
location ~ \.php$ {
# regex to split $uri to $fastcgi_script_name and $fastcgi_path
fastcgi_split_path_info ^(.+?\.php)(/.*)$;
# Check that the PHP script exists before passing it
try_files $fastcgi_script_name =404;
# Bypass the fact that try_files resets $fastcgi_path_info
# see: http://trac.nginx.org/nginx/ticket/321
set $path_info $fastcgi_path_info;
fastcgi_param PATH_INFO $path_info;
fastcgi_index index.php;
include fastcgi.conf;
set $backend "${APP_UPSTREAM}:9000";
fastcgi_pass $backend;
}
location / {
try_files $uri $uri/ =404;
}
}
}
.git/
cache/
templates.local/
themes.local/
......@@ -4,3 +4,6 @@ insert_final_newline = true
[*.php]
indent_style = tab
[*.js]
indent_style = tab
# Copy this file to .env before building the container. Put any local modifications here.
# Run FPM under this UID/GID.
# OWNER_UID=1000
# OWNER_GID=1000
# FPM settings.
#PHP_WORKER_MAX_CHILDREN=5
#PHP_WORKER_MEMORY_LIMIT=256M
# ADMIN_USER_* settings are applied on every startup.
# Set admin user password to this value. If not set, random password will be generated on startup, look for it in the 'app' container logs.
#ADMIN_USER_PASS=
# Sets admin user access level to this value. Valid values:
# -2 - forbidden to login
# -1 - readonly
# 0 - default user
# 10 - admin
#ADMIN_USER_ACCESS_LEVEL=
# Auto create another user (in addition to built-in admin) unless it already exists.
#AUTO_CREATE_USER=
#AUTO_CREATE_USER_PASS=
#AUTO_CREATE_USER_ACCESS_LEVEL=0
# Default database credentials.
TTRSS_DB_USER=postgres
TTRSS_DB_NAME=postgres
TTRSS_DB_PASS=password
# This is a fallback value for PHP CLI SAPI, it should be set to a fully-qualified tt-rss URL
# TTRSS_SELF_URL_PATH=http://example.com/tt-rss
# You can customize other config.php defines by setting overrides here. See tt-rss/.docker/app/Dockerfile for complete list. Examples:
# TTRSS_PLUGINS=auth_remote
# TTRSS_SINGLE_USER_MODE=true
# TTRSS_SESSION_COOKIE_LIFETIME=2592000
# TTRSS_FORCE_ARTICLE_PURGE=30
# ...
# Bind exposed port to 127.0.0.1 to run behind reverse proxy on the same host. If you plan expose the container, remove "127.0.0.1:".
HTTP_PORT=127.0.0.1:8280
#HTTP_PORT=8280
......@@ -2,12 +2,12 @@ module.exports = {
"env": {
"browser": true,
"es6": true,
"jquery": true,
"webextensions": true
"jquery": false,
"webextensions": false
},
"extends": "eslint:recommended",
"parserOptions": {
"ecmaVersion": 2017
"ecmaVersion": 2018
},
"rules": {
"accessor-pairs": "error",
......@@ -106,7 +106,7 @@ module.exports = {
"no-catch-shadow": "off",
"no-confusing-arrow": "error",
"no-continue": "off",
"no-console": "off",
"no-console": "off",
"no-div-regex": "error",
"no-duplicate-imports": "error",
"no-else-return": "off",
......@@ -187,7 +187,7 @@ module.exports = {
"no-trailing-spaces": "error",
"no-undef-init": "error",
"no-undefined": "off",
"no-undef": "warn",
"no-undef": "warn",
"no-underscore-dangle": "off",
"no-unmodified-loop-condition": "error",
"no-unneeded-ternary": [
......@@ -197,7 +197,7 @@ module.exports = {
}
],
"no-unused-expressions": "off",
"no-unused-vars": "warn",
"no-unused-vars": "warn",
"no-use-before-define": "off",
"no-useless-call": "error",
"no-useless-computed-key": "error",
......
Thumbs.db
/.env
/docker-compose.override.yml
/.app_is_ready
/deploy.exclude
/deploy.sh
/messages.mo
/node_modules
/package-lock.json
*~
*.DS_Store
#*
.idea/*
plugins.local/*
themes.local/*
config.php
feed-icons/*
cache/*/*
lock/*
tags
cache/htmlpurifier/*/*ser
lib/htmlpurifier/library/HTMLPurifier/DefinitionCache/Serializer/*/*ser
web.config
/.save.cson
/.tags*
/.gutentags
/locale/**/*.po~
/themes.local/*
/config.php
/feed-icons/*
/cache/*/*
/lock/*
/.vscode/settings.json
/vendor/**/.git
/.phpunit.result.cache
/.phpstan-tmp
/.tools/
{
"version": "0.2.0",
"configurations": [
{
"name": "Listen for XDebug",
"type": "php",
"request": "launch",
"pathMappings": {
"/var/www/html/tt-rss": "${workspaceRoot}",
},
"port": 9000
},
{
"name": "Launch Chrome",
"request": "launch",
"type": "chrome",
"pathMapping": {
"/tt-rss/": "${workspaceFolder}"
},
"urlFilter": "*/tt-rss/*",
"runtimeExecutable": "chrome.exe",
}
]
}
{
"version": "2.0.0",
"tasks": [
{
"type": "shell",
"label": "phpstan (watcher)",
"isBackground": true,
"problemMatcher": {
"fileLocation": [
"relative",
"${workspaceRoot}"
],
"owner": "phpstan-watcher",
"pattern": {
"regexp": "^/app/(.*?):([0-9\\?]*):(.*)$",
"file": 1,
"line": 2,
"message": 3
},
"background": {
"activeOnStart": true,
"beginsPattern": "Using configuration file",
"endsPattern": "All done"
}
},
"command": "chmod +x ${workspaceRoot}/utils/phpstan-watcher.sh && ${workspaceRoot}/utils/phpstan-watcher.sh"
},
{
"type": "shell",
"label": "phpunit",
"command": "chmod +x ${workspaceRoot}/utils/phpunit.sh && ${workspaceRoot}/utils/phpunit.sh",
"problemMatcher": []
},
{
"type": "gulp",
"task": "default",
"problemMatcher": [],
"label": "gulp: default"
"label": "gulp: default",
"options": {
"env": {
"PATH": "${env:PATH}:/usr/lib/sdk/node16/bin/"
}
}
}
]
}
\ No newline at end of file
}
## Contributing code the right way
## Contributing code the right way
TLDR: it works like Github.
TLDR: it works *almost* like Github.
1. Register on the [development website](https://git.tt-rss.org);
2. Fork the repository you're interested in;
3. Do the needful;
4. File a PR against master branch;
Due to spam, new Gitlab users are set to [external](https://docs.gitlab.com/ee/user/admin_area/external_users.html). In order to do anything, you'll need to ask for your account to be promoted. Sorry for the inconvenience.
1. Register on the [Gitlab](https://gitlab.tt-rss.org);
2. Post on the forums asking for your account to be promoted;
3. Fork the repository you're interested in;
4. Do the needful;
6. File a PR against master branch and verify that CI pipeline (especially, PHPStan) passes;
If you have any other questions, see this [forum thread](https://discourse.tt-rss.org/t/how-to-contribute-code-via-pull-requests-on-git-tt-rss-org/1850).
Please don't inline patches in forum posts, attach files instead (``.patch`` or ``.diff`` file
extensions should work).
Please don't inline patches in forum posts, attach files instead (``.patch`` or ``.diff`` file extensions should work).
### FAQ
#### How do I push or pull without SSH?
You can't use SSH directly because tt-rss Gitlab is behind Cloudflare. You can use HTTPS with personal access tokens instead.
Create a personal access token in [Gitlab preferences](https://gitlab.tt-rss.org/-/user_settings/personal_access_tokens);
Optionally, configure Git to transparently work with tt-rss Gitlab repositories using HTTPS:
## Contributing translations
```
git config --global \
--add url."https://gitlab-token:your-personal-access-token@gitlab.tt-rss.org/".insteadOf \
"git@gitlab.tt-rss.org:"
```
Believe it or not, people also spam using Weblate. Therefore, some minor jumping through hoops is involved here:
Alternatively, checkout over HTTPS while adding the token manually:
1. Register on [Weblate](https://weblate.tt-rss.org/) / forums;
2. Post in the [Weblate discussion thread](https://community.tt-rss.org/t/easier-translations-with-weblate/1680) on the forum, ask to be added to a project
you're interested in;
3. You'll be given proper access rights and will be able to edit translations.
```
git clone https://gitlab-token:your-personal-access-token@gitlab.tt-rss.org/tt-rss/tt-rss.git tt-rss
```
That's it. If the language you're interested is not available yet, ask and we'll add it;
That's it.
.docker/app/Dockerfile
\ No newline at end of file
......@@ -20,6 +20,3 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Copyright (c) 2005 Andrew Dolgov (unless explicitly stated otherwise).
Uses Silk icons by Mark James: http://www.famfamfam.com/lab/icons/silk/