Skip to content

Commit 87b7061

Browse files
authored
Add plan for adding source-build to official builds and Arcade (#1489)
* Initial source-build in official build proposal * Edits for review comments
1 parent 5d575d4 commit 87b7061

15 files changed

+1350
-0
lines changed
Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
# Arcade-powered source-build
2+
3+
Source-build existing as a process outside the Microsoft build impedes efforts
4+
to maintain the source-buildability of .NET Core. Integration into the normal
5+
build process is driven by two major goals:
6+
7+
1. When the .NET Core SDK **official build** completes, its artifacts include
8+
validated, ship-ready source-build outputs, in addition to the Microsoft
9+
build outputs.
10+
11+
* **Official builds** produce the signed bits released by Microsoft, running
12+
on a daily or per-commit basis depending on repo and point in time.
13+
14+
* This has two core benefits over the current situation: we know immediately
15+
whether an SDK can be source-built cleanly, and the status is as visible as
16+
an SDK build failure.
17+
18+
* Breaks in source-build can be detected and fixed immediately by repo
19+
owners, just as any other build failure, rather than fixed by source-build
20+
maintainers weeks to months after the fact using patches.
21+
22+
* Microsoft build process owners don't need to reject late build respins
23+
based on manual post-build source-build efforts being projected to not
24+
complete in time for release dates.
25+
26+
* Rebuilding the SDK close to a release day doesn't cause setbacks to
27+
source-build maintainers by throwing away manual build uptake work.
28+
29+
* This eliminates the delay between Microsoft build completion and
30+
source-build tarball availability, as long as we treat a source-build
31+
failure as seriously as a Microsoft build failure.
32+
33+
2. Every repo involved in source-build validates source-buildability in its **PR
34+
validation** build.
35+
36+
* **PR validation** builds run on each pull request submitted to a
37+
repository, and is typically required to succeed to merge. There are also
38+
**rolling builds** that run lower-priority and slower tests after each
39+
merge.
40+
41+
* This allows developers and release owners to understand the source-build
42+
impact of changes, reducing the frequency the source-build servicing team
43+
has to root-cause and patch over problems.
44+
45+
This doc is about where we can start, what incremental progress would look like,
46+
and the vision.
47+
48+
## Starting point: official build
49+
50+
The output of source-build is a set of tarballs that can be used to build the
51+
.NET Core SDK from source. We can move the current behavior of source-build to
52+
the Core-SDK official build. That is, Core-SDK clones all constituent repos,
53+
applies patches, builds each repo using customized build commands, and produces
54+
the source-build tarballs as artifacts.
55+
56+
This immediately makes the dotnet/source-build repo unnecessary: it only held
57+
the source-build orchestration behavior.
58+
59+
This needs more work to meet our goals due to build performance. It is simply
60+
too slow (> 2hrs) to build all constituent repos within one official build. It
61+
needs to be fast enough that it is reasonable for the entire official build to
62+
be rejected when the source-build fails.
63+
64+
> Note: practically, the source-build official build should run in an
65+
> independent build pipeline at first: the long build time would interfere with
66+
> other .NET 5 work if integrated directly.
67+
68+
For more info, see [source-build-in-pipeline.md].
69+
70+
## Starting point: PR validation
71+
72+
We can start here by adding extra jobs that run the standard source-build
73+
command and arguments. This is a simple step to confirm the build isn't
74+
fundamentally broken.
75+
76+
This needs more work to meet our goals for many reasons:
77+
78+
* Prebuilt dependency usage isn't tracked, because all dependencies are
79+
downloaded as non-source-built prebuilts.
80+
* Source-build behavior may not work with source-built upstreams.
81+
* The artifacts built by the repo may not work downstream.
82+
* Advanced build flows aren't checked, such as source-build bootstrap or using
83+
an N-1 SDK.
84+
85+
For more info, see [source-build-in-pipeline.md].
86+
87+
Related work, but not necessary to meet our goals:
88+
89+
* Unit tests are typically disabled in source-build, because test infrastructure
90+
isn't built from source. We should run tests on the source-build product to
91+
catch bugs. However, this isn't necessary to meet the maintainability goals of
92+
this plan.
93+
94+
## Incremental progress
95+
96+
### The performance gap
97+
We need to avoid building all constituent repos in the Core-SDK build. To do
98+
this, each repo needs to produce intermediate source-built artifacts during its
99+
official build, to be consumed by downstream repos. On the other end,
100+
source-build needs to support restoring from an intermediate artifact.
101+
102+
To make incremental progress, we should pick one of Core-SDK's upstreams, and
103+
add source-build functionality that produces source-built intermediates.
104+
Core-SDK should consume them. We should choose a leaf in the source-build
105+
dependency graph, say, Linker. When Core-SDK is looking at the build graph to
106+
determine which repos to build, instead of building Linker, it should restore
107+
the Linker intermediate artifact. Once we have this flow working, the
108+
functionality should be integrated into Arcade SDK for easy onboarding.
109+
110+
Then, working from the bottom (leaves) upward (towards Core-SDK), more repos
111+
should consume and produce source-built intermediates in their official builds.
112+
When this completes, each repo only needs to build itself. See
113+
[incremental-official.md] for more details about this process.
114+
115+
It is possible to instead only implement official source-build in a handful of
116+
repos. This segments the build into chunks, which must be coherent. This idea is
117+
discussed in [incremental-official-chunked.md], and is not recommended.
118+
119+
> Note: some constituent repos aren't maintained by Microsoft, so it isn't
120+
> feasible to add them directly to this flow. We could fork them and set up a
121+
> build just for source-build intermediates. If a repo builds quickly, however,
122+
> it might be better to simply rebuild it whenever the outputs are needed.
123+
124+
### Getting into Arcade
125+
The initial plan to run source-build in Core-SDK doesn't assume any changes to
126+
Arcade: this should be possible due to the extension points that already exist
127+
in the Arcade SDK. Once we have that, it will be clearer what logic is missing,
128+
and how to add it. This allows us to migrate source-build logic incrementally
129+
and in parallel with other work.
130+
131+
For more info, see [in-arcade.md].
132+
133+
### The speculative SDK
134+
It's difficult to validate that a PR won't break downstream repos. This problem
135+
is shared by source-build and the Microsoft build. "Speculative builds" have
136+
been proposed to try to help with this, but would be very difficult to implement
137+
in the Microsoft build. It may be more reasonable in the context of
138+
source-build: all builds happen on a single machine, so the problem is focused
139+
on figuring out a build graph rather than organizing dozens of machines in a
140+
build lab and flowing bits across a network.
141+
142+
This is also necessary in source-build to validate several distro maintenance
143+
scenarios: by making a PR, is it still possible to run a bootstrap build of the
144+
.NET Core SDK? Can .NET Core SDK version N be built using SDK N-1?
145+
146+
This can be developed in parallel to other efforts. See [speculative-build.md]
147+
for more info about speculative builds.
148+
149+
## End result
150+
151+
When all of this is working, the official Microsoft build of the .NET Core SDK
152+
also produces tarballs that distro maintainers can use to build it from source.
153+
Contributors in each repo use checks in PR validation to verify each change is
154+
compatible with source-build requirements, and if validation runs into a
155+
problem, they are able to reproduce the build locally using an Arcade build
156+
command.
157+
158+
---
159+
160+
## Q&A
161+
162+
### Q: How do we patch without an orchestration-focused repo?
163+
A: We shouldn't! But if we have to, use a forked branch. See
164+
[patching.md](patching.md).
165+
166+
167+
[in-arcade.md]: in-arcade.md
168+
[incremental-official-chunked.md]: incremental-official-chunked.md
169+
[incremental-official.md]: incremental-official.md
170+
[source-build-in-pipeline.md]: source-build-in-pipeline.md
171+
[speculative-build.md]: speculative-build.md
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
digraph {
2+
node [color="lightsteelblue1", style=filled];
3+
rankdir=BT;
4+
5+
"sourcelink"[color="gold"];
6+
"xliff-tasks"[color="gold"];
7+
"newtonsoft-json901"[color="gold"];
8+
"linker"[color="gold"];
9+
"application-insights"[color="gold"];
10+
"netcorecli-fsc"[color="gold"];
11+
12+
"sourcelink" -> "arcade"
13+
"arcade" -> "aspnet-extensions"
14+
"core-setup" -> "aspnet-extensions"
15+
"roslyn" -> "aspnet-extensions"
16+
"arcade" -> "aspnet-xdt"
17+
"arcade" -> "aspnetcore-tooling"
18+
"aspnet-extensions" -> "aspnetcore-tooling"
19+
"core-setup" -> "aspnetcore-tooling"
20+
"msbuild" -> "aspnetcore-tooling"
21+
"roslyn" -> "aspnetcore-tooling"
22+
"arcade" -> "aspnetcore"
23+
"aspnetcore-tooling" -> "aspnetcore"
24+
"core-setup" -> "aspnetcore"
25+
"msbuild" -> "aspnetcore"
26+
"roslyn" -> "aspnetcore"
27+
"arcade" -> "cli"
28+
"application-insights" -> "cli"
29+
"clicommandlineparser" -> "cli"
30+
"core-setup" -> "cli"
31+
"corefx" -> "cli"
32+
"msbuild" -> "cli"
33+
"nuget-client" -> "cli"
34+
"newtonsoft-json" -> "cli"
35+
"newtonsoft-json901" -> "cli"
36+
"roslyn" -> "cli"
37+
"sdk" -> "cli"
38+
"standard" -> "cli"
39+
"templating" -> "cli"
40+
"websdk" -> "cli"
41+
"xliff-tasks" -> "cli"
42+
"arcade" -> "clicommandlineparser"
43+
"newtonsoft-json" -> "common"
44+
"aspnetcore" -> "core-sdk"
45+
"newtonsoft-json" -> "core-sdk"
46+
"newtonsoft-json901" -> "core-sdk"
47+
"toolset" -> "core-sdk"
48+
"coreclr" -> "core-setup-portable"
49+
"corefx" -> "core-setup-portable"
50+
"newtonsoft-json" -> "core-setup-portable"
51+
"newtonsoft-json901" -> "core-setup-portable"
52+
"roslyn" -> "core-setup-portable"
53+
"standard" -> "core-setup-portable"
54+
"coreclr" -> "core-setup"
55+
"corefx" -> "core-setup"
56+
"newtonsoft-json" -> "core-setup"
57+
"newtonsoft-json901" -> "core-setup"
58+
"roslyn" -> "core-setup"
59+
"standard" -> "core-setup"
60+
"linker" -> "coreclr-portable"
61+
"roslyn" -> "coreclr-portable"
62+
"linker" -> "coreclr"
63+
"roslyn" -> "coreclr"
64+
"arcade" -> "corefx-portable"
65+
"linker" -> "corefx-portable"
66+
"coreclr" -> "corefx-portable"
67+
"standard" -> "corefx-portable"
68+
"arcade" -> "corefx"
69+
"linker" -> "corefx"
70+
"coreclr" -> "corefx"
71+
"standard" -> "corefx"
72+
"arcade" -> "fsharp"
73+
"newtonsoft-json901" -> "fsharp"
74+
"newtonsoft-json" -> "fsharp"
75+
"xliff-tasks" -> "fsharp"
76+
"arcade" -> "msbuild"
77+
"corefx" -> "msbuild"
78+
"roslyn" -> "msbuild"
79+
"arcade" -> "newtonsoft-json"
80+
"newtonsoft-json" -> "nuget-client"
81+
"common" -> "nuget-client"
82+
"msbuild" -> "nuget-client"
83+
"arcade" -> "roslyn"
84+
"xliff-tasks" -> "roslyn"
85+
"arcade" -> "sdk"
86+
"xliff-tasks" -> "sdk"
87+
"core-setup" -> "sdk"
88+
"msbuild" -> "sdk"
89+
"newtonsoft-json" -> "sdk"
90+
"newtonsoft-json901" -> "sdk"
91+
"nuget-client" -> "sdk"
92+
"arcade" -> "standard"
93+
"clicommandlineparser" -> "templating"
94+
"newtonsoft-json" -> "templating"
95+
"aspnetcore-tooling" -> "toolset"
96+
"cli" -> "toolset"
97+
"fsharp" -> "toolset"
98+
"netcorecli-fsc" -> "toolset"
99+
"newtonsoft-json" -> "toolset"
100+
"newtonsoft-json901" -> "toolset"
101+
"vstest" -> "toolset"
102+
"websdk" -> "toolset"
103+
"aspnet-extensions" -> "vstest"
104+
"core-setup" -> "vstest"
105+
"newtonsoft-json" -> "vstest"
106+
"arcade" -> "websdk"
107+
"aspnetcore" -> "websdk"
108+
"aspnet-xdt" -> "websdk"
109+
"newtonsoft-json" -> "websdk"
110+
}

0 commit comments

Comments
 (0)