GitLab Pages Parallel Deployments
Documentation for what is currently implemented: https://docs.gitlab.com/ee/user/project/pages/#create-multiple-deployments # Problem Currently a project can have only a single version of a GitLab Pages site. This makes it hard for customers to try new ideas on their sites without changing the only version of the site. Customers need a way to preview changes or have multiple environments for their GitLab Pages sites to make it possible to validate changes before deploying their site. # Proposed solution Add `pages_path_prefix` key to `pages` jobs to create different versions of the Pages site. The value defined on this key will be used in the Pages site URL as a prefix on the paths. For example, given the GitLab Pages project `user/site` with the following `gitlab-ci.yml` ```yaml image: busybox pages: stage: deploy script: - echo "This pages version will have this prefix > $PAGES_PREFIX <" - echo "Pages accessible through > ${CI_PAGES_URL}/${PAGES_PREFIX} <" artifacts: paths: - public variables: PAGES_PREFIX: "" # no prefix by default (master) pages: path_prefix: "$PAGES_PREFIX" environment: name: "Pages ${PAGES_PREFIX}" url: "${CI_PAGES_URL}/${PAGES_PREFIX}" rules: - if: $CI_COMMIT_BRANCH == "master" # ensure to run on master (with default PAGES_PREFIX) - if: $CI_COMMIT_BRANCH == "staging" # conditionally change the prefix on the staging branch variables: PAGES_PREFIX: 'staging' - if: $CI_PIPELINE_SOURCE == "merge_request_event" # conditionally change the prefix on Merge Requests when: manual # run pages manually on Merge Requests variables: PAGES_PREFIX: 'mr$CI_MERGE_REQUEST_IID' # prefix with the mr<iid>, like `mr123` ``` This project will have multiple GitLab Pages versions: - `user.gitlab.io/site`: The master branch builds the main version of the site, without any prefixes. - `user.gitlab.io/site/staging`: The staging branch builds a version associated the `staging` prefix. - `user.gitlab.io/site/branch_name` (where `branch_name` is the source branch of the merge request): The merge request builds a preview for the site, in this example this is a manual build to overflowing the Object Storage with pages deploys for every merge request. ## Technical details - Add `prefix` to `PagesDeployment`: - the `prefix` will be used to build the versioned url - Add a _kill switch_ for the site versioning: Add a `pages_multiple_versions_enable` to `ProjectSetting`, where the user can enable/disable the multiple version of GitLab Pages. This way the project owner has the power to disable the feature and avoid contributors to add multiple versions of the site. - Expose the versioned site URL during the ci build to make it possible to use it when creating links in the site. (The work done in the [PoC](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/122498/diffs?commit_id=c63c3378f0bea02c024b322b8b1a6ea41e819091 "Draft: [PoC] Pages merge request preview") can be used as reference) - Document the feature as `Beta` ### Feature flag `pages_multiple_versions_setting` ## Concerns This feature should initially be introduced as an [Alpha](https://docs.gitlab.com/ee/policy/experiment-beta-support.html#experiment) behind a feature flag. ### Path override Adding a prefix as the first part of the path can override existing paths of the site. For example, imagine the following site structure: ```text site/ |- index.html |- fix_problem/ |- index.html ``` if a user creates a merge request with a branch named `fix_problem` and a version of the site for that merge request, when accessing `user.gitlab.io/site/fix_problem`, the user will actually access the versioned site, seeing the `site/index.html` from the `fix_problem` branch instead of `site/fix_problem/index.html` from the `main` branch. To avoid that the user can be creative when defining the `pages_prefix`, for example by using valid [URL chars](https://www.ietf.org/rfc/rfc1738.txt) like `"$-_.+!*'(),"`. Therefore one could make every merge request version of their site be accessible with a prefix (`__`) in the branch names, like `user.gitlab.io/site/__fix_problem/`. ### Limits The number extra deployments will be limited the root level namespace to mitigate the pressure in the internal API, since it servers the available pages sites for the requested domain/namespace. #### On Saas Initial limits, for the first iteration: * ~Silver / ~"GitLab Premium" 100 * ~gold / ~"GitLab Ultimate" 500 When the limit is reached, we should show a message letting the user now the limit was reached. #### On Self-managed We're also introducing a limit on self-managed to avoid problems with the pages internal API. `1000` ### Pricing Consideration _What tier will Page Multiple Versions Support release in?_ * This feature will release in ~"GitLab Premium" and ~"GitLab Ultimate". _Why will it release in Premium and Ultimate?_ * We will start with implementing multiple environments as a ~"GitLab Premium" feature in the first iteration, then release MR Previews using this platform as a ~"GitLab Free" feature in the second iteration. This way we don't have to worry about licensing, implementing the CI variable `CI_COMMIT_REF_SLUG`, certain UI changes, or interpreting the `merge_requests` special value in the first instance. We still have to implement the retention limit but that at least removes from risk from the MR Preview work. _Is there somewhere I can read more information on this pricing decision?_ * For an in depth conversation around this decision involving the Product Manager and Engineer Manager for ~"group::knowledge" please reference [this comment thread](https://gitlab.com/gitlab-org/gitlab/-/issues/407776#note_1439962905 "[Spike] Pages Validation: Review Apps for GitLab Pages"). _Where can I contact to provide my input and who can should I tag?_ * Please leverage [this thread](https://gitlab.com/groups/gitlab-org/-/epics/10914#note_1449446960 "GitLab Pages Main Deployment / Parallel Deployments") for input around pricing. Please tag Product Manager for ~"group::knowledge" , @mmacfarlane , in your comment.
epic