diff --git a/.github/workflows/_deploy-production.yml b/.github/workflows/_deploy-production.yml index 679835db5..ad265e98d 100644 --- a/.github/workflows/_deploy-production.yml +++ b/.github/workflows/_deploy-production.yml @@ -31,17 +31,6 @@ jobs: with: fetch-depth: 0 - - name: Checkout werf repo - uses: actions/checkout@v6 - with: - repository: werf/werf - path: werf - fetch-depth: 0 - - - name: Inject trdl_channels.yaml - run: | - cp werf/trdl_channels.yaml .helm/trdl_channels.yaml - - name: Install werf uses: werf/actions/install@v2 @@ -86,7 +75,6 @@ jobs: env: WERF_REPO: ghcr.io/${{ github.repository_owner }}/werfio-guides WERF_STAGES_STORAGE: ghcr.io/werf/werfio-guides-stages - WERF_SET_ACTIVE_RELEASE: global.active_release=2 WERFIO_GITHUB_TOKEN: ${{ secrets.API_TOKEN }} WERF_NAMESPACE: "werfio-production" WERF_RELEASE: "werfio-site-production" diff --git a/.github/workflows/deploy-production.yml b/.github/workflows/deploy-production.yml index a897f913e..c55582fa6 100644 --- a/.github/workflows/deploy-production.yml +++ b/.github/workflows/deploy-production.yml @@ -4,6 +4,9 @@ on: push: branches: - main + tags: + - "v2*" + - "v1.2*" workflow_dispatch: inputs: targetCluster: diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index cc4c632ee..25a37204b 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -6,16 +6,14 @@ on: workflow_dispatch: env: - WERF_ENV: "production" WERF_REPO: "ghcr.io/${{ github.repository_owner }}/werfio-guides" WERF_STAGES_STORAGE: "ghcr.io/werf/werfio-guides-stages" - WERF_SET_ACTIVE_RELEASE: "global.active_release=2" WERFIO_GITHUB_TOKEN: "${{ secrets.API_TOKEN }}" jobs: converge: name: Deploy - if: contains(github.event.pull_request.labels.*.name, 'test website') || contains(github.event.pull_request.labels.*.name, 'stage website') + if: contains(github.event.pull_request.labels.*.name, 'test website') runs-on: prod-github-runner-0 steps: - name: Checkout code @@ -23,17 +21,6 @@ jobs: with: fetch-depth: 0 - - name: Checkout werf repo - uses: actions/checkout@v6 - with: - repository: werf/werf - path: werf - fetch-depth: 0 - - - name: Inject trdl_channels.yaml - run: | - cp werf/trdl_channels.yaml .helm/trdl_channels.yaml - - name: Install werf uses: werf/actions/install@v2 @@ -50,19 +37,6 @@ jobs: WERF_KUBE_CONFIG_BASE64: ${{ secrets.KUBECONFIG_BASE64_DEV }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - name: Deploy to stage - if: contains(github.event.pull_request.labels.*.name, 'stage website') - run: | - . $(werf ci-env github --as-file) - werf converge - env: - WERF_NAMESPACE: "werfio-stage" - WERF_RELEASE: "werfio-site-stage" - WERF_LOG_VERBOSE: "on" - WERF_ENV: "stage" - WERF_KUBE_CONFIG_BASE64: ${{ secrets.KUBECONFIG_BASE64_DEV }} - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - notification: name: Notification if: always() diff --git a/.helm/templates/12-backend.yaml b/.helm/templates/12-backend.yaml index f8ea6406d..f264d2a1b 100644 --- a/.helm/templates/12-backend.yaml +++ b/.helm/templates/12-backend.yaml @@ -37,8 +37,12 @@ spec: name: http protocol: TCP env: - - name: ACTIVE_RELEASE - value: {{ .Values.global.active_release | quote }} + - name: CURRENT_DOCS_MAJOR + value: {{ .Values.docs.currentRoot | quote }} + - name: SUPPORTED_DOCS_MAJOR_VERSIONS + value: {{ join "," .Values.docs.supportedRoots | quote }} + - name: DOCS_LATEST_ALIAS_ENABLED + value: {{ .Values.docs.latestAliasEnabled | quote }} - name: LOG_LEVEL value: "info" {{- if ne .Values.werf.env "production" }} @@ -53,13 +57,6 @@ spec: httpGet: path: /health port: 8080 - volumeMounts: - - name: trdl-data - mountPath: /app/trdl - volumes: - - name: trdl-data - configMap: - name: trdl-data --- apiVersion: v1 kind: Service @@ -96,15 +93,3 @@ spec: selector: matchLabels: service: backend ---- -apiVersion: v1 -kind: ConfigMap -metadata: - name: trdl-data -data: - trdl_channels.yaml: | -{{- if eq .Values.werf.env "production" }} -{{ .Files.Get "trdl_channels.yaml" | indent 4 }} -{{- else }} -{{ .Files.Get "trdl_channels-dev.yaml" | indent 4 }} -{{- end }} diff --git a/.helm/templates/20-ingress-tuf-router.yaml b/.helm/templates/20-ingress-tuf-router.yaml index 89caeb1fa..3ca94d792 100644 --- a/.helm/templates/20-ingress-tuf-router.yaml +++ b/.helm/templates/20-ingress-tuf-router.yaml @@ -1,8 +1,4 @@ {{- $host := pluck .Values.werf.env .Values.host | first | default .Values.host._default }} -{{- if hasPrefix "review" .Values.werf.env }} -{{- $host = ( printf "%s.%s" .Values.werf.env (pluck "dev" .Values.host | first | default .Values.host._default ) | lower ) }} -{{- end }} -{{- $ruHost := pluck .Values.werf.env .Values.ruHost | first | default (printf "ru.%s" $host) }} {{- $ingressSecretName := pluck .Values.werf.env .Values.ingressSecretName | first | default .Values.ingressSecretName._default }} apiVersion: networking.k8s.io/v1 @@ -16,7 +12,7 @@ spec: - hosts: - {{ $host }} {{- if eq .Values.werf.env "production" }} - - {{ $ruHost }} + - ru.{{ $host }} secretName: {{ $ingressSecretName }} {{- else }} - ru-{{ $host }} @@ -41,7 +37,7 @@ spec: port: name: http {{- if eq .Values.werf.env "production" }} - - host: {{ $ruHost }} + - host: ru.{{ $host }} http: paths: - path: /targets/ diff --git a/.helm/templates/20-ingress.yaml b/.helm/templates/20-ingress.yaml index e78dd441f..a25968b73 100644 --- a/.helm/templates/20-ingress.yaml +++ b/.helm/templates/20-ingress.yaml @@ -1,8 +1,4 @@ {{- $host := pluck .Values.werf.env .Values.host | first | default .Values.host._default }} -{{- if hasPrefix "review" .Values.werf.env }} -{{- $host = ( printf "%s.%s" .Values.werf.env (pluck "dev" .Values.host | first | default .Values.host._default ) | lower ) }} -{{- end }} -{{- $ruHost := pluck .Values.werf.env .Values.ruHost | first | default (printf "ru.%s" $host) }} {{- $wwwHost := printf "www.%s" $host }} {{- $ingressSecretName := pluck .Values.werf.env .Values.ingressSecretName | first | default .Values.ingressSecretName._default }} {{- if eq .Values.werf.env "production" }} @@ -24,7 +20,7 @@ spec: - hosts: - {{ $host }} - {{ $wwwHost }} - - {{ $ruHost }} + - ru.{{ $host }} secretName: {{ $ingressSecretName }} rules: - host: {{ $host }} @@ -37,7 +33,7 @@ spec: name: backend port: name: http - - host: {{ $ruHost }} + - host: ru.{{ $host }} http: paths: - path: / @@ -91,7 +87,7 @@ metadata: ssi_silent_errors on; {{- include "rewrites" . | indent 6 }} nginx.ingress.kubernetes.io/auth-response-headers: X-Auth-Request-User,X-Auth-Request-Email - nginx.ingress.kubernetes.io/auth-signin: https://$host/dex-authenticator/sign_in + nginx.ingress.kubernetes.io/auth-signin: https://ru-{{ $host }}/dex-authenticator/sign_in nginx.ingress.kubernetes.io/auth-url: https://werfio-ru-dex-authenticator.{{ $.Values.werf.namespace }}.svc.cluster.local/dex-authenticator/auth spec: ingressClassName: {{ include "ingressClassName" . }} diff --git a/.helm/templates/_helpers.tpl b/.helm/templates/_helpers.tpl index 17ca01e65..2d076e145 100644 --- a/.helm/templates/_helpers.tpl +++ b/.helm/templates/_helpers.tpl @@ -3,7 +3,7 @@ resources: requests: memory: {{ pluck .Values.werf.env .Values.resources.requests.memory | first | default .Values.resources.requests.memory._default }} limits: - memory: {{ pluck .Values.werf.env .Values.resources.requests.memory | first | default .Values.resources.requests.memory._default }} + memory: {{ pluck .Values.werf.env .Values.resources.limits.memory | first | default .Values.resources.limits.memory._default }} {{- end }} {{- define "imagePullSecrets" }} diff --git a/.helm/templates/_rewrites.tpl b/.helm/templates/_rewrites.tpl index c02fac529..1547e46d7 100644 --- a/.helm/templates/_rewrites.tpl +++ b/.helm/templates/_rewrites.tpl @@ -10,32 +10,30 @@ rewrite ^/css/(?.+) rewrite ^/images/(?.+) /assets/images/$tail redirect; rewrite ^/docs\.html$ /docs/ redirect; -rewrite ^/docs/(?v\d+(?:\.\d+(?:\.\d+(?:[^/]+)?)?)?|latest)$ /docs/$ver/ redirect; -rewrite ^/docs/(?v\d+(?:\.\d+(?:\.\d+(?:[^/]+)?)?)?|latest)/index\.html$ /docs/$ver/ redirect; -rewrite ^/(?v\d+(?:\.\d+(?:\.\d+(?:[^/]+)?)?)?|latest)/docs\.html$ /docs/$ver/ redirect; -rewrite ^/(?v\d+(?:\.\d+(?:\.\d+(?:[^/]+)?)?)?|latest)/docs/?$ /docs/$ver/ redirect; -rewrite ^/(?v\d+(?:\.\d+(?:\.\d+(?:[^/]+)?)?)?|latest)/docs/(?.+) /docs/$ver/$tail redirect; +rewrite ^/docs/(?latest|pr-[^/]+|v2(?:\.[^/]+)?|v1\.2(?:\.[^/]+)?)$ /docs/$ver/ redirect; +rewrite ^/docs/(?latest|pr-[^/]+|v2(?:\.[^/]+)?|v1\.2(?:\.[^/]+)?)/index\.html$ /docs/$ver/ redirect; +rewrite ^/(?latest|pr-[^/]+|v2(?:\.[^/]+)?|v1\.2(?:\.[^/]+)?)/docs\.html$ /docs/$ver/ redirect; +rewrite ^/(?latest|pr-[^/]+|v2(?:\.[^/]+)?|v1\.2(?:\.[^/]+)?)/docs/?$ /docs/$ver/ redirect; +rewrite ^/(?latest|pr-[^/]+|v2(?:\.[^/]+)?|v1\.2(?:\.[^/]+)?)/docs/(?.+) /docs/$ver/$tail redirect; rewrite ^/documentation\.html$ /docs/ redirect; rewrite ^/documentation/?$ /docs/ redirect; -rewrite ^/documentation/(?v\d+(?:\.\d+(?:\.\d+(?:[^/]+)?)?)?|latest)/?$ /docs/$ver/ redirect; -rewrite ^/documentation/(?v\d+(?:\.\d+(?:\.\d+(?:[^/]+)?)?)?|latest)/index\.html$ /docs/$ver/ redirect; -rewrite ^/documentation/(?v\d+(?:\.\d+(?:\.\d+(?:[^/]+)?)?)?|latest)/(?.+) /docs/$ver/$tail redirect; -rewrite ^/(?v\d+(?:\.\d+(?:\.\d+(?:[^/]+)?)?)?|latest)/documentation\.html$ /docs/$ver/ redirect; -rewrite ^/(?v\d+(?:\.\d+(?:\.\d+(?:[^/]+)?)?)?|latest)/documentation/?$ /docs/$ver/ redirect; -rewrite ^/(?v\d+(?:\.\d+(?:\.\d+(?:[^/]+)?)?)?|latest)/documentation/(?.+) /docs/$ver/$tail redirect; - -rewrite ^/(?v1\.1(?:\.\d+(?:[^/]+)?)?|latest)/how_to/?$ /docs/$ver/how_to/ redirect; -rewrite ^/(?v1\.1(?:\.\d+(?:[^/]+)?)?|latest)/how_to/(?.+) /docs/$ver/how_to/$tail redirect; +rewrite ^/documentation/(?latest|pr-[^/]+|v2(?:\.[^/]+)?|v1\.2(?:\.[^/]+)?)/?$ /docs/$ver/ redirect; +rewrite ^/documentation/(?latest|pr-[^/]+|v2(?:\.[^/]+)?|v1\.2(?:\.[^/]+)?)/index\.html$ /docs/$ver/ redirect; +rewrite ^/documentation/(?latest|pr-[^/]+|v2(?:\.[^/]+)?|v1\.2(?:\.[^/]+)?)/(?.+) /docs/$ver/$tail redirect; +rewrite ^/(?latest|pr-[^/]+|v2(?:\.[^/]+)?|v1\.2(?:\.[^/]+)?)/documentation\.html$ /docs/$ver/ redirect; +rewrite ^/(?latest|pr-[^/]+|v2(?:\.[^/]+)?|v1\.2(?:\.[^/]+)?)/documentation/?$ /docs/$ver/ redirect; +rewrite ^/(?latest|pr-[^/]+|v2(?:\.[^/]+)?|v1\.2(?:\.[^/]+)?)/documentation/(?.+) /docs/$ver/$tail redirect; ############################################ # Temporary versioned redirects ############################################ rewrite ^/docs/?$ /docs/v2/ redirect; -rewrite ^/docs/(?!(v\d+(?:\.\d+(?:\.\d+(?:[^/]+)?)?)?|latest)/)(?:.+) /docs/v2/ redirect; +rewrite ^/docs/(?!(latest|pr-[^/]+|v2(?:\.[^/]+)?|v1\.2(?:\.[^/]+)?)/)(?:.+) /docs/v2/ redirect; rewrite ^/docs/(?v2(?:\.\d+(?:\.\d+(?:[^/]+)?)?)?|latest)/?$ /docs/$ver/usage/project_configuration/overview.html redirect; +rewrite ^/docs/(?pr-[^/]+)/?$ /docs/$ver/usage/project_configuration/overview.html redirect; rewrite ^/docs/(?v2(?:\.\d+(?:\.\d+(?:[^/]+)?)?)?|latest)/usage/?$ /docs/$ver/usage/project_configuration/overview.html redirect; rewrite ^/docs/(?v2(?:\.\d+(?:\.\d+(?:[^/]+)?)?)?|latest)/usage/project_configuration/?$ /docs/$ver/usage/project_configuration/overview.html redirect; rewrite ^/docs/(?v2(?:\.\d+(?:\.\d+(?:[^/]+)?)?)?|latest)/usage/build/?$ /docs/$ver/usage/build/overview.html redirect; @@ -59,14 +57,6 @@ rewrite ^/docs/(?v1\.2(?:\.\d+(?:[^/]+)?)?|latest)/reference/?$ rewrite ^/docs/(?v1\.2(?:\.\d+(?:[^/]+)?)?|latest)/reference/cli/?$ /docs/$ver/reference/cli/overview.html redirect; rewrite ^/docs/(?v1\.2(?:\.\d+(?:[^/]+)?)?|latest)/resources/?$ /docs/$ver/resources/cheat_sheet.html redirect; -rewrite ^/docs/(?v1\.1(?:\.\d+(?:[^/]+)?)?|latest)/?$ /docs/$ver/index.html redirect; -rewrite ^/docs/(?v1\.1(?:\.\d+(?:[^/]+)?)?|latest)/configuration/?$ /docs/$ver/configuration/introduction.html redirect; -rewrite ^/docs/(?v1\.1(?:\.\d+(?:[^/]+)?)?|latest)/configuration/stapel_image/?$ /docs/$ver/configuration/stapel_image/naming.html redirect; -rewrite ^/docs/(?v1\.1(?:\.\d+(?:[^/]+)?)?|latest)/reference/?$ /docs/$ver/reference/stages_and_images.html redirect; -rewrite ^/docs/(?v1\.1(?:\.\d+(?:[^/]+)?)?|latest)/reference/deploy_process/?$ /docs/$ver/reference/deploy_process/deploy_into_kubernetes.html redirect; -rewrite ^/docs/(?v1\.1(?:\.\d+(?:[^/]+)?)?|latest)/reference/plugging_into_cicd/?$ /docs/$ver/reference/plugging_into_cicd/overview.html redirect; -rewrite ^/docs/(?v1\.1(?:\.\d+(?:[^/]+)?)?|latest)/reference/development_and_debug/?$ /docs/$ver/reference/development_and_debug/setup_minikube.html redirect; -rewrite ^/docs/(?v1\.1(?:\.\d+(?:[^/]+)?)?|latest)/reference/toolbox/?$ /docs/$ver/reference/toolbox/slug.html redirect; ############################################ # Redirects for moved or deleted urls @@ -79,76 +69,76 @@ rewrite ^/how_it_works\.html rewrite ^/introduction\.html$ /#how-it-works redirect; ############################################ -# v1.1/v1.2 redirects for moved or deleted urls +# v1.2 redirects for moved or deleted urls ############################################ -rewrite ^/docs/(?v1\.[12](?:\.\d+(?:[^/]+)?)?|latest)/quickstart\.html$ /docs/$ver/ redirect; -rewrite ^/docs/(?v1\.[12](?:\.\d+(?:[^/]+)?)?|latest)/using_with_ci_cd_systems\.html$ /docs/$ver/usage/integration_with_ci_cd_systems.html redirect; - -rewrite ^/docs/(?v1\.[12](?:\.\d+(?:[^/]+)?)?|latest)/advanced/supported_registry_implementations\.html$ /docs/$ver/usage/cleanup/cr_cleanup.html redirect; -rewrite ^/docs/(?v1\.[12](?:\.\d+(?:[^/]+)?)?|latest)/advanced/buildah_mode\.html$ /docs/$ver/usage/build/process.html redirect; -rewrite ^/docs/(?v1\.[12](?:\.\d+(?:[^/]+)?)?|latest)/advanced/building_images_with_stapel/artifacts\.html$ /docs/$ver/usage/build/stapel/imports.html redirect; -rewrite ^/docs/(?v1\.[12](?:\.\d+(?:[^/]+)?)?|latest)/advanced/building_images_with_stapel/assembly_instructions\.html$ /docs/$ver/usage/build/stapel/instructions.html redirect; -rewrite ^/docs/(?v1\.[12](?:\.\d+(?:[^/]+)?)?|latest)/advanced/building_images_with_stapel/base_image\.html$ /docs/$ver/usage/build/stapel/base.html redirect; -rewrite ^/docs/(?v1\.[12](?:\.\d+(?:[^/]+)?)?|latest)/advanced/building_images_with_stapel/docker_directive\.html$ /docs/$ver/usage/build/stapel/dockerfile.html redirect; -rewrite ^/docs/(?v1\.[12](?:\.\d+(?:[^/]+)?)?|latest)/advanced/building_images_with_stapel/git_directive\.html$ /docs/$ver/usage/build/stapel/git.html redirect; -rewrite ^/docs/(?v1\.[12](?:\.\d+(?:[^/]+)?)?|latest)/advanced/building_images_with_stapel/import_directive\.html$ /docs/$ver/usage/build/stapel/imports.html redirect; -rewrite ^/docs/(?v1\.[12](?:\.\d+(?:[^/]+)?)?|latest)/advanced/building_images_with_stapel/mount_directive\.html$ /docs/$ver/usage/build/stapel/mounts.html redirect; -rewrite ^/docs/(?v1\.[12](?:\.\d+(?:[^/]+)?)?|latest)/advanced/bundles\.html$ /docs/$ver/usage/distribute/bundles.html redirect; -rewrite ^/docs/(?v1\.[12](?:\.\d+(?:[^/]+)?)?|latest)/advanced/ci_cd/ci_cd_workflow_basics\.html$ /docs/$ver/usage/integration_with_ci_cd_systems.html redirect; -rewrite ^/docs/(?v1\.[12](?:\.\d+(?:[^/]+)?)?|latest)/advanced/ci_cd/generic_ci_cd_integration\.html$ /docs/$ver/usage/integration_with_ci_cd_systems.html redirect; -rewrite ^/docs/(?v1\.[12](?:\.\d+(?:[^/]+)?)?|latest)/advanced/ci_cd/github_actions\.html$ /docs/$ver/usage/integration_with_ci_cd_systems.html redirect; -rewrite ^/docs/(?v1\.[12](?:\.\d+(?:[^/]+)?)?|latest)/advanced/ci_cd/gitlab_ci_cd\.html$ /docs/$ver/usage/integration_with_ci_cd_systems.html redirect; -rewrite ^/docs/(?v1\.[12](?:\.\d+(?:[^/]+)?)?|latest)/advanced/ci_cd/run_in_container/run_in_docker_container\.html$ /docs/$ver/usage/integration_with_ci_cd_systems.html redirect; -rewrite ^/docs/(?v1\.[12](?:\.\d+(?:[^/]+)?)?|latest)/advanced/ci_cd/run_in_container/run_in_kubernetes\.html$ /docs/$ver/usage/integration_with_ci_cd_systems.html redirect; -rewrite ^/docs/(?v1\.[12](?:\.\d+(?:[^/]+)?)?|latest)/advanced/ci_cd/run_in_container/use_docker_container\.html$ /docs/$ver/usage/integration_with_ci_cd_systems.html redirect; -rewrite ^/docs/(?v1\.[12](?:\.\d+(?:[^/]+)?)?|latest)/advanced/ci_cd/run_in_container/use_github_actions_with_docker_executor\.html$ /docs/$ver/usage/integration_with_ci_cd_systems.html redirect; -rewrite ^/docs/(?v1\.[12](?:\.\d+(?:[^/]+)?)?|latest)/advanced/ci_cd/run_in_container/use_github_actions_with_kubernetes_executor\.html$ /docs/$ver/usage/integration_with_ci_cd_systems.html redirect; -rewrite ^/docs/(?v1\.[12](?:\.\d+(?:[^/]+)?)?|latest)/advanced/ci_cd/run_in_container/use_gitlab_ci_cd_with_docker_executor\.html$ /docs/$ver/usage/integration_with_ci_cd_systems.html redirect; -rewrite ^/docs/(?v1\.[12](?:\.\d+(?:[^/]+)?)?|latest)/advanced/ci_cd/run_in_container/use_gitlab_ci_cd_with_kubernetes_executor\.html$ /docs/$ver/usage/integration_with_ci_cd_systems.html redirect; -rewrite ^/docs/(?v1\.[12](?:\.\d+(?:[^/]+)?)?|latest)/advanced/ci_cd/run_in_container/use_kubernetes\.html$ /docs/$ver/usage/integration_with_ci_cd_systems.html redirect; -rewrite ^/docs/(?v1\.[12](?:\.\d+(?:[^/]+)?)?|latest)/advanced/ci_cd/werf_with_argocd/ci_cd_flow_overview\.html$ /docs/$ver/usage/integration_with_ci_cd_systems.html redirect; -rewrite ^/docs/(?v1\.[12](?:\.\d+(?:[^/]+)?)?|latest)/advanced/ci_cd/werf_with_argocd/configure_ci_cd\.html$ /docs/$ver/usage/integration_with_ci_cd_systems.html redirect; -rewrite ^/docs/(?v1\.[12](?:\.\d+(?:[^/]+)?)?|latest)/advanced/ci_cd/werf_with_argocd/prepare_kubernetes_cluster\.html$ /docs/$ver/usage/integration_with_ci_cd_systems.html redirect; -rewrite ^/docs/(?v1\.[12](?:\.\d+(?:[^/]+)?)?|latest)/advanced/cleanup\.html$ /docs/$ver/usage/cleanup/cr_cleanup.html redirect; -rewrite ^/docs/(?v1\.[12](?:\.\d+(?:[^/]+)?)?|latest)/advanced/configuration/giterminism\.html$ /docs/$ver/usage/project_configuration/giterminism.html redirect; -rewrite ^/docs/(?v1\.[12](?:\.\d+(?:[^/]+)?)?|latest)/advanced/configuration/organizing_configuration\.html$ /docs/$ver/usage/project_configuration/werf_yaml_template_engine.html redirect; -rewrite ^/docs/(?v1\.[12](?:\.\d+(?:[^/]+)?)?|latest)/advanced/configuration/supported_go_templates\.html$ /docs/$ver/usage/project_configuration/werf_yaml_template_engine.html redirect; -rewrite ^/docs/(?v1\.[12](?:\.\d+(?:[^/]+)?)?|latest)/advanced/development_and_debug/stage_introspection\.html$ /docs/$ver/usage/build/stapel/base.html redirect; -rewrite ^/docs/(?v1\.[12](?:\.\d+(?:[^/]+)?)?|latest)/advanced/giterminism\.html$ /docs/$ver/usage/project_configuration/giterminism.html redirect; -rewrite ^/docs/(?v1\.[12](?:\.\d+(?:[^/]+)?)?|latest)/advanced/helm/configuration/chart\.html$ /docs/$ver/usage/deploy/charts.html redirect; -rewrite ^/docs/(?v1\.[12](?:\.\d+(?:[^/]+)?)?|latest)/advanced/helm/configuration/chart_dependencies\.html$ /docs/$ver/usage/deploy/charts.html redirect; -rewrite ^/docs/(?v1\.[12](?:\.\d+(?:[^/]+)?)?|latest)/advanced/helm/configuration/giterminism\.html$ /docs/$ver/usage/project_configuration/giterminism.html redirect; -rewrite ^/docs/(?v1\.[12](?:\.\d+(?:[^/]+)?)?|latest)/advanced/helm/configuration/secrets\.html$ /docs/$ver/usage/deploy/values.html redirect; -rewrite ^/docs/(?v1\.[12](?:\.\d+(?:[^/]+)?)?|latest)/advanced/helm/configuration/templates\.html$ /docs/$ver/usage/deploy/templates.html redirect; -rewrite ^/docs/(?v1\.[12](?:\.\d+(?:[^/]+)?)?|latest)/advanced/helm/configuration/values\.html$ /docs/$ver/usage/deploy/values.html redirect; -rewrite ^/docs/(?v1\.[12](?:\.\d+(?:[^/]+)?)?|latest)/advanced/helm/deploy_process/annotating_and_labeling\.html$ /docs/$ver/usage/deploy/releases.html redirect; -rewrite ^/docs/(?v1\.[12](?:\.\d+(?:[^/]+)?)?|latest)/advanced/helm/deploy_process/deployment_order\.html$ /docs/$ver/usage/deploy/deployment_order.html redirect; -rewrite ^/docs/(?v1\.[12](?:\.\d+(?:[^/]+)?)?|latest)/advanced/helm/deploy_process/external_dependencies\.html$ /docs/$ver/usage/deploy/deployment_order.html redirect; -rewrite ^/docs/(?v1\.[12](?:\.\d+(?:[^/]+)?)?|latest)/advanced/helm/deploy_process/helm_hooks\.html$ /docs/$ver/usage/deploy/deployment_order.html redirect; -rewrite ^/docs/(?v1\.[12](?:\.\d+(?:[^/]+)?)?|latest)/advanced/helm/deploy_process/resources_adoption\.html$ /docs/$ver/usage/deploy/releases.html redirect; -rewrite ^/docs/(?v1\.[12](?:\.\d+(?:[^/]+)?)?|latest)/advanced/helm/deploy_process/steps\.html$ /docs/$ver/usage/deploy/deployment_order.html redirect; -rewrite ^/docs/(?v1\.[12](?:\.\d+(?:[^/]+)?)?|latest)/advanced/helm/overview\.html$ /docs/$ver/usage/deploy/overview.html redirect; -rewrite ^/docs/(?v1\.[12](?:\.\d+(?:[^/]+)?)?|latest)/advanced/helm/releases/manage_releases\.html$ /docs/$ver/usage/deploy/releases.html redirect; -rewrite ^/docs/(?v1\.[12](?:\.\d+(?:[^/]+)?)?|latest)/advanced/helm/releases/naming\.html$ /docs/$ver/usage/deploy/releases.html redirect; -rewrite ^/docs/(?v1\.[12](?:\.\d+(?:[^/]+)?)?|latest)/advanced/helm/releases/release\.html$ /docs/$ver/usage/deploy/releases.html redirect; -rewrite ^/docs/(?v1\.[12](?:\.\d+(?:[^/]+)?)?|latest)/advanced/helm/working_with_chart_dependencies\.html$ /docs/$ver/usage/deploy/charts.html redirect; -rewrite ^/docs/(?v1\.[12](?:\.\d+(?:[^/]+)?)?|latest)/advanced/helm/working_with_secrets\.html$ /docs/$ver/usage/deploy/values.html redirect; -rewrite ^/docs/(?v1\.[12](?:\.\d+(?:[^/]+)?)?|latest)/advanced/storage_layouts\.html$ /docs/$ver/usage/build/process.html redirect; -rewrite ^/docs/(?v1\.[12](?:\.\d+(?:[^/]+)?)?|latest)/advanced/supported_container_registries\.html$ /docs/$ver/usage/cleanup/cr_cleanup.html redirect; -rewrite ^/docs/(?v1\.[12](?:\.\d+(?:[^/]+)?)?|latest)/advanced/synchronization\.html$ /docs/$ver/usage/build/process.html redirect; - -rewrite ^/docs/(?v1\.[12](?:\.\d+(?:[^/]+)?)?|latest)/internals/build_process\.html$ /docs/$ver/usage/build/process.html redirect; -rewrite ^/docs/(?v1\.[12](?:\.\d+(?:[^/]+)?)?|latest)/internals/development/stapel_image\.html$ /docs/$ver/usage/build/stapel/base.html redirect; -rewrite ^/docs/(?v1\.[12](?:\.\d+(?:[^/]+)?)?|latest)/internals/how_ci_cd_integration_works/general_overview\.html$ /docs/$ver/usage/integration_with_ci_cd_systems.html redirect; -rewrite ^/docs/(?v1\.[12](?:\.\d+(?:[^/]+)?)?|latest)/internals/how_ci_cd_integration_works/github_actions\.html$ /docs/$ver/usage/integration_with_ci_cd_systems.html redirect; -rewrite ^/docs/(?v1\.[12](?:\.\d+(?:[^/]+)?)?|latest)/internals/how_ci_cd_integration_works/gitlab_ci_cd\.html$ /docs/$ver/usage/integration_with_ci_cd_systems.html redirect; -rewrite ^/docs/(?v1\.[12](?:\.\d+(?:[^/]+)?)?|latest)/internals/integration_with_ssh_agent\.html$ /docs/$ver/usage/build/stapel/base.html redirect; -rewrite ^/docs/(?v1\.[12](?:\.\d+(?:[^/]+)?)?|latest)/internals/stages_and_storage\.html$ /docs/$ver/usage/build/process.html redirect; -rewrite ^/docs/(?v1\.[12](?:\.\d+(?:[^/]+)?)?|latest)/internals/telemetry\.html$ /docs/$ver/resources/telemetry.html redirect; - -rewrite ^/docs/(?v1\.[12](?:\.\d+(?:[^/]+)?)?|latest)/reference/build/artifact\.html$ /docs/$ver/usage/build/stapel/imports.html redirect; -rewrite ^/docs/(?v1\.[12](?:\.\d+(?:[^/]+)?)?|latest)/reference/cheat_sheet\.html$ /docs/$ver/resources/cheat_sheet.html redirect; +rewrite ^/docs/(?v1\.2(?:\.\d+(?:[^/]+)?)?|latest)/quickstart\.html$ /docs/$ver/ redirect; +rewrite ^/docs/(?v1\.2(?:\.\d+(?:[^/]+)?)?|latest)/using_with_ci_cd_systems\.html$ /docs/$ver/usage/integration_with_ci_cd_systems.html redirect; + +rewrite ^/docs/(?v1\.2(?:\.\d+(?:[^/]+)?)?|latest)/advanced/supported_registry_implementations\.html$ /docs/$ver/usage/cleanup/cr_cleanup.html redirect; +rewrite ^/docs/(?v1\.2(?:\.\d+(?:[^/]+)?)?|latest)/advanced/buildah_mode\.html$ /docs/$ver/usage/build/process.html redirect; +rewrite ^/docs/(?v1\.2(?:\.\d+(?:[^/]+)?)?|latest)/advanced/building_images_with_stapel/artifacts\.html$ /docs/$ver/usage/build/stapel/imports.html redirect; +rewrite ^/docs/(?v1\.2(?:\.\d+(?:[^/]+)?)?|latest)/advanced/building_images_with_stapel/assembly_instructions\.html$ /docs/$ver/usage/build/stapel/instructions.html redirect; +rewrite ^/docs/(?v1\.2(?:\.\d+(?:[^/]+)?)?|latest)/advanced/building_images_with_stapel/base_image\.html$ /docs/$ver/usage/build/stapel/base.html redirect; +rewrite ^/docs/(?v1\.2(?:\.\d+(?:[^/]+)?)?|latest)/advanced/building_images_with_stapel/docker_directive\.html$ /docs/$ver/usage/build/stapel/dockerfile.html redirect; +rewrite ^/docs/(?v1\.2(?:\.\d+(?:[^/]+)?)?|latest)/advanced/building_images_with_stapel/git_directive\.html$ /docs/$ver/usage/build/stapel/git.html redirect; +rewrite ^/docs/(?v1\.2(?:\.\d+(?:[^/]+)?)?|latest)/advanced/building_images_with_stapel/import_directive\.html$ /docs/$ver/usage/build/stapel/imports.html redirect; +rewrite ^/docs/(?v1\.2(?:\.\d+(?:[^/]+)?)?|latest)/advanced/building_images_with_stapel/mount_directive\.html$ /docs/$ver/usage/build/stapel/mounts.html redirect; +rewrite ^/docs/(?v1\.2(?:\.\d+(?:[^/]+)?)?|latest)/advanced/bundles\.html$ /docs/$ver/usage/distribute/bundles.html redirect; +rewrite ^/docs/(?v1\.2(?:\.\d+(?:[^/]+)?)?|latest)/advanced/ci_cd/ci_cd_workflow_basics\.html$ /docs/$ver/usage/integration_with_ci_cd_systems.html redirect; +rewrite ^/docs/(?v1\.2(?:\.\d+(?:[^/]+)?)?|latest)/advanced/ci_cd/generic_ci_cd_integration\.html$ /docs/$ver/usage/integration_with_ci_cd_systems.html redirect; +rewrite ^/docs/(?v1\.2(?:\.\d+(?:[^/]+)?)?|latest)/advanced/ci_cd/github_actions\.html$ /docs/$ver/usage/integration_with_ci_cd_systems.html redirect; +rewrite ^/docs/(?v1\.2(?:\.\d+(?:[^/]+)?)?|latest)/advanced/ci_cd/gitlab_ci_cd\.html$ /docs/$ver/usage/integration_with_ci_cd_systems.html redirect; +rewrite ^/docs/(?v1\.2(?:\.\d+(?:[^/]+)?)?|latest)/advanced/ci_cd/run_in_container/run_in_docker_container\.html$ /docs/$ver/usage/integration_with_ci_cd_systems.html redirect; +rewrite ^/docs/(?v1\.2(?:\.\d+(?:[^/]+)?)?|latest)/advanced/ci_cd/run_in_container/run_in_kubernetes\.html$ /docs/$ver/usage/integration_with_ci_cd_systems.html redirect; +rewrite ^/docs/(?v1\.2(?:\.\d+(?:[^/]+)?)?|latest)/advanced/ci_cd/run_in_container/use_docker_container\.html$ /docs/$ver/usage/integration_with_ci_cd_systems.html redirect; +rewrite ^/docs/(?v1\.2(?:\.\d+(?:[^/]+)?)?|latest)/advanced/ci_cd/run_in_container/use_github_actions_with_docker_executor\.html$ /docs/$ver/usage/integration_with_ci_cd_systems.html redirect; +rewrite ^/docs/(?v1\.2(?:\.\d+(?:[^/]+)?)?|latest)/advanced/ci_cd/run_in_container/use_github_actions_with_kubernetes_executor\.html$ /docs/$ver/usage/integration_with_ci_cd_systems.html redirect; +rewrite ^/docs/(?v1\.2(?:\.\d+(?:[^/]+)?)?|latest)/advanced/ci_cd/run_in_container/use_gitlab_ci_cd_with_docker_executor\.html$ /docs/$ver/usage/integration_with_ci_cd_systems.html redirect; +rewrite ^/docs/(?v1\.2(?:\.\d+(?:[^/]+)?)?|latest)/advanced/ci_cd/run_in_container/use_gitlab_ci_cd_with_kubernetes_executor\.html$ /docs/$ver/usage/integration_with_ci_cd_systems.html redirect; +rewrite ^/docs/(?v1\.2(?:\.\d+(?:[^/]+)?)?|latest)/advanced/ci_cd/run_in_container/use_kubernetes\.html$ /docs/$ver/usage/integration_with_ci_cd_systems.html redirect; +rewrite ^/docs/(?v1\.2(?:\.\d+(?:[^/]+)?)?|latest)/advanced/ci_cd/werf_with_argocd/ci_cd_flow_overview\.html$ /docs/$ver/usage/integration_with_ci_cd_systems.html redirect; +rewrite ^/docs/(?v1\.2(?:\.\d+(?:[^/]+)?)?|latest)/advanced/ci_cd/werf_with_argocd/configure_ci_cd\.html$ /docs/$ver/usage/integration_with_ci_cd_systems.html redirect; +rewrite ^/docs/(?v1\.2(?:\.\d+(?:[^/]+)?)?|latest)/advanced/ci_cd/werf_with_argocd/prepare_kubernetes_cluster\.html$ /docs/$ver/usage/integration_with_ci_cd_systems.html redirect; +rewrite ^/docs/(?v1\.2(?:\.\d+(?:[^/]+)?)?|latest)/advanced/cleanup\.html$ /docs/$ver/usage/cleanup/cr_cleanup.html redirect; +rewrite ^/docs/(?v1\.2(?:\.\d+(?:[^/]+)?)?|latest)/advanced/configuration/giterminism\.html$ /docs/$ver/usage/project_configuration/giterminism.html redirect; +rewrite ^/docs/(?v1\.2(?:\.\d+(?:[^/]+)?)?|latest)/advanced/configuration/organizing_configuration\.html$ /docs/$ver/usage/project_configuration/werf_yaml_template_engine.html redirect; +rewrite ^/docs/(?v1\.2(?:\.\d+(?:[^/]+)?)?|latest)/advanced/configuration/supported_go_templates\.html$ /docs/$ver/usage/project_configuration/werf_yaml_template_engine.html redirect; +rewrite ^/docs/(?v1\.2(?:\.\d+(?:[^/]+)?)?|latest)/advanced/development_and_debug/stage_introspection\.html$ /docs/$ver/usage/build/stapel/base.html redirect; +rewrite ^/docs/(?v1\.2(?:\.\d+(?:[^/]+)?)?|latest)/advanced/giterminism\.html$ /docs/$ver/usage/project_configuration/giterminism.html redirect; +rewrite ^/docs/(?v1\.2(?:\.\d+(?:[^/]+)?)?|latest)/advanced/helm/configuration/chart\.html$ /docs/$ver/usage/deploy/charts.html redirect; +rewrite ^/docs/(?v1\.2(?:\.\d+(?:[^/]+)?)?|latest)/advanced/helm/configuration/chart_dependencies\.html$ /docs/$ver/usage/deploy/charts.html redirect; +rewrite ^/docs/(?v1\.2(?:\.\d+(?:[^/]+)?)?|latest)/advanced/helm/configuration/giterminism\.html$ /docs/$ver/usage/project_configuration/giterminism.html redirect; +rewrite ^/docs/(?v1\.2(?:\.\d+(?:[^/]+)?)?|latest)/advanced/helm/configuration/secrets\.html$ /docs/$ver/usage/deploy/values.html redirect; +rewrite ^/docs/(?v1\.2(?:\.\d+(?:[^/]+)?)?|latest)/advanced/helm/configuration/templates\.html$ /docs/$ver/usage/deploy/templates.html redirect; +rewrite ^/docs/(?v1\.2(?:\.\d+(?:[^/]+)?)?|latest)/advanced/helm/configuration/values\.html$ /docs/$ver/usage/deploy/values.html redirect; +rewrite ^/docs/(?v1\.2(?:\.\d+(?:[^/]+)?)?|latest)/advanced/helm/deploy_process/annotating_and_labeling\.html$ /docs/$ver/usage/deploy/releases.html redirect; +rewrite ^/docs/(?v1\.2(?:\.\d+(?:[^/]+)?)?|latest)/advanced/helm/deploy_process/deployment_order\.html$ /docs/$ver/usage/deploy/deployment_order.html redirect; +rewrite ^/docs/(?v1\.2(?:\.\d+(?:[^/]+)?)?|latest)/advanced/helm/deploy_process/external_dependencies\.html$ /docs/$ver/usage/deploy/deployment_order.html redirect; +rewrite ^/docs/(?v1\.2(?:\.\d+(?:[^/]+)?)?|latest)/advanced/helm/deploy_process/helm_hooks\.html$ /docs/$ver/usage/deploy/deployment_order.html redirect; +rewrite ^/docs/(?v1\.2(?:\.\d+(?:[^/]+)?)?|latest)/advanced/helm/deploy_process/resources_adoption\.html$ /docs/$ver/usage/deploy/releases.html redirect; +rewrite ^/docs/(?v1\.2(?:\.\d+(?:[^/]+)?)?|latest)/advanced/helm/deploy_process/steps\.html$ /docs/$ver/usage/deploy/deployment_order.html redirect; +rewrite ^/docs/(?v1\.2(?:\.\d+(?:[^/]+)?)?|latest)/advanced/helm/overview\.html$ /docs/$ver/usage/deploy/overview.html redirect; +rewrite ^/docs/(?v1\.2(?:\.\d+(?:[^/]+)?)?|latest)/advanced/helm/releases/manage_releases\.html$ /docs/$ver/usage/deploy/releases.html redirect; +rewrite ^/docs/(?v1\.2(?:\.\d+(?:[^/]+)?)?|latest)/advanced/helm/releases/naming\.html$ /docs/$ver/usage/deploy/releases.html redirect; +rewrite ^/docs/(?v1\.2(?:\.\d+(?:[^/]+)?)?|latest)/advanced/helm/releases/release\.html$ /docs/$ver/usage/deploy/releases.html redirect; +rewrite ^/docs/(?v1\.2(?:\.\d+(?:[^/]+)?)?|latest)/advanced/helm/working_with_chart_dependencies\.html$ /docs/$ver/usage/deploy/charts.html redirect; +rewrite ^/docs/(?v1\.2(?:\.\d+(?:[^/]+)?)?|latest)/advanced/helm/working_with_secrets\.html$ /docs/$ver/usage/deploy/values.html redirect; +rewrite ^/docs/(?v1\.2(?:\.\d+(?:[^/]+)?)?|latest)/advanced/storage_layouts\.html$ /docs/$ver/usage/build/process.html redirect; +rewrite ^/docs/(?v1\.2(?:\.\d+(?:[^/]+)?)?|latest)/advanced/supported_container_registries\.html$ /docs/$ver/usage/cleanup/cr_cleanup.html redirect; +rewrite ^/docs/(?v1\.2(?:\.\d+(?:[^/]+)?)?|latest)/advanced/synchronization\.html$ /docs/$ver/usage/build/process.html redirect; + +rewrite ^/docs/(?v1\.2(?:\.\d+(?:[^/]+)?)?|latest)/internals/build_process\.html$ /docs/$ver/usage/build/process.html redirect; +rewrite ^/docs/(?v1\.2(?:\.\d+(?:[^/]+)?)?|latest)/internals/development/stapel_image\.html$ /docs/$ver/usage/build/stapel/base.html redirect; +rewrite ^/docs/(?v1\.2(?:\.\d+(?:[^/]+)?)?|latest)/internals/how_ci_cd_integration_works/general_overview\.html$ /docs/$ver/usage/integration_with_ci_cd_systems.html redirect; +rewrite ^/docs/(?v1\.2(?:\.\d+(?:[^/]+)?)?|latest)/internals/how_ci_cd_integration_works/github_actions\.html$ /docs/$ver/usage/integration_with_ci_cd_systems.html redirect; +rewrite ^/docs/(?v1\.2(?:\.\d+(?:[^/]+)?)?|latest)/internals/how_ci_cd_integration_works/gitlab_ci_cd\.html$ /docs/$ver/usage/integration_with_ci_cd_systems.html redirect; +rewrite ^/docs/(?v1\.2(?:\.\d+(?:[^/]+)?)?|latest)/internals/integration_with_ssh_agent\.html$ /docs/$ver/usage/build/stapel/base.html redirect; +rewrite ^/docs/(?v1\.2(?:\.\d+(?:[^/]+)?)?|latest)/internals/stages_and_storage\.html$ /docs/$ver/usage/build/process.html redirect; +rewrite ^/docs/(?v1\.2(?:\.\d+(?:[^/]+)?)?|latest)/internals/telemetry\.html$ /docs/$ver/resources/telemetry.html redirect; + +rewrite ^/docs/(?v1\.2(?:\.\d+(?:[^/]+)?)?|latest)/reference/build/artifact\.html$ /docs/$ver/usage/build/stapel/imports.html redirect; +rewrite ^/docs/(?v1\.2(?:\.\d+(?:[^/]+)?)?|latest)/reference/cheat_sheet\.html$ /docs/$ver/resources/cheat_sheet.html redirect; ############################################ # v1.2 redirects for moved or deleted urls @@ -201,55 +191,4 @@ rewrite ^/docs/(?v1\.2(?:\.\d+(?:[^/]+)?)?|latest)/reference/toolbox/ssh\.h rewrite ^/docs/(?v1\.2(?:\.\d+(?:[^/]+)?)?|latest)/reference/working_with_docker_registries\.html$ /docs/$ver/usage/cleanup/cr_cleanup.html redirect; rewrite ^/docs/(?v1\.2(?:\.\d+(?:[^/]+)?)?|latest)/reference/werf_yaml_template_engine\.html$ /docs/$ver/usage/project_configuration/werf_yaml_template_engine.html redirect; -rewrite ^/docs/(?v1\.2(?:\.\d+(?:[^/]+)?)?|latest)/whats_new_in_v1_2/changelog\.html$ /docs/$ver/resources/how_to_migrate_from_v1_1_to_v1_2.html redirect; -rewrite ^/docs/(?v1\.2(?:\.\d+(?:[^/]+)?)?|latest)/whats_new_in_v1_2/how_to_migrate_from_v1_1_to_v1_2\.html$ /docs/$ver/resources/how_to_migrate_from_v1_1_to_v1_2.html redirect; - -############################################ -# v1.1 redirects for moved or deleted urls -############################################ - -rewrite ^/docs/(?v1\.1(?:\.\d+(?:[^/]+)?)?|latest)/quickstart\.html$ /docs/$ver/guides/getting_started.html redirect; - -rewrite ^/docs/(?v1\.1(?:\.\d+(?:[^/]+)?)?|latest)/how_to/?$ /docs/$ver/guides/ redirect; -rewrite ^/docs/(?v1\.1(?:\.\d+(?:[^/]+)?)?|latest)/how_to/mounts\.html$ /docs/$ver/guides/advanced_build/mounts.html redirect; -rewrite ^/docs/(?v1\.1(?:\.\d+(?:[^/]+)?)?|latest)/how_to/multi_images\.html$ /docs/$ver/guides/advanced_build/multi_images.html redirect; -rewrite ^/docs/(?v1\.1(?:\.\d+(?:[^/]+)?)?|latest)/how_to/artifacts\.html$ /docs/$ver/guides/advanced_build/artifacts.html redirect; -rewrite ^/docs/(?v1\.1(?:\.\d+(?:[^/]+)?)?|latest)/how_to/(?.+) /docs/$ver/guides/$tail redirect; - -rewrite ^/docs/(?v1\.1(?:\.\d+(?:[^/]+)?)?|latest)/guides/guides/unsupported_ci_cd_integration\.html$ /docs/$ver/guides/generic_ci_cd_integration.html redirect; - -rewrite ^/docs/(?v1\.1(?:\.\d+(?:[^/]+)?)?|latest)/cli/?$ /docs/$ver/reference/cli/ redirect; -rewrite ^/docs/(?v1\.1(?:\.\d+(?:[^/]+)?)?|latest)/cli/management/helm/get_release\.html$ /docs/$ver/reference/cli/werf_helm_get_release.html redirect; -rewrite ^/docs/(?v1\.1(?:\.\d+(?:[^/]+)?)?|latest)/cli/toolbox/meta/get_helm_release\.html$ /docs/$ver/reference/cli/werf_helm_get_release.html redirect; - -rewrite ^/docs/(?v1\.1(?:\.\d+(?:[^/]+)?)?|latest)/configuration/stapel_image/assembly_process\.html$ /docs/$ver/configuration/stapel_image/assembly_instructions.html redirect; -rewrite ^/docs/(?v1\.1(?:\.\d+(?:[^/]+)?)?|latest)/configuration/stapel_image/image_from_dockerfile\.html$ /docs/$ver/configuration/dockerfile_image.html redirect; -rewrite ^/docs/(?v1\.1(?:\.\d+(?:[^/]+)?)?|latest)/configuration/stapel_image/stage_introspection\.html$ /docs/$ver/advanced/development_and_debug/stage_introspection.html redirect; -rewrite ^/docs/(?v1\.1(?:\.\d+(?:[^/]+)?)?|latest)/configuration/stapel_image/stages\.html$ /docs/$ver/reference/stages_and_images.html redirect; -rewrite ^/docs/(?v1\.1(?:\.\d+(?:[^/]+)?)?|latest)/configuration/stapel_image/stages_and_images\.html$ /docs/$ver/internals/stages_and_storage.html redirect; - -rewrite ^/docs/(?v1\.1(?:\.\d+(?:[^/]+)?)?|latest)/reference/cleanup_process\.html$ /docs/$ver/reference/cleaning_process.html redirect; -rewrite ^/docs/(?v1\.1(?:\.\d+(?:[^/]+)?)?|latest)/reference/config\.html$ /docs/$ver/configuration/introduction.html redirect; -rewrite ^/docs/(?v1\.1(?:\.\d+(?:[^/]+)?)?|latest)/reference/stages_and_images\.html$ /docs/$ver/internals/stages_and_storage.html redirect; -rewrite ^/docs/(?v1\.1(?:\.\d+(?:[^/]+)?)?|latest)/reference/build/as_layers\.html$ /docs/$ver/reference/development_and_debug/as_layers.html redirect; -rewrite ^/docs/(?v1\.1(?:\.\d+(?:[^/]+)?)?|latest)/reference/build/stage_introspection\.html$ /docs/$ver/reference/development_and_debug/stage_introspection.html redirect; -rewrite ^/docs/(?v1\.1(?:\.\d+(?:[^/]+)?)?|latest)/reference/build/(?.+) /docs/$ver/configuration/stapel_image/$tail redirect; -rewrite ^/docs/(?v1\.1(?:\.\d+(?:[^/]+)?)?|latest)/reference/deploy/chart_configuration\.html$ /docs/$ver/reference/deploy_process/deploy_into_kubernetes.html redirect; -rewrite ^/docs/(?v1\.1(?:\.\d+(?:[^/]+)?)?|latest)/reference/deploy/deploy_to_kubernetes\.html$ /docs/$ver/reference/deploy_process/deploy_into_kubernetes.html redirect; -rewrite ^/docs/(?v1\.1(?:\.\d+(?:[^/]+)?)?|latest)/reference/deploy/minikube\.html$ /docs/$ver/reference/development_and_debug/setup_minikube.html redirect; -rewrite ^/docs/(?v1\.1(?:\.\d+(?:[^/]+)?)?|latest)/reference/deploy/secrets\.html$ /docs/$ver/reference/deploy_process/working_with_secrets.html redirect; -rewrite ^/docs/(?v1\.1(?:\.\d+(?:[^/]+)?)?|latest)/reference/deploy/track_kubernetes_resources\.html$ /docs/$ver/reference/deploy_process/differences_with_helm.html redirect; -rewrite ^/docs/(?v1\.1(?:\.\d+(?:[^/]+)?)?|latest)/reference/development_and_debug/stage_introspection\.html$ /docs/$ver/advanced/development_and_debug/stage_introspection.html redirect; -rewrite ^/docs/(?v1\.1(?:\.\d+(?:[^/]+)?)?|latest)/reference/local_development/as_layers\.html$ /docs/$ver/reference/development_and_debug/as_layers.html redirect; -rewrite ^/docs/(?v1\.1(?:\.\d+(?:[^/]+)?)?|latest)/reference/local_development/installing_minikube\.html$ /docs/$ver/reference/development_and_debug/setup_minikube.html redirect; -rewrite ^/docs/(?v1\.1(?:\.\d+(?:[^/]+)?)?|latest)/reference/local_development/lint_and_render_chart\.html$ /docs/$ver/reference/development_and_debug/lint_and_render_chart.html redirect; -rewrite ^/docs/(?v1\.1(?:\.\d+(?:[^/]+)?)?|latest)/reference/local_development/setup_minikube\.html$ /docs/$ver/reference/development_and_debug/setup_minikube.html redirect; -rewrite ^/docs/(?v1\.1(?:\.\d+(?:[^/]+)?)?|latest)/reference/local_development/stage_introspection\.html$ /docs/$ver/reference/development_and_debug/stage_introspection.html redirect; -rewrite ^/docs/(?v1\.1(?:\.\d+(?:[^/]+)?)?|latest)/reference/registry/authorization\.html$ /docs/$ver/reference/registry_authorization.html redirect; -rewrite ^/docs/(?v1\.1(?:\.\d+(?:[^/]+)?)?|latest)/reference/registry/cleaning\.html$ /docs/$ver/reference/cleaning_process.html redirect; -rewrite ^/docs/(?v1\.1(?:\.\d+(?:[^/]+)?)?|latest)/reference/registry/image_naming\.html$ /docs/$ver/reference/stages_and_images.html redirect; -rewrite ^/docs/(?v1\.1(?:\.\d+(?:[^/]+)?)?|latest)/reference/registry/publish\.html$ /docs/$ver/reference/publish_process.html redirect; -rewrite ^/docs/(?v1\.1(?:\.\d+(?:[^/]+)?)?|latest)/reference/registry/push\.html$ /docs/$ver/reference/publish_process.html redirect; -rewrite ^/docs/(?v1\.1(?:\.\d+(?:[^/]+)?)?|latest)/reference/registry/tag\.html$ /docs/$ver/reference/publish_process.html redirect; - {{- end }} diff --git a/.helm/trdl_channels-dev.yaml b/.helm/trdl_channels-dev.yaml deleted file mode 100644 index 8041101bb..000000000 --- a/.helm/trdl_channels-dev.yaml +++ /dev/null @@ -1,25 +0,0 @@ -groups: - - name: "1.2" - channels: - - name: alpha - version: 1.2.294+fix1 - - name: beta - version: 1.2.294+fix1 - - name: ea - version: 1.2.294+fix1 - - name: stable - version: 1.2.294+fix1 - - name: rock-solid - version: 1.2.294+fix1 - - name: "2" - channels: - - name: alpha - version: 2.0.3 - - name: beta - version: 2.0.3 - - name: ea - version: 2.0.3 - - name: stable - version: 2.0.3 - - name: rock-solid - version: 2.0.3 diff --git a/.helm/values.yaml b/.helm/values.yaml index 9de31e0a5..a7e906fae 100644 --- a/.helm/values.yaml +++ b/.helm/values.yaml @@ -21,13 +21,9 @@ priorityClassName: production: production-medium host: production: werf.io - stage: werf.stage.flant.dev - dev: werf.dev.flant.dev + test: werf.test.flant.dev _default: werf.test.flant.dev -ruHost: - production: ru.werf.io - ingressClassName: _default: "nginx" production: "standalone-geo" @@ -36,7 +32,6 @@ ingressClassName: ingressSecretName: _default: wildcard-dev-flant-dev test: wildcard-test-flant-dev - stage: wildcard-stage-flant-dev production: tls-werf-io resources: @@ -44,6 +39,17 @@ resources: memory: _default: 30M production: 300M + limits: + memory: + _default: 30M + production: 300M + +docs: + currentRoot: v2 + supportedRoots: + - v2 + - v1.2 + latestAliasEnabled: true backend: affinity: diff --git a/.werf/nginx-dev.conf b/.werf/nginx-dev.conf index 6aba30f0f..229ceb1ef 100644 --- a/.werf/nginx-dev.conf +++ b/.werf/nginx-dev.conf @@ -86,7 +86,9 @@ http { } location /docs/ { - rewrite ^/docs/(?v\d+(?:\.\d+(?:\.\d+(?:[^/]+)?)?)?|latest)/(?.*) /$tail break; + rewrite ^/docs/?$ /docs/latest/ redirect; + rewrite ^/docs/(?latest|pr-[^/]+|v2(?:\.[^/]+)?|v1\.2(?:\.[^/]+)?)$ /docs/$ver/ redirect; + rewrite ^/docs/(?latest|pr-[^/]+|v2(?:\.[^/]+)?|v1\.2(?:\.[^/]+)?)/(?.*) /$tail break; proxy_set_header Host $http_host; proxy_set_header X-Real-IP $remote_addr; diff --git a/_includes/_common/channel-menu-v2.html b/_includes/_common/channel-menu-v2.html deleted file mode 100644 index e716829c5..000000000 --- a/_includes/_common/channel-menu-v2.html +++ /dev/null @@ -1,28 +0,0 @@ -{% if page.lang == "ru" %}Версия{% else %}Version{% endif %}: -{%- raw %} -{{- $CurrentPageURL := .CurrentPageURL }} -{{- $CurrentPageURLRelative := .CurrentPageURLRelative }} -{{- $current := index .VersionItems 0 }} - - {{ $current.Version }} - - -{% endraw %} diff --git a/_includes/_common/channel-menu.html b/_includes/_common/channel-menu.html deleted file mode 100644 index c0aa2a2ec..000000000 --- a/_includes/_common/channel-menu.html +++ /dev/null @@ -1,25 +0,0 @@ -{%- raw %} -{{ $CurrentPageURL := .CurrentPageURL }} -{{ $CurrentPageURLRelative := .CurrentPageURLRelative }} - -{% endraw %} diff --git a/_includes/_common/group-menu-v2.html b/_includes/_common/group-menu-v2.html deleted file mode 100644 index a18949f7e..000000000 --- a/_includes/_common/group-menu-v2.html +++ /dev/null @@ -1,6 +0,0 @@ -{%- raw %} -{{ $CurrentPageURL := .CurrentPageURL }} -{{ $CurrentPageURLRelative := .CurrentPageURLRelative }} -{{- $first := index .VersionItems 0 }} - -{% endraw %} diff --git a/_includes/_common/group-menu.html b/_includes/_common/group-menu.html deleted file mode 100644 index 477f16c8f..000000000 --- a/_includes/_common/group-menu.html +++ /dev/null @@ -1,21 +0,0 @@ -{%- raw %} -{{ $CurrentPageURL := .CurrentPageURL }} -{{ $CurrentPageURLRelative := .CurrentPageURLRelative }} - -{% endraw %} diff --git a/_includes/_common/topnav-documentation.html b/_includes/_common/topnav-documentation.html index 1510e7a9d..402b7749a 100644 --- a/_includes/_common/topnav-documentation.html +++ b/_includes/_common/topnav-documentation.html @@ -77,7 +77,6 @@ {% raw %} {{ $CurrentPageURL := .CurrentPageURL }} {{ $CurrentPageURLRelative := .CurrentPageURLRelative }} - {{- if and .CurrentGroup .CurrentChannel }}{{ $CurrentPageURL = printf "v%s-%s%s" .CurrentGroup .CurrentChannel $CurrentPageURL }}{{ end }} {% endraw %} -{% endraw %} +{% endraw %} \ No newline at end of file diff --git a/assets/js/customscripts.js b/assets/js/customscripts.js index a8437ac1e..49f6f251a 100644 --- a/assets/js/customscripts.js +++ b/assets/js/customscripts.js @@ -2,7 +2,7 @@ $('#mysidebar').height($(".nav").height()); -document.addEventListener("DOMContentLoaded", function() { +document.addEventListener("DOMContentLoaded", function () { /** * AnchorJS */ @@ -10,67 +10,67 @@ document.addEventListener("DOMContentLoaded", function() { var referenceAnchors; if ($('.line-number-anchor')) { - referenceAnchors = new AnchorJS(); - referenceAnchors.options = { - placement: 'left' - }; - referenceAnchors.add('.line-number-anchor'); + referenceAnchors = new AnchorJS(); + referenceAnchors.options = { + placement: 'left' + }; + referenceAnchors.add('.line-number-anchor'); } }); -$( document ).ready(function() { +$(document).ready(function () { $('.header__menu').addClass('header__menu_active'); }); -$( document ).ready(function() { - var wh = $(window).height(); - var sh = $("#mysidebar").height(); +$(document).ready(function () { + var wh = $(window).height(); + var sh = $("#mysidebar").height(); - if (sh + 100 > wh) { - $( "#mysidebar" ).parent().addClass("layout-sidebar__sidebar_a"); - } - // activate tooltips. although this is a bootstrap js function, it must be activated this way in your theme. - $('[data-toggle="tooltip"]').tooltip({ - placement : 'top' - }); + if (sh + 100 > wh) { + $("#mysidebar").parent().addClass("layout-sidebar__sidebar_a"); + } + // activate tooltips. although this is a bootstrap js function, it must be activated this way in your theme. + $('[data-toggle="tooltip"]').tooltip({ + placement: 'top' + }); }); // needed for nav tabs on pages. See Formatting > Nav tabs for more details. // script from http://stackoverflow.com/questions/10523433/how-do-i-keep-the-current-tab-active-with-twitter-bootstrap-after-a-page-reload -$(function() { - var json, tabsState; - $('a[data-toggle="pill"], a[data-toggle="tab"]').on('shown.bs.tab', function(e) { - var href, json, parentId, tabsState; - - tabsState = localStorage.getItem("tabs-state"); - json = JSON.parse(tabsState || "{}"); - parentId = $(e.target).parents("ul.nav.nav-pills, ul.nav.nav-tabs").attr("id"); - href = $(e.target).attr('href'); - json[parentId] = href; - - return localStorage.setItem("tabs-state", JSON.stringify(json)); - }); +$(function () { + var json, tabsState; + $('a[data-toggle="pill"], a[data-toggle="tab"]').on('shown.bs.tab', function (e) { + var href, json, parentId, tabsState; tabsState = localStorage.getItem("tabs-state"); json = JSON.parse(tabsState || "{}"); + parentId = $(e.target).parents("ul.nav.nav-pills, ul.nav.nav-tabs").attr("id"); + href = $(e.target).attr('href'); + json[parentId] = href; - $.each(json, function(containerId, href) { - return $("#" + containerId + " a[href=" + href + "]").tab('show'); - }); + return localStorage.setItem("tabs-state", JSON.stringify(json)); + }); - $("ul.nav.nav-pills, ul.nav.nav-tabs").each(function() { - var $this = $(this); - if (!json[$this.attr("id")]) { - return $this.find("a[data-toggle=tab]:first, a[data-toggle=pill]:first").tab("show"); - } - }); + tabsState = localStorage.getItem("tabs-state"); + json = JSON.parse(tabsState || "{}"); + + $.each(json, function (containerId, href) { + return $("#" + containerId + " a[href=" + href + "]").tab('show'); + }); + + $("ul.nav.nav-pills, ul.nav.nav-tabs").each(function () { + var $this = $(this); + if (!json[$this.attr("id")]) { + return $this.find("a[data-toggle=tab]:first, a[data-toggle=pill]:first").tab("show"); + } + }); }); // Update GitHub stats $(document).ready(function () { var github_requests = [], - github_stats = JSON.parse(localStorage.getItem('werf_github_stats')) || null; + github_stats = JSON.parse(localStorage.getItem('werf_github_stats')) || null; function getGithubRequests() { $('[data-roadmap-step]').each(function () { @@ -96,8 +96,8 @@ $(document).ready(function () { } if (github_stats == null || Date.now() > (github_stats['updated_on'] + 1000 * 60 * 60)) { - github_stats = {'updated_on': Date.now(), 'issues': {}, 'stargazers': 0}; - $.when.apply($, getGithubRequests()).done(function() { + github_stats = { 'updated_on': Date.now(), 'issues': {}, 'stargazers': 0 }; + $.when.apply($, getGithubRequests()).done(function () { updateGithubStats(); localStorage.setItem('werf_github_stats', JSON.stringify(github_stats)); }); @@ -142,33 +142,33 @@ $(document).ready(function () { }); let CurrentGroup = getDocGroupFromURL(); - $('input[name="sitesearch"]').attr("value",function(index,currentvalue){ + $('input[name="sitesearch"]').attr("value", function (index, currentvalue) { if (CurrentGroup) { - return currentvalue + "/docs/" + CurrentGroup + "/" + return currentvalue + "/docs/" + CurrentGroup + "/" } else { - return currentvalue + return currentvalue } }) }); -$(document).ready(function() { - var adjustAnchor = function() { - var $anchor = $(':target'), fixedElementHeight = 120; - if ($anchor.length > 0) { - $('html, body').stop().animate({ - scrollTop: $anchor.offset().top - fixedElementHeight - }, 200); - } +$(document).ready(function () { + var adjustAnchor = function () { + var $anchor = $(':target'), fixedElementHeight = 120; + if ($anchor.length > 0) { + $('html, body').stop().animate({ + scrollTop: $anchor.offset().top - fixedElementHeight + }, 200); + } }; - $(window).on('hashchange load', function() { - adjustAnchor(); + $(window).on('hashchange load', function () { + adjustAnchor(); }); }); -$(document).ready(function(){ +$(document).ready(function () { // wait until fonts are loaded - setTimeout(function() { + setTimeout(function () { $('.publications__list').masonry({ itemSelector: '.publications__post', columnWidth: '.publications__sizer' @@ -176,9 +176,9 @@ $(document).ready(function(){ }, 500) }); -$(document).ready(function(){ +$(document).ready(function () { - $('h1:contains("Installation")').each(function( index ) { + $('h1:contains("Installation")').each(function (index) { var $title = $(this); var $btn1 = $title.next('p'); var $btn2 = $btn1.next('p'); @@ -198,134 +198,134 @@ $(document).ready(function(){ // Presentation -$(document).ready(function() { - if($('#presentation').length) { +$(document).ready(function () { + if ($('#presentation').length) { var magic = new ScrollMagic.Controller(); // Pin intro cheme var intro_scheme_duration = window.innerHeight; intro_scheme_duration = intro_scheme_duration > 1080 ? 1080 : intro_scheme_duration; intro_scheme_duration = intro_scheme_duration < 590 ? 590 : intro_scheme_duration; - new ScrollMagic.Scene({duration: intro_scheme_duration, offset: -10}) - .setPin('#intro-scheme', {pushFollowers: false}) - .addTo(magic); + new ScrollMagic.Scene({ duration: intro_scheme_duration, offset: -10 }) + .setPin('#intro-scheme', { pushFollowers: false }) + .addTo(magic); // Pin bg - new ScrollMagic.Scene({duration: 4000, offset: -10}) - .setPin('#intro-bg', {pushFollowers: false}) - .addTo(magic); + new ScrollMagic.Scene({ duration: 4000, offset: -10 }) + .setPin('#intro-bg', { pushFollowers: false }) + .addTo(magic); // Pin scheme - new ScrollMagic.Scene({triggerElement: '#presentation', triggerHook: 0, duration: 4000, offset: -90}) - .setPin('#presentation', {pushFollowers: false}) - .addTo(magic); + new ScrollMagic.Scene({ triggerElement: '#presentation', triggerHook: 0, duration: 4000, offset: -90 }) + .setPin('#presentation', { pushFollowers: false }) + .addTo(magic); // Pin notes - new ScrollMagic.Scene({duration: 400, triggerElement: '#presentation-notes-1', offset: 100}) - .setPin('#presentation-notes-1', {pushFollowers: false}) - .addTo(magic); - new ScrollMagic.Scene({duration: 400, triggerElement: '#presentation-notes-2', offset: 100}) - .setPin('#presentation-notes-2', {pushFollowers: false}) - .addTo(magic); - new ScrollMagic.Scene({duration: 1000, triggerElement: '#presentation-notes-3', offset: 100}) - .setPin('#presentation-notes-3', {pushFollowers: false}) - .addTo(magic); + new ScrollMagic.Scene({ duration: 400, triggerElement: '#presentation-notes-1', offset: 100 }) + .setPin('#presentation-notes-1', { pushFollowers: false }) + .addTo(magic); + new ScrollMagic.Scene({ duration: 400, triggerElement: '#presentation-notes-2', offset: 100 }) + .setPin('#presentation-notes-2', { pushFollowers: false }) + .addTo(magic); + new ScrollMagic.Scene({ duration: 1000, triggerElement: '#presentation-notes-3', offset: 100 }) + .setPin('#presentation-notes-3', { pushFollowers: false }) + .addTo(magic); // Move away title - new ScrollMagic.Scene({triggerElement: '#presentation', triggerHook: 0, duration: 250, offset: 25}).setTween( + new ScrollMagic.Scene({ triggerElement: '#presentation', triggerHook: 0, duration: 250, offset: 25 }).setTween( new TimelineMax() - .to('#presentation-title', {x: '-2000px', opacity: 0}, 0) - .to('#intro-bg', {x: '-1500px'}, 0) + .to('#presentation-title', { x: '-2000px', opacity: 0 }, 0) + .to('#intro-bg', { x: '-1500px' }, 0) ) - .addTo(magic); + .addTo(magic); // Hide arrows & smart - new ScrollMagic.Scene({triggerElement: '#presentation', triggerHook: 0, duration: 100, offset: 400}).setTween( + new ScrollMagic.Scene({ triggerElement: '#presentation', triggerHook: 0, duration: 100, offset: 400 }).setTween( new TimelineMax() - .to('#scheme_git', {opacity: '0.2'}, 0) - .to('#scheme_docker_registry', {opacity: '0.2'}, 0) - .to('#scheme_k8s', {opacity: '0.2'}, 0) - .to('#scheme_werf', {opacity: '0.2'}, 0) - .to('#scheme_arrows_gw', {opacity: '0'}, 0) - .to('#scheme_arrows_wd', {opacity: '0'}, 0) - .to('#scheme_arrows_wk', {opacity: '0'}, 0) - .to('#scheme_smart_2', {opacity: '0'}, 0) - .to('#scheme_smart', {opacity: '0'}, 0) + .to('#scheme_git', { opacity: '0.2' }, 0) + .to('#scheme_docker_registry', { opacity: '0.2' }, 0) + .to('#scheme_k8s', { opacity: '0.2' }, 0) + .to('#scheme_werf', { opacity: '0.2' }, 0) + .to('#scheme_arrows_gw', { opacity: '0' }, 0) + .to('#scheme_arrows_wd', { opacity: '0' }, 0) + .to('#scheme_arrows_wk', { opacity: '0' }, 0) + .to('#scheme_smart_2', { opacity: '0' }, 0) + .to('#scheme_smart', { opacity: '0' }, 0) ).addTo(magic); // Git - new ScrollMagic.Scene({triggerElement: '#presentation', triggerHook: 0, duration: 200, offset: 600}).setTween( + new ScrollMagic.Scene({ triggerElement: '#presentation', triggerHook: 0, duration: 200, offset: 600 }).setTween( new TimelineMax() - .to('#scheme_git', {opacity: '1'}, 0) + .to('#scheme_git', { opacity: '1' }, 0) ).addTo(magic); // Git -> werf, show - new ScrollMagic.Scene({triggerElement: '#presentation', triggerHook: 0, duration: 200, offset: 1000}).setTween( + new ScrollMagic.Scene({ triggerElement: '#presentation', triggerHook: 0, duration: 200, offset: 1000 }).setTween( new TimelineMax() - .to('#scheme_git', {opacity: '1'}, 0) - .to('#scheme_arrows_gw', {opacity: '1'}, 0) - .to('#scheme_werf', {opacity: '1'}, 0) + .to('#scheme_git', { opacity: '1' }, 0) + .to('#scheme_arrows_gw', { opacity: '1' }, 0) + .to('#scheme_werf', { opacity: '1' }, 0) ).addTo(magic); // werf -> Docker Registry, show - new ScrollMagic.Scene({triggerElement: '#presentation', triggerHook: 0, duration: 200, offset: 1400}).setTween( + new ScrollMagic.Scene({ triggerElement: '#presentation', triggerHook: 0, duration: 200, offset: 1400 }).setTween( new TimelineMax() - .to('#scheme_git', {opacity: '0.2'}, 0) - .to('#scheme_docker_registry', {opacity: '1'}, 0) - .to('#scheme_arrows_gw', {opacity: '0.2'}, 0) - .to('#scheme_arrows_wd', {opacity: '1'}, 0) - .to('#scheme_smart_2', {opacity: '1'}, 0) + .to('#scheme_git', { opacity: '0.2' }, 0) + .to('#scheme_docker_registry', { opacity: '1' }, 0) + .to('#scheme_arrows_gw', { opacity: '0.2' }, 0) + .to('#scheme_arrows_wd', { opacity: '1' }, 0) + .to('#scheme_smart_2', { opacity: '1' }, 0) ).addTo(magic); // werf -> Docker Registry, sync - new ScrollMagic.Scene({triggerElement: '#presentation', triggerHook: 0, duration: 500, offset: 1800}).setTween( + new ScrollMagic.Scene({ triggerElement: '#presentation', triggerHook: 0, duration: 500, offset: 1800 }).setTween( TweenMax - .fromTo('#scheme_smart_icon_update_arrows_2', 1, - {rotation: '0'}, {rotation: '-720', transformOrigin: '50% 50%', repeat: -1, ease: "power1.out"}) - .duration(2) + .fromTo('#scheme_smart_icon_update_arrows_2', 1, + { rotation: '0' }, { rotation: '-720', transformOrigin: '50% 50%', repeat: -1, ease: "power1.out" }) + .duration(2) ).addTo(magic); // werf -> Docker Registry, show info - new ScrollMagic.Scene({triggerElement: '#presentation', triggerHook: 0, duration: 200, offset: 2200}).setTween( + new ScrollMagic.Scene({ triggerElement: '#presentation', triggerHook: 0, duration: 200, offset: 2200 }).setTween( new TimelineMax() - .to('#scheme_smart_icon_update_2', {opacity: '0'}) - .to('#scheme_smart_icon_check_2', {opacity: '1'}) + .to('#scheme_smart_icon_update_2', { opacity: '0' }) + .to('#scheme_smart_icon_check_2', { opacity: '1' }) ).addTo(magic); // werf -> Kubernetes, show - new ScrollMagic.Scene({triggerElement: '#presentation', triggerHook: 0, duration: 200, offset: 2600}).setTween( + new ScrollMagic.Scene({ triggerElement: '#presentation', triggerHook: 0, duration: 200, offset: 2600 }).setTween( new TimelineMax() - .to('#scheme_docker_registry', {opacity: '0.2'}, 0) - .to('#scheme_arrows_wd', {opacity: '0.2'}, 0) - .to('#scheme_arrows_wk', {opacity: '1'}, 0) - .to('#scheme_smart', {opacity: '1'}, 0) - .to('#scheme_k8s', {opacity: '1'}, 0) + .to('#scheme_docker_registry', { opacity: '0.2' }, 0) + .to('#scheme_arrows_wd', { opacity: '0.2' }, 0) + .to('#scheme_arrows_wk', { opacity: '1' }, 0) + .to('#scheme_smart', { opacity: '1' }, 0) + .to('#scheme_k8s', { opacity: '1' }, 0) ).addTo(magic); // werf -> Kubernetes, sync - new ScrollMagic.Scene({triggerElement: '#presentation', triggerHook: 0, duration: 500, offset: 3000}).setTween( + new ScrollMagic.Scene({ triggerElement: '#presentation', triggerHook: 0, duration: 500, offset: 3000 }).setTween( TweenMax - .fromTo('#scheme_smart_icon_update_arrows', 1, - {rotation: '0'}, {rotation: '-720', transformOrigin: '50% 50%', repeat: -1, ease: "power1.out"}) - .duration(2) + .fromTo('#scheme_smart_icon_update_arrows', 1, + { rotation: '0' }, { rotation: '-720', transformOrigin: '50% 50%', repeat: -1, ease: "power1.out" }) + .duration(2) ).addTo(magic); // werf -> Docker Registry, show info - new ScrollMagic.Scene({triggerElement: '#presentation', triggerHook: 0, duration: 200, offset: 3400}).setTween( + new ScrollMagic.Scene({ triggerElement: '#presentation', triggerHook: 0, duration: 200, offset: 3400 }).setTween( new TimelineMax() - .to('#scheme_smart_icon_update', {opacity: '0'}) - .to('#scheme_smart_icon_check', {opacity: '1'}) + .to('#scheme_smart_icon_update', { opacity: '0' }) + .to('#scheme_smart_icon_check', { opacity: '1' }) ).addTo(magic); // Full - new ScrollMagic.Scene({triggerElement: '#presentation', triggerHook: 0, duration: 200, offset: 3800}).setTween( + new ScrollMagic.Scene({ triggerElement: '#presentation', triggerHook: 0, duration: 200, offset: 3800 }).setTween( new TimelineMax() - .to('#scheme_smart_icon_update', {opacity: '0'}) - .to('#scheme_smart_icon_check', {opacity: '1'}) - .to('#scheme_docker_registry', {opacity: '1'}, 0) - .to('#scheme_arrows_wd', {opacity: '1'}, 0) - .to('#scheme_git', {opacity: '1'}, 0) - .to('#scheme_arrows_gw', {opacity: '1'}, 0) + .to('#scheme_smart_icon_update', { opacity: '0' }) + .to('#scheme_smart_icon_check', { opacity: '1' }) + .to('#scheme_docker_registry', { opacity: '1' }, 0) + .to('#scheme_arrows_wd', { opacity: '1' }, 0) + .to('#scheme_git', { opacity: '1' }, 0) + .to('#scheme_arrows_gw', { opacity: '1' }, 0) ).addTo(magic); } }); @@ -333,50 +333,51 @@ $(document).ready(function() { // Intro scheme -$(document).ready(function() { - if($('#intro-animation').length) { +$(document).ready(function () { + if ($('#intro-animation').length) { var ia = {}; - ia.dot = '#intro-animation-dot'; - ia.dot2 = '#intro-animation-dot2'; - ia.k8s = '#intro-animation-k8s'; - ia.git = '#intro-animation-git'; - ia.docker = '#intro-animation-docker'; - ia.helm = '#intro-animation-helm'; - ia.werf = '#intro-animation-werf'; - ia.werf_k8s = '#intro-animation-werf-k8s'; - ia.werf_git = '#intro-animation-werf-git'; - ia.werf_docker = '#intro-animation-werf-docker'; - ia.werf_helm = '#intro-animation-werf-helm'; + ia.dot = '#intro-animation-dot'; + ia.dot2 = '#intro-animation-dot2'; + ia.k8s = '#intro-animation-k8s'; + ia.git = '#intro-animation-git'; + ia.docker = '#intro-animation-docker'; + ia.helm = '#intro-animation-helm'; + ia.werf = '#intro-animation-werf'; + ia.werf_k8s = '#intro-animation-werf-k8s'; + ia.werf_git = '#intro-animation-werf-git'; + ia.werf_docker = '#intro-animation-werf-docker'; + ia.werf_helm = '#intro-animation-werf-helm'; function moveDot(data) { data.timeline - .to(data.dot, {duration: 2, ease: 'power1.inOut', - motionPath: { - path: data.path, - align: data.path, - alignOrigin: [0.5, 0.5], - autoRotate: false, - start: 0, - end: data.reverse ? -1 : 1, - } - }, data.delay) - .to(data.dot, {opacity: 1, duration: 0.25}, '-=2') - .to(data.dot, {opacity: 0, duration: 0.25}, '-=0.25'); + .to(data.dot, { + duration: 2, ease: 'power1.inOut', + motionPath: { + path: data.path, + align: data.path, + alignOrigin: [0.5, 0.5], + autoRotate: false, + start: 0, + end: data.reverse ? -1 : 1, + } + }, data.delay) + .to(data.dot, { opacity: 1, duration: 0.25 }, '-=2') + .to(data.dot, { opacity: 0, duration: 0.25 }, '-=0.25'); } - var tl = gsap.timeline({repeat: -1, repeatDelay: 1, delay: 1}); + var tl = gsap.timeline({ repeat: -1, repeatDelay: 1, delay: 1 }); // Dot git werf - moveDot({timeline: tl, dot: ia.dot, path: ia.werf_git, reverse: false, delay: '=0' }); + moveDot({ timeline: tl, dot: ia.dot, path: ia.werf_git, reverse: false, delay: '=0' }); // Dot werf docker - moveDot({timeline: tl, dot: ia.dot, path: ia.werf_docker, reverse: false, delay: '=0' }); + moveDot({ timeline: tl, dot: ia.dot, path: ia.werf_docker, reverse: false, delay: '=0' }); // Dot werf helm - moveDot({timeline: tl, dot: ia.dot2, path: ia.werf_helm, reverse: true, delay: '-=2' }); + moveDot({ timeline: tl, dot: ia.dot2, path: ia.werf_helm, reverse: true, delay: '-=2' }); // Dot docker werf - moveDot({timeline: tl, dot: ia.dot, path: ia.werf_docker, reverse: true, delay: '=0' }); + moveDot({ timeline: tl, dot: ia.dot, path: ia.werf_docker, reverse: true, delay: '=0' }); // Dot helm werf - moveDot({timeline: tl, dot: ia.dot2, path: ia.werf_helm, reverse: false, delay: '-=2' }); + moveDot({ timeline: tl, dot: ia.dot2, path: ia.werf_helm, reverse: false, delay: '-=2' }); // Dot werf k8s - moveDot({timeline: tl, dot: ia.dot, path: ia.werf_k8s, reverse: true, delay: '=0' }); + moveDot({ timeline: tl, dot: ia.dot, path: ia.werf_k8s, reverse: true, delay: '=0' }); } }); @@ -395,25 +396,25 @@ $(document).ready(function () { function updateNauContent() { var $releases_container = $('#nau-releases'); - nau_data.releases.slice(0, 5).forEach(function(item) { + nau_data.releases.slice(0, 5).forEach(function (item) { $releases_container.append( - `
+ `
${item.tag_name}
- ${moment(item.published_at).format('DD.MM.YYYY') } + ${moment(item.published_at).format('DD.MM.YYYY')}
`); }); var $news_container = $('#nau-news'); $news_container.append( - ` + ` ${nau_data.news.title}
- ${moment(nau_data.news.date).format('DD.MM.YYYY') } + ${moment(nau_data.news.date).format('DD.MM.YYYY')}
`); } @@ -450,8 +451,8 @@ $(document).ready(function () { ]; if (nau_data == null || Date.now() > (nau_data['updated_on'] + 1000 * 60 * 60)) { - nau_data = {'updated_on': Date.now(), 'news': {}, 'releases': []}; - $.when.apply($, nau_requests).done(function() { + nau_data = { 'updated_on': Date.now(), 'news': {}, 'releases': [] }; + $.when.apply($, nau_requests).done(function () { updateNauContent(); localStorage.setItem('werf_news', JSON.stringify(nau_data)); }); @@ -466,28 +467,33 @@ $(document).ready(function () { }); function getDocGroupFromURL() { - let result = window.location.pathname.match(/^\/docs\/(v\d+\.\d+)/); - if ( result && result[1] ) { - return result[1]; + let result = window.location.pathname.match(/^\/docs\/(latest|pr-[^/]+|v2(?:\.[^/]+)?|v1\.2(?:\.[^/]+)?)(?:\/|$)/); + if (result && result[1]) { + if (result[1] === 'latest') { + return 'v2'; + } + if (result[1].indexOf('pr-') === 0) { + return 'v2'; + } + if (result[1].indexOf('v1.2') === 0) { + return 'v1.2'; + } + return 'v2'; } return null; } function getDocVersionFromURL() { - let result = window.location.pathname.match(/\/docs\/(v\d+\.\d+([^/]+)?)\/.*/); - if ( result ) { - if ( result.length > 2 && result[2] ) { - return result[1].replace('-plus-','+'); - } else { - return "main"; - } + let result = window.location.pathname.match(/\/docs\/(latest|pr-[^/]+|v2(?:\.[^/]+)?|v1\.2(?:\.[^/]+)?)(?:\/.*)?$/); + if (result) { + return result[1].replace('-plus-', '+'); } return null; } function getDocVersionFromPage() { let result = $("#versionNumber").text(); - if ( !result) { + if (!result) { result = ""; } return result; @@ -495,14 +501,14 @@ function getDocVersionFromPage() { function checkURLExist(url, callback) { - if ( ! $.isFunction(callback)) { - throw Error('Not a valid callback'); - } + if (!$.isFunction(callback)) { + throw Error('Not a valid callback'); + } - $.ajax({ - type: 'HEAD', - url: url, - success: $.proxy(callback, this, true), - error: $.proxy(callback, this, false) - }); + $.ajax({ + type: 'HEAD', + url: url, + success: $.proxy(callback, this, true), + error: $.proxy(callback, this, false) + }); } diff --git a/backend/common.go b/backend/common.go index 9ed17a5d3..942dca041 100644 --- a/backend/common.go +++ b/backend/common.go @@ -1,52 +1,25 @@ package main import ( - "crypto/tls" - "errors" "fmt" - "io/ioutil" - "net" "net/http" "net/url" "os" "regexp" - "slices" - "sort" - "strconv" "strings" - "time" - - log "github.com/sirupsen/logrus" - "gopkg.in/yaml.v2" ) -type ChannelType struct { - Name string `yaml:"name"` - Version string `yaml:"version"` -} - -type ReleaseType struct { - Group string `yaml:"name"` - Channels []ChannelType `yaml:"channels"` -} - -type ReleasesStatusType struct { - Releases []ReleaseType `yaml:"groups"` -} - type ApiStatusResponseType struct { - Status string `json:"status"` - Msg string `json:"msg"` - RootVersion string `json:"rootVersion"` - RootVersionURL string `json:"rootVersionURL"` - Multiwerf []ReleaseType `json:"multiwerf"` + Status string `json:"status"` + Msg string `json:"msg"` + RootVersion string `json:"rootVersion"` + RootVersionURL string `json:"rootVersionURL"` + Multiwerf []string `json:"multiwerf"` } type versionMenuType struct { VersionItems []versionMenuItems HTMLContent string - CurrentGroup string - CurrentChannel string CurrentVersion string AbsoluteVersion string // Contains explicit version, used for getting git link to source file CurrentVersionURL string @@ -56,358 +29,161 @@ type versionMenuType struct { } type versionMenuItems struct { - Group string - Channel string Version string VersionURL string // Base URL for corresponding version without a leading /, e.g. 'v1.2.3-plus-fix6'. IsCurrent bool } -var ReleasesStatus ReleasesStatusType - -var channelsListReverseStability = []string{"rock-solid", "stable", "ea", "beta", "alpha"} - -func (m *versionMenuType) getChannelMenuData(r *http.Request, releases *ReleasesStatusType) (err error) { - err = nil - - m.CurrentPageURLRelative = getDocPageURLRelative(r) - m.CurrentPageURL = getCurrentPageURL(r) - m.CurrentVersionURL = getVersionURL(r) - - if isGroupChannelURL, _ := regexp.MatchString("v[0-9]+.[0-9]+-(alpha|beta|ea|stable|rock-solid)", m.CurrentVersionURL); isGroupChannelURL { - items := strings.Split(m.CurrentVersionURL, "-") - if len(items) == 2 { - m.CurrentGroup = strings.TrimPrefix(items[0], "v") - m.CurrentChannel = items[1] - _, m.CurrentVersion = getVersionFromChannelAndGroup(releases, m.CurrentChannel, m.CurrentGroup) - m.CurrentVersionURL = VersionToURL(m.CurrentVersion) - } - } - - m.CurrentVersion = URLToVersion(m.CurrentVersionURL) - - if m.CurrentVersion == "latest" { - m.CurrentGroup = "latest" - m.CurrentChannel = "latest" - } - - if m.CurrentVersion == fmt.Sprintf("v%s", getRootRelease()) { - m.CurrentVersion = getRootRelease() - m.CurrentGroup = getRootRelease() - } - - if m.CurrentVersion == "" { - m.CurrentVersion = getRootRelease() - m.CurrentVersionURL = VersionToURL(m.CurrentVersion) - } +const ( + defaultCurrentDocsRoot = "v2" + currentDocsRootEnv = "CURRENT_DOCS_MAJOR" + supportedDocsRootsEnv = "SUPPORTED_DOCS_MAJOR_VERSIONS" + latestDocsAliasEnabledEnv = "DOCS_LATEST_ALIAS_ENABLED" +) - // Try to find current channel from URL - if m.CurrentChannel == "" || m.CurrentGroup == "" { - m.CurrentChannel, m.CurrentGroup = getChannelAndGroupFromVersion(releases, m.CurrentVersion) +func appendVersionItems(items []versionMenuItems, currentVersion string, includeLatest bool) []versionMenuItems { + if includeLatest && currentVersion != "latest" { + items = append(items, versionMenuItems{ + Version: "latest", + VersionURL: "latest", + IsCurrent: false, + }) } - // Add the first menu item (current version) - m.VersionItems = append(m.VersionItems, versionMenuItems{ - Group: m.CurrentGroup, - Channel: m.CurrentChannel, - Version: m.CurrentVersion, - VersionURL: m.CurrentVersionURL, - IsCurrent: true, - }) - - // Add item for the "latest" version - m.VersionItems = append(m.VersionItems, versionMenuItems{ - Group: "", - Channel: "", - Version: "latest", - VersionURL: "latest", - IsCurrent: false, - }) - - // Add other items - for _, group := range getGroups() { - // TODO error handling - _ = m.getChannelsFromGroup(&ReleasesStatus, group) + for _, root := range getSupportedDocsRoots() { + if root == currentVersion { + continue + } + items = append(items, versionMenuItems{ + Version: root, + VersionURL: VersionToURL(root), + IsCurrent: false, + }) } - return + return items } -func (m *versionMenuType) getVersionMenuData(r *http.Request, releases *ReleasesStatusType) (err error) { +func (m *versionMenuType) getVersionMenuData(r *http.Request) (err error) { err = nil m.CurrentPageURLRelative = getDocPageURLRelative(r) m.CurrentPageURL = getCurrentPageURL(r) - m.CurrentVersionURL = getVersionURL(r) - m.CurrentVersion = URLToVersion(m.CurrentVersionURL) + m.CurrentVersion = getCanonicalDocsVersion(getVersionURL(r)) + m.CurrentVersionURL = VersionToURL(m.CurrentVersion) + m.AbsoluteVersion = m.CurrentVersion + m.MenuDocumentationLink = fmt.Sprintf("/docs/%s/", m.CurrentVersionURL) - if m.CurrentVersion == "" { - m.CurrentVersion = fmt.Sprintf("v%s", getRootRelease()) - m.CurrentVersionURL = VersionToURL(m.CurrentVersion) - } - - re := regexp.MustCompile(`^v([0-9]+(?:\.[0-9]+)?)(\..+)?$`) - res := re.FindStringSubmatch(m.CurrentVersion) - if res == nil { - m.MenuDocumentationLink = fmt.Sprintf("/docs/%s/", VersionToURL(m.CurrentVersion)) - m.AbsoluteVersion = m.CurrentVersion - } else { - if res[2] != "" { - // Version is not a group (MAJ.MIN), but the patch version - // The old behavior (e.g., link to v2 for the v2.0.1 version) - // m.MenuDocumentationLink = fmt.Sprintf("/docs/%s/", VersionToURL(res[1])) - // The new behavior (link to v2.0.1 for the v2.0.1 version) - m.MenuDocumentationLink = fmt.Sprintf("/docs/%s/", VersionToURL(m.CurrentVersion)) - m.AbsoluteVersion = fmt.Sprintf("%s", m.CurrentVersion) - } else { - // Version is a group - m.MenuDocumentationLink = fmt.Sprintf("/docs/%s/", VersionToURL(m.CurrentVersion)) - err, m.AbsoluteVersion = getVersionFromGroup(&ReleasesStatus, res[1]) - if err != nil { - log.Debugln(fmt.Sprintf("getVersionMenuData: error determine absolute version for %s (got %s)", m.CurrentVersion, m.AbsoluteVersion)) - } - } - } - - // m.MenuDocumentationLink = fmt.Sprintf("/docs/v%s/", VersionToURL(getRootRelease())) - // if m.CurrentChannel == "" && m.CurrentGroup == "" { - // m.MenuDocumentationLink = fmt.Sprintf("/docs/%v/", VersionToURL(m.CurrentVersion)) - // } else if m.CurrentChannel == "" && m.CurrentGroup != "" { - // m.MenuDocumentationLink = fmt.Sprintf("/docs/v%v/", m.CurrentGroup) - // } else { - // m.MenuDocumentationLink = fmt.Sprintf("/docs/v%v-%v/", m.CurrentGroup, m.CurrentChannel) - // } - - // Add the first menu item m.VersionItems = append(m.VersionItems, versionMenuItems{ - Group: m.CurrentGroup, - Channel: m.CurrentChannel, Version: m.CurrentVersion, VersionURL: m.CurrentVersionURL, IsCurrent: true, }) - // for _, releaseItem_ := range releases.Releases { - // if releaseItem_.Group == m.CurrentGroup { - // for _, channelItem_ := range releaseItem_.Channels { - // if channelItem_.Name == m.CurrentChannel { - // m.VersionItems = append(m.VersionItems, versionMenuItems{ - // Group: m.CurrentGroup, - // Channel: m.CurrentChannel, - // Version: channelItem_.Version, - // VersionURL: VersionToURL(channelItem_.Version), - // IsCurrent: true, - // }) - // } - // } - // } - // } - - // Add other items - for _, group := range getGroups() { - // TODO error handling - _ = m.getChannelsFromGroup(&ReleasesStatus, group) - } + m.VersionItems = appendVersionItems(m.VersionItems, m.CurrentVersion, isLatestAliasEnabled()) return } -func (m *versionMenuType) getGroupMenuData(r *http.Request, releases *ReleasesStatusType) (err error) { - err = nil - - m.CurrentPageURLRelative = getDocPageURLRelative(r) - m.CurrentPageURL = getCurrentPageURL(r) - m.CurrentVersionURL = getVersionURL(r) - m.CurrentVersion = URLToVersion(m.CurrentVersionURL) - - if m.CurrentVersion == "" { - m.CurrentVersion = fmt.Sprintf("v%s", getRootRelease()) - m.CurrentVersionURL = VersionToURL(m.CurrentVersion) +// Resolve docs version from root alias. +func resolveRootVersionAlias(alias string) (err error, version string) { + candidate := alias + if candidate != "latest" && !strings.HasPrefix(candidate, "v") { + candidate = "v" + candidate } - - re := regexp.MustCompile(`^v([0-9]+\.[0-9]+)(\..+)?$`) - res := re.FindStringSubmatch(m.CurrentVersion) - if res != nil { - m.VersionItems = append(m.VersionItems, versionMenuItems{ - Group: res[1], - Channel: "", - Version: m.CurrentVersion, - VersionURL: m.CurrentVersionURL, - IsCurrent: true, - }) - } else { - // Version is not a group (MAJ.MIN), but the patch version - m.VersionItems = append(m.VersionItems, versionMenuItems{ - Group: "", - Channel: "", - Version: m.CurrentVersion, - VersionURL: m.CurrentVersionURL, - IsCurrent: true, - }) + canonical := getCanonicalDocsVersion(candidate) + if canonical == getCurrentDocsRoot() && candidate != canonical && candidate != "latest" { + return fmt.Errorf("unsupported docs version alias: %s", alias), "" } + return nil, canonical +} - // Add other items - for _, group := range getGroups() { - // TODO error handling - if group == "1.0" || group == "1.1" { - continue - } - m.VersionItems = append(m.VersionItems, versionMenuItems{ - Group: group, - Channel: "", - Version: "", - VersionURL: "", - IsCurrent: false, - }) +// Add prefix 'v' to a version if it doesn't have yet +func normalizeVersion(version string) string { + v := strings.TrimSpace(version) + if strings.HasPrefix(v, "v") || v == "latest" || strings.HasPrefix(v, "pr-") { + return v } + return fmt.Sprintf("v%s", v) +} - return +func getRootReleaseVersion() string { + return getCurrentDocsRoot() } -// Get channels and corresponding versions for the specified -// group according to the reverse order of stability -func (m *versionMenuType) getChannelsFromGroup(releases *ReleasesStatusType, group string) (err error) { - if group == "1.0" || group == "1.1" { - return - } - for _, item := range releases.Releases { - if item.Group == group { - for _, channel := range channelsListReverseStability { - for _, channelItem := range item.Channels { - if channelItem.Name == channel { - m.VersionItems = append(m.VersionItems, versionMenuItems{ - Group: group, - Channel: channelItem.Name, - Version: channelItem.Version, - VersionURL: VersionToURL(channelItem.Version), - IsCurrent: false, - }) - } - } - } - } - } - return +func getRootRelease() (result string) { + return strings.TrimPrefix(getCurrentDocsRoot(), "v") } -// Get channel and group for specified version -func getChannelAndGroupFromVersion(releases *ReleasesStatusType, version string) (channel, group string) { - re := regexp.MustCompile(`^v([0-9]+\.[0-9]+)$`) - res := re.FindStringSubmatch(version) - if res != nil { - return "", res[1] +func isLatestAliasEnabled() bool { + v := strings.TrimSpace(strings.ToLower(os.Getenv(latestDocsAliasEnabledEnv))) + if v == "" { + return true } + return v == "1" || v == "true" || v == "yes" || v == "on" +} - for _, group := range getGroups() { - for _, channel := range channelsListReverseStability { - for _, releaseItem := range releases.Releases { - if releaseItem.Group == group { - for _, channelItem := range releaseItem.Channels { - if channelItem.Name == channel { - if channelItem.Version == version { - return channel, group - } - } - } - } - } - } +func getCurrentDocsRoot() string { + candidate := normalizeDocsRoot(os.Getenv(currentDocsRootEnv)) + if candidate != "" { + return candidate } - return + return defaultCurrentDocsRoot } -// Get version for specified group and channel -func getVersionFromChannelAndGroup(releases *ReleasesStatusType, channel, group string) (err error, version string) { - for _, releaseItem := range releases.Releases { - if releaseItem.Group == group { - for _, channelItem := range releaseItem.Channels { - if channelItem.Name == channel { - return nil, normalizeVersion(channelItem.Version) - } - } +func getSupportedDocsRoots() []string { + raw := strings.Split(strings.TrimSpace(os.Getenv(supportedDocsRootsEnv)), ",") + roots := make([]string, 0, len(raw)+1) + seen := map[string]struct{}{} + + add := func(v string) { + if v == "" { + return + } + if _, ok := seen[v]; ok { + return } + seen[v] = struct{}{} + roots = append(roots, v) } - return errors.New(fmt.Sprintf("no matching version for group %s, channel %s", group, channel)), "" -} -// Gev version from specified group -// E.g. get v1.2.3+fix6 from v1.2 -func getVersionFromGroup(releases *ReleasesStatusType, group string) (err error, version string) { - if group == "latest" || group == getRootRelease() { - return nil, "latest" - } - if len(releases.Releases) > 0 { - for _, ReleaseGroup := range releases.Releases { - if ReleaseGroup.Group == group { - releaseVersions := make(map[string]string) - for _, channel := range ReleaseGroup.Channels { - releaseVersions[channel.Name] = channel.Version - } - - if _, ok := releaseVersions["stable"]; ok { - return nil, normalizeVersion(releaseVersions["stable"]) - } else if _, ok := releaseVersions["ea"]; ok { - return nil, normalizeVersion(releaseVersions["ea"]) - } else if _, ok := releaseVersions["beta"]; ok { - return nil, normalizeVersion(releaseVersions["beta"]) - } else if _, ok := releaseVersions["alpha"]; ok { - return nil, (releaseVersions["alpha"]) - } - } - } + add(getCurrentDocsRoot()) + for _, item := range raw { + add(normalizeDocsRoot(item)) } - return errors.New(fmt.Sprintf("Can't get version for %s", group)), "" + return roots } -// Add prefix 'v' to a version if it doesn't have yet -func normalizeVersion(version string) string { - if strings.HasPrefix(version, "v") || version == "latest" { - return version - } else { - return fmt.Sprintf("v%s", version) +func normalizeDocsRoot(raw string) string { + v := strings.TrimSpace(raw) + if v == "" { + return "" } -} - -func getRootReleaseVersion() string { - activeRelease := getRootRelease() - if activeRelease == "latest" { - return activeRelease + if !strings.HasPrefix(v, "v") { + v = "v" + v } - - _ = updateReleasesStatus() - - if len(ReleasesStatus.Releases) > 0 { - for _, ReleaseGroup := range ReleasesStatus.Releases { - if ReleaseGroup.Group == activeRelease { - releaseVersions := make(map[string]string) - for _, channel := range ReleaseGroup.Channels { - releaseVersions[channel.Name] = channel.Version - } - - if _, ok := releaseVersions["stable"]; ok { - return releaseVersions["stable"] - } else if _, ok := releaseVersions["ea"]; ok { - return releaseVersions["ea"] - } else if _, ok := releaseVersions["beta"]; ok { - return releaseVersions["beta"] - } else if _, ok := releaseVersions["alpha"]; ok { - return releaseVersions["alpha"] - } - } - } + if matched, _ := regexp.MatchString(`^v[0-9]+(?:\.[0-9]+)?$`, v); !matched { + return "" } - return "unknown" + return v } -func getRootRelease() (result string) { - if len(os.Getenv("ACTIVE_RELEASE")) > 0 { - result = os.Getenv("ACTIVE_RELEASE") - } else { - result = "2" +func getCanonicalDocsVersion(raw string) string { + v := strings.TrimSpace(URLToVersion(raw)) + if v == "" || v == "latest" { + return getCurrentDocsRoot() } - - return + if strings.HasPrefix(v, "pr-") { + return v + } + if strings.HasPrefix(v, "v1.2") { + return "v1.2" + } + if strings.HasPrefix(v, "v2") { + return "v2" + } + return getCurrentDocsRoot() } // Get the full page URL menu requested for @@ -526,73 +302,10 @@ func URLToVersion(version string) (result string) { } func validateURL(url string) error { - if strings.ToLower(os.Getenv("URL_VALIDATION")) == "false" { - return nil - } - - allowedStatusCodes := []int{200, 401} - maxRedirects := 10 - - client := &http.Client{ - Transport: &http.Transport{ - Proxy: http.ProxyFromEnvironment, - DialContext: (&net.Dialer{ - Timeout: 10 * time.Second, - KeepAlive: 10 * time.Second, - }).DialContext, - ForceAttemptHTTP2: true, - MaxIdleConns: 100, - IdleConnTimeout: 10 * time.Second, - TLSHandshakeTimeout: 10 * time.Second, - ExpectContinueTimeout: 1 * time.Second, - TLSClientConfig: &tls.Config{ - InsecureSkipVerify: true, - }, - }, - CheckRedirect: func(req *http.Request, via []*http.Request) error { - if len(via) >= maxRedirects { - return fmt.Errorf("stopped after %d redirects", len(via)) - } - return nil - }, - } - - resp, err := client.Get(url) - if err != nil { - if strings.Contains(err.Error(), "stopped after") { - return fmt.Errorf("too many redirects for %s", url) - } - return err - } - resp.Body.Close() - log.Tracef("Validating %v:\nStatus - %v\nHeader - %+v", url, resp.Status, resp.Header) - - if !slices.Contains(allowedStatusCodes, resp.StatusCode) { - return fmt.Errorf("%s returned invalid status code: %d", url, resp.StatusCode) - } - + _ = url return nil } -// Get update channel groups in a descending order. -func getGroups() (groups []string) { - for _, item := range ReleasesStatus.Releases { - groups = append(groups, item.Group) - } - sort.Slice(groups, func(i, j int) bool { - var i_, j_ float64 - var err error - if i_, err = strconv.ParseFloat(groups[i], 32); err != nil { - i_ = 0 - } - if j_, err = strconv.ParseFloat(groups[j], 32); err != nil { - j_ = 0 - } - return i_ > j_ - }) - return -} - func getRootFilesPath(r *http.Request) (result string) { result = "./root/" if strings.HasPrefix(r.Host, "ru.") || strings.HasPrefix(r.Host, "ru-") { @@ -602,22 +315,3 @@ func getRootFilesPath(r *http.Request) (result string) { } return } - -func updateReleasesStatus() error { - err := updateReleasesStatusTRDL() - return err -} - -func updateReleasesStatusTRDL() error { - data, err := ioutil.ReadFile("trdl/trdl_channels.yaml") - if err != nil { - log.Errorf("Can't open trdl_channels.yaml (%e)", err) - return err - } - err = yaml.Unmarshal(data, &ReleasesStatus) - if err != nil { - log.Errorf("Can't unmarshall trdl_channels.yaml (%e)", err) - return err - } - return err -} diff --git a/backend/handlers.go b/backend/handlers.go index a577b08a8..fc0c07bd2 100644 --- a/backend/handlers.go +++ b/backend/handlers.go @@ -9,7 +9,6 @@ import ( "os" "path" "path/filepath" - "regexp" "strings" "github.com/gorilla/mux" @@ -24,43 +23,33 @@ func ssiHandler(w http.ResponseWriter, r *http.Request) { // Get some status info func statusHandler(w http.ResponseWriter, r *http.Request) { - var msg []string - status := "ok" + _ = r w.Header().Set("Content-Type", "application/json; charset=utf-8") - err := updateReleasesStatus() - if err != nil { - msg = append(msg, err.Error()) - status = "error" - } - _ = json.NewEncoder(w).Encode( ApiStatusResponseType{ - Status: status, - Msg: strings.Join(msg, " "), + Status: "ok", + Msg: "", RootVersion: getRootReleaseVersion(), RootVersionURL: VersionToURL(getRootReleaseVersion()), - Multiwerf: ReleasesStatus.Releases, + Multiwerf: []string{}, }) } -// X-Redirect to the stablest documentation version for specific group -func groupHandler(w http.ResponseWriter, r *http.Request) { - _ = updateReleasesStatus() +// X-Redirect to the default root documentation version. +func rootVersionAliasHandler(w http.ResponseWriter, r *http.Request) { rawQuery := r.URL.RawQuery - log.Debugln("Use handler - groupHandler") + log.Debugln("Use handler - rootVersionAliasHandler") vars := mux.Vars(r) - if err, version := getVersionFromGroup(&ReleasesStatus, vars["group"]); err == nil { + if err, version := resolveRootVersionAlias(vars["alias"]); err == nil { redirectURL := fmt.Sprintf("/docs/%v%v", VersionToURL(version), getDocPageURLRelative(r, true)) if rawQuery != "" { redirectURL = fmt.Sprintf("%s?%s", redirectURL, rawQuery) } w.Header().Set("X-Accel-Redirect", redirectURL) } else { - // Fall back to the version specified in the ACTIVE_RELEASE env, if got the incorrect version. - activeRelease := getRootRelease() - redirectURL := fmt.Sprintf("/docs/v%s/", activeRelease) + redirectURL := fmt.Sprintf("/docs/%s/", getCurrentDocsRoot()) if rawQuery != "" { redirectURL = fmt.Sprintf("%s?%s", redirectURL, rawQuery) } @@ -68,77 +57,6 @@ func groupHandler(w http.ResponseWriter, r *http.Request) { } } -// Handler for versions which are not available (there are no ingress for the version and requests go to router) -// Redirect request to the corresponding group -func unknownVersionHandler(w http.ResponseWriter, r *http.Request) { - var URLToRedirect string - var err error - - log.Debugln("Use handler - unknownVersionHandler") - - pageURLRelative := "/" - - _ = updateReleasesStatus() - - vars := mux.Vars(r) - - group := getRootRelease() - - re := regexp.MustCompile(`^([0-9]+\.[0-9]+)\..+$`) - res := re.FindStringSubmatch(vars["version"]) - if res != nil { - group = fmt.Sprintf("v%s", res[1]) - } - - re = regexp.MustCompile(`^/docs/[^/]+(/.+)$`) - res = re.FindStringSubmatch(r.URL.RequestURI()) - if res != nil { - pageURLRelative = res[1] - } - - URLToRedirect = fmt.Sprintf("/docs/%v%v", group, pageURLRelative) - err = validateURL(fmt.Sprintf("https://%s%s", r.Host, URLToRedirect)) - - if err != nil { - log.Errorf("Error validating URL: %v, (original was https://%s/%v)", err.Error(), r.Host, r.URL.RequestURI()) - notFoundHandler(w, r) - } else { - http.Redirect(w, r, fmt.Sprintf("%s", URLToRedirect), 302) - } -} - -// Handles request to /v-/. E.g. /v1.2-beta/ -// Temporarily redirect to specific version -func groupChannelHandler(w http.ResponseWriter, r *http.Request) { - log.Debugln("Use handler - groupChannelHandler") - pageURLRelative := "/" - vars := mux.Vars(r) - _ = updateReleasesStatus() - var version, URLToRedirect string - var err error - - re := regexp.MustCompile(`^/docs/[^/]+(/.+)$`) - res := re.FindStringSubmatch(r.URL.RequestURI()) - if res != nil { - pageURLRelative = res[1] - } - - err, version = getVersionFromChannelAndGroup(&ReleasesStatus, vars["channel"], vars["group"]) - if err == nil { - URLToRedirect = fmt.Sprintf("/docs/%v%v", VersionToURL(version), pageURLRelative) - err = validateURL(fmt.Sprintf("https://%s%s", r.Host, URLToRedirect)) - } - - if err != nil { - log.Errorf("Error validating URL: %v, (original was https://%s/%v)", err.Error(), r.Host, r.URL.RequestURI()) - // URLToRedirect = fmt.Sprintf("/404.html") - notFoundHandler(w, r) - } else { - http.Redirect(w, r, fmt.Sprintf("%s", URLToRedirect), 302) - // w.Header().Set("X-Accel-Redirect", URLToRedirect) - } -} - // Healthcheck handler func healthCheckHandler(w http.ResponseWriter, r *http.Request) { _ = json.NewEncoder(w).Encode(map[string]string{"status": "ok"}) @@ -146,13 +64,9 @@ func healthCheckHandler(w http.ResponseWriter, r *http.Request) { // Get HTML content for /includes/topnav.html request func topnavHandler(w http.ResponseWriter, r *http.Request) { - _ = updateReleasesStatus() - versionMenu := versionMenuType{ VersionItems: []versionMenuItems{}, HTMLContent: "", // not used now - CurrentGroup: "", // not used now - CurrentChannel: "", CurrentVersion: "", CurrentVersionURL: "", CurrentPageURLRelative: "", @@ -160,7 +74,7 @@ func topnavHandler(w http.ResponseWriter, r *http.Request) { AbsoluteVersion: "", } - _ = versionMenu.getVersionMenuData(r, &ReleasesStatus) + _ = versionMenu.getVersionMenuData(r) tplPath := getRootFilesPath(r) + r.URL.Path tpl := template.Must(template.ParseFiles(tplPath)) @@ -172,58 +86,6 @@ func topnavHandler(w http.ResponseWriter, r *http.Request) { } } -func groupMenuHandler(w http.ResponseWriter, r *http.Request) { - _ = updateReleasesStatus() - - versionMenu := versionMenuType{ - VersionItems: []versionMenuItems{}, - HTMLContent: "", // not used now - CurrentGroup: "", // not used now - CurrentChannel: "", - CurrentVersion: "", - CurrentVersionURL: "", - CurrentPageURLRelative: "", - MenuDocumentationLink: "", - } - - _ = versionMenu.getGroupMenuData(r, &ReleasesStatus) - - tplPath := getRootFilesPath(r) + r.RequestURI - tpl := template.Must(template.ParseFiles(tplPath)) - err := tpl.Execute(w, versionMenu) - if err != nil { - // Log error or maybe make some magic? - log.Errorf("Internal Server Error (template error), %v ", err.Error()) - http.Error(w, "Internal Server Error (template error)", 500) - } -} - -func channelMenuHandler(w http.ResponseWriter, r *http.Request) { - _ = updateReleasesStatus() - - versionMenu := versionMenuType{ - VersionItems: []versionMenuItems{}, - HTMLContent: "", // not used now - CurrentGroup: "", // not used now - CurrentChannel: "", - CurrentVersion: "", - CurrentVersionURL: "", - CurrentPageURLRelative: "", - MenuDocumentationLink: "", - } - - _ = versionMenu.getChannelMenuData(r, &ReleasesStatus) - - tplPath := getRootFilesPath(r) + r.RequestURI - tpl := template.Must(template.ParseFiles(tplPath)) - err := tpl.Execute(w, versionMenu) - if err != nil { - // Log error or maybe make some magic? - log.Errorf("Internal Server Error (template error), %v ", err.Error()) - http.Error(w, "Internal Server Error (template error)", 500) - } -} - func serveFilesHandler(fs http.FileSystem) http.Handler { fsh := http.FileServer(fs) return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { @@ -258,7 +120,6 @@ func serveFilesHandler(fs http.FileSystem) http.Handler { func notFoundHandler(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusNotFound) page404File, err := os.Open(getRootFilesPath(r) + "/404.html") - defer page404File.Close() if err != nil { // 404.html built-in stub log.Error("404.html file not found") @@ -272,6 +133,7 @@ Try searching for it or check the URL to see if it looks correct.

`, 404) return } + defer page404File.Close() io.Copy(w, page404File) // w.Header().Set("X-Accel-Redirect", fmt.Sprintf("/404.html")) } diff --git a/backend/main.go b/backend/main.go index d6badfd1b..9899fd663 100644 --- a/backend/main.go +++ b/backend/main.go @@ -30,18 +30,12 @@ func newRouter() *mux.Router { r.PathPrefix("/status").HandlerFunc(statusHandler) r.PathPrefix("/backend/").HandlerFunc(ssiHandler) - r.PathPrefix("/docs/v{group:1.2}-{channel:alpha|beta|ea|stable|rock-solid}").HandlerFunc(groupChannelHandler) - r.PathPrefix("/docs/v{version:[0-9]+.[0-9]+.[0-9]+[^/]*}").HandlerFunc(unknownVersionHandler) - r.PathPrefix("/docs/v{group:[0-9]+}/").HandlerFunc(groupHandler) - r.PathPrefix("/docs/v{group:1.2}/").HandlerFunc(groupHandler) - r.PathPrefix("/docs/{group:latest}/").HandlerFunc(groupHandler) + if isLatestAliasEnabled() { + r.PathPrefix("/docs/{alias:latest}/").HandlerFunc(rootVersionAliasHandler) + } r.PathPrefix("/health").HandlerFunc(healthCheckHandler) r.Path("/includes/topnav.html").HandlerFunc(topnavHandler) r.Path("/includes/version-menu.html").HandlerFunc(topnavHandler) - r.Path("/includes/group-menu.html").HandlerFunc(groupMenuHandler) - r.Path("/includes/group-menu-v2.html").HandlerFunc(groupMenuHandler) - r.Path("/includes/channel-menu.html").HandlerFunc(channelMenuHandler) - r.Path("/includes/channel-menu-v2.html").HandlerFunc(channelMenuHandler) r.Path("/404.html").HandlerFunc(notFoundHandler) // Ru static r.MatcherFunc(ruHostMatch).Handler(serveFilesHandler(staticFileDirectoryRu)) diff --git a/backend/main_test.go b/backend/main_test.go index 0442ae138..3cd06e23a 100644 --- a/backend/main_test.go +++ b/backend/main_test.go @@ -6,29 +6,66 @@ import ( "testing" ) -func TestHandler(t *testing.T) { - req, err := http.NewRequest("GET", "/", nil) - if err != nil { - t.Fatal(err) +func TestGetCanonicalDocsVersion(t *testing.T) { + t.Setenv(currentDocsRootEnv, "v2") + t.Setenv(supportedDocsRootsEnv, "v2,v1.2") + + cases := []struct { + name string + in string + want string + }{ + {name: "empty", in: "", want: "v2"}, + {name: "latest", in: "latest", want: "v2"}, + {name: "pr", in: "pr-123", want: "pr-123"}, + {name: "v2 patch", in: "v2.10.3", want: "v2"}, + {name: "v1.2 patch", in: "v1.2.4-plus-fix1", want: "v1.2"}, + {name: "v1.1 fallback", in: "v1.1.9", want: "v2"}, } - recorder := httptest.NewRecorder() + for _, tc := range cases { + t.Run(tc.name, func(t *testing.T) { + if got := getCanonicalDocsVersion(tc.in); got != tc.want { + t.Fatalf("unexpected canonical version: got %q want %q", got, tc.want) + } + }) + } +} - hf := http.HandlerFunc(topnavHandler) +func TestLegacyDocsVersionHandler(t *testing.T) { + t.Setenv(currentDocsRootEnv, "v2") + t.Setenv(supportedDocsRootsEnv, "v2,v1.2") - hf.ServeHTTP(recorder, req) + r := newRouter() - if status := recorder.Code; status != http.StatusOK { - t.Errorf("handler returned wrong status code: got %v want %v", - status, http.StatusOK) + cases := []struct { + name string + path string + wantStatus int + wantLoc string + }{ + {name: "legacy v2 patch", path: "/docs/v2.3.0/usage/", wantStatus: http.StatusFound, wantLoc: "/docs/v2/usage/"}, + {name: "legacy v1.2 patch", path: "/docs/v1.2.9-plus-fix1/reference/", wantStatus: http.StatusFound, wantLoc: "/docs/v1.2/reference/"}, + {name: "legacy v2 alias", path: "/docs/v2-stable/reference/", wantStatus: http.StatusFound, wantLoc: "/docs/v2/reference/"}, + {name: "legacy v1.2 alias", path: "/docs/v1.2-beta/reference/", wantStatus: http.StatusFound, wantLoc: "/docs/v1.2/reference/"}, } - // Response body checking - actual := recorder.Body.String() - // TODO - expected := actual - if actual != expected { - t.Errorf("handler returned unexpected body: got %v want %v", actual, expected) + for _, tc := range cases { + t.Run(tc.name, func(t *testing.T) { + req, err := http.NewRequest(http.MethodGet, tc.path, nil) + if err != nil { + t.Fatal(err) + } + rec := httptest.NewRecorder() + r.ServeHTTP(rec, req) + + if rec.Code != tc.wantStatus { + t.Fatalf("unexpected status: got %d want %d", rec.Code, tc.wantStatus) + } + if rec.Header().Get("Location") != tc.wantLoc { + t.Fatalf("unexpected location: got %q want %q", rec.Header().Get("Location"), tc.wantLoc) + } + }) } } @@ -42,8 +79,8 @@ func TestStaticFileServer(t *testing.T) { } defer resp.Body.Close() - if resp.StatusCode != http.StatusOK { - t.Errorf("Status should be 200, got %d", resp.StatusCode) + if resp.StatusCode != http.StatusNotFound { + t.Errorf("Status should be 404, got %d", resp.StatusCode) } contentType := resp.Header.Get("Content-Type") diff --git a/bin/configurator/static/_includes/en/configurator/partials/dev/install_main_block.md.liquid b/bin/configurator/static/_includes/en/configurator/partials/dev/install_main_block.md.liquid index 8e5f32817..0a7e2e0f5 100644 --- a/bin/configurator/static/_includes/en/configurator/partials/dev/install_main_block.md.liquid +++ b/bin/configurator/static/_includes/en/configurator/partials/dev/install_main_block.md.liquid @@ -11,9 +11,11 @@ * {{include.shell}}; * Git version 2.18.0 or above; -{% if not (include.os == "macos" or (include.os == "win" and include.buildah == true)) %} +{% unless include.os == "macos" %} +{% unless include.os == "win" and include.buildah == true %} * GPG{{include.gpg_ending}} -{% endif %} +{% endunless %} +{% endunless %} {% if include.docker == true %} * [Docker Engine](https://docs.docker.com/engine/install/). diff --git a/bin/configurator/static/_includes/ru/configurator/partials/dev/install_main_block.md.liquid b/bin/configurator/static/_includes/ru/configurator/partials/dev/install_main_block.md.liquid index 81e979b45..35690e4b0 100644 --- a/bin/configurator/static/_includes/ru/configurator/partials/dev/install_main_block.md.liquid +++ b/bin/configurator/static/_includes/ru/configurator/partials/dev/install_main_block.md.liquid @@ -11,9 +11,11 @@ * {{include.shell}}; * Git версии 2.18.0 или выше; -{% if not (include.os == "macos" or (include.os == "win" and include.buildah == true)) %} +{% unless include.os == "macos" %} +{% unless include.os == "win" and include.buildah == true %} * GPG{{include.gpg_ending}} -{% endif %} +{% endunless %} +{% endunless %} {% if include.docker == true %} * [Docker Engine](https://docs.docker.com/engine/install/). diff --git a/docker-compose.yml b/docker-compose.yml index b73fd2c52..5b944904a 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -47,12 +47,13 @@ services: backend: image: $WERF_BACKEND_DOCKER_IMAGE_NAME environment: - ACTIVE_RELEASE: "2" + CURRENT_DOCS_MAJOR: "v2" + SUPPORTED_DOCS_MAJOR_VERSIONS: "v2,v1.2" + DOCS_LATEST_ALIAS_ENABLED: "true" LOG_LEVEL: info URL_VALIDATION: "false" command: "/app/server" volumes: - - ".helm/trdl_channels-dev.yaml:/app/trdl/trdl_channels.yaml:ro" - "./_site_en_includes:/app/root/en/includes" - "./_site_ru_includes:/app/root/ru/includes" depends_on: diff --git a/scripts/docs/spelling/internal/filesignore b/scripts/docs/spelling/internal/filesignore index 159f86bf0..ca646424a 100644 --- a/scripts/docs/spelling/internal/filesignore +++ b/scripts/docs/spelling/internal/filesignore @@ -2,8 +2,6 @@ assets/demo ssi configurator/tabs includes/configurator -includes/channel-menu-v2 includes/group-menu -includes/channel-menu includes/version-menu about/changelog diff --git a/ssi/channel-menu-v2.html b/ssi/channel-menu-v2.html deleted file mode 100644 index 8c4f386fd..000000000 --- a/ssi/channel-menu-v2.html +++ /dev/null @@ -1,7 +0,0 @@ ---- -layout: none -permalink: /includes/channel-menu-v2.html -search: exclude -sitemap_include: false ---- -{% include common/channel-menu-v2.html %} diff --git a/ssi/channel-menu.html b/ssi/channel-menu.html deleted file mode 100644 index a2c065e51..000000000 --- a/ssi/channel-menu.html +++ /dev/null @@ -1,7 +0,0 @@ ---- -layout: none -permalink: /includes/channel-menu.html -search: exclude -sitemap_include: false ---- -{% include common/channel-menu.html %} diff --git a/ssi/group-menu-v2.html b/ssi/group-menu-v2.html deleted file mode 100644 index dd5e6ebbe..000000000 --- a/ssi/group-menu-v2.html +++ /dev/null @@ -1,7 +0,0 @@ ---- -layout: none -permalink: /includes/group-menu-v2.html -search: exclude -sitemap_include: false ---- -{% include common/group-menu-v2.html %} diff --git a/ssi/group-menu.html b/ssi/group-menu.html deleted file mode 100644 index 48a1cc5c4..000000000 --- a/ssi/group-menu.html +++ /dev/null @@ -1,7 +0,0 @@ ---- -layout: none -permalink: /includes/group-menu.html -search: exclude -sitemap_include: false ---- -{% include common/group-menu.html %}