diff --git a/.github/workflows/build-and-package.yml b/.github/workflows/build-and-package.yml
new file mode 100644
index 00000000..fb098c88
--- /dev/null
+++ b/.github/workflows/build-and-package.yml
@@ -0,0 +1,132 @@
+name: Deploy blog
+
+on:
+ push:
+ branches:
+ - feature*
+ tags:
+ - '*'
+
+env:
+ # Rama principal del proyecto - modificar aquí para cambiar la rama por defecto
+ DEFAULT_BRANCH: v1636-2
+
+jobs:
+ build-and-package:
+ runs-on: ubuntu-latest
+
+ env:
+ BRANCH_NAME: ${{ github.ref_name }}
+ PACKAGE_NAME: docs-sp-${{ github.ref_name }}.tar.gz
+
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v3
+ with:
+ submodules: true
+ fetch-depth: 0
+
+ - name: Install pnpm
+ uses: pnpm/action-setup@v4
+ with:
+ version: 9.1.1
+
+ - name: Setup Node.js
+ uses: actions/setup-node@v3
+ with:
+ node-version: 20
+ cache: pnpm
+
+ - name: Install Deps
+ run: pnpm install --no-frozen-lockfile
+
+ - name: Build Blog
+ env:
+ NODE_OPTIONS: --max_old_space_size=8192
+ BRANCH_NAME: ${{ github.ref_name }}
+ DEFAULT_BRANCH: ${{ env.DEFAULT_BRANCH }}
+ run: pnpm run build:webpack
+
+ - name: Compress Build Output (tar.gz)
+ run: tar -czvf $PACKAGE_NAME -C dist .
+
+ - name: Upload site pack to S3
+ uses: BetaHuhn/do-spaces-action@v2
+ with:
+ access_key: ${{ vars.AWS_ACCESS_KEY_ID}}
+ secret_key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
+ space_name: 'docs-sp'
+ space_region: 'nyc3'
+ source: ${{ env.PACKAGE_NAME }}
+ out_dir: 'html/'
+ overwrite: true
+
+ check-digitalocean-secrets:
+ name: Check if Digitalocean registry information was set on secrets
+ needs:
+ - build-and-package
+ runs-on: ubuntu-latest
+ outputs:
+ is_have_secrets: ${{ steps.check_digitalocean_secrets_job.outputs.is_have_secrets }}
+ steps:
+ - id: check_digitalocean_secrets_job
+ run: |
+ if [[ "${{ vars.DIGITALOCEAN_REGISTRY }}" != "" && \
+ "${{ vars.DOCKER_REPO_DOCS_SP }}" != "" && \
+ "${{ secrets.DIGITALOCEAN_ACCESS_TOKEN }}" != "" ]]; \
+ then
+ echo "Secrets to use DigitalOcean container registry are configured in the repo"
+ echo "is_have_secrets=true" >> $GITHUB_OUTPUT
+ else
+ echo "Secrets to use DigitalOcean container registry were not configured in the repo"
+ echo "is_have_secrets=false" >> $GITHUB_OUTPUT
+ fi
+
+ build-nginx-image:
+ name: Build and Push Nginx Image
+ runs-on: ubuntu-latest
+ needs:
+ - check-digitalocean-secrets
+ if: needs.check-digitalocean-secrets.outputs.is_have_secrets == 'true'
+ steps:
+
+ - name: Checkout Repository
+ uses: actions/checkout@v4
+
+ - name: Create download directory
+ run: mkdir -p s3-downloads
+
+ - name: Download from DigitalOcean Spaces
+ env:
+ AWS_ACCESS_KEY_ID: ${{ vars.AWS_ACCESS_KEY_ID }}
+ AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
+ run: |
+ echo "Descargando archivos de docs-sp/html..."
+ aws s3 sync \
+ s3://docs-sp/html/ \
+ s3-downloads/ \
+ --endpoint-url https://nyc3.digitaloceanspaces.com \
+ --no-progress
+
+ - name: show-directory
+ run: ls -alh s3-downloads
+
+ - name: Set up Docker Buildx
+ uses: docker/setup-buildx-action@v3
+
+ - name: Log in to DigitalOcean Container Registry
+ uses: docker/login-action@v3
+ with:
+ registry: registry.digitalocean.com
+ username: ${{ secrets.DIGITALOCEAN_ACCESS_TOKEN }}
+ password: ${{ secrets.DIGITALOCEAN_ACCESS_TOKEN }}
+
+ - name: Build and push Nginx image
+ uses: docker/build-push-action@v5
+ with:
+ context: .
+ push: true
+ tags: ${{ vars.DIGITALOCEAN_REGISTRY }}/${{ vars.DOCKER_REPO_DOCS_SP }}:main
+ file: ./Dockerfile
+ build-args: |
+ DEFAULT_BRANCH=${{ env.DEFAULT_BRANCH }}
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
deleted file mode 100644
index e5d9de57..00000000
--- a/.github/workflows/test.yml
+++ /dev/null
@@ -1,67 +0,0 @@
-name: Test blog
-
-on:
- push:
- pull_request:
-
-jobs:
- build-test:
- name: Test build using ${{ matrix.bundler }}
- runs-on: ubuntu-latest
- strategy:
- fail-fast: false
- matrix:
- bundler:
- - webpack
- - vite
- steps:
- - name: Checkout
- uses: actions/checkout@v3
- with:
- persist-credentials: false
- submodules: true
-
- - name: Install pnpm
- uses: pnpm/action-setup@v4
- with:
- version: 9.1.1
-
- - name: Setup Node.js
- uses: actions/setup-node@v3
- with:
- node-version: 20
- cache: pnpm
-
- - name: Install Deps
- run: pnpm install --no-frozen-lockfile
-
- - name: Build Blog with ${{ matrix.bundler }}
- env:
- NODE_OPTIONS: --max_old_space_size=8192
- run: pnpm run build:${{ matrix.bundler }}
-
- linter-test:
- runs-on: ubuntu-latest
- steps:
- - name: Checkout
- uses: actions/checkout@v3
- with:
- persist-credentials: false
- submodules: true
-
- - name: Install pnpm
- uses: pnpm/action-setup@v4
- with:
- version: 9.1.1
-
- - name: Setup Node.js
- uses: actions/setup-node@v3
- with:
- node-version: 20
- cache: pnpm
-
- - name: Install Deps
- run: pnpm install --no-frozen-lockfile
-
- - name: Linter test
- run: pnpm run lint
diff --git a/Dockerfile b/Dockerfile
new file mode 100644
index 00000000..014af459
--- /dev/null
+++ b/Dockerfile
@@ -0,0 +1,31 @@
+# Usar la última versión estable de nginx
+FROM nginx:stable
+
+# Argumentos para configuración (debe ser pasado desde el build)
+ARG DEFAULT_BRANCH
+
+# Convertir los ARGs en variables de entorno
+ENV DEFAULT_BRANCH=${DEFAULT_BRANCH}
+
+# Crear directorio temporal para los archivos comprimidos
+WORKDIR /tmp
+
+# Copiar todos los archivos tar.gz descargados de S3
+COPY s3-downloads/*.tar.gz /tmp/
+
+# Copiar configuración estática de nginx
+COPY nginx.conf /etc/nginx/conf.d/default.conf
+
+# Copiar el script de configuración de base paths
+COPY configure-base-paths.sh /tmp/configure-base-paths.sh
+
+# Dar permisos de ejecución y ejecutar el script
+RUN chmod +x /tmp/configure-base-paths.sh && \
+ /tmp/configure-base-paths.sh && \
+ rm /tmp/configure-base-paths.sh
+
+# Exponer el puerto 80
+EXPOSE 80
+
+# El comando por defecto de nginx ya está definido en la imagen base
+# nginx -g "daemon off;"
diff --git a/configure-base-paths.sh b/configure-base-paths.sh
new file mode 100644
index 00000000..2f66d005
--- /dev/null
+++ b/configure-base-paths.sh
@@ -0,0 +1,87 @@
+#!/bin/bash
+set -e
+
+# La variable DEFAULT_BRANCH debe ser pasada como variable de entorno
+if [ -z "$DEFAULT_BRANCH" ]; then
+ echo "ERROR: DEFAULT_BRANCH no está definida"
+ exit 1
+fi
+
+echo "=== Configurando base paths para cada directorio ==="
+echo "DEFAULT_BRANCH: ${DEFAULT_BRANCH}"
+echo ""
+
+# Procesar cada archivo tar.gz descargado
+# TODAS las ramas van a subdirectorios (incluyendo la principal)
+for file in /tmp/*.tar.gz; do
+ if [ -f "$file" ]; then
+ filename=$(basename "$file")
+ dirname=$(basename "$file" .tar.gz)
+ # Eliminar el prefijo "docs-sp-" si existe
+ branch=${dirname#docs-sp-}
+
+ echo "Procesando: $branch"
+
+ # TODAS las ramas van a su propio subdirectorio
+ BASE_PATH="/${branch}/"
+ TARGET_DIR="/usr/share/nginx/html/${branch}"
+
+ if [ "$branch" = "${DEFAULT_BRANCH}" ]; then
+ echo " -> Base path: ${BASE_PATH} (rama principal)"
+ else
+ echo " -> Base path: ${BASE_PATH}"
+ fi
+
+ # Crear el directorio de destino
+ mkdir -p "${TARGET_DIR}"
+
+ # Descomprimir
+ echo " -> Descomprimiendo en ${TARGET_DIR}"
+ tar -xzf "$file" -C "${TARGET_DIR}/"
+
+ # Agregar/modificar el base tag en todos los archivos HTML
+ echo " -> Configurando base path en archivos HTML"
+ find "${TARGET_DIR}" -type f -name "*.html" | while read html_file; do
+ # Verificar si ya existe un
Redireccionando a /${DEFAULT_BRANCH}/...
+ + + +EOF +echo " -> Redirección creada: / → /${DEFAULT_BRANCH}/" + +echo "" +echo "=== Estructura de directorios final ===" +ls -la /usr/share/nginx/html/ +echo "" + +# Limpiar los archivos comprimidos +rm -f /tmp/*.tar.gz + +echo "=== Configuración completada ===" diff --git a/docker-compose/.env b/docker-compose/.env new file mode 100644 index 00000000..1ac9bf70 --- /dev/null +++ b/docker-compose/.env @@ -0,0 +1,7 @@ + +GENERAL_VIRTUAL_HOST="docs1.dev.solopcloud.com" +GENERAL_LETSENCRYPT_EMAIL=${GENERAL_STACK_NAME}@solopcloud.com + +# Networks +DEFAULT_NETWORK="proxy.network" +IS_EXTERNAL_NETWORK=true \ No newline at end of file diff --git a/docker-compose/docker-compose.yml b/docker-compose/docker-compose.yml new file mode 100644 index 00000000..692e6a63 --- /dev/null +++ b/docker-compose/docker-compose.yml @@ -0,0 +1,29 @@ +services: + docs-sp-nginx: + image: registry.digitalocean.com/spuy/docs-sp:main + container_name: docs-sp-nginx + ports: + - "8081:80" + restart: unless-stopped + environment: + TZ: America/Montevideo + VIRTUAL_HOST: "${GENERAL_VIRTUAL_HOST}" + VIRTUAL_PORT: 80 + LETSENCRYPT_HOST: "${GENERAL_VIRTUAL_HOST}" + LETSENCRYPT_EMAIL: test@solopcloud.com + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:80"] + interval: 30s + timeout: 10s + retries: 3 + start_period: 10s + networks: + - private_network + - shared_network + +networks: + shared_network: + name: ${DEFAULT_NETWORK} + external: ${IS_EXTERNAL_NETWORK} + private_network: + name: docs1.network \ No newline at end of file diff --git a/nginx.conf b/nginx.conf new file mode 100644 index 00000000..540ea057 --- /dev/null +++ b/nginx.conf @@ -0,0 +1,47 @@ +server { + listen 80; + server_name localhost; + + root /usr/share/nginx/html; + index index.html index.htm; + + # Logs + access_log /var/log/nginx/access.log; + error_log /var/log/nginx/error.log; + + # Desactivar logs para favicon + location = /favicon.ico { + log_not_found off; + access_log off; + } + + # Desactivar logs para robots.txt + location = /robots.txt { + log_not_found off; + access_log off; + } + + # Configuración para archivos estáticos comunes (debe ir primero para mayor prioridad) + location ~* \.(jpg|jpeg|png|gif|ico|css|js|svg|woff|woff2|ttf|eot|json|xml|txt|pdf|map)$ { + expires 1y; + add_header Cache-Control "public, immutable"; + try_files $uri =404; + } + + # Configuración para cada subdirectorio (ramas/tags) + # Cada directorio se trata como una SPA independiente + location ~ ^/([^/]+)(/|$) { + set $branch_dir $1; + + # Primero intentar servir el archivo exacto + # Si no existe, intentar como directorio con index.html + # Si tampoco existe, servir el index.html del directorio raíz de esa rama (para SPAs) + try_files $uri $uri/ /$branch_dir/index.html =404; + } + + # Configuración para la raíz - página de redirección + # Esto debe ir al final para que tenga menor prioridad + location = / { + try_files /index.html =404; + } +} diff --git a/src/.vuepress/config.ts b/src/.vuepress/config.ts index 87f0d276..b18a2ed9 100644 --- a/src/.vuepress/config.ts +++ b/src/.vuepress/config.ts @@ -3,7 +3,28 @@ import theme from "./theme"; import { searchPlugin } from '@vuepress/plugin-search' import { path } from "@vuepress/utils"; +// Configuración dinámica del base path según la rama +// TODAS las ramas usan su propio base path (incluyendo la rama principal) +// La variable BRANCH_NAME debe ser pasada desde el build +const branchName = process.env.BRANCH_NAME; + +if (!branchName) { + throw new Error('ERROR: BRANCH_NAME no está definida. Debe ser pasada desde el build.'); +} + +// Siempre usar /nombre-de-la-rama/ (sin excepciones) +const basePath = `/${branchName}/`; + +console.log('========================================'); +console.log('VuePress Base Path Configuration'); +console.log('========================================'); +console.log('BRANCH_NAME:', branchName); +console.log('Base Path:', basePath); +console.log('========================================'); + export default defineUserConfig({ + base: basePath, + alias: { "@Releases": path.resolve(__dirname, "components/Releases.vue"), }, diff --git a/src/docs/test-page/README.md b/src/docs/test-page/README.md new file mode 100644 index 00000000..ff8e72a2 --- /dev/null +++ b/src/docs/test-page/README.md @@ -0,0 +1,5 @@ + +### Página de Prueba - Nuevo Sitio + +Lorem Ipsum is simply dummy text of the printing and typesetting industry. +