{"id":22898416,"url":"https://github.com/bbtsoftware/azuredevopspolicyconfigurator","last_synced_at":"2025-08-09T05:15:52.421Z","repository":{"id":33688793,"uuid":"155180214","full_name":"bbtsoftware/AzureDevOpsPolicyConfigurator","owner":"bbtsoftware","description":"Tool for reading and updating branch policy settings based on a configuration file.","archived":false,"fork":false,"pushed_at":"2025-02-10T11:42:04.000Z","size":282,"stargazers_count":8,"open_issues_count":5,"forks_count":7,"subscribers_count":6,"default_branch":"develop","last_synced_at":"2025-07-31T04:57:27.763Z","etag":null,"topics":["azure-devops","infrastructure-as-code","policy","tfs"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bbtsoftware.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2018-10-29T08:51:40.000Z","updated_at":"2024-12-27T08:09:25.000Z","dependencies_parsed_at":"2025-05-07T23:07:18.548Z","dependency_job_id":"892d029d-5b8c-41ff-9a41-12d3debc19a2","html_url":"https://github.com/bbtsoftware/AzureDevOpsPolicyConfigurator","commit_stats":null,"previous_names":[],"tags_count":6,"template":false,"template_full_name":null,"purl":"pkg:github/bbtsoftware/AzureDevOpsPolicyConfigurator","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bbtsoftware%2FAzureDevOpsPolicyConfigurator","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bbtsoftware%2FAzureDevOpsPolicyConfigurator/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bbtsoftware%2FAzureDevOpsPolicyConfigurator/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bbtsoftware%2FAzureDevOpsPolicyConfigurator/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bbtsoftware","download_url":"https://codeload.github.com/bbtsoftware/AzureDevOpsPolicyConfigurator/tar.gz/refs/heads/develop","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bbtsoftware%2FAzureDevOpsPolicyConfigurator/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":269532365,"owners_count":24433271,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-09T02:00:10.424Z","response_time":111,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["azure-devops","infrastructure-as-code","policy","tfs"],"created_at":"2024-12-14T00:32:02.604Z","updated_at":"2025-08-09T05:15:52.332Z","avatar_url":"https://github.com/bbtsoftware.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Azure DevOps policy configurator\n\nThis tool gets the current policies for projects, repositories and branches, or applies policy settings over a team project collection based on a JSON configuration file.\n\n[![License](http://img.shields.io/:license-mit-blue.svg)](https://github.com/bbtsoftware/AzureDevOpsPolicyConfigurator/blob/develop/LICENSE)\n\n## Information\n\n| | Stable | Pre-release |\n|:--:|:--:|:--:|\n|GitHub Release|-|[![GitHub release](https://img.shields.io/github/release/bbtsoftware/AzureDevOpsPolicyConfigurator.svg)](https://github.com/bbtsoftware/AzureDevOpsPolicyConfigurator/releases/latest)|\n|Chocolatey|[![Chocolatey](https://img.shields.io/chocolatey/v/azure-devops-policy-configurator.svg)](https://www.chocolatey.org/packages/azure-devops-policy-configurator)|[![Chocolatey](https://img.shields.io/chocolatey/vpre/azure-devops-policy-configurator.svg)](https://www.chocolatey.org/packages/azure-devops-policy-configurator)|\n\n## Build Status\n\n[![Build status](https://github.com/bbtsoftware/AzureDevOpsPolicyConfigurator/actions/workflows/dotnet.yml/badge.svg?branch=develop)](https://github.com/bbtsoftware/AzureDevOpsPolicyConfigurator/actions/workflows/dotnet.yml)\n[![Build status](https://github.com/bbtsoftware/AzureDevOpsPolicyConfigurator/actions/workflows/release.yml/badge.svg)](https://github.com/bbtsoftware/AzureDevOpsPolicyConfigurator/actions/workflows/release.yml)\n[![Coverage Status](https://codecov.io/gh/bbtsoftware/AzureDevOpsPolicyConfigurator/branch/develop/graph/badge.svg?token=0VLbB8a8EF)](https://codecov.io/gh/bbtsoftware/AzureDevOpsPolicyConfigurator)\n\n## Documentation\n\n### General\n\nThe tool is targeted to .Net 7.0 / meaning, it can be used besides windows\nmachines also on linux, macs, etc. The tool is wrapped in a Chocolatey package, so it can be easily\ninstalled onto a windows 10 machine, where the package builds an executable itself, and installs\nit to the client machine. Nevertheless, the tool can be targeted onto any runtime.\nSee runtime catalog [here](https://docs.microsoft.com/en-us/dotnet/core/rid-catalog)\n\n#### Installation\n\n```ps\nchoco install azure-devops-policy-configurator\n```\n\n#### Generation to other targets\n\n##### Windows 10 example\n\n```ps\ndotnet publish -c Release -r win10-x64\n```\n\n##### Linux example\n\n```ps\ndotnet publish -c Release -r ubuntu.16.10-x64\n```\n\n##### Mac example\n\n```ps\ndotnet publish -c Release -r osx.10.12-x64\n```\n\n### Generate current structure\n\n `AzureDevOpsPolicyConfigurator generate` command generates JSON files from the current policy\n structure. The tool iterates through every Team Project, gets every policy set groups them by\n repository and saves in the `policies.json` file. In the main directory, every project is saved\n to the `projects.json` file, and the tool also gets every type available in the current Team\n Project, it stores them into the `types.json` file in each project directory.\n\n#### Generation example\n\n```cmd\nAzureDevOpsPolicyConfigurator generate --auth ntlm --collectionurl https://tfs.yourserver.ch/DefaultCollection\n```\n\n#### Command arguments for generation\n\n| Option                       | Description\n|------------------------------|---------------------------------------------------------------------------------------------------------------------\n| `--collectionUrl` or `-c`    | The Team Collection URL, e.g.: `tfs.yourserver.ch/DefaultCollection`\n| `--auth` or `-a`             | The authentication method, option values: `ntlm`, `oauth`, `basic`, `azureactivedirectory`\n| `--user` or `-u`             | The user for authentication (optional for PAT authentication, or for `ntlm` authentication with current user)\n| `--password` or `-p`         | The password, PAT or token for the authentication (optional for `ntlm` authentication with current user)\n| `--verbosity` or `-v`        | Sets the log4net root level, option values: `info`, `debug`, `warn`, `error` (optional, default is `info`)\n| `--destination` or `-d`      | optional, default value is `.\\Project`\n\n### Simulate and execute changes\n\n `AzureDevOpsPolicyConfigurator whatif` and `AzureDevOpsPolicyConfigurator execute` command executes\n a strategy stored in an input JSON file\n\n#### Simulation example\n\n```cmd\nAzureDevOpsPolicyConfigurator whatif -a ntlm -c https://tfs.yourserver.ch/DefaultCollection -i Sample\\\\testfile.json\n```\n\n#### Execution example\n\n```cmd\nAzureDevOpsPolicyConfigurator execute -a ntlm -c https://tfs.yourserver.ch/DefaultCollection -i Sample\\\\testfile.json\n```\n\n#### Command arguments for execution\n\n| Option                       | Description\n|------------------------------|---------------------------------------------------------------------------------------------------------------------\n| `--collectionUrl` or `-c`    | The Team Collection URL, e.g.: `tfs.yourserver.ch/DefaultCollection`\n| `--auth` or `-a`             | The authentication method, option values: `ntlm`, `oauth`, `basic`, `azureactivedirectory`\n| `--user` or `-u`             | The user for authentication (optional for PAT authentication, or for `ntlm` authentication with current user)\n| `--password` or `-p`         | The password or PAT for the authentication (optional for `ntlm` authentication with current user)\n| `--verbosity` or `-v`        | Sets the log4net root level, option values: `info`, `debug`, `warn`, `error` (optional, default is `info`)\n| `--in` or `-i`               | the input JSON settings file (Multiple files can be specified with the delimiter: `;`. These files will be merged.)\n\n### Input file\n\nPolicy definitions are stored in the input file, which can be defined globally, global for a project,\nglobal for a repository, global for specific branches, global for specific branches in a project,\nand for specific branches in a repository.\nIt is possible to ignore policies during the simulation or execution run, if some of them are set\nor handled manually on the UI. Use the `ignoreTypes` section for that.\nFor project, repository and type definitions, both ids and entity names can be used to ease the\nsetting of the rules.\n\nAzure DevOps stores the policies only on project level, nevertheless the tool gathers every definition and\ntakes and sets the most specific for a repository and type, meaning, first a branch and repository\nspecific, then, if that does not exist, a branch specific global policy. It applies then the\nnon-branch specific policies, the order is repository, then project specific, then global. The tool\ngoes through each and every repository in every project in the specified team collection and\nupdates it (if the rule is different, otherwise the rule won't be touched), creates the rule, or\ndeletes it, if it's not defined int the JSON file!\n\n\u003e Note:\n\u003e Do not define the `isEnabled` and `isDeleted` flags, these will be automatically set by the tool,\n\u003e and would lead to endless updates due to permanent difference!\n\nThere are types which can be used more then once on a repository (like `Status`), and defers only in\nsome sort of subtype. There is a possibility to specify these subtypes with the `subTypePropertyName`\nand `subTypePropertyValue` properties in the definition, besides this, these policy definitions\ncan also be set hierarchically.\n\n\u003e Note:\n\u003e At creation or the scope property in the definition, if defined will be removed and set by the tool,\n\u003e also, if the subType feature is used, this property will be overriden by the tool. For comparison\n\u003e these properties are ignored.\n\nThe tool has been built defensive, meaning, deletion is not allowed by default. If you want to\nenable this functionality, set the `allowDeletion` property to `true`. (The property is optional,\ndefault is `false`)\n\nIf the tool should only touch specific project(s) or repository(ies), the restriction should be\nadded to the `applyTo` section of the yaml file. (The section and its properties is optional, can\nbe removed, if not needed.)\n\n#### Input file example\n\n```json\n{\n  \"allowDeletion\":  false,\n  \"ignoreTypes\": [\n    \"Status\"\n  ],\n  \"applyTo\": {\n    \"projects\": [],\n    \"repositories\": []\n  },\n  \"policies\": [\n    {\n        \"type\": \"Minimum number of reviewers\",\n\n        \"project\": \"\",\n        \"branch\": \"\",\n        \"repository\": \"\",\n\n        \"isBlocking\": true,\n\n        \"settings\": {\n            \"minimumApproverCount\": 2,\n            \"creatorVoteCounts\": false,\n            \"allowDownvotes\": false,\n            \"resetOnSourcePush\": false\n        }\n    },\n    {\n        \"type\": \"Minimum number of reviewers\",\n\n        \"project\": \"MyProject\",\n        \"branch\": \"\",\n        \"repository\": \"\",\n\n        \"isBlocking\": true,\n\n        \"settings\": {\n            \"minimumApproverCount\": 2,\n            \"creatorVoteCounts\": false,\n            \"allowDownvotes\": false,\n            \"resetOnSourcePush\": false\n        }\n    }\n  ]\n}\n```\n\n#### Global, for every project and repository\n\n```json\n{\n    \"type\": \"Minimum number of reviewers\",\n\n    \"project\": \"\",\n    \"branch\": \"\",\n    \"repository\": \"\",\n\n    \"isBlocking\": true,\n\n    \"settings\": {\n        \"minimumApproverCount\": 2,\n        \"creatorVoteCounts\": false,\n        \"allowDownvotes\": false,\n        \"resetOnSourcePush\": false\n    }\n}\n```\n\n#### Global, for every repository in the \"MyProject\" project\n\n```json\n{\n    \"type\": \"Minimum number of reviewers\",\n\n    \"project\": \"MyProject\",\n    \"branch\": \"\",\n    \"repository\": \"\",\n\n    \"isBlocking\": true,\n\n    \"settings\": {\n        \"minimumApproverCount\": 2,\n        \"creatorVoteCounts\": false,\n        \"allowDownvotes\": false,\n        \"resetOnSourcePush\": false\n    }\n}\n```\n\n#### For a repository (Can be more strict with specifying also a project)\n\n```json\n{\n    \"type\": \"Minimum number of reviewers\",\n\n    \"project\": \"\",\n    \"branch\": \"\",\n    \"repository\": \"MyRepository\",\n\n    \"isBlocking\": true,\n\n    \"settings\": {\n        \"minimumApproverCount\": 2,\n        \"creatorVoteCounts\": false,\n        \"allowDownvotes\": false,\n        \"resetOnSourcePush\": false\n    }\n}\n```\n\n#### Global, for every branch prefixed with the phrase \"release/\"\n\n```json\n{\n    \"type\": \"Require a merge strategy\",\n\n    \"project\": \"\",\n    \"branch\": \"release/*\",\n    \"repository\": \"\",\n\n    \"isBlocking\": true,\n\n    \"settings\": {\n        \"useSquashMerge\":  false\n    }\n}\n```\n\n#### Global, for every \"master\" branch\n\n```json\n{\n    \"type\": \"Require a merge strategy\",\n\n    \"project\": \"\",\n    \"branch\": \"master\",\n    \"matchKind\": \"exact\",\n    \"repository\": \"\",\n\n    \"isBlocking\": true,\n\n    \"settings\": {\n        \"useSquashMerge\":  false\n    }\n}\n```\n\n#### Global, for every \"master\" and \"release\" branch\n\n```json\n{\n    \"type\": \"Require a merge strategy\",\n\n    \"project\": \"\",\n    \"branches\": [\"master\", \"release/*\"],\n    \"matchKind\": \"exact\",\n    \"repository\": \"\",\n\n    \"isBlocking\": true,\n\n    \"settings\": {\n        \"useSquashMerge\":  false\n    }\n}\n```\n\n#### For every feature branch under the \"MyRepository\" repository in the \"MyProject\" project\n\n```json\n{\n    \"type\": \"Require a merge strategy\",\n\n    \"project\": \"MyProject\",\n    \"branch\": \"feature/*\",\n    \"repository\": \"MyRepository\",\n\n    \"isBlocking\": true,\n\n    \"settings\": {\n        \"useSquashMerge\":  false\n    }\n}\n```\n\n#### For every feature branch under the \"MyRepository\" and \"MyRepository2\" repositories in the \"MyProject\" project\n\n```json\n{\n    \"type\": \"Require a merge strategy\",\n\n    \"project\": \"MyProject\",\n    \"branch\": \"feature/*\",\n    \"repositories\": [\"MyRepository\", \"MyRepository2\"],\n\n    \"isBlocking\": true,\n\n    \"settings\": {\n        \"useSquashMerge\":  false\n    }\n}\n```\n\n#### For the master and every feature branch under the \"MyRepository\" and \"MyRepository2\" repositories in the \"MyProject\" project\n\n```json\n{\n    \"type\": \"Require a merge strategy\",\n\n    \"project\": \"MyProject\",\n    \"branches\": [ \"master\", \"feature/*\" ],\n    \"repositories\": [\"MyRepository\", \"MyRepository2\"],\n\n    \"isBlocking\": true,\n\n    \"settings\": {\n        \"useSquashMerge\":  false\n    }\n}\n```\n\n#### Subtype definition\n\n```json\n{\n    \"type\": \"Status\",\n    \"subTypePropertyName\": \"statusName\",\n    \"subTypePropertyValue\": \"work-in-progress\",\n    \"isBlocking\": true,\n    \"settings\": {\n        \"statusGenre\": \"MyGenre\",\n        \"authorId\": \"88148664-b0c6-4fab-bbd8-aae5d3e7d233\",\n        \"invalidateOnSourceUpdate\": false,\n        \"filenamePatterns\": []\n    }\n},\n{\n    \"type\": \"Status\",\n    \"subTypePropertyName\": \"statusName\",\n    \"subTypePropertyValue\": \"pullrequest-title\",\n    \"isBlocking\": true,\n    \"settings\": {\n        \"statusName\": \"pullrequest-title\",\n        \"statusGenre\": \"MyGenre\",\n        \"authorId\": \"88148664-b0c6-4fab-bbd8-aae5d3e7d233\",\n        \"invalidateOnSourceUpdate\": false,\n        \"filenamePatterns\": []\n    }\n}\n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbbtsoftware%2Fazuredevopspolicyconfigurator","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbbtsoftware%2Fazuredevopspolicyconfigurator","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbbtsoftware%2Fazuredevopspolicyconfigurator/lists"}