|
| 1 | +# Repository Remote Check - Pre-Build Git Repository Validation Plugin |
| 2 | + |
| 3 | +This plugin validates git repositories against remote commit criteria before the build starts. It allows you to define |
| 4 | +rules that check whether the current HEAD commit in specified repositories is present or absent in specified remote |
| 5 | +URLs. |
| 6 | + |
| 7 | +This is useful for enforcing that your local repositories are using commits from the correct upstream sources, and |
| 8 | +not from incompatible forks or remotes. For example, some workspaces might use a "public" and an "internal" upstream |
| 9 | +and need to verify that both work as expected when used for a given platform build. |
| 10 | + |
| 11 | +**Important**: |
| 12 | + |
| 13 | +- This check verifies commit hashes. Therefore, the hashes will need to be consistent between the two repositories |
| 14 | + being compared. |
| 15 | +- This plugin is enabled by adding the `remote_repo_check` scope to the scopes reported by the platform in |
| 16 | + `GetActiveScopes()`. It is NOT enabled by default (i.e. it does not use the `global` scope). |
| 17 | + |
| 18 | +## Integration Instructions |
| 19 | + |
| 20 | +This plugin serves a special purpose so it is not enabled by default. As mentioned above, it is enabled by activating |
| 21 | +the `remote_repo_check` scope. You can enable only running this plugin in a server-side CI build, by adding the |
| 22 | +following logic to the `GetActiveScopes()` implementation: |
| 23 | + |
| 24 | +```python |
| 25 | + # Add remote_repo_check scope if running in server CI. |
| 26 | + # - TF_BUILD is set by Azure DevOps pipelines |
| 27 | + # - GITHUB_ACTIONS is set in GitHub workflow execution |
| 28 | + if os.environ.get('TF_BUILD') or os.environ.get('GITHUB_ACTIONS'): |
| 29 | + ps.extend(['remote_repo_check']) |
| 30 | +``` |
| 31 | + |
| 32 | +This is recommended to allow developers to customize the repo (e.g. submodule) as needed locally while developing and |
| 33 | +testing. |
| 34 | + |
| 35 | +## Configuration |
| 36 | + |
| 37 | +The plugin can be configured via a YAML or JSON configuration file. The configuration file path can be provided in two |
| 38 | +ways: |
| 39 | + |
| 40 | +1. **Command line**: `REPO_REMOTE_CHECK_CONFIG_PATH=<PATH>` |
| 41 | +2. **PlatformBuild.py**: In the `SetPlatformEnv()` method: |
| 42 | + |
| 43 | + ```python |
| 44 | + self.env.SetValue("REPO_REMOTE_CHECK_CONFIG_PATH", <PATH>, "Platform Hardcoded") |
| 45 | + ``` |
| 46 | + |
| 47 | +If no configuration path is provided, the plugin looks for `RepoRemoteCheckConfig.yml` in the workspace root. If this |
| 48 | +file is not found, the plugin exits successfully and does not perform any validation. |
| 49 | + |
| 50 | +## Configuration File Format |
| 51 | + |
| 52 | +The configuration file defines a list of repositories and their validation conditions for the current `HEAD` commit |
| 53 | +in that repository path. |
| 54 | + |
| 55 | +### YAML Example |
| 56 | + |
| 57 | +```yaml |
| 58 | +repositories: |
| 59 | + - path: "Common/MU_BASECORE" |
| 60 | + conditions: |
| 61 | + - type: "present_in_remote" |
| 62 | + remote: "https://github.com/microsoft/mu_basecore.git" |
| 63 | + - type: "not_present_in_remote" |
| 64 | + remote: "https://github.com/tianocore/edk2.git" |
| 65 | + |
| 66 | + - path: "Silicon/INTEL/IntelSiliconPkg" |
| 67 | + conditions: |
| 68 | + - type: "present_in_remote" |
| 69 | + remote: "https://github.com/tianocore/edk2-platforms.git" |
| 70 | +``` |
| 71 | +
|
| 72 | +### JSON Example |
| 73 | +
|
| 74 | +```json |
| 75 | +{ |
| 76 | + "repositories": [ |
| 77 | + { |
| 78 | + "path": "Common/MU_BASECORE", |
| 79 | + "conditions": [ |
| 80 | + { |
| 81 | + "type": "present_in_remote", |
| 82 | + "remote": "https://github.com/microsoft/mu_basecore.git" |
| 83 | + }, |
| 84 | + { |
| 85 | + "type": "not_present_in_remote", |
| 86 | + "remote": "https://github.com/tianocore/edk2.git" |
| 87 | + } |
| 88 | + ] |
| 89 | + }, |
| 90 | + { |
| 91 | + "path": "Silicon/INTEL/IntelSiliconPkg", |
| 92 | + "conditions": [ |
| 93 | + { |
| 94 | + "type": "present_in_remote", |
| 95 | + "remote": "https://github.com/tianocore/edk2-platforms.git" |
| 96 | + } |
| 97 | + ] |
| 98 | + } |
| 99 | + ] |
| 100 | +} |
| 101 | +``` |
| 102 | + |
| 103 | +## Configuration Keys |
| 104 | + |
| 105 | +### Top Level |
| 106 | + |
| 107 | +- **repositories** (required): A list of repository configurations |
| 108 | + |
| 109 | +### Repository Level |
| 110 | + |
| 111 | +- **path** (required): Relative path from workspace root to the repository directory |
| 112 | +- **conditions** (optional): A list of conditions to check against this repository |
| 113 | + |
| 114 | +### Condition Level |
| 115 | + |
| 116 | +- **type** (required): The type of check to perform. Valid values are: |
| 117 | + - `present_in_remote`: Verifies that the current `HEAD` commit exists in the specified remote |
| 118 | + - `not_present_in_remote`: Verifies that the current `HEAD` commit does NOT exist in the specified remote |
| 119 | +- **remote** (required): The remote git URL to check against |
| 120 | + |
| 121 | +## How It Works |
| 122 | + |
| 123 | +1. The plugin reads the configuration file |
| 124 | +2. For each repository in the configuration: |
| 125 | + - Validates that the repository path exists |
| 126 | + - Validates that the path is a git repository |
| 127 | + - Gets the current `HEAD` commit SHA in the local repository |
| 128 | + - Evaluates each condition for the repository path |
| 129 | + - Validates that the result matches the condition type |
| 130 | +3. Returns success (`0`) if all conditions pass, failure (`1`) if any condition |
| 131 | + fails |
| 132 | + |
| 133 | +**Note:** The plugin checks if a commit is *reachable* from any branch in the |
| 134 | +remote repository. This means the commit must exist in the remote's history and |
| 135 | +be part of at least one branch. Commits that exist in the remote but are not |
| 136 | +part of any branch (orphaned commits, dangling commits) will not be detected. |
| 137 | + |
| 138 | +## Common Errors |
| 139 | + |
| 140 | +### Repository path does not exist: \<path\> |
| 141 | + |
| 142 | +The specified repository path does not exist in the workspace. Check that: |
| 143 | + |
| 144 | +- The path is correct and relative to the workspace root |
| 145 | +- The repository has been cloned/initialized |
| 146 | +- Stuart dependencies have been fetched |
| 147 | + |
| 148 | +### Path is not a valid git repository: \<path\> |
| 149 | + |
| 150 | +The specified path exists but is not a git repository. Ensure: |
| 151 | + |
| 152 | +- The path points to a directory containing a `.git` folder |
| 153 | +- The repository was properly initialized |
| 154 | + |
| 155 | +### CONDITION FAILED: Repository '\<path\>' commit \<sha\> is NOT present in remote '\<url\>' (expected: present) |
| 156 | + |
| 157 | +The current `HEAD` commit in the repository does not exist in the specified remote, |
| 158 | +or is not reachable from any branch in that remote. This could mean: |
| 159 | + |
| 160 | +- You're using a local commit that hasn't been pushed |
| 161 | +- You're using a commit from a different fork |
| 162 | +- The repository is on the wrong branch/commit |
| 163 | +- The commit exists but is not part of any branch (orphaned/dangling commit) |
| 164 | + |
| 165 | +**Solution**: Check the commit history and ensure you're using the correct commit |
| 166 | +from the expected remote. |
| 167 | + |
| 168 | +### CONDITION FAILED: Repository '\<path\>' commit \<sha\> IS present in remote '\<url\>' (expected: not present) |
| 169 | + |
| 170 | +The current `HEAD` commit exists in a remote where it shouldn't, and is reachable |
| 171 | +from at least one branch in that remote. This could mean: |
| 172 | + |
| 173 | +- You're accidentally using commits from an incompatible upstream |
| 174 | +- The repository is tracking the wrong remote |
| 175 | + |
| 176 | +**Solution**: Verify the repository's current state and rebase/reset to the |
| 177 | +correct commit. |
| 178 | + |
| 179 | +### Invalid git remote URL: \<url\> |
| 180 | + |
| 181 | +The specified remote URL is not a valid git repository URL. Check: |
| 182 | + |
| 183 | +- The URL is correct and accessible |
| 184 | +- You have network connectivity |
| 185 | +- Authentication is properly configured if the remote requires it |
0 commit comments