]>
Commit | Line | Data |
---|---|---|
4eb2baba SB |
1 | # Edk2 Continuous Integration\r |
2 | \r | |
0e3e62fc MK |
3 | This file focuses on information for those working with the `.pytools` directory\r |
4 | directly or interested in lower-level details about how CI works.\r | |
5 | \r | |
6 | If you just want to get started building code, visit\r | |
7 | [Build Instructions](https://github.com/tianocore/tianocore.github.io/wiki/Build-Instruction)\r | |
8 | on the TianoCore wiki.\r | |
9 | \r | |
4eb2baba SB |
10 | ## Basic Status\r |
11 | \r | |
4403bbd7 BB |
12 | | Package | Windows VS2019 (IA32/X64)| Ubuntu GCC (IA32/X64/ARM/AARCH64) | Known Issues |\r |
13 | | :---- | :----- | :---- | :--- |\r | |
2942cb58 | 14 | | ArmPkg | | :heavy_check_mark: |\r |
a4cf1959 | 15 | | ArmPlatformPkg | | :heavy_check_mark: |\r |
4403bbd7 BB |
16 | | ArmVirtPkg | SEE PACKAGE README | SEE PACKAGE README |\r |
17 | | CryptoPkg | :heavy_check_mark: | :heavy_check_mark: | Spell checking in audit mode\r | |
82c65f14 | 18 | | DynamicTablesPkg | | :heavy_check_mark: |\r |
4403bbd7 BB |
19 | | EmbeddedPkg |\r |
20 | | EmulatorPkg | SEE PACKAGE README | SEE PACKAGE README | Spell checking in audit mode\r | |
21 | | FatPkg | :heavy_check_mark: | :heavy_check_mark: |\r | |
22 | | FmpDevicePkg | :heavy_check_mark: | :heavy_check_mark: |\r | |
23 | | IntelFsp2Pkg |\r | |
24 | | IntelFsp2WrapperPkg |\r | |
25 | | MdeModulePkg | :heavy_check_mark: | :heavy_check_mark: | DxeIpl dependency on ArmPkg, Depends on StandaloneMmPkg, Spell checking in audit mode\r | |
26 | | MdePkg | :heavy_check_mark: | :heavy_check_mark: | Spell checking in audit mode\r | |
27 | | NetworkPkg | :heavy_check_mark: | :heavy_check_mark: | Spell checking in audit mode\r | |
28 | | OvmfPkg | SEE PACKAGE README | SEE PACKAGE README | Spell checking in audit mode\r | |
29 | | PcAtChipsetPkg | :heavy_check_mark: | :heavy_check_mark: |\r | |
30 | | SecurityPkg | :heavy_check_mark: | :heavy_check_mark: | Spell checking in audit mode\r | |
31 | | ShellPkg | :heavy_check_mark: | :heavy_check_mark: | Spell checking in audit mode, 3 modules are not being built by DSC\r | |
32 | | SignedCapsulePkg |\r | |
33 | | SourceLevelDebugPkg |\r | |
d8d1f666 | 34 | | StandaloneMmPkg | :heavy_check_mark: | :heavy_check_mark: |\r |
4403bbd7 BB |
35 | | UefiCpuPkg | :heavy_check_mark: | :heavy_check_mark: | Spell checking in audit mode, 2 binary modules not being built by DSC\r |
36 | | UefiPayloadPkg |\r | |
37 | | UnitTestFrameworkPkg | :heavy_check_mark: | :heavy_check_mark: |\r | |
4eb2baba SB |
38 | \r |
39 | For more detailed status look at the test results of the latest CI run on the\r | |
40 | repo readme.\r | |
41 | \r | |
42 | ## Background\r | |
43 | \r | |
44 | This Continuous integration and testing infrastructure leverages the TianoCore EDKII Tools PIP modules:\r | |
45 | [library](https://pypi.org/project/edk2-pytool-library/) and\r | |
46 | [extensions](https://pypi.org/project/edk2-pytool-extensions/) (with repos\r | |
47 | located [here](https://github.com/tianocore/edk2-pytool-library) and\r | |
48 | [here](https://github.com/tianocore/edk2-pytool-extensions)).\r | |
49 | \r | |
50 | The primary execution flows can be found in the\r | |
51 | `.azurepipelines/Windows-VS2019.yml` and `.azurepipelines/Ubuntu-GCC5.yml`\r | |
52 | files. These YAML files are consumed by the Azure Dev Ops Build Pipeline and\r | |
53 | dictate what server resources should be used, how they should be configured, and\r | |
54 | what processes should be run on them. An overview of this schema can be found\r | |
55 | [here](https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema?view=azure-devops&tabs=schema).\r | |
56 | \r | |
57 | Inspection of these files reveals the EDKII Tools commands that make up the\r | |
58 | primary processes for the CI build: 'stuart_setup', 'stuart_update', and\r | |
59 | 'stuart_ci_build'. These commands come from the EDKII Tools PIP modules and are\r | |
60 | configured as described below. More documentation on the tools can be\r | |
61 | found [here](https://github.com/tianocore/edk2-pytool-extensions/blob/master/docs/using.md)\r | |
62 | and [here](https://github.com/tianocore/edk2-pytool-extensions/blob/master/docs/features/feature_invocables.md).\r | |
63 | \r | |
64 | ## Configuration\r | |
65 | \r | |
66 | Configuration of the CI process consists of (in order of precedence):\r | |
67 | \r | |
68 | * command-line arguments passed in via the Pipeline YAML\r | |
69 | * a per-package configuration file (e.g. `<package-name>.ci.yaml`) that is\r | |
70 | detected by the CI system in EDKII Tools.\r | |
71 | * a global configuration Python module (e.g. `CISetting.py`) passed in via the\r | |
72 | command-line\r | |
73 | \r | |
74 | The global configuration file is described in\r | |
75 | [this readme](https://github.com/tianocore/edk2-pytool-extensions/blob/master/docs/usability/using_settings_manager.md)\r | |
76 | from the EDKII Tools documentation. This configuration is written as a Python\r | |
77 | module so that decisions can be made dynamically based on command line\r | |
78 | parameters and codebase state.\r | |
79 | \r | |
80 | The per-package configuration file can override most settings in the global\r | |
81 | configuration file, but is not dynamic. This file can be used to skip or\r | |
82 | customize tests that may be incompatible with a specific package. Each test generally requires\r | |
83 | per package configuration which comes from this file.\r | |
84 | \r | |
85 | ## Running CI locally\r | |
86 | \r | |
87 | The EDKII Tools environment (and by extension the ci) is designed to support\r | |
0358c0bf | 88 | easily and consistently running locally and in a cloud ci environment. To do\r |
4eb2baba SB |
89 | that a few steps should be followed. Details of EDKII Tools can be found in the\r |
90 | [docs folder here](https://github.com/tianocore/edk2-pytool-extensions/tree/master/docs)\r | |
91 | \r | |
4eb2baba SB |
92 | ### Running CI\r |
93 | \r | |
0e3e62fc MK |
94 | Quick notes:\r |
95 | \r | |
96 | * By default all CI plugins are opted in.\r | |
97 | * Setting the plugin to `skip` as an argument will skip running the plugin.\r | |
98 | Examples:\r | |
99 | * `CompilerPlugin=skip` skip the build test\r | |
100 | * `GuidCheck=skip` skip the Guid check\r | |
101 | * `SpellCheck=skip` skip the spell checker\r | |
102 | * etc.\r | |
103 | * Detailed reports and logs per package are captured in the `Build` directory.\r | |
4eb2baba SB |
104 | \r |
105 | ## Current PyTool Test Capabilities\r | |
106 | \r | |
107 | All CI tests are instances of EDKII Tools plugins. Documentation on the plugin\r | |
108 | system can be found [here](https://github.com/tianocore/edk2-pytool-extensions/blob/master/docs/usability/using_plugin_manager.md)\r | |
109 | and [here](https://github.com/tianocore/edk2-pytool-extensions/blob/master/docs/features/feature_plugin_manager.md).\r | |
110 | Upon invocation, each plugin will be passed the path to the current package\r | |
111 | under test and a dictionary containing its targeted configuration, as assembled\r | |
112 | from the command line, per-package configuration, and global configuration.\r | |
113 | \r | |
114 | Note: CI plugins are considered unique from build plugins and helper plugins,\r | |
115 | even though some CI plugins may execute steps of a build.\r | |
116 | \r | |
117 | In the example, these plugins live alongside the code under test (in the\r | |
118 | `.pytool/Plugin` directory), but may be moved to the 'edk2-test' repo if that\r | |
119 | location makes more sense for the community.\r | |
120 | \r | |
121 | ### Module Inclusion Test - DscCompleteCheck\r | |
122 | \r | |
4403bbd7 BB |
123 | This scans all INF files from a package and confirms they are\r |
124 | listed in the package level DSC file. The test considers it an error if any INF\r | |
125 | does not appear in the `Components` section of the package-level DSC (indicating\r | |
126 | that it would not be built if the package were built). This is critical because\r | |
127 | much of the CI infrastructure assumes that all modules will be listed in the DSC\r | |
128 | and compiled.\r | |
129 | \r | |
130 | This test will ignore INFs in the following cases:\r | |
131 | \r | |
132 | 1. When `MODULE_TYPE` = `HOST_APPLICATION`\r | |
133 | 2. When a Library instance **only** supports the `HOST_APPLICATION` environment\r | |
134 | \r | |
135 | ### Host Module Inclusion Test - HostUnitTestDscCompleteCheck\r | |
136 | \r | |
137 | This test scans all INF files from a package for those related to host\r | |
138 | based unit tests and confirms they are listed in the unit test DSC file for the package.\r | |
139 | The test considers it an error if any INF meeting the requirements does not appear\r | |
140 | in the `Components` section of the unit test DSC. This is critical because\r | |
141 | much of the CI infrastructure assumes that modules will be listed in the DSC\r | |
142 | and compiled.\r | |
143 | \r | |
144 | This test will only require INFs in the following cases:\r | |
145 | \r | |
146 | 1. When `MODULE_TYPE` = `HOST_APPLICATION`\r | |
147 | 2. When a Library instance explicitly supports the `HOST_APPLICATION` environment\r | |
4eb2baba SB |
148 | \r |
149 | ### Code Compilation Test - CompilerPlugin\r | |
150 | \r | |
151 | Once the Module Inclusion Test has verified that all modules would be built if\r | |
152 | all package-level DSCs were built, the Code Compilation Test simply runs through\r | |
153 | and builds every package-level DSC on every toolchain and for every architecture\r | |
154 | that is supported. Any module that fails to build is considered an error.\r | |
155 | \r | |
4403bbd7 BB |
156 | ### Host Unit Test Compilation and Run Test - HostUnitTestCompilerPlugin\r |
157 | \r | |
158 | A test that compiles the dsc for host based unit test apps.\r | |
159 | On Windows this will also enable a build plugin to execute that will run the unit tests and verify the results.\r | |
160 | \r | |
161 | These tools will be invoked on any CI\r | |
162 | pass that includes the NOOPT target. In order for these tools to do their job,\r | |
163 | the package and tests must be configured in a particular way...\r | |
164 | \r | |
165 | #### Including Host-Based Tests in the Package YAML\r | |
166 | \r | |
167 | For example, looking at the `MdeModulePkg.ci.yaml` config file, there are two\r | |
168 | config options that control HostBased test behavior:\r | |
169 | \r | |
170 | ```json\r | |
171 | ## options defined .pytool/Plugin/HostUnitTestCompilerPlugin\r | |
172 | "HostUnitTestCompilerPlugin": {\r | |
173 | "DscPath": "Test/MdeModulePkgHostTest.dsc"\r | |
174 | },\r | |
175 | ```\r | |
176 | \r | |
177 | This option tell the test builder to run. The test builder needs to know which\r | |
178 | modules in this package are host-based tests, so that DSC path is provided.\r | |
179 | \r | |
180 | #### Configuring the HostBased DSC\r | |
181 | \r | |
182 | The HostBased DSC for `MdeModulePkg` is located at\r | |
183 | `MdeModulePkg/Test/MdeModulePkgHostTest.dsc`.\r | |
184 | \r | |
185 | To add automated host-based unit test building to a new package, create a\r | |
186 | similar DSC. The new DSC should make sure to have the `NOOPT` BUILD_TARGET\r | |
187 | and should include the line:\r | |
188 | \r | |
189 | ```\r | |
190 | !include UnitTestFrameworkPkg/UnitTestFrameworkPkgHost.dsc.inc\r | |
191 | ```\r | |
192 | \r | |
193 | All of the modules that are included in the `Components` section of this\r | |
194 | DSC should be of type HOST_APPLICATION.\r | |
195 | \r | |
4eb2baba SB |
196 | ### GUID Uniqueness Test - GuidCheck\r |
197 | \r | |
198 | This test works on the collection of all packages rather than an individual\r | |
199 | package. It looks at all FILE_GUIDs and GUIDs declared in DEC files and ensures\r | |
200 | that they are unique for the codebase. This prevents, for example, accidental\r | |
201 | duplication of GUIDs when using an existing INF as a template for a new module.\r | |
202 | \r | |
203 | ### Cross-Package Dependency Test - DependencyCheck\r | |
204 | \r | |
205 | This test compares the list of all packages used in INFs files for a given\r | |
206 | package against a list of "allowed dependencies" in plugin configuration for\r | |
207 | that package. Any module that depends on a disallowed package will cause a test\r | |
208 | failure.\r | |
209 | \r | |
210 | ### Library Declaration Test - LibraryClassCheck\r | |
211 | \r | |
212 | This test scans at all library header files found in the `Library` folders in\r | |
213 | all of the package's declared include directories and ensures that all files\r | |
214 | have a matching LibraryClass declaration in the DEC file for the package. Any\r | |
215 | missing declarations will cause a failure.\r | |
216 | \r | |
217 | ### Invalid Character Test - CharEncodingCheck\r | |
218 | \r | |
219 | This test scans all files in a package to make sure that there are no invalid\r | |
220 | Unicode characters that may cause build errors in some character\r | |
221 | sets/localizations.\r | |
222 | \r | |
223 | ### Spell Checking - cspell\r | |
224 | \r | |
225 | This test runs a spell checker on all files within the package. This is done\r | |
226 | using the NodeJs cspell tool. For details check `.pytool/Plugin/SpellCheck`.\r | |
227 | For this plugin to run during ci you must install nodejs and cspell and have\r | |
228 | both available to the command line when running your CI.\r | |
229 | \r | |
230 | Install\r | |
231 | \r | |
232 | * Install nodejs from https://nodejs.org/en/\r | |
233 | * Install cspell\r | |
234 | 1. Open cmd prompt with access to node and npm\r | |
235 | 2. Run `npm install -g cspell`\r | |
236 | \r | |
237 | More cspell info: https://github.com/streetsidesoftware/cspell\r | |
238 | \r | |
ec9683ec PG |
239 | ### License Checking - LicenseCheck\r |
240 | \r | |
241 | Scans all new added files in a package to make sure code is contributed under\r | |
242 | BSD-2-Clause-Patent.\r | |
243 | \r | |
244 | ### Ecc tool - EccCheck\r | |
245 | \r | |
246 | Run the Ecc tool on the package. The Ecc tool is available in the BaseTools\r | |
247 | package. It checks that the code complies to the EDKII coding standard.\r | |
248 | \r | |
dc453b51 MK |
249 | ### Coding Standard Compliance - UncrustifyCheck\r |
250 | \r | |
251 | Runs the Uncrustify application to check for coding standard compliance issues.\r | |
252 | \r | |
4eb2baba SB |
253 | ## PyTool Scopes\r |
254 | \r | |
255 | Scopes are how the PyTool ext_dep, path_env, and plugins are activated. Meaning\r | |
256 | that if an invocable process has a scope active then those ext_dep and path_env\r | |
257 | will be active. To allow easy integration of PyTools capabilities there are a\r | |
258 | few standard scopes.\r | |
259 | \r | |
260 | | Scope | Invocable | Description |\r | |
261 | | :---- | :----- | :---- |\r | |
262 | | global | edk2_invocable++ - should be base_abstract_invocable | Running an invocables |\r | |
263 | | global-win | edk2_invocable++ | Running on Microsoft Windows |\r | |
264 | | global-nix | edk2_invocable++ | Running on Linux based OS |\r | |
265 | | edk2-build | | This indicates that an invocable is building EDK2 based UEFI code |\r | |
266 | | cibuild | set in .pytool/CISettings.py | Suggested target for edk2 continuous integration builds. Tools used for CiBuilds can use this scope. Example: asl compiler |\r | |
4403bbd7 BB |
267 | | host-based-test | set in .pytool/CISettings.py | Turns on the host based tests and plugin |\r |
268 | | host-test-win | set in .pytool/CISettings.py | Enables the host based test runner for Windows |\r | |
4eb2baba SB |
269 | \r |
270 | ## Future investments\r | |
271 | \r | |
272 | * PatchCheck tests as plugins\r | |
273 | * MacOS/xcode support\r | |
274 | * Clang/LLVM support\r | |
275 | * Visual Studio AARCH64 and ARM support\r | |
276 | * BaseTools C tools CI/PR and binary release process\r | |
277 | * BaseTools Python tools CI/PR process\r | |
4eb2baba | 278 | * Extensible private/closed source platform reporting\r |
4eb2baba SB |
279 | * UEFI SCTs\r |
280 | * Other automation\r |