{"id":15022208,"url":"https://github.com/kinsondigital/branchvalidator","last_synced_at":"2025-04-12T06:16:59.011Z","repository":{"id":40554767,"uuid":"405361454","full_name":"KinsonDigital/BranchValidator","owner":"KinsonDigital","description":"Validates branch names for the organization projects","archived":false,"fork":false,"pushed_at":"2024-04-11T22:36:45.000Z","size":672,"stargazers_count":4,"open_issues_count":20,"forks_count":1,"subscribers_count":1,"default_branch":"preview","last_synced_at":"2024-04-15T07:23:40.532Z","etag":null,"topics":["action","actions","github-actions","github-actions-ci","hacktoberfest"],"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/KinsonDigital.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null},"funding":{"github":"KinsonDigital"}},"created_at":"2021-09-11T11:30:18.000Z","updated_at":"2024-02-01T18:20:08.000Z","dependencies_parsed_at":"2023-12-20T17:05:42.055Z","dependency_job_id":"aac9c044-4598-47a7-88e5-24ac43f6f52d","html_url":"https://github.com/KinsonDigital/BranchValidator","commit_stats":{"total_commits":357,"total_committers":4,"mean_commits":89.25,"dds":0.3221288515406162,"last_synced_commit":"7a3483e842a5ee77e13ffb17f47572d96dc16d2a"},"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/KinsonDigital%2FBranchValidator","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/KinsonDigital%2FBranchValidator/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/KinsonDigital%2FBranchValidator/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/KinsonDigital%2FBranchValidator/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/KinsonDigital","download_url":"https://codeload.github.com/KinsonDigital/BranchValidator/tar.gz/refs/heads/preview","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":219848753,"owners_count":16556331,"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","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":["action","actions","github-actions","github-actions-ci","hacktoberfest"],"created_at":"2024-09-24T19:57:38.642Z","updated_at":"2024-10-14T04:20:40.942Z","avatar_url":"https://github.com/KinsonDigital.png","language":"C#","funding_links":["https://github.com/sponsors/KinsonDigital"],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n\n  ![BranchingDiagram](https://raw.githubusercontent.com/KinsonDigital/BranchValidator/preview/Images/branchvalidator-logo-darkmode.png#gh-dark-mode-only)\n  ![BranchingDiagram](https://raw.githubusercontent.com/KinsonDigital/BranchValidator/preview/Images/branchvalidator-logo-lightmode.png#gh-light-mode-only)  \n  \u003cbr /\u003e\n\u003c/div\u003e\n\n\u003ch1 align=\"center\"\u003e\n\n**Branch Validator**\n\u003c/h1\u003e\n\n\u003cdiv align=\"center\"\u003e\n\n[![Build PR Status Check](https://img.shields.io/github/actions/workflow/status/KinsonDigital/BranchValidator/build-status-check.yml?label=%E2%9A%99%EF%B8%8FBuild)](https://github.com/KinsonDigital/BranchValidator/actions/workflows/build-status-check.yml)\n[![Unit Test PR Status Check](https://img.shields.io/github/actions/workflow/status/KinsonDigital/BranchValidator/unit-test-status-check.yml?label=%F0%9F%A7%AATests)](https://github.com/KinsonDigital/BranchValidator/actions/workflows/unit-test-status-check.yml)\n\n![Codecov](https://img.shields.io/codecov/c/github/KinsonDigital/BranchValidator?color=2F8840\u0026label=Code%20Coverage\u0026logo=codecov)\n\n[![Good First GitHub Issues](https://img.shields.io/github/issues/kinsondigital/BranchValidator/good%20first%20issue?color=7057ff\u0026label=Good%20First%20Issues)](https://github.com/KinsonDigital/BranchValidator/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22)\n[![Discord](https://img.shields.io/discord/481597721199902720?color=%23575CCB\u0026label=chat%20on%20discord\u0026logo=discord\u0026logoColor=white)](https://discord.gg/qewu6fNgv7)\n\n\u003c/div\u003e\n\n\u003cdiv align=\"center\"\u003e\n\n## **🤷🏼‍♂️ What is it? 🤷🏼‍♂️**\n\u003c/div\u003e\n\n\nThis **GitHub Action** can be used to check whether or not GIT branch names are valid using an expression in combination with glob syntax. \nThese expressions are functions that can be used in combination with **\u0026\u0026** and **||** logic to perform the validation.\n\n\u003cdetails closed\u003e\u003csummary\u003e\u003cb\u003eTLDR\u003c/b\u003e - Additional Information\u003c/summary\u003e\n\nWhat it really comes down to is enforcing branch \nnames and structure. In CI/CD systems, the name of the branch can determine how the system runs. The workflows \nyou have might depend on the name of a branch. For example, if the branch uses the GitHub issue number as part \nof the branch name, it will refer back to the GitHub issue. Your build may behave differently depending on which\nbranch it is building.\n\nWhen incorrect branch names are setup, they can cause issues with your build and release systems and confusion with your team. This GitHub action will help enforce project standards to help keep things running smoothly. For example, a branch name of `my-branch` does not express the purpose of the branch. Without enforcing naming conventions of branches, how is the team supposed to know the purpose of it? In addition, the ability to \nenforce an issue number to exist in the name of a branch, makes it easier for developers to find which branch \nbelongs to which issue. With this kind of enforcement, you can setup automation to trust that the branch name \ncontains a number. It also allows you to create automation to check if a GitHub issue exists, which would prevent\nincorrect issue numbers from being used in a branch name.\n\nThe applications of this GitHub action are endless!!\n\n\u003c/details\u003e\n\n\u003cdiv align=\"center\"\u003e\u003ch2 style=\"font-weight:bold\"\u003e\u003c/h2\u003e\u003c/div\u003e\n\n\u003e**Note** This GitHub action is built using C#/NET and runs in a docker container. If the job step for running this action is contained in a job that runs on **Windows**, you will need to move the step to a job that runs on **Ubuntu**. You can split up your jobs to fulfill `runs-on` requirements of the GitHub action. This can be accomplished by moving the step into its own job. You can then route the action step outputs to the job outputs and use them throughout the rest of your workflow.  \n\u003e For more information on step and job outputs, refer to the GitHub documentation links below:\n\u003e - [Defining outputs for jobs](https://docs.github.com/en/actions/using-jobs/defining-outputs-for-jobs)\n\u003e - [Setting a step action output parameter](https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#setting-an-output-parameter)\n\n\u003cdiv align=\"center\"\u003e\n  \u003ch2 style=\"font-weight:bold\"\u003e🪧 Example 🪧\u003c/h2\u003e\n\u003c/div\u003e\n\n\n```yaml\nname: Branch Validation Sample Workflow\n\non:\n  workflow_dispatch:\n\njobs:\n  Validate_Branch:\n    name: Validator Branch\n    runs-on: ubuntu-latest\n    steps:\n    - uses: actions/checkout@v3\n\n    - name: Validate Branch\n      uses: KinsonDigital/BranchValidator@v1.0.0-preview.4 # Make sure this is the latest version\n      with:\n        branch-name: \"${{ github.ref }}\" # The current branch where the workflow is running.\n        validation-logic: \"equalTo('main')\"\n        trim-from-start: \"refs/heads/\"\n        fail-when-not-valid: true # Optional. Default is true.\n```\n\n\u003cdiv align=\"center\"\u003e\n\n## **➡️ Action Inputs ⬅️**\n\u003c/div\u003e\n\n\u003ctable align=\"center\"\u003e\n    \u003ctr\u003e\n        \u003cth\u003eInput Name\u003c/th\u003e\n        \u003cth\u003eDescription\u003c/th\u003e\n        \u003cth\u003eRequired\u003c/th\u003e\n        \u003cth\u003eDefault Value\u003c/th\u003e\n    \u003c/tr\u003e\n    \u003ctr align=\"left\"\u003e\n        \u003ctd\u003ebranch-name\u003c/td\u003e\n        \u003ctd align=\"left\"\u003eThe name of the GIT branch.\u003c/td\u003e\n        \u003ctd align=\"center\"\u003eyes\u003c/td\u003e\n        \u003ctd align=\"center\"\u003eN/A\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr align=\"left\"\u003e\n        \u003ctd\u003evalidation-logic\u003c/td\u003e\n        \u003ctd align=\"left\"\u003eThe expression used to validate the branch name.\u003c/td\u003e\n        \u003ctd align=\"center\"\u003eyes\u003c/td\u003e\n        \u003ctd align=\"center\"\u003eN/A\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr align=\"left\"\u003e\n        \u003ctd\u003etrim-from-start\u003c/td\u003e\n        \u003ctd align=\"left\"\u003eTrims the text from the beginning of a branch name.\u003c/td\u003e\n        \u003ctd align=\"center\"\u003eno\u003c/td\u003e\n        \u003ctd align=\"center\"\u003eempty\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr align=\"left\"\u003e\n        \u003ctd\u003efail-when-not-valid\u003c/td\u003e\n        \u003ctd align=\"left\"\u003eFails the job if the branch is not valid.\u003c/td\u003e\n        \u003ctd align=\"center\"\u003eno\u003c/td\u003e\n        \u003ctd align=\"center\"\u003etrue\u003c/td\u003e\n    \u003c/tr\u003e    \n\u003c/table\u003e\n\n---\n\n\u003cdiv align=\"center\"\u003e\n\n## **⬅️ Action Outputs ➡️**\n\u003c/div\u003e\n\nThe name of the output is `valid-branch` and it returns a boolean of true or false. Click \u003ca href=\"#manual-fail\"\u003ehere\u003c/a\u003e to see an example of how to use the output of the action.\n\n---\n\n\u003cdiv align=\"center\" style=\"font-weight:bold\"\u003e\n\n## **Validation Logic Expression Functions**\n\u003c/div\u003e\n\nBelow is a small list of the available expression functions that you can use in the value of the `validation-logic` input. \nThese expression functions can be used in combination with the `\u0026\u0026` and `||` operators:  \n  - Example: equalTo('feature/my-*-branch') \u0026\u0026 allLowerCase()\n    - This checks to see whether or not the branch is equal to the value and that the entire branch is lower case.\n\n\u003cdetails closed\u003e\u003csummary\u003e\u003cb\u003eTLDR\u003c/b\u003e - Expression Function List\u003c/summary\u003e\n\n1. `equalTo(string)` - Checks to see whether or not the given branch name is equal to the argument value of the function. The argument value must be a string value that is surrounded by single or double quotes. The quotes used must be the opposite of the quotes used for the entire input value. Standard YAML syntax rules apply. The function value allows the use of 2 characters that provide glob-like behavior. The 2 characters are `#` and `*` and can be used together as many times as needed.\n     - _Example 1:_ `equalTo('main')`\n       - Checks whether or not the branch is equal to the value of `main`.\n     - _Example 2:_ `equalTo('feature/my-*-branch')`\n       - Checks whether or not the branch starts with the value `feature/my-` and that it ends with `-branch`. Anything is acceptable between the beginning and end of the branch where the `*` character is located. This should be a familiar concept to other systems and uses of this type of syntax.\n     - _Example 3:_ `equalTo('feature/#-sample-branch')`\n       - Returns valid if the branch name was `feature/my-sample-branch`. This checks whether or not the branch starts with the value `feature/` and ends with the value `-sample-branch`. Any text between the start and the end will be checked to see if it is a whole number of any digit size.\n         - Returns valid if the name of the branch was `feature/12-sample-branch` or `feature/12345-sample-branch`.\n         - Return as not valid if the name of the branch was `feature/10-20-sample-branch`. In this example, the branch ends with the value `-20-sample-branch`, not `-sample-branch`.\n     - _Example 4:_ `equalTo('release/v#.#.#-*.#')`\n       - Returns valid if the branch name was `release/v1.2.3-preview.4`.\n2. `allLowerCase()` - Checks whether or not the branch name is all lower case.\n    - _Example 1:_ `allLowerCase()`\n      - Returns valid if the name of the branch was _**all-lower-case**_. This would return invalid if the name of the branch was _**not-all-LOWER-case**_. \n3. `allUpperCase()` - Checks whether or not if the branch name is all upper case.\n    - _Example 1:_ `allUpperCase()`\n      - Returns valid if the name of the branch was _**ALL-UPPER-CASE**_. This would return invalid if the name of the branch was _**NOT-ALL-upper-CASE**_.\n\u003c/details\u003e\n\n\u003cdiv align=\"center\" style=\"font-weight:bold\"\u003e\n\n\u003cbr\u003e\n\n## **🪧 More Examples 🪧**\n\u003c/div\u003e\n\n\u003cdiv align=\"left\"\u003e\n\nThe workflow fails when the feature branch does not start with the value `feature/`,\nfollowed by a number and a hyphen, ends with any text, and is all lower case:\n\n```yaml\nname: Branch Validation Sample Workflow\n\non:\n  workflow_dispatch:\n\njobs:\n  Validate_Feature_Branch:\n    name: Validate Feature Branch\n    runs-on: ubuntu-latest\n    steps:\n    - uses: actions/checkout@v3\n\n    - name: Validate Branch\n      uses: KinsonDigital/BranchValidator@v1.0.0-preview.1\n      with:\n        branch-name: \"feature/123-my-branch\"\n        validation-logic: \"equalTo('feature/#-*') \u0026\u0026 allLowerCase()\"\n        fail-when-not-valid: true # Optional. Default is true.\n```\n\u003c/div\u003e\n\n\u003ch4 id=\"manual-fail\"\u003eFailing the workflow manually:\u003c/h4\u003e\n\n``` yaml\nname: Branch Validation Sample Workflow\n\non:\n  workflow_dispatch:\n\njobs:\n  Validate_Feature_Branch:\n    name: Validate Feature Branch\n    runs-on: ubuntu-latest\n    steps:\n    - uses: actions/checkout@v3\n\n    - name: Validate Branch\n      id: validate-branch\n      uses: KinsonDigital/BranchValidator@v1.0.0-preview.1\n      with:\n        branch-name: \"release/v1.2.3-preview\" # Missing the text '.4' at the end of the branch\n        validation-logic: \"equalTo('release/v#.#.#-preview.#')\"\n        fail-when-not-valid: false # This step will not fail the workflow\n\n    - name: Fail Workflow # But this step will fail the workflow instead.\n      if: ${{ steps.validate-branch.outputs.valid-branch }} = 'false'\n      run: |\n        Write-Host \"::error::The branch is invalid!!\";\n        exit 1; # Fail the workflow\n```\n\n---\n\n\u003ch2 style=\"font-weight:bold;\" align=\"center\"\u003e🙏🏼 Contributing 🙏🏼\u003c/h2\u003e\n\nInterested in contributing? If so, click [here](https://github.com/KinsonDigital/.github/blob/main/docs/CONTRIBUTING.md) to learn how to contribute your time or [here](https://github.com/sponsors/KinsonDigital) if you are interested in contributing your funds via one-time or recurring donation.\n\n\u003cdiv align=\"center\"\u003e\n\n## **🔧 Maintainers 🔧**\n\u003c/div\u003e\n\n![x-logo-dark-mode](https://raw.githubusercontent.com/KinsonDigital/.github/main/Images/x-logo-16x16-dark-mode.svg#gh-dark-mode-only)\n![x-logo-light-mode](https://raw.githubusercontent.com/KinsonDigital/.github/main/Images/x-logo-16x16-light-mode.svg#gh-light-mode-only)\n[Calvin Wilkinson](https://twitter.com/KDCoder) (KinsonDigital GitHub Organization - Owner)\n\n\n![x-logo-dark-mode](https://raw.githubusercontent.com/KinsonDigital/.github/main/Images/x-logo-16x16-dark-mode.svg#gh-dark-mode-only)\n![x-logo-light-mode](https://raw.githubusercontent.com/KinsonDigital/.github/main/Images/x-logo-16x16-light-mode.svg#gh-light-mode-only)\n[Kristen Wilkinson](https://twitter.com/kswilky) (KinsonDigital GitHub Organization - Project Management, Documentation, Tester)\n \n\u003cbr\u003e\n\n\u003ch2 style=\"font-weight:bold;\" align=\"center\"\u003e🚔 Licensing And Governance 🚔\u003c/h2\u003e\n\n\u003cdiv align=\"center\"\u003e\n\n[![Contributor Covenant](https://img.shields.io/badge/Contributor%20Covenant-2.1-4baaaa.svg?style=flat)](https://github.com/KinsonDigital/.github/blob/main/docs/code_of_conduct.md)\n[![GitHub](https://img.shields.io/github/license/kinsondigital/branchvalidator)](https://github.com/KinsonDigital/BranchValidator/blob/preview/LICENSE.md)  \n\u003c/div\u003e\n\n\nThis software is distributed under the very permissive MIT license and all dependencies are distributed under MIT-compatible licenses.\nThis project has adopted the code of conduct defined by the **Contributor Covenant** to clarify expected behavior in our community.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkinsondigital%2Fbranchvalidator","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkinsondigital%2Fbranchvalidator","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkinsondigital%2Fbranchvalidator/lists"}