--- layout: markdown_page title: "People Ops Engineering" --- ## On this page {:.no_toc} - TOC {:toc} ## Overview As GitLab continues to scale, our need for tools and automation to manage our growth expands along with it. To help the People Group, we have a dedicated [People Operations Fullstack Engineer](https://about.gitlab.com/job-families/engineering/fullstack-engineer/) to make our team more efficient and improve the effectiveness of our core [People Group](https://about.gitlab.com/handbook/people-group/). Responsibilities include automation and API integrations in recruiting, [onboarding](https://about.gitlab.com/handbook/general-onboarding/onboarding-processes/), [Internal transition issues](https://gitlab.com/gitlab-com/people-group/employment-templates-2/-/blob/master/.gitlab/issue_templates/internal_transition.md) and [offboarding](https://gitlab.com/gitlab-com/people-group/employment-templates-2/-/blob/master/.gitlab/issue_templates/offboarding.md). ### Working with us If you'd like to request engineering assistance with an issue related to People Ops processes or tools ([like BambooHR](https://about.gitlab.com/handbook/people-group/#using-bamboohr)), please start by [creating an issue](https://gitlab.com/gitlab-com/people-group/people-operations-engineering/issues/new) in the People Ops Engineering project. ### Keep yourself informed about the changes It can be hard to keep track of all the updates that are done on the different projects. The most important updates are shared in the relevant Slack channels. We also update the handbook when a new project is added. As it can happen you miss an update on Slack or handbook changes the People Ops Engineering team will make sure that the most important updates are shared in this [Google Doc](https://docs.google.com/document/d/1GUpI0YSU4QSM2ICKzj14JAZA_jOprZKewKpqU9Vt42E/edit#) ### Our workflow The [People Ops Engineering board](https://gitlab.com/gitlab-com/people-group/people-operations-engineering/-/boards/1312849) serves as the single source of truth on the engineering team's priorities. Issues follow a linear sequence, with a `Workflow::` label indicating an issue's current status: 1. `Workflow::Triage`: Issues start here. Issues in triage must be further defined before they're able to be made ready for development. Once the problem and a proposal for solving it is defined to the point where an engineer can begin work, it can be moved to `Workflow::Ready for Development`. - `Workflow::Waiting`: Issues that are waiting from input from someone or are waiting on a dependency. These are blocked issues that need input or progress from others before they can progress. 2. `Workflow::Ready for Development`: Issues that are groomed and are ready for an engineer to begin work. They're well defined in terms of the problem, and have a proposal that's defined enough for us to begin work; not every detail needs to have been defined, but an engineer should be able to start work on this issue by reading the issue description alone. - Engineers beginning work on a ready for development issue should assign the issue to themselves and move it to `Workflow::In Progress`. 3. `Workflow::In Progress`: Issues that are actively being worked on by a developer. 4. `Workflow::Verification`: Issues that have engineering work complete and ready for evaluation. At this point, the developed solution should be evaluated (by the issue reporter or another stakeholder) to verify that it solves the original problem. - Once signed off, the issue can be closed. ## Current systems ### Source of truth For all automations mentioned in this page, BambooHR database acts as the single souce of truth. We make use of a [fork](https://gitlab.com/gitlab-com/people-ops/bamboozled/) from the [Bamboozled](https://github.com/Skookum/bamboozled) Ruby gem, and interact with BambooHR using an bot user with limited access to employee details. #### Data confidentiality Because the bot user used for automations has read and write access to employee details the main project for automation resides on [ops.gitlab.com](https://ops.gitlab.net/gitlab-people-engineering/employment-automation/). The bot only gets access to the fields in BambooHR needed for the automation. TODO: Add list of fields accessible by the bot. ### Partially automated processes #### Onboarding issue creation PeopleOps specialists make use of GitLab's [ChatOps](https://docs.gitlab.com/ee/ci/chatops/) functionality to automate creation of onboarding issues that contain onboarding tasks relevant to the incoming team member. The Slack command used for this is: ``` /pops run onboarding ``` The Slack command triggers a pipeline in the `employment-automation` project, which will run the job `onboarding`, and reply with a link to the newly created onboarding issue. The onboarding issue will be automatically assigned to the PeopleOps Specialist who ran the command and the incoming team member's Manager. Besides creating an onboarding issue, it will also create an epic in the [Team Member Project](https://gitlab.com/gitlab-com/team-member-epics/). The epic will have the team member's name and the issue will be linked to the epic. The onboarding tasks that are applicable to all team members are listed in the general [`onboarding.md`](https://gitlab.com/gitlab-com/people-ops/employment-templates-2/blob/master/.gitlab/issue_templates/onboarding.md) file. It will be included by default in the onboarding issue. The job then grabs various details of the incoming team member, like country of residence, entity through which they are hired, division, department, job title etc. For each of these details, it checks for the existence of a task file in the [`onboarding_tasks` folder](https://gitlab.com/gitlab-com/people-group/employment-templates-2/-/tree/master/.gitlab%2Fissue_templates%2Fonboarding_tasks) of the `employment` project. These tasks files are of the format `country_.md`, `entity_.md`, `division_.md`, `department_.md`, etc. If such a file is found, it includes contents of those files also in the onboarding issue. ###### Note: - Due to some technical difficulties, the onboarding issue created by the command will contain onboarding tasks applicable to other job families at GitLab. PeopleOps specialists will have to manually delete all of them except the one applicable to the incoming team member. An issue to improve this can be found [here](https://gitlab.com/gitlab-com/people-ops/people-operations-engineering/issues/5). - The templates and issues live in 2 different locations. Templates live within the [`people-group`](https://gitlab.com/gitlab-com/people-group/employment-templates-2/-/tree/master/.gitlab/issue_templates), while onboarding/offboarding and transition issues live in the [`Team Member Epics`](https://gitlab.com/gitlab-com/team-member-epics/employment/-/issues) group. The templates are public but the issues remain private. Any updates to the templates can be done in the [Employment Templates](https://gitlab.com/gitlab-com/people-group/employment-templates-2/-/tree/master/.gitlab/issue_templates) project. ##### Interns If you want to create the onboarding issue for interns, you can use the same Slack command. The biggest difference is that it will read from a different template. The template is determined by the division: `onboarding_intern_.md`. Currently there's only one division that has set up a template: - [Engineering](https://gitlab.com/gitlab-com/people-group/employment-templates-2/-/blob/master/.gitlab/issue_templates/onboarding_intern_engineering.md) This is a first iteration of creating onboarding issues for interns, we can move to a similar method as we do for the "regular" onboardings. #### Offboarding issue creation PeopleOps specialists make use of GitLab's [ChatOps](https://docs.gitlab.com/ee/ci/chatops/) functionality to automate creation of offboarding issues that contain offboarding tasks relevant to the outgoing team member. The Slack command used for this is: ``` /pops run offboarding ``` The Slack command triggers a pipeline in the [`employment` project](https://gitlab.com/gitlab-com/team-member-epics/employment/-/issues), which will run the job `offboarding`, and reply with a link to the newly created offboarding issue. The offboarding issue will be automatically assigned to the PeopleOps Specialist who ran the command and the outgoing team member's Manager. The job then grabs various details of the outgoing team member, like country of residence, entity through which they are hired, division, department, job title etc. For each of these details, it checks for the existence of a task file in the [`offboarding_tasks` folder](https://gitlab.com/gitlab-com/people-group/employment-templates-2/-/tree/master/.gitlab%2Fissue_templates%2Foffboarding_tasks) of the `employment` project. These tasks files are of the format `country_.md`, `entity_.md`, `division_.md`, `department_.md`, etc. If such a file is found, it includes contents of those files also in the offboarding issue. ###### Note: - Due to some technical difficulties, the offboarding issue created by the command will contain offboarding tasks applicable to other job families at GitLab. PeopleOps specialists will have to manually delete all of them except the one applicable to the outgoing team member. An MR with a suggestion to improve this can be found [here](https://gitlab.com/gitlab-com/people-group/employment-templates/-/merge_requests/960). - The templates and issues live in 2 different locations. Templates live within the [`people-group`](https://gitlab.com/gitlab-com/people-group/employment-templates-2/-/tree/master/.gitlab/issue_templates), while onboarding/offboarding and transition issues live in the [`Team Member Epics`](https://gitlab.com/gitlab-com/team-member-epics/employment/-/issues) group. The templates are public but the issues remain private. Any updates to the templates can be done in the [Employment Templates](https://gitlab.com/gitlab-com/people-group/employment-templates-2/-/tree/master/.gitlab/issue_templates) project. ### Fully automated processes PeopleOps make use of GitLab's [scheduled pipelines] features to automate Slack announcements related to team member events like hiring and anniversaries. These are configured in the [`employment-automation`](https://gitlab.com/gitlab-people-engineering/employment-automation/pipeline_schedules) project. A Slack bot named `PeopleOps Bot` is configured to post these announcements to relevant Slack channels. #### Anniversary announcements A scheduled pipeline is configured to automatically send a message congratulating all team members celebrating a work anniversary that week to the Slack channel `#team-member-updates`. The message will contain list of all such team members and the number of years they are celebrating at GitLab. Currently, the pipeline is scheduled to be run at 10:00 AM UTC on every Thursday. #### New hire announcements A scheduled pipeline is configured to automatically send a message containing a list of all new team members who are joining GitLab in the following week. It includes details like name, email address, joining date, and their job title. The message also includes a link to a [Sisense chart](https://app.periscopedata.com/app/gitlab/503779) containing a detailed breakdown and overview of the hiring process over time. While we create this message, we check if there are any team members that have "missing data". When they do, the message, is sent to `#peopleops-alerts`. This way, the People Experience associate, can edit the message and then manually copy-paste the message to `#team-member-updates`. When there is no missing data, the message is posted directly to `#team-member-updates`. Currently, the pipeline is scheduled to be run at 08:00 AM UTC every Thursday. #### Informing PeopleOps Specialists about details missing in BambooHR for upcoming new hires For the new hire announcements to be accurate, it is required to ensure the BambooHR details of team members joining the following week is as complete as possible. To help PeopleOps team in this task, another scheduled pipeline is run to verify if the BambooHR details of all incoming team members is complete. This pipeline notifies PeopleOps specialists in `#peopleops-alerts` channel about people whose details are missing and the details that are missing for each person. Since PeopleOps Specialists should have enough time to fix these missing details before new hire announcements are sent, it is necessary this job should be run an adequate amount of time before the new hire announcements job is run. Currently, the pipeline is scheduled to be run at 02:00 PM on every Wednesday. #### Closing outdated onboarding issues It is expected that onboarding issues be completed and closed within 30 days of opening. To remind team members about this, we are using the `due date` functionality in GitLab issues. When an onboarding issue is created, we automatically set a due date of 35 days to it (we open onboarding issues the week before the team member joins, so 35 days gives them almost 30 days to complete onboarding tasks after they actually start at GitLab). GitLab will send a reminder notification email to all the assignees of the issue near the due date. In addition to this due date, team members get an additional 30 days to complete and close the onboarding issue. In total, a team member gets around 60 days to complete their onboarding issue. We have another scheduled pipeline to close the outdated issues (issues that have been open for more than 60 days). This pipeline will add a comment on the issue that it is being automatically closed and what the team members should do if they have onboarding tasks remaining. Currently, the pipeline is scheduled to be run at 09:30 PM on every Friday. It will close all the onboarding issues created before 60 days from that date. #### Offboarding Issue commenting When a team member is offboarded, there's a redirect rule that is setup on G-Suite for the outgoing team member. After 30 days this redirect rule needs to be removed. To make sure this isn't forgotten, a scheduled pipeline is set up for the bot to leave a GitLab issue comment reminding the People Experience Associates to removes the rule. Currently, the pipeline is scheduled to run at 10:30 AM on every Friday. It will comment on all the offboarding issues created before 30 days from that date. #### Internal Transition issue creation PeopleOps specialists make use of GitLab's [ChatOps](https://docs.gitlab.com/ee/ci/chatops/) functionality to automate creation of internal transition issues that contain transition tasks relevant to the team member. The Slack command used for this is: ``` /pops run transition ``` The Slack command triggers a pipeline in the `employment` project, which will run the job `transition`, and reply with a link to the newly created internal transition issue. The issue will be automatically assigned to the People Experience Associate who ran the command, the team member, the previous manager and the new manager of the team member. #### Sync data between Greenhouse and BambooHR Considering our source of truth is BambooHR, we need to make sure that applicants are created in BambooHR once they are hired. To do this, we created a custom sync between Greenhouse and BambooHR. We check hourly if new applicants have been marked as hired on Greenhouse. If there are any, we create a user on BambooHR with the applicant and offer data from Greenhouse. Before this custom sync, we used a sync within Greenhouse itself but it didn't sync the data correctly. That's why we went with a custom sync. The fields that are synced: | Greenhouse Data | BambooHR Data | | --------------------------------------------------------------- | ---------------------- | | `first_name` (Applicant data) | `firstName` | | `last_name` (Applicant data) | `lastName` | | `candidate_country` (Offer data) | `country` | | `starts_at` (Offer data) | `hireDate` | | `email_addresses.personal` (Applicant data) | `homeEmail` | | Copied from the `hiring_manager` | `department` | | Copied from the `hiring_manager` | `division` | | `employment_type` (Offer data) | `customFullOrPartTime` | | `id` (Greenhouse Applicant) | `customCandidateID` | | Mapped through `candidate_country` to the right value | `customPayFrequency` | | Mapped through `candidate_country` to the right value | `customRegion` | | Copied from the `hiring_manager` | `customCostCenter` | | `locality` (Offer data) | `customLocality` | | `starts_at` (Offer data) | `customHireDate` | | `stock_options` (Offer data) | `customShares` | | `entity` (Offer data) | `customInc/BV` | | "Hired" (Hardcoded value - not from Greenhouse) | `customNotes` | | `starts_at` (Offer data) | `date` | | `full_title_(including_level_and_specialty)` (Offer data) | `jobTitle` | | `hiring_manager` (Offer data) | `reportsTo` | | `starts_at` (Offer data) | `startDate` | | `entity` (Offer data) | `location` | | `salary` (Offer data) / `pay_frequency` | `rate` | | "Salary" (Hardcoded value - not from Greenhouse, needs fix) | `type` | | "Exempt" (Hardcoded value - not from Greenhouse) | `exempt` | | "Hire" (Hardcoded value - not from Greenhouse) | `reason` | | "Pay Period" (Hardcoded value - not from Greenhouse, needs fix) | `paidPer` | | Mapped through `candidate_country` to the right value | `paySchedule` | When required data is missing, the system is set up to send a Slack message about this applicant. Currently these candidates will need to be synced manually. This is the first iteration. In the future we want to [add more fields](https://gitlab.com/gitlab-com/people-group/people-operations-engineering/issues/30). ##### Progress
#### Access Request issue creation To get access to the tools our team members need for their job, an Access Request (AR) issue needs to created. To make sure our team members experience a good onboarding, we automated this process by creating the AR Role based entitlement issue with the bot. This automation was enabled on 2020-04-01 (so on 2020-04-02 the pipeline ran the first time.) A scheduled pipeline is configured to fetch all the team members who started the day before. For all these members it will check if it is possible to create an Access Request issue. It will only work for the members with roles that have a set template in the [role baseline access requests tasks directory](https://gitlab.com/gitlab-com/team-member-epics/access-requests/tree/master/.gitlab/issue_templates/role_baseline_access_request_tasks). The issue will be created in the [AR project](https://gitlab.com/gitlab-com/team-member-epics/access-requests). The bot will announce in Slack (#peopleops-alerts) the list of people that we were able to create the AR. As well as the list of people (with their role) that we weren't able to create the AR for. This way we can connect with the teams so they can add a template for this role. Note: PeopleOps is not responsible for creating or maintaining the templates, each team is responsible for creating the templates for their roles. This is also explained in the [README](https://gitlab.com/gitlab-com/team-member-epics/access-requests/blob/master/README.md) of the project. Here's a video with the People Ops Engineer going over the AR automation. They discuss how it works and how a template can be added.
## Access to ChatOps for PeopleOps Team Before the PeopleOps team member can excute the chat commands mentioned on this page, they need to be invited to the [employment-automation](https://ops.gitlab.net/gitlab-people-engineering/employment-automation/) project. This can be done by the owners of the project. Once you are a member of the project, you can run any `/pops` command. The PeopleOps bot will respond that you first have to connect your GitLab account. You can click the provided URL and authorize. Now you are able to run the `/pops` commands.