diff --git a/.arcconfig b/.arcconfig new file mode 100644 index 0000000..eaaa330 --- /dev/null +++ b/.arcconfig @@ -0,0 +1,7 @@ +{ + "phabricator.uri": "https://code.datenknoten.me/", + "load": [ + "src/" + ], + "history.immutable": true +} diff --git a/.arclint b/.arclint new file mode 100644 index 0000000..bcfb403 --- /dev/null +++ b/.arclint @@ -0,0 +1,69 @@ +{ + "exclude": [ + "(^externals/)" + ], + "linters": { + "chmod": { + "type": "chmod" + }, + "filename": { + "type": "filename" + }, + "generated": { + "type": "generated" + }, + "json": { + "type": "json", + "include": [ + "(^resources/arclint/.*\\.arclint\\.example$)", + "(^\\.arcconfig$)", + "(^\\.arclint$)", + "(\\.json$)" + ] + }, + "merge-conflict": { + "type": "merge-conflict" + }, + "nolint": { + "type": "nolint" + }, + "phutil-library": { + "type": "phutil-library", + "include": "(\\.php$)" + }, + "spelling": { + "type": "spelling", + "exclude": "(^resources/spelling/.*\\.json$)" + }, + "text": { + "type": "text", + "exclude": [ + "(^src/(.*/)?__tests__/[^/]+/.*\\.(txt|json|expect)|/Makefile\\z)" + ] + }, + "text-without-length": { + "type": "text", + "include": [ + "(^src/(.*/)?__tests__/[^/]+/.*\\.(txt|json|expect))" + ], + "severity": { + "3": "disabled" + } + }, + "text-without-tabs": { + "type": "text", + "include": [ + "(/Makefile\\z)" + ], + "severity": { + "2": "disabled" + } + }, + "xhpast": { + "type": "xhpast", + "include": "(\\.php$)", + "standard": "phutil.xhpast", + "xhpast.php-version": "5.5.0" + } + } +} diff --git a/.devcontainer/.env.sample b/.devcontainer/.env.sample new file mode 100644 index 0000000..b62da80 --- /dev/null +++ b/.devcontainer/.env.sample @@ -0,0 +1,12 @@ +#.env sample file for the phorge-devcontainer + +# The HTTP Port that Phorge will run on +PHORGE_WEB_PORT=80 + +# The SSH Port that Phorge Repos will run on +PHORGE_SSH_PORT=22280 + +# The base URI that you will map on your local machine to 127.0.0.1 +# NOTE: If you use a PHORGE_WEB_PORT other than port 80, you will need to update this URI to include the port +# For example, if PHORGE_WEB_PORT=8020 then set PHORGE_BASE_URI=http://phorge.localhost:8020 +PHORGE_BASE_URI=http://phorge.localhost diff --git a/.devcontainer/.gitignore b/.devcontainer/.gitignore new file mode 100644 index 0000000..2eea525 --- /dev/null +++ b/.devcontainer/.gitignore @@ -0,0 +1 @@ +.env \ No newline at end of file diff --git a/.devcontainer/.vscode/launch.json b/.devcontainer/.vscode/launch.json new file mode 100644 index 0000000..c39b4eb --- /dev/null +++ b/.devcontainer/.vscode/launch.json @@ -0,0 +1,14 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "Listen for Xdebug", + "type": "php", + "request": "launch", + "port": 9001 + }, + ] +} \ No newline at end of file diff --git a/.devcontainer/application/Dockerfile b/.devcontainer/application/Dockerfile new file mode 100644 index 0000000..8f1db9f --- /dev/null +++ b/.devcontainer/application/Dockerfile @@ -0,0 +1,64 @@ +FROM debian:bookworm-backports + + +# == Get ca-certificates up to date == +RUN apt-get -y update +RUN apt-get -y install ca-certificates + + +# == Copy Data == +COPY install_scripts /install_scripts + +# == Configure Ubuntu == +WORKDIR /install_scripts +RUN sh install_dependencies.sh +RUN sh add_users.sh + +# == Set up the Phorge code base == +RUN mkdir /srv/phorge +RUN chown git:wwwgrp-phorge /srv/phorge +USER git +WORKDIR /srv/phorge +RUN git clone https://we.phorge.it/source/phorge.git +RUN git clone https://we.phorge.it/source/arcanist.git +USER root +WORKDIR / +RUN mkdir -p /var/tmp/phd/log +RUN chown phorge-daemon:2000 /var/tmp/phd/log + +# == Expose Ports == + +# Nginx +EXPOSE 80 +# Aphlict +EXPOSE 22280 +# SSH +EXPOSE 2222 + +# == Add service config files == +ADD /config/nginx.conf.org /etc/nginx/ +ADD /config/fastcgi.conf /etc/nginx/ +ADD /config/php-fpm.conf /etc/php/8.2/fpm/ +ADD /config/php.ini /etc/php/8.2/fpm/ +ADD /config/aphlict.phorge.json /install_scripts/ + +# == Add Supervisord config files == +RUN mkdir -p /var/log/supervisor +RUN mkdir -p /etc/supervisor/conf.d/ + +ADD config/supervisord.conf /etc/supervisor/ +COPY config/*.sv.conf /etc/supervisor/conf.d/ + +# == Configure Phorge SSH service == +RUN mkdir /etc/phorge-ssh +RUN mkdir /var/run/sshd/ +RUN chmod 0755 /var/run/sshd +ADD config/sshd_config.phorge /etc/phorge-ssh/ +ADD config/phorge-ssh-hook.sh /etc/phorge-ssh/ +RUN chown root:root /etc/phorge-ssh/* + +# == Copy other scripts == # +COPY user-config /user-config +COPY startup.sh / + +CMD bash ./startup.sh && supervisord diff --git a/.devcontainer/application/config/aphlict.phorge.json b/.devcontainer/application/config/aphlict.phorge.json new file mode 100644 index 0000000..1abb2e4 --- /dev/null +++ b/.devcontainer/application/config/aphlict.phorge.json @@ -0,0 +1,13 @@ +[{ + "type": "client", + "host": "phorge.localhost", + "port": 22280, + "protocol": "http" + }, + { + "type": "admin", + "host": "127.0.0.1", + "port": 22281, + "protocol": "http" + } +] \ No newline at end of file diff --git a/.devcontainer/application/config/aphlict.sv.conf b/.devcontainer/application/config/aphlict.sv.conf new file mode 100644 index 0000000..9dc7635 --- /dev/null +++ b/.devcontainer/application/config/aphlict.sv.conf @@ -0,0 +1,3 @@ +[program:aphlict] +command=/srv/phorge/phorge/bin/aphlict debug --config /srv/phorge/phorge/conf/aphlict/aphlict.default.json +user=phorge-daemon \ No newline at end of file diff --git a/.devcontainer/application/config/fastcgi.conf b/.devcontainer/application/config/fastcgi.conf new file mode 100644 index 0000000..4419b42 --- /dev/null +++ b/.devcontainer/application/config/fastcgi.conf @@ -0,0 +1,24 @@ + fastcgi_param QUERY_STRING $query_string; + fastcgi_param REQUEST_METHOD $request_method; + fastcgi_param CONTENT_TYPE $content_type; + fastcgi_param CONTENT_LENGTH $content_length; + + fastcgi_param SCRIPT_NAME $fastcgi_script_name; + fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; + fastcgi_param REQUEST_URI $request_uri; + fastcgi_param DOCUMENT_URI $document_uri; + fastcgi_param DOCUMENT_ROOT $document_root; + fastcgi_param SERVER_PROTOCOL $server_protocol; + + fastcgi_param GATEWAY_INTERFACE CGI/1.1; + fastcgi_param SERVER_SOFTWARE nginx; + + fastcgi_param REMOTE_ADDR $remote_addr; + fastcgi_param REMOTE_PORT $remote_port; + fastcgi_param SERVER_ADDR $server_addr; + fastcgi_param SERVER_PORT $server_port; + fastcgi_param SERVER_NAME $server_name; + + fastcgi_param HTTPS $https; + + fastcgi_read_timeout 6000; diff --git a/.devcontainer/application/config/nginx.conf.org b/.devcontainer/application/config/nginx.conf.org new file mode 100644 index 0000000..3c64fc7 --- /dev/null +++ b/.devcontainer/application/config/nginx.conf.org @@ -0,0 +1,45 @@ +worker_processes 1; +daemon off; +pid /run/nginx.pid; + +events { + worker_connections 1024; + use epoll; +} + +http { + include mime.types; + default_type application/octet-stream; + sendfile on; + keepalive_timeout 65; + gzip on; + client_max_body_size 200M; + client_body_buffer_size 200M; + + server { + listen *:80; + + access_log /var/log/nginx/access.log; + error_log /var/log/nginx/access.log; + + root /srv/phorge/phorge/webroot; + try_files $uri $uri/ /index.php; + + location / { + index index.php; + + if ( !-f $request_filename ) + { + rewrite ^/(.*)$ /index.php?__path__=/$1 last; + break; + } + } + + location /index.php { + include /etc/nginx/fastcgi.conf; + fastcgi_param PATH "/usr/local/bin:/usr/bin:/sbin:/usr/sbin:/bin:/usr/games"; + fastcgi_pass unix:/tmp/php-fpm-phorge.sock; + } + } +} + diff --git a/.devcontainer/application/config/nginx.sv.conf b/.devcontainer/application/config/nginx.sv.conf new file mode 100644 index 0000000..9c664a7 --- /dev/null +++ b/.devcontainer/application/config/nginx.sv.conf @@ -0,0 +1,2 @@ +[program:nginx] +command=nginx \ No newline at end of file diff --git a/.devcontainer/application/config/phorge-phd.sv.conf b/.devcontainer/application/config/phorge-phd.sv.conf new file mode 100644 index 0000000..836784e --- /dev/null +++ b/.devcontainer/application/config/phorge-phd.sv.conf @@ -0,0 +1,32 @@ +[program:PhabricatorRepositoryPullLocalDaemon] +user=phorge-daemon +command=/srv/phorge/phorge/bin/phd debug PhabricatorRepositoryPullLocalDaemon +stdout_logfile=/var/log/supervisor/PhabricatorRepositoryPullLocalDaemon.log +stderr_logfile=/var/log/supervisor/PhabricatorRepositoryPullLocalDaemon_err.log + +[program:PhabricatorTaskmasterDaemon1] +user=phorge-daemon +command=/srv/phorge/phorge/bin/phd debug PhabricatorTaskmasterDaemon +stdout_logfile=/var/log/supervisor/PhabricatorTaskmasterDaemon1.log +stderr_logfile=/var/log/supervisor/PhabricatorTaskmasterDaemon1_err.log + +[program:PhabricatorTaskmasterDaemon2] +user=phorge-daemon +command=/srv/phorge/phorge/bin/phd debug PhabricatorTaskmasterDaemon +stdout_logfile=/var/log/supervisor/PhabricatorTaskmasterDaemon2.log +stderr_logfile=/var/log/supervisor/PhabricatorTaskmasterDaemon2_err.log + +[program:PhabricatorTaskmasterDaemon3] +user=phorge-daemon +command=/srv/phorge/phorge/bin/phd debug PhabricatorTaskmasterDaemon +stdout_logfile=/var/log/supervisor/PhabricatorTaskmasterDaemon3.log +stderr_logfile=/var/log/supervisor/PhabricatorTaskmasterDaemon3_err.log + +[program:PhabricatorTaskmasterDaemon4] +user=phorge-daemon +command=/srv/phorge/phorge/bin/phd debug PhabricatorTaskmasterDaemon +stdout_logfile=/var/log/supervisor/PhabricatorTaskmasterDaemon4.log +stderr_logfile=/var/log/supervisor/PhabricatorTaskmasterDaemon4_err.log + +[group:phd] +programs=PhabricatorRepositoryPullLocalDaemon,PhabricatorTaskmasterDaemon1,PhabricatorTaskmasterDaemon2,PhabricatorTaskmasterDaemon3,PhabricatorTaskmasterDaemon4 diff --git a/.devcontainer/application/config/phorge-ssh-hook.sh b/.devcontainer/application/config/phorge-ssh-hook.sh new file mode 100755 index 0000000..4008bdf --- /dev/null +++ b/.devcontainer/application/config/phorge-ssh-hook.sh @@ -0,0 +1,13 @@ +#!/bin/sh + +# NOTE: Replace this with the username that you expect users to connect with. +VCSUSER="git" + +ROOT="/srv/phorge/phorge" + +if [ "$1" != "$VCSUSER" ]; +then + exit 1 +fi + +exec "$ROOT/bin/ssh-auth" $@ diff --git a/.devcontainer/application/config/phorge-sshd.sv.conf b/.devcontainer/application/config/phorge-sshd.sv.conf new file mode 100644 index 0000000..ede0546 --- /dev/null +++ b/.devcontainer/application/config/phorge-sshd.sv.conf @@ -0,0 +1,2 @@ +[program:phorge-sshd] +command=/usr/sbin/sshd -D -f /etc/phorge-ssh/sshd_config.phorge \ No newline at end of file diff --git a/.devcontainer/application/config/php-fpm.conf b/.devcontainer/application/config/php-fpm.conf new file mode 100644 index 0000000..c202891 --- /dev/null +++ b/.devcontainer/application/config/php-fpm.conf @@ -0,0 +1,19 @@ +[global] +pid = /run/php-fpm.pid +error_log = /tmp/phorge.log +daemonize = no + +[phorge] +user = git +group = wwwgrp-phorge +listen = /tmp/php-fpm-phorge.sock +listen.owner = git +listen.group = wwwgrp-phorge +listen.mode = 0666 +pm = dynamic +pm.max_children = 4 +pm.start_servers = 2 +pm.min_spare_servers = 1 +pm.max_spare_servers = 4 +catch_workers_output = yes +php_admin_value[error_log] = /tmp/phorge.php.log diff --git a/.devcontainer/application/config/php.ini b/.devcontainer/application/config/php.ini new file mode 100644 index 0000000..7a663b0 --- /dev/null +++ b/.devcontainer/application/config/php.ini @@ -0,0 +1,196 @@ +[PHP] +engine = On +short_open_tag = Off +asp_tags = Off +precision = 14 +y2k_compliance = On +output_buffering = 4096 +zlib.output_compression = Off +unserialize_callback_func = +serialize_precision = 17 +allow_call_time_pass_reference = Off +safe_mode = Off +safe_mode_gid = Off +safe_mode_include_dir = +safe_mode_exec_dir = +safe_mode_allowed_env_vars = PHP_ +safe_mode_protected_env_vars = LD_LIBRARY_PATH +disable_functions = +disable_classes = +zend.enable_gc = On +expose_php = On +max_input_time = 60 +memory_limit = 4G +error_reporting = E_ALL & ~E_DEPRECATED +display_errors = On +display_startup_errors = Off +log_errors = On +log_errors_max_len = 1024 +ignore_repeated_errors = Off +ignore_repeated_source = Off +report_memleaks = On +track_errors = Off +error_log = /tmp/php_errors.log +variables_order = "GPCS" +request_order = "GP" +register_globals = Off +register_long_arrays = Off +auto_globals_jit = On +post_max_size = 4G +magic_quotes_gpc = Off +magic_quotes_runtime = Off +magic_quotes_sybase = Off +auto_prepend_file = +auto_append_file = +default_mimetype = "text/html" +include_path = ".:/usr/share/php7:/usr/share/php7/PEAR:/srv/phorge/PHPExcel/Classes" +doc_root = +user_dir = +enable_dl = Off +file_uploads = On +upload_max_filesize = 4G +max_file_uploads = 20 +allow_url_fopen = On +allow_url_include = Off +default_socket_timeout = 60 +opcache.validate_timestamps = On +opcache.revalidate_freq = 0 +xdebug.remote_enable=1 +xdebug.remote_autostart=1 +xdebug.remote_port="9001" +xdebug.profiler_enable=0 +xdebug.profiler_output_dir="/tmp" +xdebug.max_nesting_level=1000 +xdebug.idekey = "PHPSTORM" +[Date] +date.timezone = 'UTC' +[filter] +[iconv] +[intl] +[sqlite] +[sqlite3] +[Pcre] +[Pdo] +[Pdo_mysql] +pdo_mysql.cache_size = 2000 +pdo_mysql.default_socket= +[Phar] +[Syslog] +define_syslog_variables = Off +[mail function] +SMTP = localhost +smtp_port = 25 +mail.add_x_header = On +[SQL] +sql.safe_mode = Off +[ODBC] +odbc.allow_persistent = On +odbc.check_persistent = On +odbc.max_persistent = -1 +odbc.max_links = -1 +odbc.defaultlrl = 4096 +odbc.defaultbinmode = 1 +[Interbase] +ibase.allow_persistent = 1 +ibase.max_persistent = -1 +ibase.max_links = -1 +ibase.timestampformat = "%Y-%m-%d %H:%M:%S" +ibase.dateformat = "%Y-%m-%d" +ibase.timeformat = "%H:%M:%S" +[MySQL] +mysql.allow_local_infile = On +mysql.allow_persistent = Off +mysql.cache_size = 2000 +mysql.max_persistent = -1 +mysql.max_links = -1 +mysql.default_port = +mysql.default_socket = +mysql.default_host = +mysql.default_user = +mysql.default_password = +mysql.connect_timeout = 3 +mysql.trace_mode = Off +[MySQLi] +mysqli.max_persistent = -1 +mysqli.allow_persistent = Off +mysqli.max_links = -1 +mysqli.cache_size = 2000 +mysqli.default_port = 3306 +mysqli.default_socket = +mysqli.default_host = +mysqli.default_user = +mysqli.default_pw = +mysqli.reconnect = Off +[mysqlnd] +mysqlnd.collect_statistics = On +mysqlnd.collect_memory_statistics = Off +[OCI8] +[PostgreSQL] +pgsql.allow_persistent = On +pgsql.auto_reset_persistent = Off +pgsql.max_persistent = -1 +pgsql.max_links = -1 +pgsql.ignore_notice = 0 +pgsql.log_notice = 0 +[Sybase-CT] +sybct.allow_persistent = On +sybct.max_persistent = -1 +sybct.max_links = -1 +sybct.min_server_severity = 10 +sybct.min_client_severity = 10 +[bcmath] +bcmath.scale = 0 +[browscap] +[Session] +session.save_handler = files +session.save_path = "/var/lib/php5" +session.use_cookies = 1 +session.use_only_cookies = 1 +session.name = PHPSESSID +session.auto_start = 0 +session.cookie_lifetime = 0 +session.cookie_path = / +session.cookie_domain = +session.cookie_httponly = +session.serialize_handler = php +session.gc_probability = 1 +session.gc_divisor = 1000 +session.gc_maxlifetime = 1440 +session.bug_compat_42 = Off +session.bug_compat_warn = Off +session.referer_check = +session.entropy_length = 32 +session.entropy_file = /dev/urandom +session.cache_limiter = nocache +session.cache_expire = 180 +session.use_trans_sid = 0 +session.hash_function = sha256 +session.hash_bits_per_character = 5 +url_rewriter.tags = "a=href,area=href,frame=src,input=src,form=fakeentry" +[MSSQL] +mssql.allow_persistent = On +mssql.max_persistent = -1 +mssql.max_links = -1 +mssql.min_error_severity = 10 +mssql.min_message_severity = 10 +mssql.compatability_mode = Off +mssql.secure_connection = Off +[Assertion] +[COM] +[mbstring] +[gd] +[exif] +[Tidy] +tidy.clean_output = Off +[soap] +soap.wsdl_cache_enabled=1 +soap.wsdl_cache_dir="/tmp" +soap.wsdl_cache_ttl=86400 +soap.wsdl_cache_limit = 5 +[sysvshm] +[ldap] +ldap.max_links = -1 +[mcrypt] +[dba] +[xsl] + diff --git a/.devcontainer/application/config/php8-fpm.sv.conf b/.devcontainer/application/config/php8-fpm.sv.conf new file mode 100644 index 0000000..c46a972 --- /dev/null +++ b/.devcontainer/application/config/php8-fpm.sv.conf @@ -0,0 +1,2 @@ +[program:php-fpm8.2] +command=php-fpm8.2 -F diff --git a/.devcontainer/application/config/sshd_config.phorge b/.devcontainer/application/config/sshd_config.phorge new file mode 100644 index 0000000..e397c37 --- /dev/null +++ b/.devcontainer/application/config/sshd_config.phorge @@ -0,0 +1,24 @@ +# NOTE: You must have OpenSSHD 6.2 or newer; support for AuthorizedKeysCommand +# was added in this version. + +# NOTE: Edit these to the correct values for your setup. + +AuthorizedKeysCommand /etc/phorge-ssh/phorge-ssh-hook.sh +AuthorizedKeysCommandUser git +AllowUsers git + +# You may need to tweak these options, but mostly they just turn off everything +# dangerous. + +Port 2222 +Protocol 2 +PermitRootLogin no +AllowAgentForwarding no +AllowTcpForwarding no +PrintMotd no +PrintLastLog no +PasswordAuthentication no +AuthorizedKeysFile none + +PidFile /run/sshd-phorge.pid + diff --git a/.devcontainer/application/config/supervisord.conf b/.devcontainer/application/config/supervisord.conf new file mode 100644 index 0000000..49500f1 --- /dev/null +++ b/.devcontainer/application/config/supervisord.conf @@ -0,0 +1,29 @@ +; supervisor config file + +[unix_http_server] +file=/var/run/supervisor.sock ; (the path to the socket file) +chmod=0700 ; sockef file mode (default 0700) + +[supervisord] +nodaemon=true +logfile=/var/log/supervisor/supervisord.log ; (main log file;default $CWD/supervisord.log) +pidfile=/var/run/supervisord.pid ; (supervisord pidfile;default supervisord.pid) +childlogdir=/var/log/supervisor ; ('AUTO' child log dir, default $TEMP) + +; the below section must remain in the config file for RPC +; (supervisorctl/web interface) to work, additional interfaces may be +; added by defining them in separate rpcinterface: sections +[rpcinterface:supervisor] +supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface + +[supervisorctl] +serverurl=unix:///var/run/supervisor.sock ; use a unix:// URL for a unix socket + +; The [include] section can just contain the "files" setting. This +; setting can list multiple files (separated by whitespace or +; newlines). It can also contain wildcards. The filenames are +; interpreted as relative to this file. Included files *cannot* +; include files themselves. + +[include] +files = /etc/supervisor/conf.d/*.conf \ No newline at end of file diff --git a/.devcontainer/application/install_scripts/add_users.sh b/.devcontainer/application/install_scripts/add_users.sh new file mode 100644 index 0000000..5fa3685 --- /dev/null +++ b/.devcontainer/application/install_scripts/add_users.sh @@ -0,0 +1,20 @@ +#!/bin/bash + +# Add users +echo "git:x:2000:2000:user for phorge ssh:/srv/phorge:/bin/bash" >> /etc/passwd +echo "phorge-daemon:x:2001:2000:user for phorge daemons:/srv/phorge:/bin/bash" >> /etc/passwd +echo "wwwgrp-phorge:!:2000:nginx" >> /etc/group + +usermod -p NP git + +# Add repo directory +mkdir -p /var/repo/ +chown phorge-daemon:2000 /var/repo/ +mkdir -p /var/tmp/phd/pid +chmod 0777 /var/tmp/phd/pid + +# Add git to sudoers +echo "git ALL=(phorge-daemon) SETENV: NOPASSWD: /usr/bin/git-upload-pack, /usr/bin/git-receive-pack, /usr/bin/git, /usr/lib/git-core/git-http-backend" > /etc/sudoers.d/git + +echo 'export PATH="/srv/phorge/arcanist/bin:$PATH"' >> /root/.bashrc +echo 'export PATH="/srv/phorge/phorge/bin:$PATH"' >> /root/.bashrc diff --git a/.devcontainer/application/install_scripts/install_dependencies.sh b/.devcontainer/application/install_scripts/install_dependencies.sh new file mode 100644 index 0000000..3808e39 --- /dev/null +++ b/.devcontainer/application/install_scripts/install_dependencies.sh @@ -0,0 +1,34 @@ +#!/bin/bash + +export DEBIAN_FRONTEND=noninteractive + +apt-get -qq update +apt-get -y -qq install \ + git \ + nginx \ + php \ + php-fpm \ + php-mysql \ + php-gd \ + php-curl \ + php-apcu \ + php-cli \ + php-json \ + php-mbstring \ + php-zip \ + php-xdebug \ + ssh \ + wget \ + vim \ + less \ + zip \ + cron \ + lsof \ + sudo \ + supervisor \ + python3-pygments \ + mariadb-client \ + gcc \ + g++ \ + nodejs \ + npm diff --git a/.devcontainer/application/startup.sh b/.devcontainer/application/startup.sh new file mode 100755 index 0000000..d145399 --- /dev/null +++ b/.devcontainer/application/startup.sh @@ -0,0 +1,58 @@ + +#!/bin/bash + +set -x + +echo "Waiting for mysql" +until mysql -h"$SQL_HOST" -P"$SQL_PORT" -u"$SQL_USER" -p"$SQL_PASSWORD" &> /dev/null +do + printf "." + sleep 1 +done + +echo -e "\nmysql ready" + +pushd /srv/phorge/phorge + +./bin/config set mysql.host $SQL_HOST +./bin/config set mysql.port $SQL_PORT +./bin/config set mysql.user $SQL_USER +./bin/config set mysql.pass $SQL_PASSWORD + +./bin/config set phabricator.base-uri $BASE_URI + +./bin/config set phd.user phorge-daemon +./bin/config set diffusion.ssh-user git +./bin/config set diffusion.ssh-port 2222 +./bin/config set diffusion.allow-http-auth true + +./bin/config set phabricator.developer-mode true +./bin/config set phabricator.show-prototypes true +./bin/config set darkconsole.enabled true + +./bin/config set storage.mysql-engine.max-size 268435456 +./bin/config set pygments.enabled true + +./bin/config set environment.append-paths '["/usr/lib/git-core"]' + +./bin/config set notification.servers --stdin < /install_scripts/aphlict.phorge.json + +echo '["/srv/phorge/deepclone/src"]' | ./bin/config set load-libraries --stdin + +if [ -e /user-config/script.post ]; then + echo "Applying post-configuration script..." + /user-config/script.post +fi + +popd + +pushd /srv/phorge/phorge/support/aphlict/server + +npm ci + +popd + +find /srv/phorge/deepclone + +cp /etc/nginx/nginx.conf.org /etc/nginx/nginx.conf +/srv/phorge/phorge/bin/storage upgrade --force diff --git a/.devcontainer/application/user-config/.exists b/.devcontainer/application/user-config/.exists new file mode 100644 index 0000000..e69de29 diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 0000000..549780d --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,25 @@ +// For format details, see https://aka.ms/devcontainer.json. For config options, see the README at: +// https://github.com/microsoft/vscode-dev-containers/tree/v0.183.0/containers/docker-existing-docker-compose +{ + "name": "Phorge Dev", + + // Update the 'dockerComposeFile' list if you have more compose files or use different names. + // The .devcontainer/docker-compose.yml file contains any overrides you need/want to make. + "dockerComposeFile": [ + "docker-compose.yml" + ], + + // The 'service' property is the name of the service for the container that VS Code should + // use. Update this value and .devcontainer/docker-compose.yml to the real service name. + "service": "app", + + // The optional 'workspaceFolder' property is the path VS Code should open by default when + // connected. This is typically a file mount in .devcontainer/docker-compose.yml + "workspaceFolder": "/srv/phorge", + + // Add the IDs of extensions you want installed when the container is created. + "extensions": [ + "bmewburn.vscode-intelephense-client", + "felixfbecker.php-debug" + ] +} diff --git a/.devcontainer/docker-compose.yml b/.devcontainer/docker-compose.yml new file mode 100644 index 0000000..565e847 --- /dev/null +++ b/.devcontainer/docker-compose.yml @@ -0,0 +1,24 @@ +version: "3.9" +services: + db: + image: mariadb + restart: always + volumes: + - ./mysql:/etc/mysql/conf.d:ro + environment: + MYSQL_ROOT_PASSWORD: phorge-dev + app: + build: ./application + ports: + - "${PHORGE_WEB_PORT:-80}:80" + - "${PHORGE_SSH_PORT:-22280}:22280" + environment: + SQL_HOST: db + SQL_PORT: 3306 + SQL_USER: root + SQL_PASSWORD: phorge-dev + BASE_URI: "${PHORGE_BASE_URI:-http://phorge.localhost/}" + volumes: + - "./.vscode:/srv/phorge/.vscode" + - "..:/srv/phorge/deepclone" + - "./application/startup.sh:/startup.sh" diff --git a/.devcontainer/mysql/custom.cnf b/.devcontainer/mysql/custom.cnf new file mode 100644 index 0000000..d9d4abe --- /dev/null +++ b/.devcontainer/mysql/custom.cnf @@ -0,0 +1,5 @@ +[mysqld] +sql_mode=STRICT_ALL_TABLES +max_allowed_packet=33554432 +innodb_buffer_pool_size=1600M +local_infile=0 \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..6b193c3 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.phutil_module_cache diff --git a/src/__phutil_library_init__.php b/src/__phutil_library_init__.php new file mode 100644 index 0000000..169fd20 --- /dev/null +++ b/src/__phutil_library_init__.php @@ -0,0 +1,3 @@ + 2, + 'class' => array( + 'DeepcloneApplication' => 'deepclone/application/DeepcloneApplication.php', + 'DeepcloneUIEventListener' => 'deepclone/events/DeepcloneUIEventListener.php', + ), + 'function' => array(), + 'xmap' => array( + 'DeepcloneApplication' => 'PhabricatorApplication', + 'DeepcloneUIEventListener' => 'PhabricatorEventListener', + ), +)); diff --git a/src/deepclone/application/DeepcloneApplication.php b/src/deepclone/application/DeepcloneApplication.php new file mode 100644 index 0000000..fa2c0e4 --- /dev/null +++ b/src/deepclone/application/DeepcloneApplication.php @@ -0,0 +1,13 @@ +listen(PhabricatorEventType::TYPE_UI_DIDRENDERACTIONS); + } + + public function handleEvent(PhutilEvent $event) { + switch ($event->getType()) { + case PhabricatorEventType::TYPE_UI_DIDRENDERACTIONS: + $this->handleActionEvent($event); + break; + } + } + + private function handleActionEvent($event) { + $viewer = $event->getUser(); + $object = $event->getValue('object'); + + if (!$object || !$object->getPHID()) { + // If we have no object, or the object doesn't have a PHID, we can't + // do anything useful. + return; + } + + $phid = $object->getPHID(); + + $button = id(new PhabricatorActionView()) + ->setIcon('fa-asterisk') + ->setName(pht('Clone')) + ->setHref(urisprintf('/clone/%s/', $phid)) + ->setWorkflow(true); + + $actions = $event->getValue('actions'); + $actions[] = $button; + $event->setValue('actions', $actions); + } +}