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