From 670c830ea2b1877d3d7ae6a24d098042023158b4 Mon Sep 17 00:00:00 2001 From: Max Flintoff <146855155+maxflintoff-tomtom@users.noreply.github.com> Date: Fri, 21 Jun 2024 10:32:17 +0200 Subject: [PATCH] chore: update from upstream (#4) * added API docs for using Safe Settings (#634) * docs: update and consolidate documentation (#643) * docs: update and consolidate documentation * docs(readme): fix formatting * Update CRON schedule to address rate limit issues (#631) * Upgrade to node.js 20 (#609) * chore: fix issues with logging in tests Fix errors thrown by lack of child function in logging stubs * chore: fix branches tests Fix the branch tests to include default properties --------- Co-authored-by: primetheus <865381+primetheus@users.noreply.github.com> Co-authored-by: Elio Di Nino <52972357+ElioDiNino@users.noreply.github.com> Co-authored-by: Igor Costa Co-authored-by: Benjamin Manuel --- .devcontainer/Dockerfile | 18 +- .devcontainer/devcontainer.json | 4 +- .github/workflows/node-ci.yml | 7 +- .nvmrc | 2 +- Dockerfile | 8 +- README.md | 442 ++++------------ app.yml | 7 +- docs/README.md | 12 + docs/deploy.md | 119 ++--- .../github-settings/1. repository-settings.md | 418 +++++++++++++++ .../2. repository-variables.md | 50 ++ docs/github-settings/3. collaborators.md | 53 ++ docs/github-settings/4. teams.md | 52 ++ docs/github-settings/5. branch-protection.md | 338 ++++++++++++ .../6. deployment-environments.md | 177 +++++++ docs/github-settings/7. autolinks.md | 69 +++ docs/github-settings/8. labels.md | 65 +++ docs/github-settings/README.md | 12 + docs/sample-settings/org-ruleset.json | 115 ---- docs/sample-settings/org-ruleset.yml | 153 ------ docs/sample-settings/repo.yml | 209 +------- docs/sample-settings/settings.yml | 491 +++++++++++++----- docs/sample-settings/suborg.yml | 193 +------ lib/mergeDeep.js | 2 +- lib/plugins/validator.js | 2 + safe-settings.yaml | 5 +- serverless.yml | 6 +- test/unit/lib/plugins/autolinks.test.js | 2 +- test/unit/lib/plugins/branches.test.js | 12 +- test/unit/lib/plugins/collaborators.test.js | 5 +- .../lib/plugins/custom_properties.test.js | 4 +- test/unit/lib/plugins/environments.test.js | 14 +- test/unit/lib/plugins/labels.test.js | 5 +- test/unit/lib/plugins/repository.test.js | 1 + test/unit/lib/plugins/teams.test.js | 2 +- test/unit/lib/settings.test.js | 12 +- 36 files changed, 1841 insertions(+), 1245 deletions(-) create mode 100644 docs/README.md create mode 100644 docs/github-settings/1. repository-settings.md create mode 100644 docs/github-settings/2. repository-variables.md create mode 100644 docs/github-settings/3. collaborators.md create mode 100644 docs/github-settings/4. teams.md create mode 100644 docs/github-settings/5. branch-protection.md create mode 100644 docs/github-settings/6. deployment-environments.md create mode 100644 docs/github-settings/7. autolinks.md create mode 100644 docs/github-settings/8. labels.md create mode 100644 docs/github-settings/README.md delete mode 100644 docs/sample-settings/org-ruleset.json delete mode 100644 docs/sample-settings/org-ruleset.yml diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index d5f630b3..191e6a6a 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -1,11 +1,11 @@ # See here for image contents: https://github.com/microsoft/vscode-dev-containers/tree/v0.195.0/containers/javascript-node/.devcontainer/base.Dockerfile # [Choice] Node.js version (use -bullseye variants on local arm64/Apple Silicon): 16, 14, 12, 16-bullseye, 14-bullseye, 12-bullseye, 16-buster, 14-buster, 12-buster -ARG VARIANT=16-bullseye -FROM mcr.microsoft.com/vscode/devcontainers/javascript-node:0-${VARIANT} +ARG VARIANT=20-bookworm +FROM mcr.microsoft.com/devcontainers/javascript-node:1-${VARIANT} # [Optional] Uncomment this section to install additional OS packages. RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \ - && apt-get -y install --no-install-recommends python pip + && apt-get -y install --no-install-recommends python3 python3-pip # [Optional] Uncomment if you want to install an additional version of node using nvm # ARG EXTRA_NODE_VERSION=10 @@ -17,6 +17,14 @@ RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \ # Update npm RUN npm install -g npm # Intall aws cli -RUN curl "https://awscli.amazonaws.com/awscli-exe-linux-aarch64.zip" -o "awscliv2.zip" && unzip awscliv2.zip && sudo ./aws/install +RUN curl "https://awscli.amazonaws.com/awscli-exe-linux-$(uname -m).zip" -o "awscliv2.zip" && \ + unzip awscliv2.zip && \ + sudo ./aws/install && \ + rm -rf ./aws && \ + rm awscliv2.zip # Install sam cli -RUN pip install aws-sam-cli \ No newline at end of file +RUN curl -L "https://github.com/aws/aws-sam-cli/releases/latest/download/aws-sam-cli-linux-$(dpkg --print-architecture).zip" -o "aws-sam-cli.zip" && \ + unzip aws-sam-cli.zip -d sam-installation && \ + sudo ./sam-installation/install && \ + rm -rf ./sam-installation && \ + rm aws-sam-cli.zip diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index abe388ea..62232b1d 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -7,7 +7,7 @@ // Update 'VARIANT' to pick a Node version: 16, 14, 12. // Append -bullseye or -buster to pin to an OS version. // Use -bullseye variants on local arm64/Apple Silicon. - "args": { "VARIANT": "16-bullseye" } + "args": { "VARIANT": "20-bookworm" } }, "settings": {}, @@ -34,4 +34,4 @@ "remoteUser": "node", -} \ No newline at end of file +} diff --git a/.github/workflows/node-ci.yml b/.github/workflows/node-ci.yml index 06933f4a..d599430e 100644 --- a/.github/workflows/node-ci.yml +++ b/.github/workflows/node-ci.yml @@ -15,7 +15,12 @@ jobs: - name: Setup node uses: actions/setup-node@v4 with: - node-version: 16.x + node-version: ${{ matrix.node-version }} cache: npm - run: npm install - run: npm run test:unit:ci + strategy: + matrix: + node-version: + - 18 + - 20 diff --git a/.nvmrc b/.nvmrc index 6f7f377b..9a2a0e21 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -v16 +v20 diff --git a/Dockerfile b/Dockerfile index 740c9fb3..5c2fcdf5 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM node:16-alpine +FROM node:20-alpine WORKDIR /opt/safe-settings ENV NODE_ENV production ## Set the Labels @@ -8,12 +8,12 @@ LABEL version="1.0" \ ## These files are copied separately to allow updates ## to the image to be as small as possible -COPY package.json /opt/safe-settings/ +COPY package*.json /opt/safe-settings/ COPY index.js /opt/safe-settings/ COPY lib /opt/safe-settings/lib ## Install the app and dependencies -RUN npm install +RUN npm ci ## This app will listen on port 3000 EXPOSE 3000 @@ -22,4 +22,4 @@ USER node ## This does not start properly when using the ['npm','start'] format ## so stick with just calling it outright -CMD npm start \ No newline at end of file +CMD npm start diff --git a/README.md b/README.md index fe8d58c8..0c5f00bd 100644 --- a/README.md +++ b/README.md @@ -2,46 +2,44 @@ [![Create a release](https://github.com/github/safe-settings/actions/workflows/create-release.yml/badge.svg)](https://github.com/github/safe-settings/actions/workflows/create-release.yml) -`Safe-settings`– an app to manage policy-as-code and apply repository settings to repositories across an organization. - -1. In `safe-settings` all the settings are stored centrally in an `admin` repo within the organization. This is important. Unlike [Settings Probot](https://github.com/probot/settings), the settings files cannot be in individual repositories. - > [!Note] - > It is possible to override this behavior and specify a custom repo instead of the `admin` repo.
- > This could be done by setting an `env` variable called `ADMIN_REPO`. - -2. The **settings** in the **default** branch is applied. If the settings are changed in a non-default branch and a PR is created to merge the changes, it would be run in a `dry-run` mode to evaluate and validate the settings, and checks would pass or fail based on that. -2. In `safe-settings` the settings can have 2 types of targets: - 1. `org` - These settings are applied to the `org`. `Org`-targeted settings are defined in `.github/settings.yml` . Currently, only `rulesets` are supported as `org`-targeted settings. - 2. `repo` - These settings are applied to `repos` - -3. For The `repo`-targeted settings there can be at 3 levels at which the settings could be managed: - 1. Org-level settings are defined in `.github/settings.yml` -> [!Note] -> It is possible to override this behavior and specify a different filename for the `settings` yml repo.
-> This could be done by setting an `env` variable called `SETTINGS_FILE_PATH`.
-> Similarly, the `.github` directory can be overridden with an `env` variable called `CONFIG_PATH`. - - 2. `Suborg` level settings. A `suborg` is an arbitrary collection of repos belonging to projects, business units, or teams. The `suborg` settings reside in a yaml file for each `suborg` in the `.github/suborgs` folder. - -> [!Note] -> In `safe-settings`, sub orgs could be groups of repos based on `repo names`, or `teams` which the repos have collaborators from, or `custom property values` set for the repos - - 3. `Repo` level settings. They reside in a repo specific yaml in `.github/repos` folder -4. It is recommended to break the settings into org-level, suborg-level, and repo-level units. This will allow different teams to define and manage policies for their specific projects or business units. With `CODEOWNERS`, this will allow different people to be responsible for approving changes in different projects. - -> [!Note] -> `Suborg` and `Repo` level settings directory structure cannot be customized. +`Safe-settings` – an app to manage policy-as-code and apply repository settings across an organization. + +1. In `safe-settings`, all the settings are stored centrally in an `admin` repo within the organization. Unlike the [GitHub Repository Settings App](https://github.com/repository-settings/app), the settings files cannot be in individual repositories. + + > It is possible specify a custom repo instead of the `admin` repo with `ADMIN_REPO`. See [Environment variables](#environment-variables) for more details. + +1. The **settings** in the **default** branch are applied. If the settings are changed on a non-default branch and a PR is created to merge the changes, the app runs in a `dry-run` mode to evaluate and validate the changes. Checks pass or fail based on the `dry-run` results. + +1. In `safe-settings` the settings can have 2 types of targets: + 1. `org` - These settings are applied to the organization. `Org`-targeted settings are defined in `.github/settings.yml`. Currently, only `rulesets` are supported as `org`-targeted settings. + 1. `repo` - These settings are applied to repositories. + +1. For the `repo`-targeted settings, there can be 3 levels at which the settings are managed: + 1. `Org`-level settings are defined in `.github/settings.yml` + + > It is possible to override this behavior and specify a different filename for the `settings.yml` file with `SETTINGS_FILE_PATH`. Similarly, the `.github` directory can be overridden with `CONFIG_PATH`. See [Environment variables](#environment-variables) for more details. + + 1. `Suborg` level settings. A `suborg` is an arbitrary collection of repos belonging to projects, business units, or teams. The `suborg` settings reside in a yaml file for each `suborg` in the `.github/suborgs` folder. + + > In `safe-settings`, `suborgs` could be groups of repos based on `repo names`, or `teams` which the repos have collaborators from, or `custom property values` set for the repos + + 1. `Repo` level settings. They reside in a repo specific yaml in `.github/repos` folder + +1. It is recommended to break the settings into `org`-level, `suborg`-level, and `repo`-level units. This will allow different teams to define and manage policies for their specific projects or business units. With `CODEOWNERS`, this will allow different people to be responsible for approving changes in different projects. + +> [!NOTE] +> The `suborg` and `repo` level settings directory structure cannot be customized. > -> The settings file must have a `.yml` extension only. `.yaml` extension is ignored, for now. +> Settings files must have a `.yml` extension only. For now, the `.yaml` extension is ignored. ## How it works ### Events The App listens to the following webhook events: -- **push**: If the settings are created or modified, that is, if push happens in the `default` branch of the `admin` repo and the file added or changed is `.github/settings.yml` or `.github/repos/*.yml`or `.github/suborgs/*.yml`, then the settings would be applied either globally to all the repos, or specific repos. For each repo, the settings that are actually applied depend on the default settings for the org, overlayed with settings for the suborg that the repo belongs to, overlayed with the settings for that specific repo. - -- **repository.created**: If a repository is created in the org, the settings for the repo - the default settings for the org, overlayed with settings for the suborg that the repo belongs to, overlayed with the settings for that specific repo - is applied. +- **push**: If the settings are created or modified, that is, if push happens in the `default` branch of the `admin` repo and the file added or changed is `.github/settings.yml` or `.github/repos/*.yml`or `.github/suborgs/*.yml`, then the settings would be applied either globally to all the repos, or specific repos. For each repo, the settings that are actually applied depend on the default settings for the org, overlaid with settings for the suborg that the repo belongs to, overlaid with the settings for that specific repo. + +- **repository.created**: If a repository is created in the org, the settings for the repo - the default settings for the org, overlaid with settings for the suborg that the repo belongs to, overlaid with the settings for that specific repo - is applied. - **branch_protection_rule**: If a branch protection rule is modified or deleted, `safe-settings` will `sync` the settings to prevent any unauthorized changes. @@ -49,7 +47,7 @@ The App listens to the following webhook events: - **repository.renamed**: If a repository is renamed, the default behavior is safe-settings will ignore this (for backward-compatibility). If `BLOCK_REPO_RENAME_BY_HUMAN` env variable is set to true, `safe-settings` will revert the repo to the previous name unless it is renamed using a `bot`. If it is renamed using a `bot`, it will try to copy the existing `.yml` to `.yml` so that the repo config yml stays consistent. If a file already exists, it doesn't create a new one. -- **pull_request.opened**, **pull_request.reopened**, **check_suite.requested**: If the settings are changed, but it is not in the `default` branch, and there is an existing PR, the code will validate the settings changes by running safe-settings in `nop` mode and update the PR with the `dry-run` status. +- **pull_request.opened**, **pull_request.reopened**, **check_suite.requested**: If the settings are changed, but it is not in the `default` branch, and there is an existing PR, the code will validate the settings changes by running safe-settings in `nop` mode and update the PR with the `dry-run` status. - **repository_ruleset**: If the `ruleset` settings are modified in the UI manually, `safe-settings` will `sync` the settings to prevent any unauthorized changes. @@ -60,32 +58,31 @@ The App listens to the following webhook events: - __custom_property_values__: If new repository properties are set for a repository, `safe-settings` will run to so that if a sub-org config is defined by that property, it will be applied for the repo ### Use `safe-settings` to rename repos -If you rename a that corresponds to a repo, safe-settings will rename the repo to the new name. This behavior will take effect whether the env variable `BLOCK_REPO_RENAME_BY_HUMAN` is set or not. +If you rename a `` that corresponds to a repo, safe-settings will rename the repo to the new name. This behavior will take effect whether the env variable `BLOCK_REPO_RENAME_BY_HUMAN` is set or not. ### Restricting `safe-settings` to specific repos -`safe-settings` can be turned on only to a subset of repos by specifying them in the runtime settings file, `deployment-settings.yml`. -If no file is specified, then the following repositories - `'admin', '.github', 'safe-settings'` are exempted by default. +`safe-settings` can be turned on only to a subset of repos by specifying them in the runtime settings file, `deployment-settings.yml`. If no file is specified, then the following repositories - `'admin', '.github', 'safe-settings'` are exempted by default. A sample of `deployment-settings` file is found [here](docs/sample-settings/sample-deployment-settings.yml). To apply `safe-settings` __only__ to a specific list of repos, add them to the `restrictedRepos` section as `include` array. To ignore `safe-settings` for a specific list of repos, add them to the `restrictedRepos` section as `exclude` array. -> [!Note] +> [!NOTE] > The `include` and `exclude` attributes support as well regular expressions. > By default they look for regex, Example include: ['SQL'] will look apply to repos with SQL and SQL_ and SQL- etc if you want only SQL repo then use include:['^SQL$'] ### Custom rules -Admins setting up `safe-settings` can include custom rules that would be validated before applying a setting or overidding a broader scoped setting. +Admins setting up `safe-settings` can include custom rules that would be validated before applying a setting or overriding a broader scoped setting. -The code has to return `true` if validation is successful, or `false` if it isn't. +The code has to return `true` if validation is successful, or `false` if it isn't. If the validation fails, the `error` attribute specified would be used to create the error message in the logs or in the `PR checks`. -The first use case is where a custom rule has to be applied for a setting on its own. For e.g. No collaborator should be given `admin` permissions. +The first use case is where a custom rule has to be applied for a setting on its own. For e.g. No collaborator should be given `admin` permissions. -For this type of validation, admins can provide custom code as `configvalidators` which validates the setting by itself. +For this type of validation, admins can provide custom code as `configvalidators` which validates the setting by itself. For e.g. for the case above, it would look like: ```yaml @@ -102,20 +99,20 @@ For convenience this script has access to a variable, `baseconfig`, that contain The second use case is where custom rule has to be applied when a setting in the org or suborg level is being overridden. Such as, when default branch protection is being overridden. -For this type of validation, admins can provide custom code as `overridevalidators`. The script can access two variables, `baseconfig` and `overrideconfig` which represent the base setting and the setting that is overriding it. +For this type of validation, admins can provide custom code as `overridevalidators`. The script can access two variables, `baseconfig` and `overrideconfig` which represent the base setting and the setting that is overriding it. A sample would look like: ```yaml overridevalidators: - - plugin: branches + - plugin: branches error: | `Branch protection required_approving_review_count cannot be overidden to a lower value` script: | console.log(`baseConfig ${JSON.stringify(baseconfig)}`) console.log(`overrideConfig ${JSON.stringify(overrideconfig)}`) if (baseconfig.protection.required_pull_request_reviews.required_approving_review_count && overrideconfig.protection.required_pull_request_reviews.required_approving_review_count ) { - return overrideconfig.protection.required_pull_request_reviews.required_approving_review_count >= baseconfig.protection.required_pull_request_reviews.required_approving_review_count + return overrideconfig.protection.required_pull_request_reviews.required_approving_review_count >= baseconfig.protection.required_pull_request_reviews.required_approving_review_count } return true ``` @@ -236,21 +233,20 @@ the results of comparison would be: ### Schedule The App can be configured to apply the settings on a schedule. This could be a way to address configuration drift since webhooks are not always guaranteed to be delivered. -To periodically converge the settings to the configuration, set the `CRON` environment variable. This is based on [node-cron](https://www.npmjs.com/package/node-cron) and details on the possible values can be found [here](#env-variables). +To periodically converge the settings to the configuration, set the `CRON` environment variable. See [Environment variables](#environment-variables) for more details. ### Pull Request Workflow -It is -`Safe-settings` explicitly looks in the `admin` repo in the organization for the settings files. The `admin` repo could be a restricted repository with `branch protections` and `codeowners` +`Safe-settings` explicitly looks in the `admin` repo in the organization for the settings files. The `admin` repo could be a restricted repository with `branch protections` and `CODEOWNERS` -In that set up, when changes happen to the settings files and there is a PR for merging the changes back to the `default` branch in the `admin` repo, `safe-settings` will run `checks` – which will run in **nop** mode and produce a report of the changes that would happen, including the API calls and the payload. +In that set up, when changes happen to the settings files and there is a PR for merging the changes back to the `default` branch in the `admin` repo, `safe-settings` will run `checks` – which will run in **nop** mode and produce a report of the changes that would happen, including the API calls and the payload. -For e.g. If we have `override` validators that will fail if `org-level` branch protections are overridden at the repo or suborg level with a lesser number of required approvers, here is an screenshot of what users will see in the PR. +For e.g. If we have `override` validators that will fail if `org`-level branch protections are overridden at the repo or suborg level with a lesser number of required approvers, here is an screenshot of what users will see in the PR.

image

> [!NOTE] -> If you don't want the PR message to have these details, it can be turned off by `env` setting `CREATE_PR_COMMENT`=`false` +> If you don't want the PR message to have these details, they can be turned off with `CREATE_PR_COMMENT`. See [Environment variables](#environment-variables) for more details. Here is a screenshot of what the users will see in the `checkrun` page:

@@ -258,7 +254,7 @@ Here is a screenshot of what the users will see in the `checkrun` page:

### Error handling -The app creates a `Check` at the end of its processing to indicate if there were any errors. The `Check` is called `safe-settings` and corrosponds to the latest commit on the `default` branch of the `admin` repo. +The app creates a `Check` at the end of its processing to indicate if there were any errors. The `Check` is called `safe-settings` and corresponds to the latest commit on the `default` branch of the `admin` repo. Here is an example of a `checkrun` result:

@@ -270,292 +266,88 @@ And the `checkrun` page will look like this: image

-### The Settings file +### The Settings File -The settings file can be used to set the policies at the `Org`, `suborg` or `repo` level. +The settings file can be used to set the policies at the `org`, `suborg` or `repo` level. -Using the settings, the following things could be configured: +The following can be configured: - `Repository settings` - home page, url, visibility, has_issues, has_projects, wikis, etc. -- `default branch` - naming and renaming -- `Repository Topics` +- `Default branch` - naming and renaming +- `Topics` +- `Custom properties` - `Teams and permissions` - `Collaborators and permissions` - `Issue labels` +- `Milestones` - `Branch protections` - if the name of the branch is `default` in the settings, it is applied to the `default` branch of the repo. - `Autolinks` -- `repository name validation` using regex pattern +- `Repository name validation` using regex pattern +- `Rulesets` It is possible to provide an `include` or `exclude` settings to restrict the `collaborators`, `teams`, `labels` to a list of repos or exclude a set of repos for a collaborator. -Here is an example settings file: - - -```yaml -# These settings are synced to GitHub by https://github.com/github/safe-settings - -repository: - # This is the settings that need to be applied to all repositories in the org - # See https://docs.github.com/en/rest/reference/repos#create-an-organization-repository for all available settings for a repository - # A short description of the repository that will show up on GitHub - description: description of the repo - - # A URL with more information about the repository - homepage: https://example.github.io/ - - # Keep this as true for most cases - # A lot of the policies below cannot be implemented on bare repos - # Pass true to create an initial commit with empty README. - auto_init: true - - # A list of topics to set on the repository - can alternatively set like this: [github, probot, new-topic, another-topic, topic-12] - topics: - - github - - probot - - new-topic - - another-topic - - topic-12 - - # Settings for Code security and analysis - # Dependabot Alerts - security: - enableVulnerabilityAlerts: true - enableAutomatedSecurityFixes: true - - # Either `true` to make the repository private, or `false` to make it public. - # If this value is changed and if Org members cannot change the visibility of repos - # it would result in an error when updating a repo - private: true - - # Can be public or private. If your organization is associated with an enterprise account using - # GitHub Enterprise Cloud or GitHub Enterprise Server 2.20+, visibility can also be internal. - visibility: private - - # Either `true` to enable issues for this repository, `false` to disable them. - has_issues: true - - # Either `true` to enable projects for this repository, or `false` to disable them. - # If projects are disabled for the organization, passing `true` will cause an API error. - has_projects: true - - # Either `true` to enable the wiki for this repository, `false` to disable it. - has_wiki: true - - # The default branch for this repository. - default_branch: main-enterprise - - # Desired language or platform [.gitignore template](https://github.com/github/gitignore) - # to apply. Use the name of the template without the extension. - # For example, "Haskell". - gitignore_template: node - - # Choose an [open source license template](https://choosealicense.com/) - # that best suits your needs, and then use the - # [license keyword](https://help.github.com/articles/licensing-a-repository/#searching-github-by-license-type) - # as the `license_template` string. For example, "mit" or "mpl-2.0". - license_template: mit - - # Either `true` to allow squash-merging pull requests, or `false` to prevent - # squash-merging. - allow_squash_merge: true - - # Either `true` to allow merging pull requests with a merge commit, or `false` - # to prevent merging pull requests with merge commits. - allow_merge_commit: true - - # Either `true` to allow rebase-merging pull requests, or `false` to prevent - # rebase-merging. - allow_rebase_merge: true - - # Either `true` to allow auto-merge on pull requests, - # or `false` to disallow auto-merge. - # Default: `false` - allow_auto_merge: true - - # Either `true` to allow automatically deleting head branches - # when pull requests are merged, or `false` to prevent automatic deletion. - # Default: `false` - delete_branch_on_merge: true - - # Either `true` to allow update branch on pull requests, - # or `false` to disallow update branch. - # Default: `false` - allow_update_branch: true - - # Whether to archive this repository. false will unarchive a previously archived repository. - archived: false - -# The following attributes are applied to any repo within the org -# So if a repo is not listed above is created or edited -# The app will apply the following settings to it -labels: - # Labels: define labels for Issues and Pull Requests - include: - - name: bug - color: CC0000 - description: An issue with the system - - - name: feature - # If including a `#`, make sure to wrap it with quotes! - color: '#336699' - description: New functionality. - - - name: first-timers-only - # include the old name to rename an existing label - oldname: Help Wanted - color: '#326699' - - - name: new-label - # include the old name to rename an existing label - oldname: Help Wanted - color: '#326699' - exclude: - # don't delete any labels created on GitHub that starts with "release" - - name: ^release - -milestones: -# Milestones: define milestones for Issues and Pull Requests - - title: milestone-title - description: milestone-description - # The state of the milestone. Either `open` or `closed` - state: open - -collaborators: -# Collaborators: give specific users access to any repository. -# See https://docs.github.com/en/rest/reference/collaborators#add-a-repository-collaborator for available options -- username: regpaco - permission: push -# The permission to grant the collaborator. Can be one of: -# * `pull` - can pull, but not push to or administer this repository. -# * `push` - can pull and push, but not administer this repository. -# * `admin` - can pull, push and administer this repository. -- username: beetlejuice - permission: pull -# You can exclude a list of repos for this collaborator and all repos except these repos would have this collaborator - exclude: - - actions-demo -- username: thor - permission: push -# You can include a list of repos for this collaborator and only those repos would have this collaborator - include: - - actions-demo - - another-repo - -teams: -# Teams See https://docs.github.com/en/rest/reference/teams#create-a-team for available options - - name: core - # The permission to grant the team. Can be one of: - # * `pull` - can pull, but not push to or administer this repository. - # * `push` - can pull and push, but not administer this repository. - # * `admin` - can pull, push and administer this repository. - permission: admin - - name: docss - permission: push - - name: docs - permission: pull - # Visibility is only honored when the team is created not for existing teams. - # It can be either secret (default) or closed (visible to all members of the org) - - name: globalteam - permission: push - visibility: closed - -branches: - # If the name of the branch value is specified as `default`, then the app will create a branch protection rule to apply against the default branch in the repo - - name: default - # https://docs.github.com/en/rest/reference/branches#update-branch-protection - # Branch Protection settings. Set to null to disable - protection: - # Required. Require at least one approving review on a pull request, before merging. Set to null to disable. - required_pull_request_reviews: - # The number of approvals required. (1-6) - required_approving_review_count: 1 - # Dismiss approved reviews automatically when a new commit is pushed. - dismiss_stale_reviews: true - # Blocks merge until code owners have reviewed. - require_code_owner_reviews: true - # Whether the most recent reviewable push must be approved by someone other than the person who pushed it. - require_last_push_approval: true - # Allow specific users, teams, or apps to bypass pull request requirements. Set to null to disable. - bypass_pull_request_allowances: - apps: [] - users: [] - teams: [] - # Specify which users and teams can dismiss pull request reviews. Pass an empty dismissal_restrictions object to disable. User and team dismissal_restrictions are only available for organization-owned repositories. Omit this parameter for personal repositories. - dismissal_restrictions: - users: [] - teams: [] - # Required. Require status checks to pass before merging. Set to null to disable - required_status_checks: - # Required. Require branches to be up to date before merging. - strict: true - # Required. The list of status checks to require in order to merge into this branch - contexts: [] - # Required. Enforce all configured restrictions for administrators. Set to true to enforce required status checks for repository administrators. Set to null to disable. - enforce_admins: true - # Required. Restrict who can push to this branch. Team and user restrictions are only available for organization-owned repositories. Set to null to disable. - restrictions: - apps: [] - users: [] - teams: [] - -# Custom properties -# See https://docs.github.com/en/rest/repos/custom-properties?apiVersion=2022-11-28 -custom_properties: - - name: test - value: test - -# See the docs (https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/managing-repository-settings/configuring-autolinks-to-reference-external-resources) for a description of autolinks and replacement values. -autolinks: - - key_prefix: 'JIRA-' - url_template: 'https://jira.github.com/browse/JIRA-' - - key_prefix: 'MYLINK-' - url_template: 'https://mywebsite.com/' - -validator: - #pattern: '[a-zA-Z0-9_-]+_[a-zA-Z0-9_-]+.*' - pattern: '[a-zA-Z0-9_-]+' -``` - +See [`docs/sample-settings/settings.yml`](docs/sample-settings/settings.yml) for a sample settings file. ### Additional values -In addition to these values above, the settings file can have some additional values: +In addition to the values in the file above, the settings file can have some additional values: -1. `force_create`: This is set in the repo-level settings to force create the repo if the repo does not exist. +1. `force_create`: This is set in the repo-level settings to force create the repo if the repo does not exist. 2. `template`: This is set in the repo-level settings, and is used with the `force_create` flag to use a specific repo template when creating the repo 3. `suborgrepos`: This is set in the suborg-level settings to define an array of repos. This field can also take a `glob` pattern to allow wild-card expression to specify repos in a suborg. For e.g. `test*` would include `test`, `test1`, `testing`, etc. -4. The `suborgteams` section contains a list of teams, and all the repos belonging to the teams would be part of the `suborg` - - - -### Env variables - -You can pass environment variables; easiest way to do it is in a `.env`file. - -1. __CRON__ you can pass a cron input to run `safe-settings` at a regular schedule. This is based on [node-cron](https://www.npmjs.com/package/node-cron). For eg. -``` -# ┌────────────── second (optional) -# │ ┌──────────── minute -# │ │ ┌────────── hour -# │ │ │ ┌──────── day of month -# │ │ │ │ ┌────── month -# │ │ │ │ │ ┌──── day of week -# │ │ │ │ │ │ -# │ │ │ │ │ │ -# * * * * * * -CRON=* * * * * # Run every minute -``` -2. Logging level could be set using **LOG_LEVEL**. For e.g. -``` -LOG_LEVEL=trace -``` -3. Enable Pull Request comment using **ENABLE_PR_COMMENT**. For e.g. -``` -ENABLE_PR_COMMENT=true -``` - -### Runtime Settings +4. The `suborgteams` section contains a list of teams, and all the repos belonging to the teams would be part of the `suborg` + + +### Environment variables + +You can pass environment variables; the easiest way to do it is via a `.env` file. + +1. `CRON` you can pass a cron input to run `safe-settings` at a regular schedule. This is based on [node-cron](https://www.npmjs.com/package/node-cron). For eg. + ``` + # ┌────────────── second (optional) + # │ ┌──────────── minute + # │ │ ┌────────── hour + # │ │ │ ┌──────── day of month + # │ │ │ │ ┌────── month + # │ │ │ │ │ ┌──── day of week + # │ │ │ │ │ │ + # │ │ │ │ │ │ + # * * * * * * + CRON=* * * * * # Run every minute + ``` +1. Logging level can be set using `LOG_LEVEL`. For e.g. + ``` + LOG_LEVEL=trace + ``` +1. Configure the source repository using `ADMIN_REPO` (default is `admin`). For e.g. + ``` + ADMIN_REPO=safe-settings-config + ``` +1. Configure the config path using `CONFIG_PATH` (default is `.github`). For e.g. + ``` + CONFIG_PATH=.github + ``` +1. Configure the settings file path using `SETTINGS_FILE_PATH` (default is `settings.yml`). For e.g. + ``` + SETTINGS_FILE_PATH=settings.yml + ``` +1. Configure the deployment settings file path using `DEPLOYMENT_CONFIG_FILE` (default is `deployment-settings.yml`). For e.g. + ``` + DEPLOYMENT_CONFIG_FILE=deployment-settings.yml + ``` +1. Enable the pull request comment using `ENABLE_PR_COMMENT` (default is `true`). For e.g. + ``` + ENABLE_PR_COMMENT=true + ``` +1. Block repository renaming manually using `BLOCK_REPO_RENAME_BY_HUMAN` (default is `false`). For e.g. + ``` + BLOCK_REPO_RENAME_BY_HUMAN=true + ``` + + +### Runtime Settings 1. Besides the above settings files, the application can be bootstrapped with `runtime` settings. 2. The `runtime` settings are configured in `deployment-settings.yml` that is in the directory from where the GitHub app is running. @@ -569,20 +361,14 @@ ENABLE_PR_COMMENT=true 2. The precedence order is repository > suborg > org (.github/repos/*.yml > .github/suborgs/*.yml > .github/settings.yml - ## How to use -1. __[Install the app](docs/deploy.md)__. - -2. Create an `admin` repo within your organization (the repository must be called `admin`). - -3. Add the settings for the `org`, `suborgs`, and `repos` . List of sample files could be found [here](docs/sample-settings). +1. __[Deploy and install the app](docs/deploy.md)__. - +2. Create an `admin` repo (or an alternative of your choosing) within your organization. Remember to set `CONFIG_REPO` if you choose something other than `admin`. See [Environment variables](#environment-variables) for more details. -## Deployment +3. Add the settings for the `org`, `suborgs`, and `repos`. Sample files can be found [here](docs/sample-settings). -See [docs/deploy.md](docs/deploy.md) if you would like to run your own instance of this plugin. ## License diff --git a/app.yml b/app.yml index 99403d76..24c28282 100644 --- a/app.yml +++ b/app.yml @@ -13,15 +13,16 @@ # The list of events the GitHub App subscribes to. # Uncomment the event names below to enable them. default_events: - - custom_property_values - - repository_ruleset + - branch_protection_rule - check_run - check_suite - - branch_protection_rule + - create + - custom_property_values - member - pull_request - push - repository + - repository_ruleset - team diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 00000000..6d1f1743 --- /dev/null +++ b/docs/README.md @@ -0,0 +1,12 @@ +## Configuring GitHub Repository settings as code + +| Section | API Spec | +| --- | --- | +| Configure general settings for a repository or group of repositories | [Repository Settings](github-settings/1.%20repository-settings.md) | +| Configure repository-level variables | [Repository Variables](github-settings/2.%20repository-variables.md) | +| Configure individual collaborator permissions | [Collaborators](github-settings/3.%20collaborators.md) | +| Configure team permissions | [Teams](github-settings/4.%20teams.md) | +| Configure branch protection rules | [Branch Protection](github-settings/5.%20branch-protection.md) | +| Configure deployment environments | [Deployment Environments](github-settings/6.%20deployment-environments.md) | +| Configure auto-link references | [AutoLinks](github-settings/7.%20autolinks.md) | +| Configure pre-defined labels for issues and pull requests | [Labels](github-settings/8.%20labels.md) | diff --git a/docs/deploy.md b/docs/deploy.md index 06f825be..7e016777 100644 --- a/docs/deploy.md +++ b/docs/deploy.md @@ -1,5 +1,21 @@ # Deployment +## Deployment Environment Variables + +To deploy the app anywhere, you will need 3 key environment variables: + +- `APP_ID`: the ID of the app, which you can get from the [app settings page](https://github.com/settings/apps). + +- `WEBHOOK_SECRET`: the **Webhook Secret** that you generated when you created the app. + + And one of: + +- `PRIVATE_KEY`: (preferred approach) the contents of the private key you downloaded after creating the app, and base64 encode it ...or +- `PRIVATE_KEY_PATH`: the path to a private key file. This will require modification for different environments to make sure the file is available. E.g. For Docker: modify the Dockerfile to COPY the file into the container. + +> [!NOTE] +> `PRIVATE_KEY` takes precedence over `PRIVATE_KEY_PATH`. + ## Deploy the app ### Prepare the source code @@ -9,13 +25,13 @@ Note: If running locally without Docker, ensure that Node 16.x or later is insta - Clone the codebase - `git clone https://github.com/github/safe-settings.git` or `git clone ` - + - Change directory to inside the code base - `cd safe-settings/` - + - Run `npm install` to build the code -- The easiest way to create the Github App is using the [manifest flow](https://docs.github.com/en/developers/apps/building-github-apps/creating-a-github-app-from-a-manifest#using-probot-to-implement-the-github-app-manifest-flow) . To set up the app in an org, provide the `GH_ORG` env variable in the .env file +- The easiest way to create the Github App is using the [manifest flow](https://docs.github.com/en/developers/apps/building-github-apps/creating-a-github-app-from-a-manifest#using-probot-to-implement-the-github-app-manifest-flow). To set up the app in an org, provide the `GH_ORG` env variable in the .env file - If using the `manifest` flow, create `.env` from `.env.example` and set the `GH_ORG` variable if installing the app in an org. @@ -26,32 +42,15 @@ Note: If running locally without Docker, ensure that Node 16.x or later is insta - If not using the `manifest flow` then follow the steps in [Create the GitHub App](#create-the-github-app) - Create `.env` from `.env.example` - - - `cp .env.example .env` - -- Update the `.env` with the needed fields. - - To deploy an app to any cloud provider, you will need 3 environment variables: - -- `APP_ID`: the ID of the app, which you can get from the [app settings page](https://github.com/settings/apps). -- `WEBHOOK_SECRET`: the **Webhook Secret** that you generated when you created the app. - -And one of: -(You will need to copy the contents of the `.pem` created from **GitHub** . This will be used when the app is built and deployed.) -- `PRIVATE_KEY`: (preferred approach) the contents of the private key you downloaded after creating the app, and base64 encode it ...or -- `PRIVATE_KEY_PATH`: the path to a private key file. (Modify the Dockerfile to COPY the file if this is done) + - `cp .env.example .env` -`PRIVATE_KEY` takes precedence over `PRIVATE_KEY_PATH`. +- Update the `.env` with the fields outlined in the [Deployment Environment Variables](#deployment-environment-variables) section -Other Optional values in the .env are: -- `LOG_LEVEL`: Control the logging level -- `ADMIN_REPO`: default is `admin` -- `SETTINGS_FILE_PATH`: default is `settings.yml` -- `DEPLOYMENT_CONFIG_FILE`: default is `deployment-settings.yml` +Optional values in the .env file can be found under the [Environment variables](../README.md#environment-variables) section. Additionally, you can set: - `NODE_TLS_REJECT_UNAUTHORIZED`: `0` for ignoring SSL validation and errors - `GHE_HOST`: This is a required field for **GitHub Enterprise Server** implementations (_Example: github.mycompany.com_) -- `WEBHOOK_PROXY_URL`: SMEE Url for testing locally +- `WEBHOOK_PROXY_URL`: SMEE Url for testing locally Once you have the `.env` file configured, you are ready to start the building of the container. @@ -95,9 +94,9 @@ This will start the container in the background and detached. ### __Deploying using kubectl__ - Create and push your image to a container registry -- Create a `imagePullSecret` - - For e.g. - `kubectl create secret docker-registry regcred --docker-server=DOCKER_REGISTRY_SERVER --docker-username=DOCKER_USER --docker-password=DOCKER_PASSWORD --docker-email=DOCKER_EMAIL` +- Create a `imagePullSecret` + - For e.g. + `kubectl create secret docker-registry regcred --docker-server=DOCKER_REGISTRY_SERVER --docker-username=DOCKER_USER --docker-password=DOCKER_PASSWORD --docker-email=DOCKER_EMAIL` - Create app secrets from the `.env` file `kubectl create secret generic app-env --from-env-file=.env` - Deploy the app @@ -110,76 +109,64 @@ This will start the container in the background and detached. [Helm](https://helm.sh/) must be installed to use the charts. Please refer to Helm's [documentation](https://helm.sh/docs/) to get started. -Once Helm is set up properly, add the Helm Repository as follows: +Once Helm is set up properly, view the latest Helm chart version: ```bash -$ helm repo add decyjphr https://decyjphr-org.github.io/charts/ +helm show chart oci://ghcr.io/github/helm-charts/safe-settings ``` -Once a Helm Repository is added, it can be updated as follows: +__Configure required values__ +See the values that can be configured. ```bash -$ helm repo update decyjphr +helm show values oci://ghcr.io/github/helm-charts/safe-settings ``` -See the charts. -```bash -helm search repo safe-settings -``` +Make sure to set the [Deployment Environment Variables](#deployment-environment-variables) in a `myvalues.yaml` file. -__Configure required values.__ +Optionally, you can set other values like LOG_LEVEL. See [Environment variables](../README.md#environment-variables) for more details. -See the values that can be configured. -```bash -helm show values decyjphr/safe-settings -``` +You can also override the `deploymentConfig` value. -- APP_ID -- PRIVATE_KEY -- WEBHOOK_SECRET +__Install the chart__ -Optionally, you can set other values like LOG_LEVEL. - -You can also override the `deploymentConfig` value. - -__Install the chart__ -Set the values for APP_ID, PRIVATE_KEY, WEBHOOK_SECRET using `--values` (Preferred approach) +Set the values using `--values` (preferred approach) ```bash -helm install safe-settings decyjphr/safe-settings --values myvalues.yaml +helm install safe-settings oci://ghcr.io/github/helm-charts/safe-settings --values myvalues.yaml ``` -Set the with values for APP_ID, PRIVATE_KEY, WEBHOOK_SECRET using `--set` +Set the with values using `--set` ```bash -helm install safe-settings decyjphr/safe-settings --set appEnv.APP_ID="\"0000\"" --set appEnv.PRIVATE_KEY="TFM...==" --set appEnv.WEBHOOK_SECRET="ZjZlYTFjN...==" +helm install safe-settings oci://ghcr.io/github/helm-charts/safe-settings --set appEnv.APP_ID="\"0000\"" --set appEnv.PRIVATE_KEY="TFM...==" --set appEnv.WEBHOOK_SECRET="ZjZlYTFjN...==" ``` -`NOTE:`Setting up Ingress controller is out of scope of this doc, but is recommended. +> [!NOTE] +> Setting up Ingress controller is out of scope of this doc, but is recommended. __If not doing an install using Helm. Generate Kubernetes YAMLs__ ```bash -helm template safe-settings decyjphr/safe-settings --values myvalues.yaml +helm template safe-settings oci://ghcr.io/github/helm-charts/safe-settings --values myvalues.yaml ``` -Chart documentation is available in [decyjphr charts repo](https://github.com/decyjphr-org/charts/). - *See [helm repo](https://helm.sh/docs/helm/helm_repo/) for command documentation.* **Consider using a custom image** -For production use cases one should consider to build a custom safe-settings app image which conforms to your org standards. +For production use cases one should consider to build a custom safe-settings app image which conforms to your org standards. Follow the instructions [here](#build-the-docker-container) on how to do it. -`NOTE:` If you want a reproducible build then you should specify a non floating tag for the image `yadhav/safe-settings:2.0.3` . +> [!NOTE] +> If you want a reproducible build then you should specify a non floating tag for the image `ghcr.io/github/safe-settings:2.1.10` . Once you built the image and pushed it to your registry you can specify it in your `values` file like this: ```yaml image: - repository: yadhav/safe-settings + repository: custom-registry/safe-settings pullPolicy: IfNotPresent # Overrides the image tag whose default is the chart appVersion. tag: "" @@ -254,7 +241,7 @@ Probot runs like [any other Node app](https://devcenter.heroku.com/articles/depl Every deployment will need an [App](https://developer.github.com/apps/). -1. The easiest way to create the Github App is using the [manifest flow](https://docs.github.com/en/developers/apps/building-github-apps/creating-a-github-app-from-a-manifest#using-probot-to-implement-the-github-app-manifest-flow) . If you set up the app using the `manifest flow`, congrats, you are DONE! +1. The easiest way to create the Github App is using the [manifest flow](https://docs.github.com/en/developers/apps/building-github-apps/creating-a-github-app-from-a-manifest#using-probot-to-implement-the-github-app-manifest-flow). If you set up the app using the `manifest flow`, congrats, you are DONE! 2. [Create a new GitHub App](https://github.com/settings/apps/new) with: - **Homepage URL**: the URL to the GitHub repository for your app - **Webhook URL**: Use `https://example.com/` for now, we'll come back in a minute to update this with the URL of your deployed app. @@ -272,28 +259,34 @@ Every deployment will need an [App](https://developer.github.com/apps/). - Checks: **Read & Write** - Commit statuses: **Read & Write** - Contents: **Read & Write** +- Custom properties: **Read & Write** - Issues: **Read & Write** +- Metadata: **Read-only** - Pull requests: **Read & Write** #### Organization Permissions -- Members: **Read & Write** - Administration: **Read & Write** +- Custom properties: **Admin** +- Members: **Read & Write** ### Events - Branch protection rule - Check run - Check suite +- Create +- Custom property values - Member -- Push - Pull request +- Push - Repository +- Repository ruleset - Team 1. Download the private key from the app. -1. Make sure that you click the green **Install** button on the top left of the app page. This gives you an option of installing the app on all or a subset of your repositories. __**Important: Install this App for `All` repos in the Org**__ +2. Make sure that you click the green **Install** button on the top left of the app page. This gives you an option of installing the app on all or a subset of your repositories. __**Important: Install this App for `All` repos in the Org**__ diff --git a/docs/github-settings/1. repository-settings.md b/docs/github-settings/1. repository-settings.md new file mode 100644 index 00000000..4d7fc078 --- /dev/null +++ b/docs/github-settings/1. repository-settings.md @@ -0,0 +1,418 @@ +## Configuring repository settings + +>[!NOTE] +>This section can be applied to `repos/.yml` or `suborgs/.yml`. It will most commonly appear in the individual repos though. Defaults will be taken from `settings.yml`. + +### Example repository definition + +```yaml +# These settings are synced to GitHub by https://github.com/github/safe-settings +repository: + auto_init: true + gitignore_template: node + license_template: mit + description: This is my repository description + homepage: https://www.example.com + private: true + visibility: internal + topics: [github, probot, new-topic, another-topic, topic-12] + security_and_analysis: + advanced_security: + status: enabled + secret_scanning: + status: enabled + secret_scanning_push_protection: + status: enabled + has_issues: true + has_projects: false + has_wiki: false + is_template: false + default_branch: main + allow_squash_merge: true + allow_merge_commit: true + allow_rebase_merge: true + allow_auto_merge: true + delete_branch_on_merge: true + allow_update_branch: true + squash_merge_commit_title: PR_TITLE + squash_merge_commit_message: COMMIT_MESSAGES + merge_commit_title: PR_TITLE + merge_commit_message: PR_TITLE + archived: false + allow_forking: false + web_commit_signoff_required: false + security: + enableVulnerabilityAlerts: true + enableAutomatedSecurityFixes: true +``` + +## Repository API Spec + +>[!TIP] +>GitHub's API documentation defines these inputs and types: +>1. [Update an environment](https://docs.github.com/en/rest/repos/repos?apiVersion=2022-11-28#update-a-repository) +>2. [Replace all repository topics](https://docs.github.com/en/rest/repos/repos?apiVersion=2022-11-28#replace-all-repository-topics) + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

namestring

+

This is the name of the repository

+
+Example: + +```yaml +repository: + - name: super-repo +... +``` + +
+

descriptionstring

+

A short description of this repository

+
+Example: + +```yaml +repository: + - description: This repo is so awesome, we named it super-repo +... +``` + +
+

homepagestring

+

A URL with more information about the repository.

+
+Example: + +```yaml +repository: + - homepage: https://awesomeness.super-repo.com +... +``` + +
+

privateboolean

+

Either true to make the repository private or false to make it public. Default: null. +Note: You will get a 422 error if you set this to , if your company restricts changing repository visibility to organization owners and public repositories are not permitted within the enterprise.

Default: null +

+Example: + +```yaml +repository: + - private: true +... +``` + +
+

visibilitystring

+

The visibility of the repository. It is recommended to set your defaults to internal to help drive InnerSource. Private repositories will encourage the perpetuation of silos

+

Can be one of: internal, private +

+Example: + +```yaml +repository: + - private: true + visibility: internal +... +``` + +
+

security_and_analysisobject or null

+

Specify which security and analysis features to enable or disable for the repository.

+

To use this parameter, you must have admin permissions for the repository or be an owner or security manager for the organization that owns the repository. For more information, see "Managing security managers in your organization."

+ +
Properties of security_and_analysis + +
+

advanced_securityobject

+

  Use the status property to enable or disable GitHub Advanced Security for this repository. For more information, see "About GitHub Advanced Security."

+
Properties of advanced_security +
+

statusstring

+

  Can be enabled or disabled.

+
+
+

secret_scanningobject

+

  Use the status property to enable or disable secret scanning for this repository. For more information, see "About secret scanning."

+
Properties of secret_scanning +
+

statusstring

+

  Can be enabled or disabled.

+
+
+

secret_scanning_push_protectionobject

+

  Use the status property to enable or disable secret scanning push protection for this repository. For more information, see "Protecting pushes with secret scanning."

+
Properties of secret_scanning_push_protection +
+

statusstring

+

  Can be enabled or disabled.

+
+ +
+
+ +```yaml +repository: + security_and_analysis: + advanced_security: + status: enabled + secret_scanning: + status: enabled + secret_scanning_push_protection: + status: enabled +... +``` + +
+

has_issuesboolean

+

Either true to enable issues for this repository or false to disable them.

+

Default: true

+
+ +```yaml +repository: + - has_issues: false +... +``` + +
+

has_projectsboolean

+

Either true to enable projects for this repository or false to disable them. Note: If you're creating a repository in an organization that has disabled repository projects, the default is false, and if you pass true, the API returns an error.

+

Default: true

+
+ +```yaml +repository: + - has_projects: false +... +``` + +
+

has_wikiboolean

+

Either true to enable the wiki for this repository or false to disable it.

+

Default: true

+
+ +```yaml +repository: + - has_wiki: false +... +``` + +
+

is_templateboolean

+

Either true to make this repo available as a template repository or false to prevent it.

+

Default: false

+
+ +```yaml +repository: + - is_template: false +... +``` + +
+

default_branchboolean

+

Updates the default branch for this repository.

+
+ +```yaml +repository: + - default_branch: main +... +``` + +
+

allow_squash_mergeboolean

+

Either true to allow squash-merging pull requests, or false to prevent squash-merging.

+

Default: true

+
+ +```yaml +repository: + - allow_squash_merge: false +... +``` + +
+

allow_merge_commitboolean

+

Either true to allow merging pull requests with a merge commit, or false to prevent merging pull requests with merge commits.

+

Default: true

+
+ +```yaml +repository: + - allow_merge_commit: false +... +``` + +
+

allow_rebase_mergeboolean

+

Either true to allow rebase-merging pull requests, or false to prevent rebase-merging.

+

Default: true

+
+ +```yaml +repository: + - allow_rebase_merge: false +... +``` + +
+

allow_auto_mergeboolean

+

Either true to allow auto-merge on pull requests, or false to disallow auto-merge.

+

Default: false

+
+ +```yaml +repository: + - allow_auto_merge: true +... +``` + +
+

delete_branch_on_mergeboolean

+

Either true to allow automatically deleting head branches when pull requests are merged, or false to prevent automatic deletion.

+

Default: false

+
+ +```yaml +repository: + - delete_branch_on_merge: true +... +``` + +
+

allow_update_branchboolean

+

Either true to always allow a pull request head branch that is behind its base branch to be updated even if it is not required to be up to date before merging, or false otherwise.

+

Default: false

+
+ +```yaml +repository: + - allow_update_branch: true +... +``` + +
+

squash_merge_commit_titlestring

+

The default value for a squash merge commit title:

+

 •PR_TITLE - default to the pull request's title.
+ •COMMIT_OR_PR_TITLE - default to the commit's title (if only one commit) or the pull request's title (when more than one commit).

+

Can be one of: PR_TITLE, COMMIT_OR_PR_TITLE

+
+ +```yaml +repository: + - squash_merge_commit_title: PR_TITLE +... +``` + +
+

squash_merge_commit_messagestring

+

The default value for a squash merge commit title:

+

PR_BODY - default to the pull request's body.
+•COMMIT_MESSAGES - default to the branch's commit messages.
+•BLANK - default to a blank commit message.

+

Can be one of: PR_BODY, COMMIT_MESSAGES, BLANK

+
+ +```yaml +repository: + - squash_merge_commit_message: PR_BODY +... +``` + +
+

merge_commit_titlestring

+

The default value for a squash merge commit title:

+

 •PR_TITLE - default to the pull request's title.
+ •MERGE_MESSAGE - default to the classic title for a merge message (e.g., Merge pull request #123 from branch-name).

+

Can be one of: PR_TITLE, MERGE_MESSAGE

+
+ +```yaml +repository: + - merge_commit_title: PR_TITLE +... +``` + +
+

merge_commit_messagestring

+

The default value for a squash merge commit title:

+

 •PR_TITLE - default to the pull request's title.
+ •PR_BODY - default to the pull request's body.
+ •BLANK - default to a blank commit message.

+

Can be one of: PR_TITLE, PR_BODY, BLANK

+
+ +```yaml +repository: + - merge_commit_message: PR_BODY +... +``` + +
+

archivedboolean

+

Whether to archive this repository. false will unarchive a previously archived repository.

+

Default: false

+
+ +```yaml +repository: + - archived: true +... +``` + +
+

allow_forkingboolean

+

Either true to allow private forks, or false to prevent private forks.

+

Default: false

+
+ +```yaml +repository: + - allow_forking: false +... +``` + +
+

web_commit_signoff_requiredboolean

+

Either true to require contributors to sign off on web-based commits, or false to not require contributors to sign off on web-based commits.

+

Default: false

+
+ +```yaml +repository: + - web_commit_signoff_required: false +... +``` + +
diff --git a/docs/github-settings/2. repository-variables.md b/docs/github-settings/2. repository-variables.md new file mode 100644 index 00000000..5a9871b7 --- /dev/null +++ b/docs/github-settings/2. repository-variables.md @@ -0,0 +1,50 @@ +## Configuring repository variables + +>[!NOTE] +>This section can be applied to `repos/.yml` or `suborgs/.yml`. It will most commonly appear in the individual repos though. + +### Example variable definition + +```yaml +# These settings are synced to GitHub by https://github.com/github/safe-settings +variables: + - name: MY_AWESOME_VAR + value: '845705' + - name: my_lowercase_var + value: I have spaces +``` + +## Repository Variable API Spec + +>[!TIP] +>GitHub's API documentation defines these inputs and types: +>1. [Update a repository variable](https://docs.github.com/en/rest/actions/variables?apiVersion=2022-11-28#update-a-repository-variable) + + + +
+

variablesarray of objects

+

Repository variables that can be referenced in a GitHub Actions workflow

+ +
Properties of variables + +
+

namestring${\text{\color{orange}Required}}$

+

  The name of the variable.

+ +

valuestring${\text{\color{orange}Required}}$

+

  The value of the variable.

+ +
+ +
+Example: + +```yaml +variables: + - name: MY_AWESOME_VAR + value: super duper value +... +``` + +
diff --git a/docs/github-settings/3. collaborators.md b/docs/github-settings/3. collaborators.md new file mode 100644 index 00000000..bbc971c1 --- /dev/null +++ b/docs/github-settings/3. collaborators.md @@ -0,0 +1,53 @@ +## Configuring collaborator permissions + +Your organization's default permissions will set the baseline, but in order to add users to CODEOWNERS they will still need to be added explicitly to a repository. For example, if your orgaization sets a baseline of `push`/`write` and a user is given `read` as a collabotor or team, they will be given CODEOWNERS access, but will inherit the `write` permission. + +>[!NOTE] +>This section can be applied to `repos/.yml` or `suborgs/.yml`. It will most commonly appear in the individual repos though. + +### Example collaborator definition + +```yaml +# These settings are synced to GitHub by https://github.com/github/safe-settings +collaborators: + - username: Batman + permission: maintain + - username: Superman + permission: admin +``` + +## Collaborator API Spec + +>[!TIP] +>GitHub's API documentation defines these inputs and types: +>1. [Add a repository collaborator](https://docs.github.com/en/rest/collaborators/collaborators?apiVersion=2022-11-28#add-a-repository-collaborator) +>2. [Remove a repository collaborator](https://docs.github.com/en/rest/collaborators/collaborators?apiVersion=2022-11-28#remove-a-repository-collaborator) + + + + +
+

usernamestring${\text{\color{orange}Required}}$

+

The handle for the GitHub user account.

+
+ +```yaml +collaborators: + - username: AquaMan + permission: maintain +... +``` + +
+

permissionstring

+

The permission to grant the collaborator. Only valid on organization-owned repositories. We accept the following permissions to be set: pull, triage, push, maintain, admin and you can also specify a custom repository role name, if the owning organization has defined any.

+

Default: push

+
+ +```yaml +collaborators: + - username: WonderWoman + permission: maintain +``` + +
diff --git a/docs/github-settings/4. teams.md b/docs/github-settings/4. teams.md new file mode 100644 index 00000000..496b30a3 --- /dev/null +++ b/docs/github-settings/4. teams.md @@ -0,0 +1,52 @@ +## Configuring team permissions + +If your organizations default to `push`/`write` permissions, it is still required that a team have access to the repository explicitly in order for `CODEOWNERS` to recognize the team as a valid owner. To add teams with custom permissions, use the collaborators endpoint. + +>[!NOTE] +>This section can be applied to `repos/.yml` or `suborgs/.yml`. It will most commonly appear in the individual repos though. + +### Example team definition + +```yaml +# These settings are synced to GitHub by https://github.com/github/safe-settings +teams: + - name: JusticeLeague + permission: maintain + - name: Avengers + permission: maintain +``` + +## Team API Spec + +>[!TIP] +>GitHub's API documentation defines these inputs and types: +>1. [Add or update team repository permissions](https://docs.github.com/en/rest/teams/teams?apiVersion=2022-11-28#add-or-update-team-repository-permissions) + + + + +
+

namestring${\text{\color{orange}Required}}$

+

The slug of the team name.

+
+ +```yaml +teams: + - name: JusticeLeague + permission: maintain +... +``` + +
+

permissionstring

+

The permission to grant the team on this repository. We accept the following permissions to be set: pull, triage, push, maintain, admin and you can also specify a custom repository role name, if the owning organization has defined any. If no permission is specified, the team's permission attribute will be used to determine what permission to grant the team on this repository.

+

Default: push

+
+ +```yaml +teams: + - name: SuperFriends + permission: maintain +``` + +
diff --git a/docs/github-settings/5. branch-protection.md b/docs/github-settings/5. branch-protection.md new file mode 100644 index 00000000..4874a1d7 --- /dev/null +++ b/docs/github-settings/5. branch-protection.md @@ -0,0 +1,338 @@ +## Configuring branch protection policies + +Protected branches are available in public repositories with GitHub Free and GitHub Free for organizations, and in public and private repositories with GitHub Pro, GitHub Team, GitHub Enterprise Cloud, and GitHub Enterprise Server. For more information, see [GitHub's products](https://docs.github.com/github/getting-started-with-github/githubs-products) in the GitHub Help documentation. + +Protecting a branch requires admin or owner permissions to the repository. + +Note: Passing new arrays of `users` and `teams` replaces their previous values. + +Note: The list of users, apps, and teams in total is limited to 100 items. + +>[!NOTE] +>This section can be applied to `repos/.yml` or `suborgs/.yml`. It will most commonly appear in the individual repos though. + +### Example branch protection definition + +```yaml +# These settings are synced to GitHub by https://github.com/github/safe-settings +branches: + - name: default + protection: + required_pull_request_reviews: + required_approving_review_count: 2 + dismiss_stale_reviews: true + require_code_owner_reviews: true + require_last_push_approval: true + required_signatures: true + require_linear_history: false + bypass_pull_request_allowances: + apps: + - Jarvis + - Edith + users: + - TonyStank + teams: + - Avengers + dismissal_restrictions: + users: + - Hulk + teams: + - Revengers + required_status_checks: + strict: true + checks: + - stark-industries/barndoor-protocol + - stark-industries/sokovia-accords + enforce_admins: true + restrictions: + users: + - starlord + teams: + - guardians +``` + +## Branch Protection API Spec + +>[!TIP] +>GitHub's API documentation defines these inputs and types: +>1. [Update a repository variable](https://docs.github.com/en/rest/actions/variables?apiVersion=2022-11-28#update-a-repository-variable) + + + + + + + + + + + + + + +
+

required_status_checksobject or null${\text{\color{orange}Required}}$

+

Require status checks to pass before merging. Set to null to disable.

+ +
Properties of required_status_checks + +
+

strictboolean${\text{\color{orange}Required}}$

+

  Require branches to be up to date before merging.

+ +

contextsarray of strings${\text{\color{orange}Required}}$

+

  Deprecated: The list of status checks to require in order to merge into this branch. If any of these checks have recently been set by a particular GitHub App, they will be required to come from that app in future for the branch to merge. Use checks instead of contexts for more fine-grained control.

+ +

checksarray of strings${\text{\color{orange}Required}}$

+

  The list of status checks to require in order to merge into this branch.

+ +
+ +
+Example: + +```yaml +branches: + - name: default + protection: + required_status_checks: + strict: true + checks: + - stark-industries/barndoor-protocol + - stark-industries/sokovia-accords +... +``` + +
+

enforce_adminsboolean${\text{\color{orange}Required}}$

+

Enforce all configured restrictions for administrators. Set to true to enforce required status checks for repository administrators. Set to null to disable.

+
+ +```yaml +branches: + - name: default + protection: + required_status_checks: + strict: true + checks: + - stark-industries/barndoor-protocol + - stark-industries/sokovia-accords + enforce_admins: true +``` + +
+

required_pull_request_reviewsobject or null${\text{\color{orange}Required}}$

+

Require at least one approving review on a pull request, before merging. Set to null to disable.

+ +
Properties of required_pull_request_reviews + +
+

dismissal_restrictionsobject

+

  Specify which users, teams, and apps can dismiss pull request reviews. Pass an empty dismissal_restrictions object to disable. User and team dismissal_restrictions are only available for organization-owned repositories. Omit this parameter for personal repositories.

+
Properties of dismissal_restrictions +
+

usersarray of strings

+

  The list of user logins with dismissal access.

+

teamsarray of strings

+

  The list of team slugs with dismissal access.

+

appsarray of strings

+

  The list of app slugs with dismissal access.

+
+
+

dismiss_stale_reviewsboolean

+

  Set to true if you want to automatically dismiss approving reviews when someone pushes a new commit.

+
+

require_code_owner_reviewsboolean

+

  Blocks merging pull requests until code owners review them.

+
+

required_approving_review_countinteger

+

  Specify the number of reviewers required to approve pull requests. Use a number between 1 and 6 or 0 to not require reviewers.

+
+

require_last_push_approvalboolean

+

  Whether the most recent push must be approved by someone other than the person who pushed it.

+

Default: false.

+
+

bypass_pull_request_allowancesobject

+

  Allow specific users, teams, or apps to bypass pull request requirements.

+
Properties of bypass_pull_request_allowances +
+

usersarray of strings

+

  The list of user logins allowed to bypass pull request requirements.

+

teamsarray of strings

+

  The list of team slugs allowed to bypass pull request requirements.

+

appsarray of strings

+

  The list of app slugs allowed to bypass pull request requirements.

+
+
+ + +
+ +```yaml +branches: + - name: default + protection: + required_pull_request_reviews: + required_approving_review_count: 2 + dismiss_stale_reviews: true + require_code_owner_reviews: true + require_last_push_approval: true + required_signatures: true + bypass_pull_request_allowances: + apps: + - Jarvis + - Edith + users: + - TonyStank + teams: + - Avengers + dismissal_restrictions: + users: + - Hulk + teams: + - Revengers +... +``` + +
+

restrictionsobject or null${\text{\color{orange}Required}}$

+

Restrict who can push to the protected branch. User, app, and team restrictions are only available for organization-owned repositories. Set to null to disable.

+ +
Properties of restrictions +
+

usersarray of strings

+

  The list of user logins with push access.

+

teamsarray of strings

+

  The list of team slugs with push access.

+

appsarray of strings

+

  The list of app slugs with push access.

+
+ +
+Example: + +```yaml +branches: + - name: default + protection: + ... + restrictions: + users: + - superman + teams: + - justice-league +... +``` + +
+

required_linear_historyboolean

+

Enforces a linear commit Git history, which prevents anyone from pushing merge commits to a branch. Set to true to enforce a linear commit history. Set to false to disable a linear commit Git history. Your repository must allow squash merging or rebase merging before you can enable a linear commit history. For more information, see "Requiring a linear commit history" in the GitHub Help documentation.

+

Default: false

+
+ +```yaml +branches: + - name: default + protection: + require_linear_history: false +... +``` + +
+

allow_force_pushesboolean or null

+

Permits force pushes to the protected branch by anyone with write access to the repository. Set to true to allow force pushes. Set to false or null to block force pushes. Default: false. For more information, see "Enabling force pushes to a protected branch" in the GitHub Help documentation.

+
+ +```yaml +branches: + - name: default + protection: + allow_force_pushes: false +... +``` + +
+

allow_deletionsboolean

+

Allows deletion of the protected branch by anyone with write access to the repository. Set to false to prevent deletion of the protected branch. For more information, see "Enabling force pushes to a protected branch" in the GitHub Help documentation.

+

Default: false

+
+ +```yaml +branches: + - name: default + protection: + allow_deletions: false +... +``` + +
+

block_creationsboolean

+

If set to true, the restrictions branch protection settings which limits who can push will also block pushes which create new branches, unless the push is initiated by a user, team, or app which has the ability to push. Set to true to restrict new branch creation.

+

Default: false

+
+ +```yaml +branches: + - name: default + protection: + block_creations: false +... +``` + +
+

required_conversation_resolutionboolean

+

Requires all conversations on code to be resolved before a pull request can be merged into a branch that matches this rule. Set to false to disable.

+

Default: false

+
+ +```yaml +branches: + - name: default + protection: + required_conversation_resolution: false +... +``` + +
+

lock_branchboolean

+

Whether to set the branch as read-only. If this is true, users will not be able to push to the branch.

+

Default: false

+
+ +```yaml +branches: + - name: default + protection: + lock_branch: false +... +``` + +
+

allow_fork_syncingboolean

+

Whether users can pull changes from upstream when the branch is locked. Set to true to allow fork syncing. Set to false to prevent fork syncing.

+

Default: false

+
+ +```yaml +branches: + - name: default + protection: + allow_fork_syncing: false +... +``` + +
+

required_signaturesboolean

+

Whether users are required to configure SSH or GPG signatures for all commits pushed to this branch.

+

Default: false

+
+ +```yaml +branches: + - name: default + protection: + required_signatures: true +... +``` + +
diff --git a/docs/github-settings/6. deployment-environments.md b/docs/github-settings/6. deployment-environments.md new file mode 100644 index 00000000..f42611d1 --- /dev/null +++ b/docs/github-settings/6. deployment-environments.md @@ -0,0 +1,177 @@ +## Configuring environments + +>[!NOTE] +>This section can be applied to `repos/.yml` or `suborgs/.yml`. It will most commonly appear in the individual repos though. + +### Example environment definition + +```yaml +... +teams: + # This team must be given explicit permission + # before we can add them as a reviewer below + - name: super-friends + permission: write +collaborators: + # This user must be given explicit permission + # before we can add them as a reviewer below + - username: KalEl + permission: write +environments: + - name: production + wait_timer: 0 + prevent_self_review: true + reviewers: + - type: Team + id: 1234647 + - type: User + id: 139262123 + deployment_branch_policy: + protected_branches: true + custom_branch_policies: false + variables: + - name: MY_AWESOME_VAR + value: '845705' + - name: my_lowercase_var + value: I have spaces +``` + +## Environment API Spec + +>[!TIP] +>GitHub's API documentation defines these inputs and types: +>1. [Create or update an environment](https://docs.github.com/en/rest/deployments/environments?apiVersion=2022-11-28#create-or-update-an-environment) +>2. [Create an environment variable](https://docs.github.com/en/rest/actions/variables?apiVersion=2022-11-28#create-an-environment-variable) + + + + + + + + +
+

namestring${\text{\color{orange}Required}}$

+

This is the name of the environment, and will be what is referenced in a workflow with environment: <name>

+
+Example: + +```yaml +environments: + - name: dms-prod-example +... +``` + +
+

wait_timerinteger

+

The amount of time to delay a job after the job is initially triggered. The time (in minutes) must be an integer between 0 and 43,200 (30 days).

+
+Example: + +```yaml +environments: + - name: dms-prod-example + wait_timer: 30 +... +``` + +
+

prevent_self_reviewboolean

+

Whether or not a user who created the job is prevented from approving their own job.

+
+Example: + +```yaml +environments: + - name: dms-prod-example + prevent_self_review: true +... +``` + +
+

reviewersarray of objects or null${\text{\color{orange}Required}}$ ${\text{\color{orange}if}}$ ${\text{\color{orange}prevent\_self\_review}}$ ${\text{\color{orange}is}}$ ${\text{\color{orange}true}}$

+

The people or teams that may review jobs that reference the environment. You can list up to six users or teams as reviewers. The reviewers must be given explicit access to the repository as either a team or collaborator. Only one of the required reviewers needs to approve the job for it to proceed.

+ +
Properties of reviewers + +
+

typestring

+

  The type of reviewer.
+  Can be one of: User, Team.

+ +

idinteger

+

  The id of the user or team who can review the deployment

+

  Can be obtained by: +
   Team:gh api /orgs/<org>/teams/<team-slug> | jq .id +
   User:gh api /users/<username> | jq .id

+ +
+
+ +```yaml +environments: + - name: production + prevent_self_review: true + reviewers: + - type: Team + id: 1234647 + - type: User + id: 139262123 +... +``` + +
+

deployment_branch_policyobject or null

+

The type of deployment branch policy for this environment. To allow all branches to deploy, set to null.

+ +
Properties of deployment_branch_policy +
+

protected_branchesstring${\text{\color{orange}Required}}$

+

  Whether only branches with branch protection rules can deploy
  to this environment. If protected_branches is true,
  custom_branch_policies must be false; if protected_branches
  is false, custom_branch_policies must be true.

+ +

idinteger

+

  Whether only branches that match the specified name patterns
  can deploy to this environment. If custom_branch_policies
  is true, protected_branches must be false; if
  custom_branch_policies is false, protected_branches
  must be true.

+ +
+ +
+Example: + +```yaml +environments: + - name: production + ... + deployment_branch_policy: + protected_branches: true + custom_branch_policies: false +... +``` + +
+

variablesarray of objects

+

Environment variables that can be referenced in a GitHub Actions workflow

+ +
Properties of variables + +
+

namestring${\text{\color{orange}Required}}$

+

  The name of the variable.

+ +

valuestring${\text{\color{orange}Required}}$

+

  The value of the variable.

+ +
+ +
+Example: + +```yaml +environments: + - name: production + variables: + - name: MY_AWESOME_VAR + value: super duper value +... +``` + +
diff --git a/docs/github-settings/7. autolinks.md b/docs/github-settings/7. autolinks.md new file mode 100644 index 00000000..9ae3c19f --- /dev/null +++ b/docs/github-settings/7. autolinks.md @@ -0,0 +1,69 @@ +## Configuring autolink references + +To help streamline your workflow, you can use the REST API to add autolinks to external resources like JIRA issues and Zendesk tickets. For more information, see "[Configuring autolinks to reference external resources](https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/managing-repository-settings/configuring-autolinks-to-reference-external-resources)." + +>[!NOTE] +>This section can be applied to `repos/.yml` or `suborgs/.yml`. It will most commonly appear in the individual repos though. + +### Example autolink definition + +```yaml +# These settings are synced to GitHub by https://github.com/FICO-1ES/1es-safe-settings +variables: + - name: MY_AWESOME_VAR + value: '845705' + - name: my_lowercase_var + value: I have spaces +``` + +## AutoLink API Spec + +>[!TIP] +>GitHub's API documentation defines these inputs and types: +>1. [Create an autolink reference for a repository](https://docs.github.com/en/rest/repos/autolinks?apiVersion=2022-11-28#create-an-autolink-reference-for-a-repository) + + + + + +
+

key_prefixstring${\text{\color{orange}Required}}$

+

Either true to enable issues for this repository or false to disable them.

+

Default: true

+
+ +```yaml +autolinks: + - key_prefix: JIRA- + url_template: https://jira.example.com/browse/JIRA- +... +``` + +
+

url_templatestring${\text{\color{orange}Required}}$

+

Either true to enable issues for this repository or false to disable them.

+

Default: true

+
+ +```yaml +autolinks: + - key_prefix: JIRA- + url_template: https://jira.example.com/browse/JIRA- +... +``` + +
+

is_alphanumericboolean

+

Whether this autolink reference matches alphanumeric characters. If true, the <num> parameter of the url_template matches alphanumeric characters A-Z (case insensitive), 0-9, and -. If false, this autolink reference only matches numeric characters.

+

Default: true

+
+ +```yaml +autolinks: + - key_prefix: JIRA- + url_template: https://jira.examole.com/browse/JIRA- + is_alphanumeric: false +... +``` + +
diff --git a/docs/github-settings/8. labels.md b/docs/github-settings/8. labels.md new file mode 100644 index 00000000..ddf4c4b4 --- /dev/null +++ b/docs/github-settings/8. labels.md @@ -0,0 +1,65 @@ +## Configuring repository labels + +You can use the REST API to manage labels for a repository and add or remove labels to issues and pull requests. Every pull request is an issue, but not every issue is a pull request. For this reason, "shared" actions for both features, like managing assignees, labels, and milestones, are provided within the Issues endpoints. + +>[!NOTE] +>This section can be applied to `repos/.yml` or `suborgs/.yml`. It will most commonly appear in the individual repos though. + +### Example label definition + +```yaml +# These settings are synced to GitHub by https://github.com/github/safe-settings +labels: + - name: bug + color: CC0000 + description: An issue with the system +``` + +## Team API Spec + +>[!TIP] +>GitHub's API documentation defines these inputs and types: +>1. [Create a label](https://docs.github.com/en/rest/issues/labels?apiVersion=2022-11-28#create-a-label) +>2. [Update a label](https://docs.github.com/en/rest/issues/labels?apiVersion=2022-11-28#update-a-label) +>3. [Delete a label](https://docs.github.com/en/rest/issues/labels?apiVersion=2022-11-28#delete-a-label) + + + + + +
+

namestring${\text{\color{orange}Required}}$

+

The name of the label. Emoji can be added to label names, using either native emoji or colon-style markup. For example, typing :strawberry: will render the emoji :strawberry:. For a full list of available emoji and codes, see "Emoji cheat sheet."

+
+ +```yaml +labels: + - name: bug +... +``` + +
+

colorstring

+

The hexadecimal color code for the label, without the leading #.

+
+ +```yaml +labels: + - name: bug + color: CC0000 +... +``` + +
+

descriptionstring

+

A short description of the label. Must be 100 characters or fewer.

+
+ +```yaml +labels: + - name: bug + description: Something isn't working +... +``` + +
diff --git a/docs/github-settings/README.md b/docs/github-settings/README.md new file mode 100644 index 00000000..af91a44f --- /dev/null +++ b/docs/github-settings/README.md @@ -0,0 +1,12 @@ +## Configuring GitHub Repository settings as code + +| Section | API Spec | +| --- | --- | +| Configure general settings for a repository or group of repositories | [Repository Settings](1.%20repository-settings.md) | +| Configure repository-level variables | [Repository Variables](2.%20repository-variables.md) | +| Configure individual collaborator permissions | [Collaborators](3.%20collaborators.md) | +| Configure team permissions | [Teams](4.%20teams.md) | +| Configure branch protection rules | [Branch Protection](5.%20branch-protection.md) | +| Configure deployment environments | [Deployment Environments](6.%20deployment-environments.md) | +| Configure auto-link references | [AutoLinks](7.%20autolinks.md) | +| Configure pre-defined labels for issues and pull requests | [Labels](8.%20labels.md) | \ No newline at end of file diff --git a/docs/sample-settings/org-ruleset.json b/docs/sample-settings/org-ruleset.json deleted file mode 100644 index 4d9ade2c..00000000 --- a/docs/sample-settings/org-ruleset.json +++ /dev/null @@ -1,115 +0,0 @@ -{ - "name": "demo repo ruleset", - "target": "branch", - "enforcement": "disabled", - "bypass_actors": [ - { - "actor_id": 3974045, - "actor_type": "Team", - "bypass_mode": "pull_request" - }, - { - "actor_id": 7898, - "actor_type": "RepositoryRole", - "bypass_mode": "always" - }, - { - "actor_id": 210920, - "actor_type": "Integration", - "bypass_mode": "always" - }, - { - "actor_id": 1, - "actor_type": "OrganizationAdmin", - "bypass_mode": "always" - }, - { - "actor_id": 5, - "actor_type": "RepositoryRole", - "bypass_mode": "pull_request" - } - ], - "conditions": { - "ref_name": { - "include": [ - "~DEFAULT_BRANCH" - ], - "exclude": [ - "refs/heads/oldmaster" - ] - }, - "repository_name": { - "include": [ - "test*" - ], - "exclude": [ - "test", - "test1" - ], - "protected": true - } - }, - "rules": [ - { - "type": "creation" - }, - { - "type": "update" - }, - { - "type": "deletion" - }, - { - "type": "required_linear_history" - }, - { - "type": "required_signatures" - }, - { - "type": "pull_request", - "parameters": { - "dismiss_stale_reviews_on_push": true, - "require_code_owner_review": true, - "require_last_push_approval": true, - "required_approving_review_count": 10, - "required_review_thread_resolution": true - } - }, - { - "type": "commit_message_pattern", - "parameters": { - "name": "test commit_message_pattern", - "negate": true, - "operator": "starts_with", - "pattern": "skip*" - } - }, - { - "type": "commit_author_email_pattern", - "parameters": { - "name": "test commit_author_email_pattern", - "negate": false, - "operator": "regex", - "pattern": "^.*@example.com$" - } - }, - { - "type": "committer_email_pattern", - "parameters": { - "name": "test committer_email_pattern", - "negate": false, - "operator": "regex", - "pattern": "^.*@example.com$" - } - }, - { - "type": "branch_name_pattern", - "parameters": { - "name": "test branch_name_pattern", - "negate": false, - "operator": "regex", - "pattern": "^(feature|bugfix|improvement|library|prerelease|release|hotfix)\/[a-z0-9._-]+$" - } - } - ] -} \ No newline at end of file diff --git a/docs/sample-settings/org-ruleset.yml b/docs/sample-settings/org-ruleset.yml deleted file mode 100644 index f53549e6..00000000 --- a/docs/sample-settings/org-ruleset.yml +++ /dev/null @@ -1,153 +0,0 @@ -rulesets: -- name: demo - # Name of the rule - target: branch - # The target of the ruleset. Can be one of: - # - branch - # - tag - enforcement: disabled - # The enforcement level of the ruleset. `evaluate` allows admins to test - # rules before enforcing them. - # - disabled - # - active - # - evaluate - bypass_actors: - # The actors that can bypass the rules in this ruleset - - actor_id: 3974045 - actor_type: Team - # type: The type of actor that can bypass a ruleset - # - RepositoryRole - # - Team - # - Integration - # - OrganizationAdmin - bypass_mode: pull_request - # When the specified actor can bypass the ruleset. `pull_request` - # means that an actor can only bypass rules on pull requests. - # - always - # - pull_request - - - actor_id: 1 - actor_type: OrganizationAdmin - bypass_mode: always - - - actor_id: 7898 - actor_type: RepositoryRole - bypass_mode: always - - - actor_id: 210920 - actor_type: Integration - bypass_mode: always - - conditions: - ref_name: - # Parameters for a repository ruleset ref name condition - include: ["~DEFAULT_BRANCH"] - # Array of ref names or patterns to include. One of these - # patterns must match for the condition to pass. Also accepts - # `~DEFAULT_BRANCH` to include the default branch or `~ALL` to - # include all branches. - exclude: ["refs/heads/oldmaster"] - # Array of ref names or patterns to exclude. The condition - # will not pass if any of these patterns match. - repository_name: - include: ["test*"] - # Array of repository names or patterns to include. - # One of these patterns must match for the condition - # to pass. Also accepts `~ALL` to include all - # repositories. - exclude: ["test","test1"] - # Array of repository names or patterns to exclude. The - # condition will not pass if any of these patterns - # match. - protected: true - # Whether renaming of target repositories is - # prevented. - - rules: - - type: creation - - type: update - - type: update_allows_fetch_and_merge - - type: deletion - - type: required_linear_history - - type: required_signatures - - type: required_deployments - parameters: - required_deployment_environments: ["test"] - - type: pull_request - parameters: - dismiss_stale_reviews_on_push: true - # New, reviewable commits pushed will dismiss previous pull - # request review approvals. - require_code_owner_review: true - # Require an approving review in pull requests that modify - # files that have a designated code owner - require_last_push_approval: true - # Whether the most recent reviewable push must be approved - # by someone other than the person who pushed it. - required_approving_review_count: 10 - # The number of approving reviews that are required before a - # pull request can be merged. - required_review_thread_resolution: true - # All conversations on code must be resolved before a pull - # request can be merged. - - - type: required_status_checks - # Choose which status checks must pass before branches can be merged - # into a branch that matches this rule. When enabled, commits must - # first be pushed to another branch, then merged or pushed directly - # to a branch that matches this rule after status checks have - # passed. - parameters: - strict_required_status_checks_policy: false - # Whether pull requests targeting a matching branch must be - # tested with the latest code. This setting will not take - # effect unless at least one status check is enabled. - required_status_checks: - - context: CodeQL - integration_id: 1234 - - context: GHAS Compliance - integration_id: 1234 - - - type: commit_message_pattern - parameters: - name: test commit_message_pattern - # required: - # - operator - # - pattern - negate: true - operator: starts_with - # The operator to use for matching. - # - starts_with - # - ends_with - # - contains - # - regex - pattern: skip* - # The pattern to match with. - - - type: commit_author_email_pattern - parameters: - name: test commit_author_email_pattern - negate: false - operator: regex - pattern: "^.*@example.com$" - - - type: committer_email_pattern - parameters: - name: test committer_email_pattern - negate: false - operator: regex - pattern: "^.*@example.com$" - - - type: branch_name_pattern - parameters: - name: test branch_name_pattern - negate: false - operator: regex - pattern: ".*\/.*" - - - type: "tag_name_pattern" - parameters: - name: test tag_name_pattern - negate: false - operator: regex - pattern: ".*\/.*" \ No newline at end of file diff --git a/docs/sample-settings/repo.yml b/docs/sample-settings/repo.yml index a3d70914..1a1f693f 100644 --- a/docs/sample-settings/repo.yml +++ b/docs/sample-settings/repo.yml @@ -1,209 +1,10 @@ -# This settings can be used to create repo level settings -repository: - # Name of the repo - name: test - - # Create the repo if it is not existing +# This settings file can be used to create repo-level settings + +repository: + # Create the repo if doesn't exist force_create: true # Use a template when creating the repo template: template_repo - # This is the settings that need to be applied to all repositories in the org - # See https://developer.github.com/v3/repos/#edit for all available settings for a repository - # A short description of the repository that will show up on GitHub - description: description of the repo - - # A URL with more information about the repository - homepage: https://example.github.io/ - - # Keep this as true for most cases - # A lot of the policies below cannot be implemented on bare repos - # Pass true to create an initial commit with empty README. - auto_init: true - - # A comma-separated list of topics to set on the repository - topics: - - github - - safe-settings - - new-topic - - another-topic - - topic-12 - - # Settings for Code security and analysis - # Dependabot Alerts - security: - enableVulnerabilityAlerts: true - enableAutomatedSecurityFixes: true - - # Either `true` to make the repository private, or `false` to make it public. - # If this value is changed and if Org members cannot change the visibility of repos - # it would result in an error when updating a repo - private: false - - # Can be public or private. If your organization is associated with an enterprise account using - # GitHub Enterprise Cloud or GitHub Enterprise Server 2.20+, visibility can also be internal. - visibility: private - - # Either `true` to enable issues for this repository, `false` to disable them. - has_issues: true - - # Either `true` to enable projects for this repository, or `false` to disable them. - # If projects are disabled for the organization, passing `true` will cause an API error. - has_projects: true - - # Either `true` to enable the wiki for this repository, `false` to disable it. - has_wiki: true - - # The default branch for this repository. - default_branch: main - - # Desired language or platform [.gitignore template](https://github.com/github/gitignore) - # to apply. Use the name of the template without the extension. - # For example, "Haskell". - gitignore_template: node - - # Choose an [open source license template](https://choosealicense.com/) - # that best suits your needs, and then use the - # [license keyword](https://help.github.com/articles/licensing-a-repository/#searching-github-by-license-type) - # as the `license_template` string. For example, "mit" or "mpl-2.0". - license_template: mit - - # Either `true` to allow squash-merging pull requests, or `false` to prevent - # squash-merging. - allow_squash_merge: true - - # Either `true` to allow merging pull requests with a merge commit, or `false` - # to prevent merging pull requests with merge commits. - allow_merge_commit: true - - # Either `true` to allow rebase-merging pull requests, or `false` to prevent - # rebase-merging. - allow_rebase_merge: true - - # Either `true` to allow auto-merge on pull requests, - # or `false` to disallow auto-merge. - # Default: `false` - allow_auto_merge: false - - # Either `true` to allow automatically deleting head branches - # when pull requests are merged, or `false` to prevent automatic deletion. - # Default: `false` - delete_branch_on_merge: false - -# The following attributes are applied to any repo within the org -# So if a repo is not listed above is created or edited -# The app will apply the following settings to it -labels: - # Labels: define labels for Issues and Pull Requests - - name: bug - color: CC0000 - description: An issue with the system - - - name: feature - # If including a `#`, make sure to wrap it with quotes! - color: '#336699' - description: New functionality. - - - name: first-timers-only - # include the old name to rename an existing label - oldname: Help Wanted - color: '#326699' - - - name: new-label - # include the old name to rename an existing label - oldname: Help Wanted - color: '#326699' - -# Collaborators: give specific users access to any repository. -# See https://developer.github.com/v3/repos/collaborators/#add-user-as-a-collaborator for available options -# The permission to grant the collaborator. Can be one of: -# * `pull` - can pull, but not push to or administer this repository. -# * `push` - can pull and push, but not administer this repository. -# * `admin` - can pull, push and administer this repository. -# * ` - Give the custom role name -collaborators: -- username: drstrange - permission: push -- username: beetlejuice - permission: pull - exclude: - - actions-demo -# You can exclude a list of repos for this collaborator and all repos except these repos would have this collaborator -- username: thor - permission: push - include: - - actions-demo - - another-repo -# You can include a list of repos for this collaborator and only those repos would have this collaborator - -# See https://developer.github.com/v3/teams/#add-or-update-team-repository for available options -# The permission to grant the team. Can be one of: -# * `pull` - can pull, but not push to or administer this repository. -# * `push` - can pull and push, but not administer this repository. -# * `admin` - can pull, push and administer this repository. -teams: - - name: core - permission: admin - - name: docs - permission: push - exclude: - - actions-demo -# You can exclude a list of repos for this collaborator and all repos except these repos would have this collaborator - -# Autolinks -autolinks: - - key_prefix: ASDF- - url_template: https://jira.company.com/browse/ASDF- - - key_prefix: BOLIGRAFO- - url_template: https://jira.company.com/browse/BOLIGRAFO- - -branches: - # If the name of the branch value is specified as `default`, then the app will create a branch protection rule to apply against the default branch in the repo - - name: default - # https://developer.github.com/v3/repos/branches/#update-branch-protection - # Branch Protection settings. Set to null to disable - protection: - # Required. Require at least one approving review on a pull request, before merging. Set to null to disable. - required_pull_request_reviews: - # The number of approvals required. (1-6) - required_approving_review_count: 1 - # Dismiss approved reviews automatically when a new commit is pushed. - dismiss_stale_reviews: true - # Blocks merge until code owners have reviewed. - require_code_owner_reviews: true - # Whether the most recent reviewable push must be approved by someone other than the person who pushed it. - require_last_push_approval: true - # Allow specific users, teams, or apps to bypass pull request requirements. Set to null to disable. - bypass_pull_request_allowances: - apps: [] - users: [] - teams: [] - # Specify which users and teams can dismiss pull request reviews. Pass an empty dismissal_restrictions object to disable. User and team dismissal_restrictions are only available for organization-owned repositories. Omit this parameter for personal repositories. - dismissal_restrictions: - users: [] - teams: [] - # Required. Require status checks to pass before merging. Set to null to disable - required_status_checks: - # Required. Require branches to be up to date before merging. - strict: true - # Required. The list of status checks to require in order to merge into this branch - contexts: [] - # Required. Enforce all configured restrictions for administrators. Set to true to enforce required status checks for repository administrators. Set to null to disable. - enforce_admins: true - # Required. Restrict who can push to this branch. Team and user restrictions are only available for organization-owned repositories. Set to null to disable. - restrictions: - apps: [] - users: [] - teams: [] - -# Custom properties -# See https://docs.github.com/en/rest/repos/custom-properties?apiVersion=2022-11-28 -custom_properties: - - name: test - value: test - -validator: - pattern: '[a-zA-Z0-9_-]+_[a-zA-Z0-9_-]+.*' - - +# Every other property is the same as the org level settings and can be overridden here diff --git a/docs/sample-settings/settings.yml b/docs/sample-settings/settings.yml index c05484de..7e19d335 100644 --- a/docs/sample-settings/settings.yml +++ b/docs/sample-settings/settings.yml @@ -1,192 +1,399 @@ -# This settings can be used to create org level settings +# This settings file can be used to create org-level settings -#repository: - # This is the settings that need to be applied to all repositories in the org - # See https://developer.github.com/v3/repos/#edit for all available settings for a repository +# This is the settings that need to be applied to all repositories in the org +# See https://docs.github.com/en/rest/repos/repos?apiVersion=2022-11-28#create-an-organization-repository for all available settings for a repository +repository: # A short description of the repository that will show up on GitHub - #description: description of the repo - + description: description of the repo + # A URL with more information about the repository - #homepage: https://example.github.io/ - - # Keep this as true for most cases - # A lot of the policies below cannot be implemented on bare repos - # Pass true to create an initial commit with empty README. - #auto_init: true - - # A list of topics to set on the repository - #topics: - #- github - #- safe-settings - #- new-topic - #- another-topic - #- topic-12 + homepage: https://example.github.io/ + + # Create an initial commit with empty README. + # Keep this set to true in most cases since many of the policies below cannot be implemented on bare repos + auto_init: true + + # A list of topics to set on the repository - can alternatively set like this: [github, probot, new-topic, another-topic, topic-12] + topics: + - new-topic + - another-topic # Settings for Code security and analysis # Dependabot Alerts - # security: - # enableVulnerabilityAlerts: true - # enableAutomatedSecurityFixes: true - - # Either `true` to make the repository private, or `false` to make it public. - # If this value is changed and if Org members cannot change the visibility of repos + security: + enableVulnerabilityAlerts: true + enableAutomatedSecurityFixes: true + + # Either `true` to make the repository private, or `false` to make it public. + # If this value is changed and if org members cannot change the visibility of repos # it would result in an error when updating a repo - #private: false - - # Can be public or private. If your organization is associated with an enterprise account using - # GitHub Enterprise Cloud or GitHub Enterprise Server 2.20+, visibility can also be internal. - #visibility: private - + private: true + + # Can be public or private. If your organization is associated with an enterprise account using + # GitHub Enterprise Cloud or GitHub Enterprise Server 2.20+, visibility can also be internal. + visibility: private + # Either `true` to enable issues for this repository, `false` to disable them. - #has_issues: true - + has_issues: true + # Either `true` to enable projects for this repository, or `false` to disable them. # If projects are disabled for the organization, passing `true` will cause an API error. - #has_projects: true - + has_projects: true + # Either `true` to enable the wiki for this repository, `false` to disable it. - #has_wiki: true - + has_wiki: true + # The default branch for this repository. - #default_branch: main - - # Desired language or platform [.gitignore template](https://github.com/github/gitignore) - # to apply. Use the name of the template without the extension. + default_branch: main + + # Desired language or platform [.gitignore template](https://github.com/github/gitignore) + # to apply. Use the name of the template without the extension. # For example, "Haskell". - #gitignore_template: node - - # Choose an [open source license template](https://choosealicense.com/) - # that best suits your needs, and then use the - # [license keyword](https://help.github.com/articles/licensing-a-repository/#searching-github-by-license-type) + gitignore_template: node + + # Choose an [open source license template](https://choosealicense.com/) + # that best suits your needs, and then use the + # [license keyword](https://help.github.com/articles/licensing-a-repository/#searching-github-by-license-type) # as the `license_template` string. For example, "mit" or "mpl-2.0". - #license_template: mit - + license_template: mit + # Either `true` to allow squash-merging pull requests, or `false` to prevent # squash-merging. - #allow_squash_merge: true - + allow_squash_merge: true + # Either `true` to allow merging pull requests with a merge commit, or `false` # to prevent merging pull requests with merge commits. - #allow_merge_commit: true - + allow_merge_commit: true + # Either `true` to allow rebase-merging pull requests, or `false` to prevent # rebase-merging. - #allow_rebase_merge: true - - # Either `true` to allow auto-merge on pull requests, + allow_rebase_merge: true + + # Either `true` to allow auto-merge on pull requests, # or `false` to disallow auto-merge. # Default: `false` - #allow_auto_merge: true - - # Either `true` to allow automatically deleting head branches + allow_auto_merge: true + + # Either `true` to allow automatically deleting head branches # when pull requests are merged, or `false` to prevent automatic deletion. # Default: `false` - #delete_branch_on_merge: true + delete_branch_on_merge: true - # Either `true` to allow update branch on pull requests, + # Either `true` to allow update branch on pull requests, # or `false` to disallow update branch. # Default: `false` - # allow_update_branch: true - + allow_update_branch: true + + # Whether to archive this repository. false will unarchive a previously archived repository. + archived: false + # The following attributes are applied to any repo within the org # So if a repo is not listed above is created or edited # The app will apply the following settings to it -#labels: +labels: # Labels: define labels for Issues and Pull Requests - #- name: bug - # color: CC0000 - # description: An issue with the system - - #- name: feature - # If including a `#`, make sure to wrap it with quotes! - # color: '#336699' - # description: New functionality. - - #- name: first-timers-only - # include the old name to rename an existing label - # oldname: Help Wanted - # color: '#326699' - - #- name: new-label - # include the old name to rename an existing label - # oldname: Help Wanted - # color: '#326699' - -#collaborators: + include: + - name: bug + color: CC0000 + description: An issue with the system + + - name: feature + # If including a `#`, make sure to wrap it with quotes! + color: "#336699" + description: New functionality. + + - name: first-timers-only + # include the old name to rename an existing label + oldname: Help Wanted + color: "#326699" + + - name: new-label + # include the old name to rename an existing label + oldname: Help Wanted + color: "#326699" + exclude: + # don't delete any labels created on GitHub that starts with "release" + - name: ^release + +# Milestones: define milestones for Issues and Pull Requests +milestones: + - title: milestone-title + description: milestone-description + # The state of the milestone. Either `open` or `closed` + state: open + # Collaborators: give specific users access to any repository. -# See https://developer.github.com/v3/repos/collaborators/#add-user-as-a-collaborator for available options - -#- username: drstrange -# permission: push -# The permission to grant the collaborator. Can be one of: -# * `pull` - can pull, but not push to or administer this repository. -# * `push` - can pull and push, but not administer this repository. -# * `admin` - can pull, push and administer this repository. -#- username: beetlejuice -# permission: pull -# exclude: -# - actions-demo -# You can exclude a list of repos for this collaborator and all repos except these repos would have this collaborator -#- username: thor -# permission: push -# include: -# - actions-demo -# - another-repo -# You can include a list of repos for this collaborator and only those repos would have this collaborator - -# See https://developer.github.com/v3/teams/#add-or-update-team-repository for available options -#teams: -# - name: core - # The permission to grant the team. Can be one of: +# See https://docs.github.com/en/rest/collaborators/collaborators?apiVersion=2022-11-28#add-a-repository-collaborator for available options +collaborators: + - username: regpaco + # The permission to grant the collaborator. Can be one of: # * `pull` - can pull, but not push to or administer this repository. # * `push` - can pull and push, but not administer this repository. # * `admin` - can pull, push and administer this repository. -# permission: admin -# - name: docs -# permission: push -# exclude: -# - actions-demo -# You can exclude a list of repos for this collaborator and all repos except these repos would have this collaborator + permission: push + - username: beetlejuice + permission: pull + # You can exclude a list of repos for this collaborator and all repos except these repos would have this collaborator + exclude: + - actions-demo + - username: thor + permission: push + # You can include a list of repos for this collaborator and only those repos would have this collaborator + include: + - actions-demo + - another-repo +# Teams +# See https://docs.github.com/en/rest/teams/teams?apiVersion=2022-11-28#create-a-team for available options +teams: + - name: core + # The permission to grant the team. Can be one of: + # * `pull` - can pull, but not push to or administer this repository. + # * `push` - can pull and push, but not administer this repository. + # * `admin` - can pull, push and administer this repository. + permission: admin + - name: docss + permission: push + - name: docs + permission: pull + # Visibility is only honored when the team is created not for existing teams. + # It can be either secret (default) or closed (visible to all members of the org) + - name: globalteam + permission: push + visibility: closed -#branches: +# Branch protection rules +# See https://docs.github.com/en/rest/branches/branch-protection?apiVersion=2022-11-28#update-branch-protection for available options +branches: # If the name of the branch value is specified as `default`, then the app will create a branch protection rule to apply against the default branch in the repo -# - name: default - # https://developer.github.com/v3/repos/branches/#update-branch-protection - # Branch Protection settings. Set to null to disable -# protection: + - name: default + protection: # Required. Require at least one approving review on a pull request, before merging. Set to null to disable. -# required_pull_request_reviews: + required_pull_request_reviews: # The number of approvals required. (1-6) -# required_approving_review_count: 1 + required_approving_review_count: 1 # Dismiss approved reviews automatically when a new commit is pushed. -# dismiss_stale_reviews: true + dismiss_stale_reviews: true # Blocks merge until code owners have reviewed. -# require_code_owner_reviews: true + require_code_owner_reviews: true # Whether the most recent reviewable push must be approved by someone other than the person who pushed it. -# require_last_push_approval: true + require_last_push_approval: true # Allow specific users, teams, or apps to bypass pull request requirements. Set to null to disable. -# bypass_pull_request_allowances: -# apps: [] -# users: [] -# teams: [] + bypass_pull_request_allowances: + apps: [] + users: [] + teams: [] # Specify which users and teams can dismiss pull request reviews. Pass an empty dismissal_restrictions object to disable. User and team dismissal_restrictions are only available for organization-owned repositories. Omit this parameter for personal repositories. -# dismissal_restrictions: -# users: [] -# teams: [] + dismissal_restrictions: + users: [] + teams: [] # Required. Require status checks to pass before merging. Set to null to disable -# required_status_checks: + required_status_checks: # Required. Require branches to be up to date before merging. -# strict: true + strict: true # Required. The list of status checks to require in order to merge into this branch -# contexts: [] + contexts: [] # Required. Enforce all configured restrictions for administrators. Set to true to enforce required status checks for repository administrators. Set to null to disable. -# enforce_admins: true + enforce_admins: true # Required. Restrict who can push to this branch. Team and user restrictions are only available for organization-owned repositories. Set to null to disable. -# restrictions: -# apps: [] -# users: [] -# teams: [] - -#validator: - #pattern: '[a-zA-Z0-9_-]+_[a-zA-Z0-9_-]+.*' + restrictions: + apps: [] + users: [] + teams: [] + +# Custom properties +# See https://docs.github.com/en/rest/repos/custom-properties?apiVersion=2022-11-28 +custom_properties: + - name: test + value: test + +# See the docs (https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/managing-repository-settings/configuring-autolinks-to-reference-external-resources) for a description of autolinks and replacement values. +autolinks: + - key_prefix: "JIRA-" + url_template: "https://jira.github.com/browse/JIRA-" + is_alphanumeric: false + - key_prefix: "MYLINK-" + url_template: "https://mywebsite.com/" + +# Repository name validation +validator: + #pattern: '[a-zA-Z0-9_-]+_[a-zA-Z0-9_-]+.*' + pattern: "[a-zA-Z0-9_-]+" + +# Rulesets +# See https://docs.github.com/en/rest/orgs/rules?apiVersion=2022-11-28#create-an-organization-repository-rulesetfor available options +rulesets: + - name: Template + # The target of the ruleset. Can be one of: + # - branch + # - tag + target: branch + # The enforcement level of the ruleset. `evaluate` allows admins to test + # rules before enforcing them. + # - disabled + # - active + # - evaluate + enforcement: active + + # The actors that can bypass the rules in this ruleset + bypass_actors: + - actor_id: number + # type: The type of actor that can bypass a ruleset + # - RepositoryRole + # - Team + # - Integration + # - OrganizationAdmin + actor_type: Team + # When the specified actor can bypass the ruleset. `pull_request` + # means that an actor can only bypass rules on pull requests. + # - always + # - pull_request + bypass_mode: pull_request + + - actor_id: 1 + actor_type: OrganizationAdmin + bypass_mode: always + + - actor_id: 7898 + actor_type: RepositoryRole + bypass_mode: always + + - actor_id: 210920 + actor_type: Integration + bypass_mode: always + + conditions: + # Parameters for a repository ruleset ref name condition + ref_name: + # Array of ref names or patterns to include. One of these + # patterns must match for the condition to pass. Also accepts + # `~DEFAULT_BRANCH` to include the default branch or `~ALL` to + # include all branches. + include: ["~DEFAULT_BRANCH"] + + # Array of ref names or patterns to exclude. The condition + # will not pass if any of these patterns match. + exclude: ["refs/heads/oldmaster"] + + # This condition only exists at the org level (remove for suborg and repo level rulesets) + repository_name: + # Array of repository names or patterns to include. + # One of these patterns must match for the condition + # to pass. Also accepts `~ALL` to include all + # repositories. + include: ["test*"] + # Array of repository names or patterns to exclude. The + # condition will not pass if any of these patterns + # match. + exclude: ["test", "test1"] + # Whether renaming of target repositories is + # prevented. + protected: true + + # Refer to https://docs.github.com/en/rest/orgs/rules#create-an-organization-repository-ruleset + rules: + - type: creation + - type: update + parameters: + # Branch can pull changes from its upstream repository + update_allows_fetch_and_merge: true + - type: deletion + - type: required_linear_history + - type: required_signatures + + - type: required_deployments + parameters: + required_deployment_environments: ["staging"] + + - type: pull_request + parameters: + # Reviewable commits pushed will dismiss previous pull + # request review approvals. + dismiss_stale_reviews_on_push: true + # Require an approving review in pull requests that modify + # files that have a designated code owner + require_code_owner_review: true + # Whether the most recent reviewable push must be approved + # by someone other than the person who pushed it. + require_last_push_approval: true + # The number of approving reviews that are required before a + # pull request can be merged. + required_approving_review_count: 1 + # All conversations on code must be resolved before a pull + # request can be merged. + required_review_thread_resolution: true + + # Choose which status checks must pass before branches can be merged + # into a branch that matches this rule. When enabled, commits must + # first be pushed to another branch, then merged or pushed directly + # to a branch that matches this rule after status checks have + # passed. + - type: required_status_checks + parameters: + # Whether pull requests targeting a matching branch must be + # tested with the latest code. This setting will not take + # effect unless at least one status check is enabled. + strict_required_status_checks_policy: true + required_status_checks: + - context: CodeQL + integration_id: 1234 + - context: GHAS Compliance + integration_id: 1234 + + # Choose which workflows must pass before branches can be merged. + - type: workflows + parameters: + workflows: + - path: .github/workflows/example.yml + # Run $("meta[name=octolytics-dimension-repository_id]").getAttribute('content') + # in the browser console of the repository to get the repository_id + repository_id: 123456 + # One of the following: + # Branch or tag + ref: refs/heads/main + # Commit SHA + sha: 1234567890abcdef + + - type: commit_message_pattern + parameters: + name: test commit_message_pattern + # required: + # - operator + # - pattern + negate: true + operator: starts_with + # The operator to use for matching. + # - starts_with + # - ends_with + # - contains + # - regex + pattern: skip* + # The pattern to match with. + + - type: commit_author_email_pattern + parameters: + name: test commit_author_email_pattern + negate: false + operator: regex + pattern: "^.*@example.com$" + + - type: committer_email_pattern + parameters: + name: test committer_email_pattern + negate: false + operator: regex + pattern: "^.*@example.com$" + + - type: branch_name_pattern + parameters: + name: test branch_name_pattern + negate: false + operator: regex + pattern: ".*\/.*" + + - type: "tag_name_pattern" + parameters: + name: test tag_name_pattern + negate: false + operator: regex + pattern: ".*\/.*" diff --git a/docs/sample-settings/suborg.yml b/docs/sample-settings/suborg.yml index 48398a9a..a509847c 100644 --- a/docs/sample-settings/suborg.yml +++ b/docs/sample-settings/suborg.yml @@ -1,201 +1,16 @@ -# This settings can be used to create suborg level settings +# This settings file can be used to create suborg-level settings # List of repos that belong to the suborg +# You can use Glob patterns suborgrepos: - test* -# You can use Glob patterns # List of repos that belong to the suborg suborgteams: - core # List of repos that belong to the suborg based on custom properties -suborgproperties: +suborgproperties: - EDP: true -#repository: - # This is the settings that need to be applied to all repositories in the org - # See https://developer.github.com/v3/repos/#edit for all available settings for a repository - # A short description of the repository that will show up on GitHub - #description: description of the repo - - # A URL with more information about the repository - #homepage: https://example.github.io/ - - # Keep this as true for most cases - # A lot of the policies below cannot be implemented on bare repos - # Pass true to create an initial commit with empty README. - #auto_init: true - - # A comma-separated list of topics to set on the repository - #topics: - #- github - #- safe-settings - #- new-topic - #- another-topic - #- topic-12 - - # Either `true` to make the repository private, or `false` to make it public. - # If this value is changed and if Org members cannot change the visibility of repos - # it would result in an error when updating a repo - #private: false - - # Can be public or private. If your organization is associated with an enterprise account using - # GitHub Enterprise Cloud or GitHub Enterprise Server 2.20+, visibility can also be internal. - #visibility: private - - # Either `true` to enable issues for this repository, `false` to disable them. - #has_issues: true - - # Either `true` to enable projects for this repository, or `false` to disable them. - # If projects are disabled for the organization, passing `true` will cause an API error. - #has_projects: true - - # Either `true` to enable the wiki for this repository, `false` to disable it. - #has_wiki: true - - # The default branch for this repository. - #default_branch: main - - # Desired language or platform [.gitignore template](https://github.com/github/gitignore) - # to apply. Use the name of the template without the extension. - # For example, "Haskell". - #gitignore_template: node - - # Choose an [open source license template](https://choosealicense.com/) - # that best suits your needs, and then use the - # [license keyword](https://help.github.com/articles/licensing-a-repository/#searching-github-by-license-type) - # as the `license_template` string. For example, "mit" or "mpl-2.0". - #license_template: mit - - # Either `true` to allow squash-merging pull requests, or `false` to prevent - # squash-merging. - #allow_squash_merge: true - - # Either `true` to allow merging pull requests with a merge commit, or `false` - # to prevent merging pull requests with merge commits. - #allow_merge_commit: true - - # Either `true` to allow rebase-merging pull requests, or `false` to prevent - # rebase-merging. - #allow_rebase_merge: true - - # Either `true` to allow auto-merge on pull requests, - # or `false` to disallow auto-merge. - # Default: `false` - #allow_auto_merge: true - - # Either `true` to allow automatically deleting head branches - # when pull requests are merged, or `false` to prevent automatic deletion. - # Default: `false` - #delete_branch_on_merge: true - - # Either `true` to allow update branch on pull requests, - # or `false` to disallow update branch. - # Default: `false` - # allow_update_branch: true - -# The following attributes are applied to any repo within the org -# So if a repo is not listed above is created or edited -# The app will apply the following settings to it -#labels: - # Labels: define labels for Issues and Pull Requests - #- name: bug - # color: CC0000 - # description: An issue with the system - - #- name: feature - # If including a `#`, make sure to wrap it with quotes! - # color: '#336699' - # description: New functionality. - - #- name: first-timers-only - # include the old name to rename an existing label - # oldname: Help Wanted - # color: '#326699' - - #- name: new-label - # include the old name to rename an existing label - # oldname: Help Wanted - # color: '#326699' - -#collaborators: -# Collaborators: give specific users access to any repository. -# See https://developer.github.com/v3/repos/collaborators/#add-user-as-a-collaborator for available options - -#- username: drstrange -# permission: push -# The permission to grant the collaborator. Can be one of: -# * `pull` - can pull, but not push to or administer this repository. -# * `push` - can pull and push, but not administer this repository. -# * `admin` - can pull, push and administer this repository. -#- username: beetlejuice -# permission: pull -# exclude: -# - actions-demo -# You can exclude a list of repos for this collaborator and all repos except these repos would have this collaborator -#- username: thor -# permission: push -# include: -# - actions-demo -# - another-repo -# You can include a list of repos for this collaborator and only those repos would have this collaborator - -# See https://developer.github.com/v3/teams/#add-or-update-team-repository for available options -#teams: -# - name: core - # The permission to grant the team. Can be one of: - # * `pull` - can pull, but not push to or administer this repository. - # * `push` - can pull and push, but not administer this repository. - # * `admin` - can pull, push and administer this repository. -# permission: admin -# - name: docs -# permission: push -# exclude: -# - actions-demo -# You can exclude a list of repos for this collaborator and all repos except these repos would have this collaborator - - -#branches: - # If the name of the branch value is specified as `default`, then the app will create a branch protection rule to apply against the default branch in the repo -# - name: default - # https://developer.github.com/v3/repos/branches/#update-branch-protection - # Branch Protection settings. Set to null to disable -# protection: - # Required. Require at least one approving review on a pull request, before merging. Set to null to disable. -# required_pull_request_reviews: - # The number of approvals required. (1-6) -# required_approving_review_count: 1 - # Dismiss approved reviews automatically when a new commit is pushed. -# dismiss_stale_reviews: true - # Blocks merge until code owners have reviewed. -# require_code_owner_reviews: true - # Whether the most recent reviewable push must be approved by someone other than the person who pushed it. -# require_last_push_approval: true - # Allow specific users, teams, or apps to bypass pull request requirements. Set to null to disable. -# bypass_pull_request_allowances: -# apps: [] -# users: [] -# teams: [] - # Specify which users and teams can dismiss pull request reviews. Pass an empty dismissal_restrictions object to disable. User and team dismissal_restrictions are only available for organization-owned repositories. Omit this parameter for personal repositories. -# dismissal_restrictions: -# users: [] -# teams: [] - # Required. Require status checks to pass before merging. Set to null to disable -# required_status_checks: - # Required. Require branches to be up to date before merging. -# strict: true - # Required. The list of status checks to require in order to merge into this branch -# contexts: [] - # Required. Enforce all configured restrictions for administrators. Set to true to enforce required status checks for repository administrators. Set to null to disable. -# enforce_admins: true - # Required. Restrict who can push to this branch. Team and user restrictions are only available for organization-owned repositories. Set to null to disable. -# restrictions: -# apps: [] -# users: [] -# teams: [] - -#validator: - #pattern: '[a-zA-Z0-9_-]+_[a-zA-Z0-9_-]+.*' - - +# Every other property is the same as the org level settings and can be overridden here diff --git a/lib/mergeDeep.js b/lib/mergeDeep.js index a43a5db7..95f78935 100644 --- a/lib/mergeDeep.js +++ b/lib/mergeDeep.js @@ -7,7 +7,7 @@ const GET_NAME_USERNAME_PROPERTY = item => { if (NAME_USERNAME_PROPERTY(item)) r class MergeDeep { constructor (log, github, ignorableFields = [], configvalidators = {}, overridevalidators = {}) { - this.log = log.child({ context: 'MergeDeep' }) + this.log = log this.github = github this.ignorableFields = ignorableFields this.configvalidators = DeploymentConfig.configvalidators diff --git a/lib/plugins/validator.js b/lib/plugins/validator.js index 4d105311..bae120b7 100644 --- a/lib/plugins/validator.js +++ b/lib/plugins/validator.js @@ -1,4 +1,6 @@ const NopCommand = require('../nopcommand') +const ErrorStash = require('./errorStash') + module.exports = class Validator extends ErrorStash { constructor (nop, github, repo, settings, log) { super([], log, repo.repo) diff --git a/safe-settings.yaml b/safe-settings.yaml index cacc4b3a..a97a3eec 100644 --- a/safe-settings.yaml +++ b/safe-settings.yaml @@ -20,9 +20,8 @@ spec: app: safe-settings spec: containers: - - image: docker.io/yadhav/safe-settings:0.1.0-rc.29 + - image: ghcr.io/github/safe-settings:2.1.10 name: safe-settings envFrom: - - secretRef: + - secretRef: name: app-env - diff --git a/serverless.yml b/serverless.yml index ea98f1e6..775039e9 100644 --- a/serverless.yml +++ b/serverless.yml @@ -5,7 +5,7 @@ frameworkVersion: '3' provider: name: aws - runtime: nodejs16.x + runtime: nodejs20.x lambdaHashingVersion: 20201221 environment: APP_ID: ${param:APP_ID} @@ -30,6 +30,6 @@ functions: LOG_LEVEL: debug events: - schedule: - rate: rate(30 minutes) - enabled: false # set to true to auto-enable + rate: rate(4 hours) + enabled: true # set to true to auto-enable input: {} diff --git a/test/unit/lib/plugins/autolinks.test.js b/test/unit/lib/plugins/autolinks.test.js index 63d82927..312bd47a 100644 --- a/test/unit/lib/plugins/autolinks.test.js +++ b/test/unit/lib/plugins/autolinks.test.js @@ -5,7 +5,7 @@ describe('Autolinks', () => { let github function configure (config) { - const log = { debug: jest.fn(), error: console.error } + const log = { child: jest.fn(), debug: jest.fn(), error: console.error } const nop = false const errors = [] return new Autolinks(nop, github, repo, config, log, errors) diff --git a/test/unit/lib/plugins/branches.test.js b/test/unit/lib/plugins/branches.test.js index 68290ea4..4208e443 100644 --- a/test/unit/lib/plugins/branches.test.js +++ b/test/unit/lib/plugins/branches.test.js @@ -6,6 +6,7 @@ const Branches = require('../../../../lib/plugins/branches') describe('Branches', () => { let github const log = jest.fn() + log.child = jest.fn() log.debug = jest.fn() log.error = jest.fn() @@ -65,7 +66,9 @@ describe('Branches', () => { required_pull_request_reviews: { require_code_owner_reviews: true }, - headers: { accept: 'application/vnd.github.hellcat-preview+json,application/vnd.github.luke-cage-preview+json,application/vnd.github.zzzax-preview+json' } + headers: { accept: 'application/vnd.github.hellcat-preview+json,application/vnd.github.luke-cage-preview+json,application/vnd.github.zzzax-preview+json' }, + required_linear_history: undefined, + restrictions: null, }) }) }) @@ -192,12 +195,15 @@ describe('Branches', () => { return plugin.sync().then(() => { expect(github.repos.updateBranchProtection).toHaveBeenCalledTimes(2) - expect(github.repos.updateBranchProtection).toHaveBeenLastCalledWith({ + expect(github.repos.updateBranchProtection).toHaveBeenLastCalledWith({ owner: 'bkeepers', repo: 'test', branch: 'other', enforce_admins: false, - headers: { accept: 'application/vnd.github.hellcat-preview+json,application/vnd.github.luke-cage-preview+json,application/vnd.github.zzzax-preview+json' } + headers: { accept: 'application/vnd.github.hellcat-preview+json,application/vnd.github.luke-cage-preview+json,application/vnd.github.zzzax-preview+json' }, + required_linear_history: undefined, + required_status_checks: null, + restrictions: null, }) }) }) diff --git a/test/unit/lib/plugins/collaborators.test.js b/test/unit/lib/plugins/collaborators.test.js index 359dd461..45d77bdc 100644 --- a/test/unit/lib/plugins/collaborators.test.js +++ b/test/unit/lib/plugins/collaborators.test.js @@ -4,8 +4,9 @@ describe('Collaborators', () => { let github function configure (config) { - const log = { debug: jest.fn(), error: console.error } - return new Collaborators(undefined, github, { owner: 'bkeepers', repo: 'test' }, config, log) + const log = { child: jest.fn(), debug: jest.fn(), error: console.error } + const errors = [] + return new Collaborators(undefined, github, { owner: 'bkeepers', repo: 'test' }, config, log, errors) } beforeEach(() => { diff --git a/test/unit/lib/plugins/custom_properties.test.js b/test/unit/lib/plugins/custom_properties.test.js index 69568a28..6b102480 100644 --- a/test/unit/lib/plugins/custom_properties.test.js +++ b/test/unit/lib/plugins/custom_properties.test.js @@ -20,7 +20,7 @@ describe('CustomProperties', () => { // ] // }) } - log = { debug: jest.fn(), error: console.error } + log = { child: jest.fn(), debug: jest.fn(), error: console.error } }) describe('sync', () => { @@ -125,4 +125,4 @@ describe('CustomProperties', () => { }) }) }) -}) \ No newline at end of file +}) diff --git a/test/unit/lib/plugins/environments.test.js b/test/unit/lib/plugins/environments.test.js index e826e005..18bc7d90 100644 --- a/test/unit/lib/plugins/environments.test.js +++ b/test/unit/lib/plugins/environments.test.js @@ -5,7 +5,7 @@ describe('Environments', () => { let github const org = 'bkeepers' const repo = 'test' - + function fillEnvironment(attrs) { if (!attrs.wait_timer) attrs.wait_timer = 0; if (!attrs.prevent_self_review) attrs.prevent_self_review = false; @@ -82,8 +82,10 @@ describe('Environments', () => { ] } ], { - debug: function() {} - }); + child: function() {}, + debug: function() {}, + error: function() {}, + }, []); when(github.request) .calledWith('GET /repos/:org/:repo/environments', { org, repo }) @@ -121,7 +123,7 @@ describe('Environments', () => { ] } }); - + ['wait-timer', 'reviewers', 'prevent-self-review', 'deployment-branch-policy', 'deployment-branch-policy-custom', 'variables', 'deployment-protection-rules'].forEach((environment_name) => { when(github.request) .calledWith('GET /repos/:org/:repo/environments/:environment_name/variables', { org, repo, environment_name }) @@ -139,7 +141,7 @@ describe('Environments', () => { data: { custom_deployment_protection_rules: [] } - }) + }) }); when(github.request) @@ -271,4 +273,4 @@ describe('Environments', () => { })); }) }) -}) \ No newline at end of file +}) diff --git a/test/unit/lib/plugins/labels.test.js b/test/unit/lib/plugins/labels.test.js index a94ffb5b..4538188c 100644 --- a/test/unit/lib/plugins/labels.test.js +++ b/test/unit/lib/plugins/labels.test.js @@ -6,7 +6,8 @@ describe('Labels', () => { function configure(config) { const nop = false; - return new Labels(nop, github, { owner: 'bkeepers', repo: 'test' }, config, log) + const errors = [] + return new Labels(nop, github, { owner: 'bkeepers', repo: 'test' }, config, log, errors) } beforeEach(() => { @@ -26,7 +27,7 @@ describe('Labels', () => { updateLabel: jest.fn().mockImplementation(() => Promise.resolve()) } } - log = { debug: jest.fn(), error: console.error } + log = { child: jest.fn(), debug: jest.fn(), error: console.error } }) describe('sync', () => { diff --git a/test/unit/lib/plugins/repository.test.js b/test/unit/lib/plugins/repository.test.js index b7af3912..3f124980 100644 --- a/test/unit/lib/plugins/repository.test.js +++ b/test/unit/lib/plugins/repository.test.js @@ -13,6 +13,7 @@ describe('Repository', () => { } } const log = jest.fn() + log.child = jest.fn() log.debug = jest.fn() log.error = jest.fn() diff --git a/test/unit/lib/plugins/teams.test.js b/test/unit/lib/plugins/teams.test.js index f289421e..b295b132 100644 --- a/test/unit/lib/plugins/teams.test.js +++ b/test/unit/lib/plugins/teams.test.js @@ -15,7 +15,7 @@ describe('Teams', () => { const org = 'bkeepers' function configure (config) { - const log = { debug: jest.fn(), error: console.error } + const log = { child: jest.fn(), debug: jest.fn(), error: console.error } const errors = [] return new Teams(undefined, github, { owner: 'bkeepers', repo: 'test' }, config, log, errors) } diff --git a/test/unit/lib/settings.test.js b/test/unit/lib/settings.test.js index c289f563..6aca9b60 100644 --- a/test/unit/lib/settings.test.js +++ b/test/unit/lib/settings.test.js @@ -21,17 +21,7 @@ describe('Settings Tests', () => { } }, octokit: jest.fn(), - log: { - debug: jest.fn((msg) => { - console.log(msg) - }), - info: jest.fn((msg) => { - console.log(msg) - }), - error: jest.fn((msg) => { - console.log(msg) - }) - } + log: require('pino')() } mockRepo = jest.fn()