Project setup
This page guides you through the complete process of creating and configuring new GitLab projects for Customer Support Operations.
Warning
- All Customer Support Operations team members creating new projects must follow this process to ensure our projects are setup properly in a secured and maintainable way.
- This should only be done if there is a corresponding request issue (Feature Request, Administrative, Bug, etc.). If one does not exist, you should first create one (and let it go through the standard process before working it).
Process
The process consists of 7 steps:
- Create the project
- Adjust project settings
- Invite the correct groups
- Add initial files
- Setup CI/CD variables
- Configure additional requirements (if needed)
- Document the project
Step 1 - Create the project
The starting place to create the project itself. When doing so, you need to consider the following:
- The location of the project
- The name of the project
- The slug of the project
Location of the project
To create a project, you need to know where the project will be. When possible, we group similar projects together. Using this, you can often find an existing subgroup for the project to be in.
As an example, if making a sync repo for Zendesk Global, it will be within the subgroup gitlab-support-readiness/zendesk-global because:
- It is a Customer Support Operations non-public project (thus within our private namespace
gitlab-support-readiness) - It relates to Zendesk Global (thus within the subgroup
zendesk-global)
If the sync repo being created was relating to ticket attributes or metadata (such as ticket forms, ticket fields, etc.), you would then create it in the gitlab-support-readiness/zendesk-global/tickets subgroup.
If you do not see a subgroup for the project to exist within that already exists, speak to the team concerning this to determine the best place for the project to be created within.
Name of the project
We should strive for concise and self-explainable naming when creating projects. This should utilize the location in that effort.
So if making a project that handles processing of tickets for Zendesk US Government, we know from determining the location that it will be within the subgroup gitlab-support-readiness/zendesk-us-government/tickets. Knowing that, we can simply name the project Processor, since the location pathing will already dictate it is relating to Zendesk US Government tickets.
If you are ever unsure of what to name a project, speak to the team concerning this to determine the best name to use.
Slug of the project
Much like when determining the name, the slug should, with the pathing, be concise and self-explainable. Most often, the slug generated by GitLab will work for this purpose.
If you are ever unsure of what the slug for a project should be, speak to the team concerning this to determine the best slug to use.
Step 2 - Adjust the settings
With the project created, we need to manually adjust the settings to the following:
General
- Visibility, project features, permissions
- Project visibility: Private
- Additional options
- Require authentication to view media files
- Issues: disabled
- Repository: enabled
- Merge requests: enabled
- Forks: disabled
- Git Large File Storage (LFS): disabled
- CI/CD: enabled
- Container registry: disabled
- Analytics: disabled
- Requirements: disabled
- Security and Compliance: disabled
- Wiki: disabled
- Snippets: enabled
- Package registry: disabled
- Model experiments: disabled
- Model registry: disabled
- Pages: disabled
- Monitor: disabled
- Environments: disabled
- Feature flags: disabled
- Infrastructure: disabled
- Releases: disabled
- Email notifications
- Enable email notifications
- Include diff previews
- Show default emoji reactions
- Warn about Potentially Unwanted Characters
- Enable email notifications
- CI/CD Catalog project: disabled
- Badges
- None
- GitLab Duo
- GitLab Duo: enabled
- Allow flow execution: enabled
- Service Desk
- Disabled
Integrations
- None
Webhooks
- None
Access tokens
- None
Repository
- Branch defaults
- Default branch: master
- Auto-close references issues on default branch
- Branch rules
- All branches
- Squash commits: Require
- master
- Requires CODEOWNERS approval
- Allowed to merge: Developers+Maintainers
- Allowed to push and merge: 1 user
- NOTE: The 1 user here is the
gl-support-botuser
- NOTE: The 1 user here is the
- All branches
- Push rules
- Reject unverified users
- Reject inconsistent user name
- Reject unsigned commits
- Reject commits that aren’t DCO certified
- Do not allow users to remove Git tags with git push
- Check whether the commit author is a GitLab user
- Prevent pushing secret files
- Require expression in commit messages: blank
- Reject expression in commit messages: blank
- Branch name: blank
- Commit author’s email: blank
- Prohibited file names: blank
- Maximum file size (MB): 0
- Mirroring repositories
- None
- Protected branches
- master
- Allowed to merge: Maintainers
- Allowed to push and merge: GitLab Support Bot
- Allowed to force push: disabled
- Code owner approval: enabled
- master
- Protected tags
- None
- Deploy tokens
- None
- Deploy keys
- None
Merge Requests
- Merge requests
-
Merge method: Merge commit
-
Merge options
- Enable merged results pipelines
- NOTE: In rare situations this may be enabled, but never by default
- Automatically resolve merge request diff threads when they become outdated
- Show link to create or view a merge request when pushing from the command line
- Enable “Delete source branch” option by default
- Enable merged results pipelines
-
Squash commits when merging: Require
-
Merge checks
- Pipelines must succeed
- NOTE: This will vary based on project template type.
- All threads must be resolved
- Status checks must succeed
- Pipelines must succeed
-
Status checks
- None
-
Merge suggestions: blank
-
Merge commit message template
Merge branch '%{source_branch}' into '%{target_branch}' %{title} %{issues} See merge request %{reference} -
Squash commit message template
%{title} -
Default description template for merge requests: blank
-
- Merge request approvals
- Coverage-Check: disabled
- Minimum required approvals: 0
- Approval settings
- Prevent approval by author
- Prevent approvals by users who add commits
- Prevent editing approval rules in merge requests
- Require user re-authentication (password or SAML) to approve
- When a commit is added: Removal all approvals
- Merge request branch workflow
- None
CI/CD
- General pipelines
- Project-based pipeline visibility
- Auto-cancel redundant pipelines
- Prevent outdated deployment jobs
- Allow job retries even if the deployment job is outdated.
- Use separate caches for protected branches
- Minimum role required to cancel a pipeline or job: Developer
- CI/CD configuration file: blank
- Git strategy: git fetch
- Git shallow clone: 20
- Timeout: 15m
- NOTE: You might need to adjust this depending on what your project is doing exactly
- Automatic pipeline cleanup: 5d
- Auto DevOps
- Default to Auto DevOps pipeline
- Protected environments
- None
- Pipeline trigger tokens
- None
- Automatic deployment rollbacks
- Enable automatic rollbacks
- Deploy freezes
- None
- Job token permissions
- Authorized groups and projects: Only this project and any groups and projects in the allowlist
- CI/CD job token allowlist
- Only the project itself should be present in the list
- Limit access from this project (Deprecated): disabled
- Add an existing project to the scope
- Only the project itself should be present in the list
- Secure files
- None
- Pipeline subscriptions
- Subscriptions
- None
- Subscribed to this project
- None
- Subscriptions
Monitor
- Error tracking
- Enable error tracking
- Active
- Error tracking backend: GitLab
- Enable error tracking
- Alerts
- None
- Incidents
- Active: disabled
- Status page
- Active
- Status page URL: blank
- S3 Bucket name: blank
- AWS region: blank
- AWS access key ID: blank
- AWS Secret access key: blank
Step 3 - Invite the correct groups
After adjusting the settings for your new project, you need to invite the correct groups as members to it. Due to our inheritance setup, project access is handled automatically through group membership. So this is really about what the CODEOWNERS file will use (for merge request approvals).
- For projects pertaining to subjects that require Customer Support Operations leadership, you would invite gitlab-support-readiness/cust_support_ops_critical_access
- For projects requiring US citizenship, you would invite gitlab-support-readiness/cust_support_ops_team_us_citizens
- NOTE We should strive to not need a project to require any specific citizenship. If your project is requiring it, it indicates some form of output within the project (the code, CI/CD, etc.) involves citizenship protected data. While this is not always avoidable, you should always aim to NOT have citizenship protected data within gitlab.com.
- For anything else, you would invite gitlab-support-readiness/cust_support_ops_team
If you are ever unsure of what group(s) to invite, speak to the team for assistance.
Step 4 - Add your files
In this stage, you are going to make the initial commit to the project to add the files. The exact files you will need to add are going to vary depending on what the project is for (and what it does). Please review the below guidelines for various files to ensure you align with how we setup projects:
-
.gitlab/CODEOWNERS- The exact contents of this are going to vary depending on the code you use, but the starting place for this should always be:
[Customer Support Operations] * @GROUP_TO_INVITE- See Step 3 for more information for the value of
GROUP_TO_INVITE
-
bin/post_in_slack.sh- This file should always have executable permissions
- The contents for this file should always be:
curl -ss $SLACK_URL_PIPELINE_FAIL \ -X POST \ -H 'Content-type: application/json' \ --data "{\"text\": \"<$CI_PROJECT_URL|$CI_PROJECT_PATH> pipeline <$CI_PIPELINE_URL|#$CI_PIPELINE_ID> failed $DATE\", \"mrkdwn\": true }" -
.gitlab-ci.yml-
The exact contents of this are going to vary depending on the code you use, but you can use the following start templates for common project types:
Sync repos
image: "registry.gitlab.com/gitlab-support-readiness/images/ruby:3.2.2" stages: - compare - sync - notify before_script: - ruby -v - gem install bundler - bundle compare: stage: compare script: - ./bin/compare rules: - if: $CI_PIPELINE_SOURCE == 'merge_request_event' retry: max: 2 when: - runner_system_failure - stuck_or_timeout_failure sync: stage: sync script: - ./bin/sync rules: - if: $CI_PIPELINE_SOURCE == 'trigger' retry: max: 2 when: - runner_system_failure - stuck_or_timeout_failure post_in_slack_on_failure: before_script: '' stage: notify when: on_failure image: registry.gitlab.com/gitlab-support-readiness/images/curl:latest script: - ./bin/post_in_slack.shZendesk apps
image: "registry.gitlab.com/gitlab-support-readiness/images/ruby:3.2.2" stages: - compare - sync - notify before_script: - ruby -v - gem install bundler - bundle compare_instances: stage: compare script: - ./bin/compare_sandbox - ./bin/compare_production rules: - if: $CI_PIPELINE_SOURCE == 'merge_request_event' retry: max: 2 when: - runner_system_failure - stuck_or_timeout_failure force_sandbox_sync: stage: sync script: - ./bin/sync_sandbox force needs: ['compare_instances'] when: manual rules: - if: $CI_PIPELINE_SOURCE == 'merge_request_event' retry: max: 2 when: - runner_system_failure - stuck_or_timeout_failure perform_sandbox_sync: stage: sync script: - ./bin/sync_sandbox rules: - if: $CI_PIPELINE_SOURCE == 'schedule' && $SANDBOX == 'true' retry: max: 2 when: - runner_system_failure - stuck_or_timeout_failure perform_production_sync: stage: sync script: - ./bin/sync_production rules: - if: $CI_PIPELINE_SOURCE == 'schedule' && $SANDBOX == 'false' retry: max: 2 when: - runner_system_failure - stuck_or_timeout_failure post_in_slack_on_failure: before_script: '' stage: notify when: on_failure image: registry.gitlab.com/gitlab-support-readiness/images/curl:latest script: - ./bin/post_in_slack.sh -
If you are unsure of what to have here, reach out to the rest of the team for assistance
-
-
.rubocop.yml- The contents of this file should always align with the current ruby version we are working with. That means it should be:
AllCops: NewCops: enable TargetRubyVersion: 3.2.2 -
.ruby-version- The contents of this file should always be the current ruby version we are working with. That means it should be:
3.2.2 -
Gemfile- The list of gems should be in alphabetic order
- The exact gems required are going to vary depending on the code you use, but the starting place for this should always be:
# frozen_string_literal: true source 'https://rubygems.org' -
README.md- The exact content of this is going to vary, but you should ensure you have the following documented in your README.md file:
- Name of project
- Brief description
- Filetree layout
- Requirements
- CI/CD pipeline information
- If you are unsure of what to have here, reach out to the rest of the team for assistance
- The exact content of this is going to vary, but you should ensure you have the following documented in your README.md file:
Step 5 - Setup CI/CD variables
Configure the CI/CD variables required for your project. Many variables are inherited from the parent namespace, so focus on project-specific values:
Common variables to add:
- API token values (e.g.
ZD_TOKEN,GL_TOKEN,CALENDLY_API_TOKEN, etc.) - Slack webhooks (except
SLACK_URL_PIPELINE_FAILwhich is inherited)
To check inherited variables:
- Navigate to Settings > CI/CD > Variables in your project
- Review the “Inherited from group” section to see what’s already available
- Add only the variables not already provided by the parent namespace
Variable protection:
- Mark sensitive tokens as “Masked”
Step 6 - Additional configuration (if needed)
For most projects, Steps 1-5 are sufficient. However, some projects may require additional configuration such as:
- Setting up webhooks for external integrations
- Mirroring the code to a different project
- Configuring external service integrations
- Setting up scheduled pipelines
If you’re unsure whether additional configuration is needed, consult with the team.
Step 7 - Document it
The final step in your project creation is to update our handbook pages with information about the project. This should include:
- What it is
- What it does
- How it works
- The type of deployment strategy it uses
- How to make changes
- Any troubleshooting information
After Project Creation
Once your project is created and documented:
- The project will be accessible to the appropriate team members based on group membership
- CI/CD pipelines will run according to the configured rules
- Changes will require merge requests with CODEOWNERS approval
- Monitor the project’s initial pipelines to ensure everything is configured correctly
7d49549f)
