Преглед изворни кода

Improve github actions: railway deploy#5668

Aleksandr Trofimov пре 1 месец
родитељ
комит
abfa4341c1
4 измењених фајлова са 261 додато и 1 уклоњено
  1. 88 1
      .github/workflows/ci.yml
  2. 39 0
      scripts/railway/Dockerfile
  3. 127 0
      scripts/railway/entrypoint.sh
  4. 7 0
      scripts/railway/railway.toml

+ 88 - 1
.github/workflows/ci.yml

@@ -5,12 +5,14 @@ on:
     branches: [ "master" ]
   pull_request:
     branches: [ "master" ]
+    types: [opened, synchronize, reopened, closed]
 
 permissions:
   contents: read
 
 jobs:
   test:
+    if: github.event_name == 'push' || github.event.action != 'closed'
     runs-on: ubuntu-latest
 
     services:
@@ -55,7 +57,7 @@ jobs:
     - name: Prepare writable paths
       run: |
         mkdir -p cache cache_public logs tmp storage
-        chmod -R a+rwX inc cache cache_public logs tmp storage
+        chmod a+rwX inc cache cache_public logs tmp storage
         test -f plugins/ffmpeg/ffmpeg.exe && chmod 0755 plugins/ffmpeg/ffmpeg.exe
 
     - name: Install UNA
@@ -82,3 +84,88 @@ jobs:
         name: una-package
         path: packages/*.zip
         if-no-files-found: error
+
+  deploy:
+    name: Deploy PR to Railway
+    needs: test
+    if: github.event_name == 'pull_request' && github.event.action != 'closed'
+    runs-on: ubuntu-latest
+    env:
+      RAILWAY_API_TOKEN: ${{ secrets.RAILWAY_API_TOKEN }}
+      RAILWAY_PROJECT_ID: ${{ vars.RAILWAY_PROJECT_ID }}
+      RAILWAY_BASE_ENVIRONMENT: ${{ vars.RAILWAY_ENVIRONMENT }}
+      RAILWAY_PR_ENVIRONMENT: pr-${{ github.event.pull_request.number }}
+    steps:
+    - uses: actions/checkout@v4
+
+    - uses: actions/download-artifact@v4
+      with:
+        name: una-package
+        path: packages
+
+    - name: Prepare artefact
+      run: |
+        mkdir -p deploy
+        unzip -q packages/*.zip -d /tmp/una-pkg
+        pkg_dir=$(find /tmp/una-pkg -mindepth 1 -maxdepth 1 -type d | head -n 1)
+        cp -a "$pkg_dir"/. deploy/
+        cp scripts/railway/Dockerfile scripts/railway/entrypoint.sh scripts/railway/railway.toml deploy/
+        chmod +x deploy/entrypoint.sh
+
+    - name: Install Railway CLI
+      run: |
+        curl -fsSL https://railway.com/install.sh | sh
+        echo "$HOME/.railway/bin" >> "$GITHUB_PATH"
+
+    - name: Provision PR environment
+      run: |
+        if [ -z "$RAILWAY_API_TOKEN" ] || [ -z "$RAILWAY_PROJECT_ID" ]; then
+          echo "Set secret RAILWAY_API_TOKEN (account token) and variable RAILWAY_PROJECT_ID" >&2
+          exit 1
+        fi
+        base="${RAILWAY_BASE_ENVIRONMENT:-production}"
+        railway link --project "$RAILWAY_PROJECT_ID" --environment "$base" --json
+        railway environment new "$RAILWAY_PR_ENVIRONMENT" || true
+        railway add --image mariadb:11 --service mariadb --environment "$RAILWAY_PR_ENVIRONMENT" \
+          --variables MARIADB_ROOT_PASSWORD=una \
+          --variables MARIADB_DATABASE=una \
+          --variables MARIADB_USER=una \
+          --variables MARIADB_PASSWORD=una \
+          || true
+        railway add --service una --environment "$RAILWAY_PR_ENVIRONMENT" || true
+        railway variable set --service una --environment "$RAILWAY_PR_ENVIRONMENT" --skip-deploys \
+          MYSQLHOST=mariadb.railway.internal \
+          MYSQLPORT=3306 \
+          MYSQLDATABASE=una \
+          MYSQLUSER=una \
+          MYSQLPASSWORD=una \
+          || true
+        railway domain --service una --environment "$RAILWAY_PR_ENVIRONMENT" || true
+
+    - name: Deploy artefact
+      run: railway up ./deploy --path-as-root --no-gitignore --ci --service una --environment "$RAILWAY_PR_ENVIRONMENT" --project "$RAILWAY_PROJECT_ID"
+
+  teardown:
+    name: Remove PR Railway environment
+    if: github.event_name == 'pull_request' && github.event.action == 'closed'
+    runs-on: ubuntu-latest
+    env:
+      RAILWAY_API_TOKEN: ${{ secrets.RAILWAY_API_TOKEN }}
+      RAILWAY_PROJECT_ID: ${{ vars.RAILWAY_PROJECT_ID }}
+      RAILWAY_BASE_ENVIRONMENT: ${{ vars.RAILWAY_ENVIRONMENT }}
+      RAILWAY_PR_ENVIRONMENT: pr-${{ github.event.pull_request.number }}
+    steps:
+    - name: Install Railway CLI
+      run: |
+        curl -fsSL https://railway.com/install.sh | sh
+        echo "$HOME/.railway/bin" >> "$GITHUB_PATH"
+
+    - name: Delete PR environment
+      run: |
+        if [ -z "$RAILWAY_API_TOKEN" ] || [ -z "$RAILWAY_PROJECT_ID" ]; then
+          echo "Set secret RAILWAY_API_TOKEN (account token) and variable RAILWAY_PROJECT_ID" >&2
+          exit 1
+        fi
+        base="${RAILWAY_BASE_ENVIRONMENT:-production}"
+        railway link --project "$RAILWAY_PROJECT_ID" --environment "$base" --json
+        railway environment delete "$RAILWAY_PR_ENVIRONMENT" -y || true

+ 39 - 0
scripts/railway/Dockerfile

@@ -0,0 +1,39 @@
+FROM php:8.3-apache
+
+RUN apt-get update && apt-get install -y --no-install-recommends \
+        libfreetype6-dev \
+        libjpeg62-turbo-dev \
+        libpng-dev \
+        libzip-dev \
+    && docker-php-ext-configure gd --with-freetype --with-jpeg \
+    && docker-php-ext-install -j$(nproc) gd mysqli pdo_mysql zip exif opcache \
+    && a2enmod rewrite \
+    && rm -rf /var/lib/apt/lists/*
+
+RUN printf '%s\n' \
+        'short_open_tag=On' \
+        'memory_limit=256M' \
+        'upload_max_filesize=64M' \
+        'post_max_size=64M' \
+        'max_input_vars=5000' \
+        'variables_order=EGPCS' \
+        > /usr/local/etc/php/conf.d/una.ini
+
+COPY --chown=www-data:www-data . /var/www/html
+
+RUN mv /var/www/html/entrypoint.sh /usr/local/bin/entrypoint.sh \
+    && chmod +x /usr/local/bin/entrypoint.sh \
+    && rm -f /var/www/html/Dockerfile /var/www/html/railway.toml \
+    && mkdir -p /var/www/html/cache /var/www/html/cache_public /var/www/html/logs /var/www/html/tmp /var/www/html/storage \
+    && chown -R www-data:www-data \
+        /var/www/html/inc \
+        /var/www/html/cache \
+        /var/www/html/cache_public \
+        /var/www/html/logs \
+        /var/www/html/tmp \
+        /var/www/html/storage \
+    && if [ -f /var/www/html/plugins/ffmpeg/ffmpeg.exe ]; then chmod 0755 /var/www/html/plugins/ffmpeg/ffmpeg.exe; fi
+
+WORKDIR /var/www/html
+ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]
+CMD ["apache2-foreground"]

+ 127 - 0
scripts/railway/entrypoint.sh

@@ -0,0 +1,127 @@
+#!/bin/sh
+set -eu
+
+cd /var/www/html
+
+PORT="${PORT:-80}"
+if [ "$PORT" != "80" ]; then
+    sed -i "s/Listen 80/Listen ${PORT}/" /etc/apache2/ports.conf
+    sed -i "s/:80/:${PORT}/g" /etc/apache2/sites-available/000-default.conf
+fi
+a2dismod mpm_event mpm_worker >/dev/null 2>&1 || true
+a2enmod mpm_prefork rewrite >/dev/null 2>&1 || true
+
+mkdir -p cache cache_public logs tmp storage
+chmod a+rwX inc cache cache_public logs tmp storage
+if [ -f plugins/ffmpeg/ffmpeg.exe ]; then
+    chmod 0755 plugins/ffmpeg/ffmpeg.exe
+fi
+
+parse_mysql_url() {
+    _url="$1"
+    _url="${_url#mysql://}"
+    _url="${_url#mariadb://}"
+    DB_USER="${_url%%:*}"
+    _url="${_url#*:}"
+    DB_PASSWORD="${_url%%@*}"
+    _url="${_url#*@}"
+    _hostport="${_url%%/*}"
+    DB_NAME="${_url#*/}"
+    DB_NAME="${DB_NAME%%\?*}"
+    case "$_hostport" in
+        *:*)
+            DB_HOST="${_hostport%:*}"
+            DB_PORT="${_hostport##*:}"
+            ;;
+        *)
+            DB_HOST="$_hostport"
+            DB_PORT="3306"
+            ;;
+    esac
+}
+
+DB_URL="${DATABASE_URL:-${MYSQL_URL:-${MARIADB_PRIVATE_URL:-${MARIADB_URL:-}}}}"
+if [ -n "$DB_URL" ]; then
+    parse_mysql_url "$DB_URL"
+else
+    DB_HOST="${MYSQLHOST:-${MARIADB_HOST:-${MARIADBHOST:-mariadb.railway.internal}}}"
+    DB_PORT="${MYSQLPORT:-${MARIADB_PORT:-${MARIADBPORT:-3306}}}"
+    DB_NAME="${MYSQLDATABASE:-${MARIADB_DATABASE:-una}}"
+    DB_USER="${MYSQLUSER:-${MARIADB_USER:-una}}"
+    DB_PASSWORD="${MYSQLPASSWORD:-${MARIADB_PASSWORD:-una}}"
+fi
+
+export DB_HOST DB_PORT DB_NAME DB_USER DB_PASSWORD
+export UNA_DB_HOST="$DB_HOST"
+export UNA_DB_PORT="$DB_PORT"
+export UNA_DB_NAME="$DB_NAME"
+export UNA_DB_USER="$DB_USER"
+export UNA_DB_PWD="$DB_PASSWORD"
+export UNA_ROOT_DIR=/var/www/html/
+export UNA_AUTO_HOSTNAME=1
+export UNA_SKIP_INSTALL_FOLDER_CHECK=1
+export UNA_SKIP_REDIRECT=1
+
+db_status() {
+    php -r '
+        $m = @new mysqli(
+            getenv("DB_HOST"),
+            getenv("DB_USER"),
+            getenv("DB_PASSWORD"),
+            getenv("DB_NAME"),
+            (int)(getenv("DB_PORT") ?: 3306)
+        );
+        if ($m->connect_error) {
+            fwrite(STDERR, $m->connect_error . "\n");
+            exit(1);
+        }
+        $r = $m->query("SHOW TABLES LIKE \"sys_options\"");
+        exit($r && $r->num_rows ? 0 : 2);
+    '
+}
+
+echo "Waiting for MariaDB at ${DB_HOST}:${DB_PORT}..."
+i=0
+rc=1
+set +e
+while [ "$i" -lt 60 ]; do
+    db_status
+    rc=$?
+    if [ "$rc" -eq 0 ] || [ "$rc" -eq 2 ]; then
+        break
+    fi
+    i=$((i + 1))
+    sleep 2
+done
+set -e
+
+if [ "$rc" -eq 1 ]; then
+    echo "MariaDB is not reachable" >&2
+    exit 1
+fi
+
+if [ "$rc" -eq 2 ]; then
+    echo "Installing UNA with cmd.php..."
+    php install/cmd.php \
+        --db_host="$DB_HOST" \
+        --db_port="$DB_PORT" \
+        --db_name="$DB_NAME" \
+        --db_user="$DB_USER" \
+        --db_password="$DB_PASSWORD" \
+        --server_http_host="${RAILWAY_PUBLIC_DOMAIN:-localhost}" \
+        --server_php_self=/install/index.php \
+        --server_doc_root=/var/www/html/ \
+        --site_title="${UNA_SITE_TITLE:-UNA}" \
+        --admin_username="${UNA_ADMIN_USERNAME:-admin}" \
+        --admin_password="${UNA_ADMIN_PASSWORD:-unauna}"
+else
+    echo "UNA already installed; writing header from environment."
+    if [ ! -f inc/header.inc.php ]; then
+        cp install/patterns/header.inc.php inc/header.inc.php
+        chmod 0666 inc/header.inc.php
+    fi
+fi
+
+chown -R www-data:www-data inc cache cache_public logs tmp storage
+
+exec "$@"

+ 7 - 0
scripts/railway/railway.toml

@@ -0,0 +1,7 @@
+[build]
+builder = "DOCKERFILE"
+dockerfilePath = "Dockerfile"
+
+[deploy]
+restartPolicyType = "ON_FAILURE"
+restartPolicyMaxRetries = 5