mirror of
https://github.com/microsoft/terminal.git
synced 2026-04-06 14:19:45 +00:00
Compare commits
171 Commits
dev/duhowe
...
dev/pabhoj
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5a9f3529d7 | ||
|
|
18b0ecbb2a | ||
|
|
71a1a97a9a | ||
|
|
077d63e6a3 | ||
|
|
7a8dd90294 | ||
|
|
59dcbbe0e9 | ||
|
|
a5c269b280 | ||
|
|
17cc109081 | ||
|
|
9e86c9811f | ||
|
|
0289cb043c | ||
|
|
19efcfee9d | ||
|
|
49c177f219 | ||
|
|
68b5e58754 | ||
|
|
16bac45714 | ||
|
|
188a2ae4c8 | ||
|
|
c2fde69ff5 | ||
|
|
798ab586f1 | ||
|
|
9892ade4e0 | ||
|
|
7fd476d9ed | ||
|
|
c0275018ea | ||
|
|
229ba89c83 | ||
|
|
b6593e713e | ||
|
|
7e2be66ec5 | ||
|
|
4b58fc6c8e | ||
|
|
d0d3039963 | ||
|
|
d8c7719bfb | ||
|
|
e1c69a99ce | ||
|
|
d496a5fb80 | ||
|
|
08f30330d1 | ||
|
|
64b5b2884a | ||
|
|
1745857407 | ||
|
|
f2c3ddd105 | ||
|
|
0b9f041706 | ||
|
|
27e1081c8c | ||
|
|
ee17d6c55e | ||
|
|
544cdd78af | ||
|
|
0144cdd7bc | ||
|
|
af8e20c3b6 | ||
|
|
d801375883 | ||
|
|
4efee36376 | ||
|
|
775e7ebe1f | ||
|
|
145c4d3641 | ||
|
|
5aadddaea9 | ||
|
|
d0c228e95a | ||
|
|
6ecdae796f | ||
|
|
f6e1126b77 | ||
|
|
4ee21b38b5 | ||
|
|
70ad67053d | ||
|
|
47728dc38b | ||
|
|
4145f18768 | ||
|
|
aafb91745e | ||
|
|
59aaba7c5b | ||
|
|
8521aae889 | ||
|
|
f6425dbd59 | ||
|
|
b9cbf0f24c | ||
|
|
6489f6b39d | ||
|
|
1669036e59 | ||
|
|
4c795b5bcd | ||
|
|
828c1ebf66 | ||
|
|
3eae898ddc | ||
|
|
3e0b3e3925 | ||
|
|
057d1334db | ||
|
|
f1a868517c | ||
|
|
ac2b0e744c | ||
|
|
1b143e34a8 | ||
|
|
4382a17352 | ||
|
|
cc2ba5350d | ||
|
|
3fc5286052 | ||
|
|
7073ec01bf | ||
|
|
198c11f36d | ||
|
|
cf193858f6 | ||
|
|
310814bb30 | ||
|
|
aef2dbd076 | ||
|
|
6183b27547 | ||
|
|
b772b2da57 | ||
|
|
74748394c1 | ||
|
|
c7f30a86d7 | ||
|
|
e0fc3bcd0a | ||
|
|
2ecfac80e7 | ||
|
|
18dae6dae8 | ||
|
|
86ad3c84cb | ||
|
|
29a22c9e8a | ||
|
|
41f7ed73c1 | ||
|
|
d38bb906ec | ||
|
|
fc4a37ee91 | ||
|
|
c1bdcf8b97 | ||
|
|
75f3d4f3df | ||
|
|
d272fc4644 | ||
|
|
9b986a16cf | ||
|
|
059f7701f2 | ||
|
|
b5333f64e5 | ||
|
|
523edd7941 | ||
|
|
394b942a56 | ||
|
|
59248de1e4 | ||
|
|
2e91e9c6de | ||
|
|
3550e19751 | ||
|
|
4370da9549 | ||
|
|
f494d68f11 | ||
|
|
5f9624f6ea | ||
|
|
8daf89e318 | ||
|
|
1f3779e05a | ||
|
|
741633ef7a | ||
|
|
2fa8e766bb | ||
|
|
4bc34e490c | ||
|
|
37b0cfd32b | ||
|
|
4ddfc3eaf3 | ||
|
|
43535b0d1c | ||
|
|
d19aaf7ead | ||
|
|
5d300b20ed | ||
|
|
2f7f759af4 | ||
|
|
3830c62a81 | ||
|
|
2f41d23d6d | ||
|
|
6cff135f37 | ||
|
|
b53ddd1b47 | ||
|
|
0cbde94e4b | ||
|
|
c5e0908b98 | ||
|
|
60843faa9e | ||
|
|
5fb2518117 | ||
|
|
636be7e514 | ||
|
|
d54ce33afc | ||
|
|
c4436157c1 | ||
|
|
821ae3af2d | ||
|
|
2fb4a7fa91 | ||
|
|
cd80f3c764 | ||
|
|
5651f08770 | ||
|
|
0f61b5f97d | ||
|
|
7a05501907 | ||
|
|
b024efb3b7 | ||
|
|
10ea38c9a7 | ||
|
|
30eb9eed49 | ||
|
|
e10b7e4fb9 | ||
|
|
921d7c3316 | ||
|
|
8f20ea6b2d | ||
|
|
333fcd89b3 | ||
|
|
21c2dee50a | ||
|
|
df648208d5 | ||
|
|
6cb14d226d | ||
|
|
59a7dabf3b | ||
|
|
d28b6bf1f2 | ||
|
|
a7a44901c2 | ||
|
|
3701d0ee95 | ||
|
|
127df073fa | ||
|
|
3afe7a8d11 | ||
|
|
8f4c63e81b | ||
|
|
e5a430ff68 | ||
|
|
b556594793 | ||
|
|
a0c88bb511 | ||
|
|
69eff7e9fd | ||
|
|
d943fa41f6 | ||
|
|
5b44476048 | ||
|
|
e9c8391fd5 | ||
|
|
256d46ad6b | ||
|
|
6a29ca2ada | ||
|
|
1ed57cc5c9 | ||
|
|
9b70a40bf9 | ||
|
|
c6e5f79115 | ||
|
|
2d7066f5c6 | ||
|
|
07566fac4c | ||
|
|
a4340af1e7 | ||
|
|
57b9549ff8 | ||
|
|
1f9426b051 | ||
|
|
cbe915c554 | ||
|
|
d70794a246 | ||
|
|
1a40ff3746 | ||
|
|
a132ba82e7 | ||
|
|
7aada2fd1e | ||
|
|
553ad121af | ||
|
|
154ac2b916 | ||
|
|
3c104440a8 | ||
|
|
b6feabe9cc | ||
|
|
a0624bedaa |
9
.github/actions/spelling/allow/allow.txt
vendored
9
.github/actions/spelling/allow/allow.txt
vendored
@@ -1,3 +1,4 @@
|
||||
aci
|
||||
admins
|
||||
allcolors
|
||||
Apc
|
||||
@@ -8,11 +9,13 @@ breadcrumbs
|
||||
bsd
|
||||
calt
|
||||
ccmp
|
||||
ccon
|
||||
changelog
|
||||
clickable
|
||||
clig
|
||||
CMMI
|
||||
copyable
|
||||
Counterintuitively
|
||||
CtrlDToClose
|
||||
cybersecurity
|
||||
dalet
|
||||
@@ -90,11 +93,14 @@ reserialize
|
||||
reserializes
|
||||
rlig
|
||||
runtimes
|
||||
servicebus
|
||||
shcha
|
||||
slnt
|
||||
Sos
|
||||
ssh
|
||||
sustainability
|
||||
stakeholders
|
||||
sxn
|
||||
timeline
|
||||
timelines
|
||||
timestamped
|
||||
@@ -111,7 +117,10 @@ und
|
||||
unregister
|
||||
versioned
|
||||
vsdevcmd
|
||||
walkthrough
|
||||
walkthroughs
|
||||
We'd
|
||||
westus
|
||||
wildcards
|
||||
XBox
|
||||
YBox
|
||||
|
||||
7
.github/actions/spelling/allow/apis.txt
vendored
7
.github/actions/spelling/allow/apis.txt
vendored
@@ -28,6 +28,7 @@ CYICON
|
||||
Dacl
|
||||
dataobject
|
||||
dcomp
|
||||
debugbreak
|
||||
delayimp
|
||||
DERR
|
||||
dlldata
|
||||
@@ -52,6 +53,7 @@ futex
|
||||
GETDESKWALLPAPER
|
||||
GETHIGHCONTRAST
|
||||
GETMOUSEHOVERTIME
|
||||
GETTEXTLENGTH
|
||||
Hashtable
|
||||
HIGHCONTRASTON
|
||||
HIGHCONTRASTW
|
||||
@@ -186,6 +188,7 @@ snprintf
|
||||
spsc
|
||||
sregex
|
||||
SRWLOC
|
||||
srwlock
|
||||
SRWLOCK
|
||||
STDCPP
|
||||
STDMETHOD
|
||||
@@ -207,6 +210,7 @@ tlg
|
||||
TME
|
||||
tmp
|
||||
tmpdir
|
||||
tokeninfo
|
||||
tolower
|
||||
toupper
|
||||
TRACKMOUSEEVENT
|
||||
@@ -217,16 +221,19 @@ UFIELD
|
||||
ULARGE
|
||||
UOI
|
||||
UPDATEINIFILE
|
||||
urlmon
|
||||
userenv
|
||||
USEROBJECTFLAGS
|
||||
Vcpp
|
||||
Viewbox
|
||||
virtualalloc
|
||||
vsnwprintf
|
||||
wcsnlen
|
||||
wcsstr
|
||||
wcstoui
|
||||
WDJ
|
||||
winhttp
|
||||
wininet
|
||||
winmain
|
||||
winsta
|
||||
winstamin
|
||||
|
||||
4
.github/actions/spelling/allow/microsoft.txt
vendored
4
.github/actions/spelling/allow/microsoft.txt
vendored
@@ -4,6 +4,7 @@ advapi
|
||||
altform
|
||||
altforms
|
||||
appendwttlogging
|
||||
appinstaller
|
||||
appx
|
||||
appxbundle
|
||||
appxerror
|
||||
@@ -59,12 +60,13 @@ PRIINFO
|
||||
propkey
|
||||
pscustomobject
|
||||
QWORD
|
||||
rdpclip
|
||||
regedit
|
||||
resfiles
|
||||
robocopy
|
||||
SACLs
|
||||
segoe
|
||||
sdkddkver
|
||||
segoe
|
||||
Shobjidl
|
||||
sid
|
||||
Skype
|
||||
|
||||
1
.github/actions/spelling/expect/alphabet.txt
vendored
1
.github/actions/spelling/expect/alphabet.txt
vendored
@@ -21,6 +21,7 @@ BBBBCCCCC
|
||||
BBGGRR
|
||||
efg
|
||||
EFG
|
||||
efgh
|
||||
EFGh
|
||||
KLMNOQQQQQQQQQQ
|
||||
QQQQQQQQQQABCDEFGHIJ
|
||||
|
||||
77
.github/actions/spelling/expect/expect.txt
vendored
77
.github/actions/spelling/expect/expect.txt
vendored
@@ -7,7 +7,6 @@ ABCF
|
||||
abgr
|
||||
abi
|
||||
ABORTIFHUNG
|
||||
ACCESSTOKEN
|
||||
acidev
|
||||
ACIOSS
|
||||
ACover
|
||||
@@ -18,7 +17,6 @@ ADDALIAS
|
||||
ADDREF
|
||||
ADDSTRING
|
||||
ADDTOOL
|
||||
AEnd
|
||||
AFew
|
||||
AFill
|
||||
AFX
|
||||
@@ -117,10 +115,8 @@ binplace
|
||||
binplaced
|
||||
bitcoin
|
||||
bitcrazed
|
||||
bitflag
|
||||
bitmask
|
||||
BITOPERATION
|
||||
bitsets
|
||||
BKCOLOR
|
||||
BKGND
|
||||
Bksp
|
||||
@@ -149,12 +145,12 @@ bufferout
|
||||
buffersize
|
||||
buflen
|
||||
buildtransitive
|
||||
BUILDURI
|
||||
burriter
|
||||
BValue
|
||||
bytebuffer
|
||||
cac
|
||||
cacafire
|
||||
CALLCONV
|
||||
capslock
|
||||
CARETBLINKINGENABLED
|
||||
CARRIAGERETURN
|
||||
@@ -192,13 +188,14 @@ changelist
|
||||
chaof
|
||||
charinfo
|
||||
CHARSETINFO
|
||||
chcbpat
|
||||
chh
|
||||
chk
|
||||
chshdng
|
||||
CHT
|
||||
Cic
|
||||
cielab
|
||||
Cielab
|
||||
Clcompile
|
||||
CLE
|
||||
cleartype
|
||||
CLICKACTIVE
|
||||
@@ -229,7 +226,6 @@ codepage
|
||||
codepath
|
||||
codepoints
|
||||
coinit
|
||||
COLLECTIONURI
|
||||
colorizing
|
||||
COLORMATRIX
|
||||
COLORREFs
|
||||
@@ -381,7 +377,6 @@ dai
|
||||
DATABLOCK
|
||||
DBatch
|
||||
dbcs
|
||||
DBCSCHAR
|
||||
DBCSFONT
|
||||
dbg
|
||||
DBGALL
|
||||
@@ -503,7 +498,6 @@ devicecode
|
||||
Dext
|
||||
DFactory
|
||||
DFF
|
||||
dhandler
|
||||
dialogbox
|
||||
directio
|
||||
DIRECTX
|
||||
@@ -521,7 +515,6 @@ dllmain
|
||||
DLLVERSIONINFO
|
||||
DLOAD
|
||||
DLOOK
|
||||
dmp
|
||||
DONTCARE
|
||||
doskey
|
||||
dotnet
|
||||
@@ -599,7 +592,6 @@ eplace
|
||||
EPres
|
||||
EQU
|
||||
ERASEBKGND
|
||||
etcoreapp
|
||||
ETW
|
||||
EUDC
|
||||
EVENTID
|
||||
@@ -641,7 +633,6 @@ FGs
|
||||
FILEDESCRIPTION
|
||||
FILESUBTYPE
|
||||
FILESYSPATH
|
||||
fileurl
|
||||
FILEW
|
||||
FILLATTR
|
||||
FILLCONSOLEOUTPUT
|
||||
@@ -690,7 +681,7 @@ FSINFOCLASS
|
||||
fte
|
||||
Ftm
|
||||
Fullscreens
|
||||
fullwidth
|
||||
Fullwidth
|
||||
FUNCTIONCALL
|
||||
fuzzer
|
||||
fuzzmain
|
||||
@@ -761,7 +752,6 @@ gfx
|
||||
GGI
|
||||
GHIJK
|
||||
GHIJKL
|
||||
GHIJKLM
|
||||
gitfilters
|
||||
gitmodules
|
||||
gle
|
||||
@@ -823,7 +813,6 @@ HIWORD
|
||||
HKCU
|
||||
hkey
|
||||
hkl
|
||||
HKLM
|
||||
hlocal
|
||||
hlsl
|
||||
HMB
|
||||
@@ -831,7 +820,6 @@ HMK
|
||||
hmod
|
||||
hmodule
|
||||
hmon
|
||||
homeglyphs
|
||||
homoglyph
|
||||
HORZ
|
||||
hostable
|
||||
@@ -919,6 +907,7 @@ INSERTMODE
|
||||
INTERACTIVITYBASE
|
||||
INTERCEPTCOPYPASTE
|
||||
INTERNALNAME
|
||||
Interner
|
||||
intsafe
|
||||
INVALIDARG
|
||||
INVALIDATERECT
|
||||
@@ -935,12 +924,10 @@ itermcolors
|
||||
ITerminal
|
||||
itf
|
||||
Ith
|
||||
itoa
|
||||
IUI
|
||||
IUnknown
|
||||
ivalid
|
||||
IWIC
|
||||
IXMP
|
||||
IXP
|
||||
jconcpp
|
||||
JOBOBJECT
|
||||
@@ -964,7 +951,6 @@ kernelbasestaging
|
||||
KEYBDINPUT
|
||||
keychord
|
||||
keydown
|
||||
keyevent
|
||||
KEYFIRST
|
||||
KEYLAST
|
||||
Keymapping
|
||||
@@ -1011,13 +997,11 @@ LINEWRAP
|
||||
LINKERRCAP
|
||||
LINKERROR
|
||||
linputfile
|
||||
listproperties
|
||||
listptr
|
||||
listptrsize
|
||||
lld
|
||||
llx
|
||||
LMENU
|
||||
LMNOP
|
||||
lnk
|
||||
lnkd
|
||||
lnkfile
|
||||
@@ -1117,6 +1101,7 @@ MDs
|
||||
MEASUREITEM
|
||||
megamix
|
||||
memallocator
|
||||
meme
|
||||
MENUCHAR
|
||||
MENUCONTROL
|
||||
MENUDROPALIGNMENT
|
||||
@@ -1130,7 +1115,6 @@ MIIM
|
||||
milli
|
||||
mincore
|
||||
mindbogglingly
|
||||
minimizeall
|
||||
minkernel
|
||||
MINMAXINFO
|
||||
minwin
|
||||
@@ -1240,7 +1224,6 @@ nonspace
|
||||
NOOWNERZORDER
|
||||
Nop
|
||||
NOPAINT
|
||||
NOPQRST
|
||||
noprofile
|
||||
NOREDRAW
|
||||
NOREMOVE
|
||||
@@ -1317,7 +1300,7 @@ onecoreuuid
|
||||
ONECOREWINDOWS
|
||||
onehalf
|
||||
oneseq
|
||||
ONLCR
|
||||
OOM
|
||||
openbash
|
||||
opencode
|
||||
opencon
|
||||
@@ -1327,13 +1310,6 @@ openps
|
||||
openvt
|
||||
ORIGINALFILENAME
|
||||
osc
|
||||
OSCBG
|
||||
OSCCT
|
||||
OSCFG
|
||||
OSCRCC
|
||||
OSCSCB
|
||||
OSCSCC
|
||||
OSCWT
|
||||
OSDEPENDSROOT
|
||||
OSG
|
||||
OSGENG
|
||||
@@ -1465,8 +1441,8 @@ prc
|
||||
prealigned
|
||||
prect
|
||||
prefast
|
||||
preflighting
|
||||
prefs
|
||||
preinstalled
|
||||
prepopulated
|
||||
presorted
|
||||
PREVENTPINNING
|
||||
@@ -1479,7 +1455,6 @@ prioritization
|
||||
processenv
|
||||
processhost
|
||||
PROCESSINFOCLASS
|
||||
procs
|
||||
PROPERTYID
|
||||
PROPERTYKEY
|
||||
PROPERTYVAL
|
||||
@@ -1494,7 +1469,6 @@ propvariant
|
||||
propvarutil
|
||||
psa
|
||||
PSECURITY
|
||||
pseudocode
|
||||
pseudoconsole
|
||||
pseudoterminal
|
||||
psh
|
||||
@@ -1524,7 +1498,6 @@ pwsz
|
||||
pythonw
|
||||
Qaabbcc
|
||||
qos
|
||||
QRSTU
|
||||
QUERYOPEN
|
||||
QUESTIONMARK
|
||||
quickedit
|
||||
@@ -1613,12 +1586,10 @@ rgrc
|
||||
rgs
|
||||
rgui
|
||||
rgw
|
||||
rgwch
|
||||
RIGHTALIGN
|
||||
RIGHTBUTTON
|
||||
riid
|
||||
Rike
|
||||
RIPMSG
|
||||
RIS
|
||||
roadmap
|
||||
robomac
|
||||
@@ -1774,7 +1745,6 @@ SND
|
||||
SOLIDBOX
|
||||
Solutiondir
|
||||
somefile
|
||||
SOURCEBRANCH
|
||||
sourced
|
||||
spammy
|
||||
SRCCODEPAGE
|
||||
@@ -1805,11 +1775,11 @@ stdafx
|
||||
STDAPI
|
||||
stdc
|
||||
stdcpp
|
||||
STDEXT
|
||||
STDMETHODCALLTYPE
|
||||
STDMETHODIMP
|
||||
STGM
|
||||
stl
|
||||
stoutapot
|
||||
Stri
|
||||
Stringable
|
||||
STRINGTABLE
|
||||
@@ -1826,7 +1796,6 @@ SUBLANG
|
||||
subresource
|
||||
subsystemconsole
|
||||
subsystemwindows
|
||||
suiteless
|
||||
swapchain
|
||||
swapchainpanel
|
||||
swappable
|
||||
@@ -1865,13 +1834,11 @@ TBM
|
||||
tchar
|
||||
TCHFORMAT
|
||||
TCI
|
||||
tcome
|
||||
tcommandline
|
||||
tcommands
|
||||
Tdd
|
||||
TDelegated
|
||||
TDP
|
||||
TEAMPROJECT
|
||||
tearoff
|
||||
Teb
|
||||
Techo
|
||||
@@ -1883,23 +1850,16 @@ terminalrenderdata
|
||||
TERMINALSCROLLING
|
||||
terminfo
|
||||
TEs
|
||||
testbuildplatform
|
||||
testcon
|
||||
testd
|
||||
testdlls
|
||||
testenv
|
||||
testlab
|
||||
testlist
|
||||
testmd
|
||||
testmode
|
||||
testname
|
||||
testnameprefix
|
||||
TESTNULL
|
||||
testpass
|
||||
testpasses
|
||||
testtestabc
|
||||
testtesttesttesttest
|
||||
testtimeout
|
||||
TEXCOORD
|
||||
texel
|
||||
TExpected
|
||||
@@ -1927,7 +1887,6 @@ TJson
|
||||
TLambda
|
||||
TLDP
|
||||
TLEN
|
||||
Tlgdata
|
||||
TMAE
|
||||
TMPF
|
||||
TMult
|
||||
@@ -1947,6 +1906,7 @@ touchpad
|
||||
Tpp
|
||||
Tpqrst
|
||||
tprivapi
|
||||
tput
|
||||
tracelog
|
||||
tracelogging
|
||||
traceloggingprovider
|
||||
@@ -1987,11 +1947,14 @@ UAC
|
||||
uap
|
||||
uapadmin
|
||||
UAX
|
||||
UBool
|
||||
ucd
|
||||
uch
|
||||
UChars
|
||||
udk
|
||||
UDM
|
||||
uer
|
||||
UError
|
||||
uget
|
||||
uia
|
||||
UIACCESS
|
||||
@@ -2021,13 +1984,14 @@ unknwn
|
||||
UNORM
|
||||
unparseable
|
||||
unregistering
|
||||
untests
|
||||
untextured
|
||||
untimes
|
||||
UPDATEDISPLAY
|
||||
UPDOWN
|
||||
UPKEY
|
||||
UPSS
|
||||
uregex
|
||||
URegular
|
||||
usebackq
|
||||
USECALLBACK
|
||||
USECOLOR
|
||||
@@ -2049,8 +2013,10 @@ USESIZE
|
||||
USESTDHANDLES
|
||||
usp
|
||||
USRDLL
|
||||
utext
|
||||
UText
|
||||
UTEXT
|
||||
utr
|
||||
UVWX
|
||||
UVWXY
|
||||
UVWXYZ
|
||||
uwa
|
||||
@@ -2109,8 +2075,6 @@ VTRGBTo
|
||||
vtseq
|
||||
vtterm
|
||||
vttest
|
||||
VWX
|
||||
waaay
|
||||
waitable
|
||||
WANSUNG
|
||||
WANTARROWS
|
||||
@@ -2132,7 +2096,6 @@ WDDMCONSOLECONTEXT
|
||||
wdm
|
||||
webpage
|
||||
websites
|
||||
websockets
|
||||
wekyb
|
||||
wex
|
||||
wextest
|
||||
@@ -2160,7 +2123,6 @@ windbg
|
||||
WINDEF
|
||||
windll
|
||||
WINDOWALPHA
|
||||
Windowbuffer
|
||||
windowdpiapi
|
||||
WINDOWEDGE
|
||||
windowext
|
||||
@@ -2230,7 +2192,6 @@ wprp
|
||||
wprpi
|
||||
wregex
|
||||
writeback
|
||||
writechar
|
||||
WRITECONSOLE
|
||||
WRITECONSOLEINPUT
|
||||
WRITECONSOLEOUTPUT
|
||||
@@ -2304,12 +2265,12 @@ xunit
|
||||
xutr
|
||||
XVIRTUALSCREEN
|
||||
XWalk
|
||||
xxyyzz
|
||||
yact
|
||||
YCast
|
||||
YCENTER
|
||||
YCount
|
||||
YDPI
|
||||
YLimit
|
||||
YOffset
|
||||
YSubstantial
|
||||
YVIRTUALSCREEN
|
||||
|
||||
1
.github/actions/spelling/expect/web.txt
vendored
1
.github/actions/spelling/expect/web.txt
vendored
@@ -4,3 +4,4 @@ appshellintegration
|
||||
mdtauk
|
||||
gfycat
|
||||
Guake
|
||||
xkcd
|
||||
|
||||
@@ -101,7 +101,7 @@ If you don't have any additional info/context to add but would like to indicate
|
||||
|
||||
If you're able & willing to help fix issues and/or implement features, we'd love your contribution!
|
||||
|
||||
The best place to start is the list of ["good first issue"](https://github.com/microsoft/terminal/issues?q=is%3Aopen+is%3Aissue+label%3A%22Help+Wanted%22++label%3A%22good+first+issue%22+)s. These are bugs or tasks that we on the team believe would be easier to implement for someone without any prior experience in the codebase. Once you're feeling more comfortable in the codebase, feel free to just use the ["Help Wanted"](https://github.com/microsoft/terminal/issues?q=is%3Aopen+is%3Aissue+label%3A%22Help+Wanted%22+) label, or just find an issue you're interested in and hop in!
|
||||
The best place to start is the list of ["walkthroughs"](https://aka.ms/terminal-walkthroughs). This is a collection of issues where we've written a "walkthrough", little guides to help get started with a particular issue. These are usually good first issues, and are a great way to get familiar with the codebase. Additionally, the list of ["good first issue"](https://github.com/microsoft/terminal/issues?q=is%3Aopen+is%3Aissue+label%3A%22Help+Wanted%22++label%3A%22good+first+issue%22+)s is another set of issues that might be easier for first-time contributors. Once you're feeling more comfortable in the codebase, feel free to just use the ["Help Wanted"](https://github.com/microsoft/terminal/issues?q=is%3Aopen+is%3Aissue+label%3A%22Help+Wanted%22+) label, or just find any issue you're interested in and hop in!
|
||||
|
||||
Generally, we categorize issues in the following way, which is largely derived from our old internal work tracking system:
|
||||
* ["Bugs"](https://github.com/microsoft/terminal/issues?q=is%3Aopen+is%3Aissue+label%3A%22Issue-Bug%22+) are parts of the Terminal & Console that are not quite working the right way. There's code to already support some scenario, but it's not quite working right. Fixing these is generally a matter of debugging the broken functionality and fixing the wrong code.
|
||||
|
||||
@@ -239,8 +239,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Shared", "Shared", "{89CDCC
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Types.Unit.Tests", "src\types\ut_types\Types.Unit.Tests.vcxproj", "{34DE34D3-1CD6-4EE3-8BD9-A26B5B27EC73}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PublicTerminalCore", "src\cascadia\PublicTerminalCore\PublicTerminalCore.vcxproj", "{84848BFA-931D-42CE-9ADF-01EE54DE7890}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WpfTerminalControl", "src\cascadia\WpfTerminalControl\WpfTerminalControl.csproj", "{376FE273-6B84-4EB5-8B30-8DE9D21B022C}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "UnitTests_TerminalApp", "src\cascadia\ut_app\TerminalApp.UnitTests.vcxproj", "{CA5CAD1A-9333-4D05-B12A-1905CBF112F9}"
|
||||
@@ -334,7 +332,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "fmt", "src\dep\fmt\fmt.vcxp
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WpfTerminalTestNetCore", "src\cascadia\WpfTerminalTestNetCore\WpfTerminalTestNetCore.csproj", "{1588FD7C-241E-4E7D-9113-43735F3E6BAD}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{84848BFA-931D-42CE-9ADF-01EE54DE7890} = {84848BFA-931D-42CE-9ADF-01EE54DE7890}
|
||||
{CA5CAD1A-F542-4635-A069-7CAEFB930070} = {CA5CAD1A-F542-4635-A069-7CAEFB930070}
|
||||
{A22EC5F6-7851-4B88-AC52-47249D437A52} = {A22EC5F6-7851-4B88-AC52-47249D437A52}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
@@ -1711,34 +1709,6 @@ Global
|
||||
{34DE34D3-1CD6-4EE3-8BD9-A26B5B27EC73}.Release|x64.Build.0 = Release|x64
|
||||
{34DE34D3-1CD6-4EE3-8BD9-A26B5B27EC73}.Release|x86.ActiveCfg = Release|Win32
|
||||
{34DE34D3-1CD6-4EE3-8BD9-A26B5B27EC73}.Release|x86.Build.0 = Release|Win32
|
||||
{84848BFA-931D-42CE-9ADF-01EE54DE7890}.AuditMode|Any CPU.ActiveCfg = AuditMode|Win32
|
||||
{84848BFA-931D-42CE-9ADF-01EE54DE7890}.AuditMode|ARM.ActiveCfg = AuditMode|Win32
|
||||
{84848BFA-931D-42CE-9ADF-01EE54DE7890}.AuditMode|ARM64.ActiveCfg = AuditMode|ARM64
|
||||
{84848BFA-931D-42CE-9ADF-01EE54DE7890}.AuditMode|x64.ActiveCfg = AuditMode|x64
|
||||
{84848BFA-931D-42CE-9ADF-01EE54DE7890}.AuditMode|x64.Build.0 = AuditMode|x64
|
||||
{84848BFA-931D-42CE-9ADF-01EE54DE7890}.AuditMode|x86.ActiveCfg = AuditMode|Win32
|
||||
{84848BFA-931D-42CE-9ADF-01EE54DE7890}.AuditMode|x86.Build.0 = AuditMode|Win32
|
||||
{84848BFA-931D-42CE-9ADF-01EE54DE7890}.Debug|Any CPU.ActiveCfg = Debug|Win32
|
||||
{84848BFA-931D-42CE-9ADF-01EE54DE7890}.Debug|ARM.ActiveCfg = Debug|Win32
|
||||
{84848BFA-931D-42CE-9ADF-01EE54DE7890}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
||||
{84848BFA-931D-42CE-9ADF-01EE54DE7890}.Debug|ARM64.Build.0 = Debug|ARM64
|
||||
{84848BFA-931D-42CE-9ADF-01EE54DE7890}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{84848BFA-931D-42CE-9ADF-01EE54DE7890}.Debug|x64.Build.0 = Debug|x64
|
||||
{84848BFA-931D-42CE-9ADF-01EE54DE7890}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{84848BFA-931D-42CE-9ADF-01EE54DE7890}.Debug|x86.Build.0 = Debug|Win32
|
||||
{84848BFA-931D-42CE-9ADF-01EE54DE7890}.Fuzzing|Any CPU.ActiveCfg = Fuzzing|Win32
|
||||
{84848BFA-931D-42CE-9ADF-01EE54DE7890}.Fuzzing|ARM.ActiveCfg = Fuzzing|Win32
|
||||
{84848BFA-931D-42CE-9ADF-01EE54DE7890}.Fuzzing|ARM64.ActiveCfg = Fuzzing|ARM64
|
||||
{84848BFA-931D-42CE-9ADF-01EE54DE7890}.Fuzzing|x64.ActiveCfg = Fuzzing|x64
|
||||
{84848BFA-931D-42CE-9ADF-01EE54DE7890}.Fuzzing|x86.ActiveCfg = Fuzzing|Win32
|
||||
{84848BFA-931D-42CE-9ADF-01EE54DE7890}.Release|Any CPU.ActiveCfg = Release|Win32
|
||||
{84848BFA-931D-42CE-9ADF-01EE54DE7890}.Release|ARM.ActiveCfg = Release|Win32
|
||||
{84848BFA-931D-42CE-9ADF-01EE54DE7890}.Release|ARM64.ActiveCfg = Release|ARM64
|
||||
{84848BFA-931D-42CE-9ADF-01EE54DE7890}.Release|ARM64.Build.0 = Release|ARM64
|
||||
{84848BFA-931D-42CE-9ADF-01EE54DE7890}.Release|x64.ActiveCfg = Release|x64
|
||||
{84848BFA-931D-42CE-9ADF-01EE54DE7890}.Release|x64.Build.0 = Release|x64
|
||||
{84848BFA-931D-42CE-9ADF-01EE54DE7890}.Release|x86.ActiveCfg = Release|Win32
|
||||
{84848BFA-931D-42CE-9ADF-01EE54DE7890}.Release|x86.Build.0 = Release|Win32
|
||||
{376FE273-6B84-4EB5-8B30-8DE9D21B022C}.AuditMode|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{376FE273-6B84-4EB5-8B30-8DE9D21B022C}.AuditMode|ARM.ActiveCfg = Debug|Any CPU
|
||||
{376FE273-6B84-4EB5-8B30-8DE9D21B022C}.AuditMode|ARM.Build.0 = Debug|Any CPU
|
||||
@@ -2894,7 +2864,6 @@ Global
|
||||
{05500DEF-2294-41E3-AF9A-24E580B82836} = {89CDCC5C-9F53-4054-97A4-639D99F169CD}
|
||||
{1E4A062E-293B-4817-B20D-BF16B979E350} = {89CDCC5C-9F53-4054-97A4-639D99F169CD}
|
||||
{34DE34D3-1CD6-4EE3-8BD9-A26B5B27EC73} = {89CDCC5C-9F53-4054-97A4-639D99F169CD}
|
||||
{84848BFA-931D-42CE-9ADF-01EE54DE7890} = {4DAF0299-495E-4CD1-A982-9BAC16A45932}
|
||||
{376FE273-6B84-4EB5-8B30-8DE9D21B022C} = {4DAF0299-495E-4CD1-A982-9BAC16A45932}
|
||||
{CA5CAD1A-9333-4D05-B12A-1905CBF112F9} = {BDB237B6-1D1D-400F-84CC-40A58FA59C8E}
|
||||
{CA5CAD1A-9A12-429C-B551-8562EC954746} = {59840756-302F-44DF-AA47-441A9D673202}
|
||||
|
||||
40
README.md
40
README.md
@@ -1,4 +1,4 @@
|
||||

|
||||

|
||||
|
||||
# Welcome to the Windows Terminal, Console and Command-Line repo
|
||||
|
||||
@@ -21,7 +21,8 @@ Related repositories include:
|
||||
|
||||
## Installing and running Windows Terminal
|
||||
|
||||
> **Note**: Windows Terminal requires Windows 10 2004 (build 19041) or later
|
||||
> **Note**\
|
||||
> Windows Terminal requires Windows 10 2004 (build 19041) or later
|
||||
|
||||
### Microsoft Store [Recommended]
|
||||
|
||||
@@ -52,9 +53,10 @@ fails for any reason, you can try the following command at a PowerShell prompt:
|
||||
Add-AppxPackage Microsoft.WindowsTerminal_<versionNumber>.msixbundle
|
||||
```
|
||||
|
||||
> **Note**: If you install Terminal manually:
|
||||
> **Note**\
|
||||
> If you install Terminal manually:
|
||||
>
|
||||
> * You may need to install the [VC++ v14 Desktop Framework Package](https://docs.microsoft.com/troubleshoot/cpp/c-runtime-packages-desktop-bridge#how-to-install-and-update-desktop-framework-packages).
|
||||
> * You may need to install the [VC++ v14 Desktop Framework Package](https://docs.microsoft.com/troubleshoot/cpp/c-runtime-packages-desktop-bridge#how-to-install-and-update-desktop-framework-packages).
|
||||
> This should only be necessary on older builds of Windows 10 and only if you get an error about missing framework packages.
|
||||
> * Terminal will not auto-update when new builds are released so you will need
|
||||
> to regularly install the latest Terminal release to receive all the latest
|
||||
@@ -70,7 +72,8 @@ package:
|
||||
winget install --id Microsoft.WindowsTerminal -e
|
||||
```
|
||||
|
||||
> **Note** Due to a dependency issue, Terminal's current versions cannot be installed via the Windows Package Manager CLI. To install the stable release 1.17 or later, or the Preview release 1.18 or later, please use an alternative installation method.
|
||||
> **Note**\
|
||||
> Dependency support is available in WinGet version [1.6.2631 or later](https://github.com/microsoft/winget-cli/releases). To install the Terminal stable release 1.18 or later, please make sure you have the updated version of the WinGet client.
|
||||
|
||||
#### Via Chocolatey (unofficial)
|
||||
|
||||
@@ -115,9 +118,31 @@ repository.
|
||||
|
||||
---
|
||||
|
||||
## Installing Windows Terminal Canary
|
||||
Windows Terminal Canary is a nightly build of Windows Terminal. This build has the latest code from our `main` branch, giving you an opportunity to try features before they make it to Windows Terminal Preview.
|
||||
|
||||
Windows Terminal Canary is our least stable offering, so you may discover bugs before we have had a chance to find them.
|
||||
|
||||
Windows Terminal Canary is available as an App Installer distribution and a Portable ZIP distribution.
|
||||
|
||||
The App Installer distribution supports automatic updates. Due to platform limitations, this installer only works on Windows 11.
|
||||
|
||||
The Portable ZIP distribution is a portable application. It will not automatically update and will not automatically check for updates. This portable ZIP distribution works on Windows 10 (19041+) and Windows 11.
|
||||
|
||||
| Distribution | Architecture | Link |
|
||||
|---------------|:---------------:|------------------------------------------------------|
|
||||
| App Installer | x64, arm64, x86 | [download](https://aka.ms/terminal-canary-installer) |
|
||||
| Portable ZIP | x64 | [download](https://aka.ms/terminal-canary-zip-x64) |
|
||||
| Portable ZIP | ARM64 | [download](https://aka.ms/terminal-canary-zip-arm64) |
|
||||
| Portable ZIP | x86 | [download](https://aka.ms/terminal-canary-zip-x86) |
|
||||
|
||||
_Learn more about the [types of Windows Terminal distributions](https://learn.microsoft.com/windows/terminal/distributions)._
|
||||
|
||||
---
|
||||
|
||||
## Windows Terminal Roadmap
|
||||
|
||||
The plan for the Windows Terminal [is described here](/doc/roadmap-2022.md) and
|
||||
The plan for the Windows Terminal [is described here](/doc/roadmap-2023.md) and
|
||||
will be updated as the project proceeds.
|
||||
|
||||
## Project Build Status
|
||||
@@ -237,7 +262,8 @@ Cause: You're launching the incorrect solution in Visual Studio.
|
||||
Solution: Make sure you're building & deploying the `CascadiaPackage` project in
|
||||
Visual Studio.
|
||||
|
||||
> **Note**: `OpenConsole.exe` is just a locally-built `conhost.exe`, the classic
|
||||
> **Note**\
|
||||
> `OpenConsole.exe` is just a locally-built `conhost.exe`, the classic
|
||||
> Windows Console that hosts Windows' command-line infrastructure. OpenConsole
|
||||
> is used by Windows Terminal to connect to and communicate with command-line
|
||||
> applications (via
|
||||
|
||||
@@ -1,175 +0,0 @@
|
||||
function GetAzureDevOpsBaseUri
|
||||
{
|
||||
Param(
|
||||
[string]$CollectionUri,
|
||||
[string]$TeamProject
|
||||
)
|
||||
|
||||
return $CollectionUri + $TeamProject
|
||||
}
|
||||
|
||||
function GetQueryTestRunsUri
|
||||
{
|
||||
Param(
|
||||
[string]$CollectionUri,
|
||||
[string]$TeamProject,
|
||||
[string]$BuildUri,
|
||||
[switch]$IncludeRunDetails
|
||||
)
|
||||
|
||||
if ($IncludeRunDetails)
|
||||
{
|
||||
$includeRunDetailsParameter = "&includeRunDetails=true"
|
||||
}
|
||||
else
|
||||
{
|
||||
$includeRunDetailsParameter = ""
|
||||
}
|
||||
|
||||
$baseUri = GetAzureDevOpsBaseUri -CollectionUri $CollectionUri -TeamProject $TeamProject
|
||||
$queryUri = "$baseUri/_apis/test/runs?buildUri=$BuildUri$includeRunDetailsParameter&api-version=5.0"
|
||||
return $queryUri
|
||||
}
|
||||
|
||||
function Get-HelixJobTypeFromTestRun
|
||||
{
|
||||
Param ($testRun)
|
||||
|
||||
$testRunSingleResultUri = "$($testRun.url)/results?`$top=1&`$skip=0&api-version=5.1"
|
||||
$singleTestResult = Invoke-RestMethod -Uri $testRunSingleResultUri -Method Get -Headers $azureDevOpsRestApiHeaders
|
||||
$count = $singleTestResult.value.Length
|
||||
if($count -eq 0)
|
||||
{
|
||||
# If the count is 0, then results have not yet been reported for this run.
|
||||
# We only care about completed runs with results, so it is ok to just return 'UNKNOWN' for this run.
|
||||
return "UNKNOWN"
|
||||
}
|
||||
else
|
||||
{
|
||||
$info = ConvertFrom-Json $singleTestResult.value.comment
|
||||
$helixJobId = $info.HelixJobId
|
||||
$job = Invoke-RestMethodWithRetries "https://helix.dot.net/api/2019-06-17/jobs/${helixJobId}?access_token=${HelixAccessToken}"
|
||||
return $job.Type
|
||||
}
|
||||
}
|
||||
|
||||
function Append-HelixAccessTokenToUrl
|
||||
{
|
||||
Param ([string]$url, [string]$token)
|
||||
if($url.Contains("?"))
|
||||
{
|
||||
$url = "$($url)&access_token=$($token)"
|
||||
}
|
||||
else
|
||||
{
|
||||
$url = "$($url)?access_token=$($token)"
|
||||
}
|
||||
return $url
|
||||
}
|
||||
|
||||
|
||||
# The Helix Rest api is sometimes unreliable. So we call these apis with retry logic.
|
||||
# Note: The Azure DevOps apis are stable and do not need to be called with this retry logic.
|
||||
$helixApiRetries = 0
|
||||
$helixApiRetriesMax = 10
|
||||
|
||||
function Download-StringWithRetries
|
||||
{
|
||||
Param ([string]$fileName, [string]$url)
|
||||
|
||||
$result = ""
|
||||
$done = $false
|
||||
|
||||
while(!($done))
|
||||
{
|
||||
try
|
||||
{
|
||||
Write-Host "Downloading $fileName"
|
||||
$result = (New-Object System.Net.WebClient).DownloadString($url)
|
||||
$done = $true
|
||||
}
|
||||
catch
|
||||
{
|
||||
Write-Host "Failed to download $fileName $($PSItem.Exception)"
|
||||
|
||||
$helixApiRetries = $helixApiRetries + 1
|
||||
if($helixApiRetries -lt $helixApiRetriesMax)
|
||||
{
|
||||
Write-Host "Sleep and retry download of $fileName"
|
||||
Start-Sleep 60
|
||||
}
|
||||
else
|
||||
{
|
||||
throw "Failed to download $fileName"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $result
|
||||
}
|
||||
|
||||
function Invoke-RestMethodWithRetries
|
||||
{
|
||||
Param ([string]$url,$Headers)
|
||||
|
||||
$result = @()
|
||||
$done = $false
|
||||
|
||||
while(!($done))
|
||||
{
|
||||
try
|
||||
{
|
||||
$result = Invoke-RestMethod -Uri $url -Method Get -Headers $Headers
|
||||
$done = $true
|
||||
}
|
||||
catch
|
||||
{
|
||||
Write-Host "Failed to invoke Rest method $($PSItem.Exception)"
|
||||
|
||||
$helixApiRetries = $helixApiRetries + 1
|
||||
if($helixApiRetries -lt $helixApiRetriesMax)
|
||||
{
|
||||
Write-Host "Sleep and retry invoke"
|
||||
Start-Sleep 60
|
||||
}
|
||||
else
|
||||
{
|
||||
throw "Failed to invoke Rest method"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $result
|
||||
}
|
||||
|
||||
function Download-FileWithRetries
|
||||
{
|
||||
Param ([string]$fileurl, [string]$destination)
|
||||
|
||||
$done = $false
|
||||
|
||||
while(!($done))
|
||||
{
|
||||
try
|
||||
{
|
||||
Write-Host "Downloading $destination"
|
||||
$webClient.DownloadFile($fileurl, $destination)
|
||||
$done = $true
|
||||
}
|
||||
catch
|
||||
{
|
||||
Write-Host "Failed to download $destination $($PSItem.Exception)"
|
||||
|
||||
$helixApiRetries = $helixApiRetries + 1
|
||||
if($helixApiRetries -lt $helixApiRetriesMax)
|
||||
{
|
||||
Write-Host "Sleep and retry download of $destination"
|
||||
Start-Sleep 60
|
||||
}
|
||||
else
|
||||
{
|
||||
throw "Failed to download $destination"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -20,9 +20,7 @@ Param(
|
||||
$helixResultsContainerUri = $Env:HELIX_RESULTS_CONTAINER_URI
|
||||
$helixResultsContainerRsas = $Env:HELIX_RESULTS_CONTAINER_RSAS
|
||||
|
||||
$rerunPassesRequiredToAvoidFailure = $env:rerunPassesRequiredToAvoidFailure
|
||||
|
||||
Add-Type -Language CSharp -ReferencedAssemblies System.Xml,System.Xml.Linq,System.Runtime.Serialization,System.Runtime.Serialization.Json (Get-Content $PSScriptRoot\HelixTestHelpers.cs -Raw)
|
||||
|
||||
$testResultParser = [HelixTestHelpers.TestResultParser]::new($TestNamePrefix, $helixResultsContainerUri, $helixResultsContainerRsas)
|
||||
$testResultParser.ConvertWttLogToXUnitLog($WttInputPath, $WttSingleRerunInputPath, $WttMultipleRerunInputPath, $XUnitOutputPath, $rerunPassesRequiredToAvoidFailure)
|
||||
$testResultParser.ConvertWttLogToXUnitLog($WttInputPath, $WttSingleRerunInputPath, $WttMultipleRerunInputPath, $XUnitOutputPath)
|
||||
|
||||
@@ -1,112 +0,0 @@
|
||||
$scriptDirectory = $script:MyInvocation.MyCommand.Path | Split-Path -Parent
|
||||
|
||||
# List all processes to aid debugging:
|
||||
Write-Host "All processes running:"
|
||||
Get-Process
|
||||
|
||||
tasklist /svc
|
||||
|
||||
# Add this test directory as an exclusion for Windows Defender
|
||||
Write-Host "Add $scriptDirectory as Exclusion Path"
|
||||
Add-MpPreference -ExclusionPath $scriptDirectory
|
||||
Write-Host "Add $($env:HELIX_CORRELATION_PAYLOAD) as Exclusion Path"
|
||||
Add-MpPreference -ExclusionPath $env:HELIX_CORRELATION_PAYLOAD
|
||||
Get-MpPreference
|
||||
Get-MpComputerStatus
|
||||
|
||||
|
||||
# Minimize all windows:
|
||||
$shell = New-Object -ComObject "Shell.Application"
|
||||
$shell.minimizeall()
|
||||
|
||||
# Kill any instances of Windows Security Alert:
|
||||
$windowTitleToMatch = "*Windows Security Alert*"
|
||||
$procs = Get-Process | Where {$_.MainWindowTitle -like "*Windows Security Alert*"}
|
||||
foreach ($proc in $procs)
|
||||
{
|
||||
Write-Host "Found process with '$windowTitleToMatch' title: $proc"
|
||||
$proc.Kill();
|
||||
}
|
||||
|
||||
# Kill processes by name that are known to interfere with our tests:
|
||||
$processNamesToStop = @("Microsoft.Photos", "WinStore.App", "SkypeApp", "SkypeBackgroundHost", "OneDriveSetup", "OneDrive")
|
||||
foreach($procName in $processNamesToStop)
|
||||
{
|
||||
Write-Host "Attempting to kill $procName if it is running"
|
||||
Stop-Process -ProcessName $procName -Verbose -ErrorAction Ignore
|
||||
}
|
||||
Write-Host "All processes running after attempting to kill unwanted processes:"
|
||||
Get-Process
|
||||
|
||||
tasklist /svc
|
||||
|
||||
$platform = $env:testbuildplatform
|
||||
if(!$platform)
|
||||
{
|
||||
$platform = "x86"
|
||||
}
|
||||
|
||||
function UninstallApps {
|
||||
Param([string[]]$appsToUninstall)
|
||||
|
||||
foreach($pkgName in $appsToUninstall)
|
||||
{
|
||||
foreach($pkg in (Get-AppxPackage $pkgName).PackageFullName)
|
||||
{
|
||||
Write-Output "Removing: $pkg"
|
||||
Remove-AppxPackage $pkg
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function UninstallTestApps {
|
||||
Param([string[]]$appsToUninstall)
|
||||
|
||||
foreach($pkgName in $appsToUninstall)
|
||||
{
|
||||
foreach($pkg in (Get-AppxPackage $pkgName).PackageFullName)
|
||||
{
|
||||
Write-Output "Removing: $pkg"
|
||||
Remove-AppxPackage $pkg
|
||||
}
|
||||
|
||||
# Sometimes an app can get into a state where it is no longer returned by Get-AppxPackage, but it is still present
|
||||
# which prevents other versions of the app from being installed.
|
||||
# To handle this, we can directly call Remove-AppxPackage against the full name of the package. However, without
|
||||
# Get-AppxPackage to find the PackageFullName, we just have to manually construct the name.
|
||||
$packageFullName = "$($pkgName)_1.0.0.0_$($platform)__8wekyb3d8bbwe"
|
||||
Write-Host "Removing $packageFullName if installed"
|
||||
Remove-AppPackage $packageFullName -ErrorVariable appxerror -ErrorAction SilentlyContinue
|
||||
if($appxerror)
|
||||
{
|
||||
foreach($error in $appxerror)
|
||||
{
|
||||
# In most cases, Remove-AppPackage will fail due to the package not being found. Don't treat this as an error.
|
||||
if(!($error.Exception.Message -match "0x80073CF1"))
|
||||
{
|
||||
Write-Error $error
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Write-Host "Successfully removed $packageFullName"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Write-Host "Uninstall AppX packages that are known to cause issues with our tests"
|
||||
UninstallApps("*Skype*", "*Windows.Photos*")
|
||||
|
||||
Write-Host "Uninstall any of our test apps that may have been left over from previous test runs"
|
||||
UninstallTestApps("NugetPackageTestApp", "NugetPackageTestAppCX", "IXMPTestApp", "MUXControlsTestApp")
|
||||
|
||||
Write-Host "Uninstall MUX Framework package that may have been left over from previous test runs"
|
||||
# We don't want to uninstall all versions of the MUX Framework package, as there may be other apps preinstalled on the system
|
||||
# that depend on it. We only uninstall the Framework package that corresponds to the version of MUX that we are testing.
|
||||
[xml]$versionData = (Get-Content "version.props")
|
||||
$versionMajor = $versionData.GetElementsByTagName("MUXVersionMajor").'#text'
|
||||
$versionMinor = $versionData.GetElementsByTagName("MUXVersionMinor").'#text'
|
||||
UninstallApps("Microsoft.UI.Xaml.$versionMajor.$versionMinor")
|
||||
|
||||
Get-Process
|
||||
@@ -1,336 +0,0 @@
|
||||
[CmdLetBinding()]
|
||||
Param(
|
||||
[Parameter(Mandatory = $true)]
|
||||
[string]$TestFile,
|
||||
|
||||
[Parameter(Mandatory = $true)]
|
||||
[string]$OutputProjFile,
|
||||
|
||||
[Parameter(Mandatory = $true)]
|
||||
[string]$JobTestSuiteName,
|
||||
|
||||
[Parameter(Mandatory = $true)]
|
||||
[string]$TaefPath,
|
||||
|
||||
[string]$TaefQuery
|
||||
)
|
||||
|
||||
Class TestCollection
|
||||
{
|
||||
[string]$Name
|
||||
[string]$SetupMethodName
|
||||
[string]$TeardownMethodName
|
||||
[System.Collections.Generic.Dictionary[string, string]]$Properties
|
||||
|
||||
TestCollection()
|
||||
{
|
||||
if ($this.GetType() -eq [TestCollection])
|
||||
{
|
||||
throw "This class should never be instantiated directly; it should only be derived from."
|
||||
}
|
||||
}
|
||||
|
||||
TestCollection([string]$name)
|
||||
{
|
||||
$this.Init($name)
|
||||
}
|
||||
|
||||
hidden Init([string]$name)
|
||||
{
|
||||
$this.Name = $name
|
||||
$this.Properties = @{}
|
||||
}
|
||||
}
|
||||
|
||||
Class Test : TestCollection
|
||||
{
|
||||
Test([string]$name)
|
||||
{
|
||||
$this.Init($name)
|
||||
}
|
||||
}
|
||||
|
||||
Class TestClass : TestCollection
|
||||
{
|
||||
[System.Collections.Generic.List[Test]]$Tests
|
||||
|
||||
TestClass([string]$name)
|
||||
{
|
||||
$this.Init($name)
|
||||
$this.Tests = @{}
|
||||
}
|
||||
}
|
||||
|
||||
Class TestModule : TestCollection
|
||||
{
|
||||
[System.Collections.Generic.List[TestClass]]$TestClasses
|
||||
|
||||
TestModule([string]$name)
|
||||
{
|
||||
$this.Init($name)
|
||||
$this.TestClasses = @{}
|
||||
}
|
||||
}
|
||||
|
||||
function Parse-TestInfo([string]$taefOutput)
|
||||
{
|
||||
enum LineType
|
||||
{
|
||||
None
|
||||
TestModule
|
||||
TestClass
|
||||
Test
|
||||
Setup
|
||||
Teardown
|
||||
Property
|
||||
}
|
||||
|
||||
[string]$testModuleIndentation = " "
|
||||
[string]$testClassIndentation = " "
|
||||
[string]$testIndentation = " "
|
||||
[string]$setupBeginning = "Setup: "
|
||||
[string]$teardownBeginning = "Teardown: "
|
||||
[string]$propertyBeginning = "Property["
|
||||
|
||||
function Get-LineType([string]$line)
|
||||
{
|
||||
if ($line.Contains($setupBeginning))
|
||||
{
|
||||
return [LineType]::Setup;
|
||||
}
|
||||
elseif ($line.Contains($teardownBeginning))
|
||||
{
|
||||
return [LineType]::Teardown;
|
||||
}
|
||||
elseif ($line.Contains($propertyBeginning))
|
||||
{
|
||||
return [LineType]::Property;
|
||||
}
|
||||
elseif ($line.StartsWith($testModuleIndentation) -and -not $line.StartsWith("$testModuleIndentation "))
|
||||
{
|
||||
return [LineType]::TestModule;
|
||||
}
|
||||
elseif ($line.StartsWith($testClassIndentation) -and -not $line.StartsWith("$testClassIndentation "))
|
||||
{
|
||||
return [LineType]::TestClass;
|
||||
}
|
||||
elseif ($line.StartsWith($testIndentation) -and -not $line.StartsWith("$testIndentation "))
|
||||
{
|
||||
return [LineType]::Test;
|
||||
}
|
||||
else
|
||||
{
|
||||
return [LineType]::None;
|
||||
}
|
||||
}
|
||||
|
||||
[string[]]$lines = $taefOutput.Split(@([Environment]::NewLine, "`n"), [StringSplitOptions]::RemoveEmptyEntries)
|
||||
[System.Collections.Generic.List[TestModule]]$testModules = @()
|
||||
|
||||
[TestModule]$currentTestModule = $null
|
||||
[TestClass]$currentTestClass = $null
|
||||
[Test]$currentTest = $null
|
||||
|
||||
[TestCollection]$lastTestCollection = $null
|
||||
|
||||
foreach ($rawLine in $lines)
|
||||
{
|
||||
[LineType]$lineType = (Get-LineType $rawLine)
|
||||
|
||||
# We don't need the whitespace around the line anymore, so we'll discard it to make things easier.
|
||||
[string]$line = $rawLine.Trim()
|
||||
|
||||
if ($lineType -eq [LineType]::TestModule)
|
||||
{
|
||||
if ($currentTest -ne $null -and $currentTestClass -ne $null)
|
||||
{
|
||||
$currentTestClass.Tests.Add($currentTest)
|
||||
}
|
||||
|
||||
if ($currentTestClass -ne $null -and $currentTestModule -ne $null)
|
||||
{
|
||||
$currentTestModule.TestClasses.Add($currentTestClass)
|
||||
}
|
||||
|
||||
if ($currentTestModule -ne $null)
|
||||
{
|
||||
$testModules.Add($currentTestModule)
|
||||
}
|
||||
|
||||
$currentTestModule = [TestModule]::new($line)
|
||||
$currentTestClass = $null
|
||||
$currentTest = $null
|
||||
$lastTestCollection = $currentTestModule
|
||||
}
|
||||
elseif ($lineType -eq [LineType]::TestClass)
|
||||
{
|
||||
if ($currentTest -ne $null -and $currentTestClass -ne $null)
|
||||
{
|
||||
$currentTestClass.Tests.Add($currentTest)
|
||||
}
|
||||
|
||||
if ($currentTestClass -ne $null -and $currentTestModule -ne $null)
|
||||
{
|
||||
$currentTestModule.TestClasses.Add($currentTestClass)
|
||||
}
|
||||
|
||||
$currentTestClass = [TestClass]::new($line)
|
||||
$currentTest = $null
|
||||
$lastTestCollection = $currentTestClass
|
||||
}
|
||||
elseif ($lineType -eq [LineType]::Test)
|
||||
{
|
||||
if ($currentTest -ne $null -and $currentTestClass -ne $null)
|
||||
{
|
||||
$currentTestClass.Tests.Add($currentTest)
|
||||
}
|
||||
|
||||
$currentTest = [Test]::new($line)
|
||||
$lastTestCollection = $currentTest
|
||||
}
|
||||
elseif ($lineType -eq [LineType]::Setup)
|
||||
{
|
||||
if ($lastTestCollection -ne $null)
|
||||
{
|
||||
$lastTestCollection.SetupMethodName = $line.Replace($setupBeginning, "")
|
||||
}
|
||||
}
|
||||
elseif ($lineType -eq [LineType]::Teardown)
|
||||
{
|
||||
if ($lastTestCollection -ne $null)
|
||||
{
|
||||
$lastTestCollection.TeardownMethodName = $line.Replace($teardownBeginning, "")
|
||||
}
|
||||
}
|
||||
elseif ($lineType -eq [LineType]::Property)
|
||||
{
|
||||
if ($lastTestCollection -ne $null)
|
||||
{
|
||||
foreach ($match in [Regex]::Matches($line, "Property\[(.*)\]\s+=\s+(.*)"))
|
||||
{
|
||||
[string]$propertyKey = $match.Groups[1].Value;
|
||||
[string]$propertyValue = $match.Groups[2].Value;
|
||||
$lastTestCollection.Properties.Add($propertyKey, $propertyValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($currentTest -ne $null -and $currentTestClass -ne $null)
|
||||
{
|
||||
$currentTestClass.Tests.Add($currentTest)
|
||||
}
|
||||
|
||||
if ($currentTestClass -ne $null -and $currentTestModule -ne $null)
|
||||
{
|
||||
$currentTestModule.TestClasses.Add($currentTestClass)
|
||||
}
|
||||
|
||||
if ($currentTestModule -ne $null)
|
||||
{
|
||||
$testModules.Add($currentTestModule)
|
||||
}
|
||||
|
||||
return $testModules
|
||||
}
|
||||
|
||||
Write-Verbose "TaefQuery = $TaefQuery"
|
||||
|
||||
$TaefSelectQuery = ""
|
||||
$TaefQueryToAppend = ""
|
||||
if($TaefQuery)
|
||||
{
|
||||
$TaefSelectQuery = "/select:`"$TaefQuery`""
|
||||
$TaefQueryToAppend = " and $TaefQuery"
|
||||
}
|
||||
Write-Verbose "TaefSelectQuery = $TaefSelectQuery"
|
||||
|
||||
|
||||
$taefExe = "$TaefPath\te.exe"
|
||||
[string]$taefOutput = & "$taefExe" /listproperties $TaefSelectQuery $TestFile | Out-String
|
||||
|
||||
[System.Collections.Generic.List[TestModule]]$testModules = (Parse-TestInfo $taefOutput)
|
||||
|
||||
$projFileContent = @"
|
||||
<Project>
|
||||
<ItemGroup>
|
||||
"@
|
||||
|
||||
foreach ($testModule in $testModules)
|
||||
{
|
||||
foreach ($testClass in $testModules.TestClasses)
|
||||
{
|
||||
Write-Host "Generating Helix work item for test class $($testClass.Name)..."
|
||||
[System.Collections.Generic.List[string]]$testSuiteNames = @()
|
||||
|
||||
$testSuiteExists = $false
|
||||
$suitelessTestExists = $false
|
||||
|
||||
foreach ($test in $testClass.Tests)
|
||||
{
|
||||
# A test method inherits its 'TestSuite' property from its TestClass
|
||||
if (!$test.Properties.ContainsKey("TestSuite") -and $testClass.Properties.ContainsKey("TestSuite"))
|
||||
{
|
||||
$test.Properties["TestSuite"] = $testClass.Properties["TestSuite"]
|
||||
}
|
||||
|
||||
if ($test.Properties.ContainsKey("TestSuite"))
|
||||
{
|
||||
[string]$testSuite = $test.Properties["TestSuite"]
|
||||
|
||||
if (-not $testSuiteNames.Contains($testSuite))
|
||||
{
|
||||
Write-Host " Found test suite $testSuite. Generating Helix work item for it as well."
|
||||
$testSuiteNames.Add($testSuite)
|
||||
}
|
||||
|
||||
$testSuiteExists = $true
|
||||
}
|
||||
else
|
||||
{
|
||||
$suitelessTestExists = $true
|
||||
}
|
||||
}
|
||||
|
||||
$testClassSelectPattern = "$($testClass.Name).*"
|
||||
if($testClass.Name.Contains("::"))
|
||||
{
|
||||
$testClassSelectPattern = "$($testClass.Name)::*"
|
||||
}
|
||||
$testNameQuery= "(@Name='$testClassSelectPattern')"
|
||||
|
||||
$workItemName = $testClass.Name
|
||||
# Native tests use '::' as a separator, which is not valid for workItem names.
|
||||
$workItemName = $workItemName -replace "::", "-"
|
||||
|
||||
if ($suitelessTestExists)
|
||||
{
|
||||
$projFileContent += @"
|
||||
|
||||
<HelixWorkItem Include="$($workItemName)" Condition="'`$(TestSuite)'=='$($JobTestSuiteName)'">
|
||||
<Timeout>00:30:00</Timeout>
|
||||
<Command>call %HELIX_CORRELATION_PAYLOAD%\runtests.cmd /select:"(@Name='$($testClass.Name)*'$(if ($testSuiteExists) { "and not @TestSuite='*'" }))$($TaefQueryToAppend)"</Command>
|
||||
</HelixWorkItem>
|
||||
"@
|
||||
}
|
||||
|
||||
foreach ($testSuiteName in $testSuiteNames)
|
||||
{
|
||||
$projFileContent += @"
|
||||
|
||||
<HelixWorkItem Include="$($workItemName)-$testSuiteName" Condition="'`$(TestSuite)'=='$($JobTestSuiteName)'">
|
||||
<Timeout>00:30:00</Timeout>
|
||||
<Command>call %HELIX_CORRELATION_PAYLOAD%\runtests.cmd /select:"(@Name='$($testClass.Name)*' and @TestSuite='$testSuiteName')$($TaefQueryToAppend)"</Command>
|
||||
</HelixWorkItem>
|
||||
"@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$projFileContent += @"
|
||||
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
"@
|
||||
|
||||
Set-Content $OutputProjFile $projFileContent -NoNewline -Encoding UTF8
|
||||
@@ -20,32 +20,13 @@ namespace HelixTestHelpers
|
||||
public string Name { get; set; }
|
||||
public string SourceWttFile { get; set; }
|
||||
public bool Passed { get; set; }
|
||||
public bool Skipped { get; set; }
|
||||
public bool CleanupPassed { get; set; }
|
||||
public TimeSpan ExecutionTime { get; set; }
|
||||
public string Details { get; set; }
|
||||
|
||||
public List<string> Screenshots { get; private set; }
|
||||
public List<TestResult> RerunResults { get; private set; }
|
||||
|
||||
// Returns true if the test pass rate is sufficient to avoid being counted as a failure.
|
||||
public bool PassedOrUnreliable(int requiredNumberOfPasses)
|
||||
{
|
||||
if(Passed)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(RerunResults.Count == 1)
|
||||
{
|
||||
return RerunResults[0].Passed;
|
||||
}
|
||||
else
|
||||
{
|
||||
return RerunResults.Where(r => r.Passed).Count() >= requiredNumberOfPasses;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
@@ -221,7 +202,9 @@ namespace HelixTestHelpers
|
||||
testsExecuting--;
|
||||
|
||||
// If any inner test fails, we'll still fail the outer
|
||||
currentResult.Passed &= element.Attribute("Result").Value == "Pass";
|
||||
var value = element.Attribute("Result").Value;
|
||||
currentResult.Passed = value == "Pass";
|
||||
currentResult.Skipped = value == "Skipped";
|
||||
|
||||
// Only gather execution data if this is the outer test we ran initially
|
||||
if (testsExecuting == 0)
|
||||
@@ -498,7 +481,7 @@ namespace HelixTestHelpers
|
||||
return subResultsJsonByMethod;
|
||||
}
|
||||
|
||||
public void ConvertWttLogToXUnitLog(string wttInputPath, string wttSingleRerunInputPath, string wttMultipleRerunInputPath, string xunitOutputPath, int requiredPassRateThreshold)
|
||||
public void ConvertWttLogToXUnitLog(string wttInputPath, string wttSingleRerunInputPath, string wttMultipleRerunInputPath, string xunitOutputPath)
|
||||
{
|
||||
TestPass testPass = TestPass.ParseTestWttFileWithReruns(wttInputPath, wttSingleRerunInputPath, wttMultipleRerunInputPath, cleanupFailuresAreRegressions: true, truncateTestNames: false);
|
||||
var results = testPass.TestResults;
|
||||
@@ -510,8 +493,8 @@ namespace HelixTestHelpers
|
||||
// If the test failed sufficiently often enough for it to count as a failed test (determined by a property on the
|
||||
// Azure DevOps job), we'll later mark it as failed during test results processing.
|
||||
|
||||
int failedCount = results.Where(r => !r.PassedOrUnreliable(requiredPassRateThreshold)).Count();
|
||||
int skippedCount = results.Where(r => !r.Passed && r.PassedOrUnreliable(requiredPassRateThreshold)).Count();
|
||||
int failedCount = results.Where(r => !r.Passed).Count();
|
||||
int skippedCount = results.Where(r => (!r.Passed && r.Skipped)).Count();
|
||||
|
||||
var root = new XElement("assemblies");
|
||||
|
||||
@@ -557,12 +540,13 @@ namespace HelixTestHelpers
|
||||
|
||||
string resultString = string.Empty;
|
||||
|
||||
if (result.Passed)
|
||||
if (result.Passed && !result.Skipped)
|
||||
{
|
||||
resultString = "Pass";
|
||||
}
|
||||
else if(result.PassedOrUnreliable(requiredPassRateThreshold))
|
||||
else if (result.Skipped)
|
||||
{
|
||||
|
||||
resultString = "Skip";
|
||||
}
|
||||
else
|
||||
@@ -571,31 +555,25 @@ namespace HelixTestHelpers
|
||||
}
|
||||
|
||||
|
||||
test.SetAttributeValue("result", resultString);
|
||||
|
||||
if (!result.Passed)
|
||||
{
|
||||
// If a test failed, we'll have rerun it multiple times.
|
||||
// We'll save the subresults to a JSON text file that we'll upload to the helix results container -
|
||||
// this allows it to be as long as we want, whereas the reason field in Azure DevOps has a 4000 character limit.
|
||||
string subResultsFileName = methodName + "_subresults.json";
|
||||
string subResultsFilePath = Path.Combine(Path.GetDirectoryName(wttInputPath), subResultsFileName);
|
||||
|
||||
if (result.PassedOrUnreliable(requiredPassRateThreshold))
|
||||
if (result.Skipped)
|
||||
{
|
||||
var reason = new XElement("reason");
|
||||
reason.Add(new XCData(GetUploadedFileUrl(subResultsFileName, helixResultsContainerUri, helixResultsContainerRsas)));
|
||||
reason.Add(new XCData("Test skipped"));
|
||||
test.Add(reason);
|
||||
}
|
||||
else
|
||||
{
|
||||
else {
|
||||
var failure = new XElement("failure");
|
||||
var message = new XElement("message");
|
||||
message.Add(new XCData(GetUploadedFileUrl(subResultsFileName, helixResultsContainerUri, helixResultsContainerRsas)));
|
||||
message.Add(new XCData("Test failed"));
|
||||
failure.Add(message);
|
||||
test.Add(failure);
|
||||
}
|
||||
}
|
||||
|
||||
test.SetAttributeValue("result", resultString);
|
||||
|
||||
collection.Add(test);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
# Displaying progress is unnecessary and is just distracting.
|
||||
$ProgressPreference = "SilentlyContinue"
|
||||
|
||||
$dependencyFiles = Get-ChildItem -Filter "*Microsoft.VCLibs.*.appx"
|
||||
|
||||
foreach ($file in $dependencyFiles)
|
||||
{
|
||||
Write-Host "Adding dependency $($file)..."
|
||||
|
||||
Add-AppxPackage $file
|
||||
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
Param(
|
||||
[Parameter(Mandatory = $true)]
|
||||
[string]$WttInputPath
|
||||
)
|
||||
|
||||
Add-Type -Language CSharp -ReferencedAssemblies System.Xml,System.Xml.Linq,System.Runtime.Serialization,System.Runtime.Serialization.Json (Get-Content $PSScriptRoot\HelixTestHelpers.cs -Raw)
|
||||
|
||||
[HelixTestHelpers.FailedTestDetector]::OutputFailedTestQuery($WttInputPath)
|
||||
@@ -1,32 +0,0 @@
|
||||
Param(
|
||||
[Parameter(Mandatory = $true)]
|
||||
[string]$WttInputPath,
|
||||
|
||||
[Parameter(Mandatory = $true)]
|
||||
[string]$WttSingleRerunInputPath,
|
||||
|
||||
[Parameter(Mandatory = $true)]
|
||||
[string]$WttMultipleRerunInputPath,
|
||||
|
||||
[Parameter(Mandatory = $true)]
|
||||
[string]$TestNamePrefix
|
||||
)
|
||||
|
||||
# Ideally these would be passed as parameters to the script. However ps makes it difficult to deal with string literals containing '&', so we just
|
||||
# read the values directly from the environment variables
|
||||
$helixResultsContainerUri = $Env:HELIX_RESULTS_CONTAINER_URI
|
||||
$helixResultsContainerRsas = $Env:HELIX_RESULTS_CONTAINER_RSAS
|
||||
|
||||
Add-Type -Language CSharp -ReferencedAssemblies System.Xml,System.Xml.Linq,System.Runtime.Serialization,System.Runtime.Serialization.Json (Get-Content $PSScriptRoot\HelixTestHelpers.cs -Raw)
|
||||
|
||||
$testResultParser = [HelixTestHelpers.TestResultParser]::new($TestNamePrefix, $helixResultsContainerUri, $helixResultsContainerRsas)
|
||||
[System.Collections.Generic.Dictionary[string, string]]$subResultsJsonByMethodName = $testResultParser.GetSubResultsJsonByMethodName($WttInputPath, $WttSingleRerunInputPath, $WttMultipleRerunInputPath)
|
||||
|
||||
$subResultsJsonDirectory = [System.IO.Path]::GetDirectoryName($WttInputPath)
|
||||
|
||||
foreach ($methodName in $subResultsJsonByMethodName.Keys)
|
||||
{
|
||||
$subResultsJson = $subResultsJsonByMethodName[$methodName]
|
||||
$subResultsJsonPath = [System.IO.Path]::Combine($subResultsJsonDirectory, $methodName + "_subresults.json")
|
||||
Out-File $subResultsJsonPath -Encoding utf8 -InputObject $subResultsJson
|
||||
}
|
||||
38
build/Helix/OutputTestErrorsForAzureDevops.ps1
Normal file
38
build/Helix/OutputTestErrorsForAzureDevops.ps1
Normal file
@@ -0,0 +1,38 @@
|
||||
Param(
|
||||
[Parameter(Mandatory = $true)]
|
||||
[string]$XUnitOutputPath
|
||||
)
|
||||
|
||||
# This script is used to parse the XUnit output from the test runs and print out
|
||||
# the tests that failed.
|
||||
#
|
||||
# Why you might ask? Well, it sure seems like Azure DevOps doesn't like the fact
|
||||
# that we just call our tests in a powershell script. It can't seemingly find
|
||||
# the actual errors in the TAEF logs. That means when you just go to the
|
||||
# "Checks" page on GitHub, the Azure DevOps integration doesn't have anything
|
||||
# meaningful to say other than "PowerShell exited with code '1'". If we however,
|
||||
# just manually emit the test names formatted with "#[error]" in front of them,
|
||||
# well, then the integration will all work like magic.
|
||||
|
||||
# Load the test results as a XML object
|
||||
$testResults = [xml](Get-Content -Path $XUnitOutputPath)
|
||||
|
||||
# Our XML looks like:
|
||||
# <assemblies>
|
||||
# <assembly name="MUXControls.Test.dll" test-framework="TAEF" run-date="2023-08-14" run-time="11:38:01" total="524" passed="520" failed="4" skipped="1" time="8943" errors="0">
|
||||
# <collection total="524" passed="520" failed="4" skipped="1" name="Test collection" time="8943">
|
||||
# <test name="ControlCoreTests::TestSimpleClickSelection" type="ControlCoreTests" method="TestSimpleClickSelection" time="0.016" result="Fail">
|
||||
|
||||
# Iterate over all the assemblies and print all the tests that failed
|
||||
foreach ($assembly in $testResults.assemblies.assembly) {
|
||||
foreach ($collection in $assembly.collection) {
|
||||
foreach ($test in $collection.test) {
|
||||
if ($test.result -eq "Fail") {
|
||||
# This particular format is taken from the Azure DevOps documentation:
|
||||
# https://github.com/microsoft/azure-pipelines-tasks/blob/master/docs/authoring/commands.md
|
||||
# This will treat this line as an error message
|
||||
Write-Output "##vso[task.logissue type=error]$($test.name) Failed"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,131 +0,0 @@
|
||||
Param(
|
||||
[Parameter(Mandatory = $true)]
|
||||
[int]$MinimumExpectedTestsExecutedCount,
|
||||
|
||||
[string]$AccessToken = $env:SYSTEM_ACCESSTOKEN,
|
||||
[string]$CollectionUri = $env:SYSTEM_COLLECTIONURI,
|
||||
[string]$TeamProject = $env:SYSTEM_TEAMPROJECT,
|
||||
[string]$BuildUri = $env:BUILD_BUILDURI,
|
||||
[bool]$CheckJobAttempt
|
||||
)
|
||||
|
||||
$azureDevOpsRestApiHeaders = @{
|
||||
"Accept"="application/json"
|
||||
"Authorization"="Basic $([System.Convert]::ToBase64String([System.Text.ASCIIEncoding]::ASCII.GetBytes(":$AccessToken")))"
|
||||
}
|
||||
|
||||
. "$PSScriptRoot/AzurePipelinesHelperScripts.ps1"
|
||||
|
||||
Write-Host "Checking test results..."
|
||||
|
||||
$queryUri = GetQueryTestRunsUri -CollectionUri $CollectionUri -TeamProject $TeamProject -BuildUri $BuildUri -IncludeRunDetails
|
||||
Write-Host "queryUri = $queryUri"
|
||||
|
||||
$testRuns = Invoke-RestMethodWithRetries $queryUri -Headers $azureDevOpsRestApiHeaders
|
||||
[System.Collections.Generic.List[string]]$failingTests = @()
|
||||
[System.Collections.Generic.List[string]]$unreliableTests = @()
|
||||
[System.Collections.Generic.List[string]]$unexpectedResultTest = @()
|
||||
|
||||
[System.Collections.Generic.List[string]]$namesOfProcessedTestRuns = @()
|
||||
$totalTestsExecutedCount = 0
|
||||
|
||||
# We assume that we only have one testRun with a given name that we care about
|
||||
# We only process the last testRun with a given name (based on completedDate)
|
||||
# The name of a testRun is set to the Helix queue that it was run on (e.g. windows.10.amd64.client21h1.xaml)
|
||||
# If we have multiple test runs on the same queue that we care about, we will need to re-visit this logic
|
||||
foreach ($testRun in ($testRuns.value | Sort-Object -Property "completedDate" -Descending))
|
||||
{
|
||||
if ($CheckJobAttempt)
|
||||
{
|
||||
if ($namesOfProcessedTestRuns -contains $testRun.name)
|
||||
{
|
||||
Write-Host "Skipping test run '$($testRun.name)', since we have already processed a test run of that name."
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
Write-Host "Processing results from test run '$($testRun.name)'"
|
||||
$namesOfProcessedTestRuns.Add($testRun.name)
|
||||
|
||||
$totalTestsExecutedCount += $testRun.totalTests
|
||||
|
||||
$testRunResultsUri = "$($testRun.url)/results?api-version=5.0"
|
||||
$testResults = Invoke-RestMethodWithRetries "$($testRun.url)/results?api-version=5.0" -Headers $azureDevOpsRestApiHeaders
|
||||
|
||||
foreach ($testResult in $testResults.value)
|
||||
{
|
||||
$shortTestCaseTitle = $testResult.testCaseTitle -replace "[a-zA-Z0-9]+.[a-zA-Z0-9]+.Windows.UI.Xaml.Tests.MUXControls.",""
|
||||
|
||||
if ($testResult.outcome -eq "Failed")
|
||||
{
|
||||
if (-not $failingTests.Contains($shortTestCaseTitle))
|
||||
{
|
||||
$failingTests.Add($shortTestCaseTitle)
|
||||
}
|
||||
}
|
||||
elseif ($testResult.outcome -eq "Warning")
|
||||
{
|
||||
if (-not $unreliableTests.Contains($shortTestCaseTitle))
|
||||
{
|
||||
$unreliableTests.Add($shortTestCaseTitle)
|
||||
}
|
||||
}
|
||||
elseif ($testResult.outcome -ne "Passed")
|
||||
{
|
||||
# We should only see tests with result "Passed", "Failed" or "Warning"
|
||||
if (-not $unexpectedResultTest.Contains($shortTestCaseTitle))
|
||||
{
|
||||
$unexpectedResultTest.Add($shortTestCaseTitle)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($unreliableTests.Count -gt 0)
|
||||
{
|
||||
Write-Host @"
|
||||
##vso[task.logissue type=warning;]Unreliable tests:
|
||||
##vso[task.logissue type=warning;]$($unreliableTests -join "$([Environment]::NewLine)##vso[task.logissue type=warning;]")
|
||||
|
||||
"@
|
||||
}
|
||||
|
||||
if ($failingTests.Count -gt 0)
|
||||
{
|
||||
Write-Host @"
|
||||
##vso[task.logissue type=error;]Failing tests:
|
||||
##vso[task.logissue type=error;]$($failingTests -join "$([Environment]::NewLine)##vso[task.logissue type=error;]")
|
||||
|
||||
"@
|
||||
}
|
||||
|
||||
if ($unexpectedResultTest.Count -gt 0)
|
||||
{
|
||||
Write-Host @"
|
||||
##vso[task.logissue type=error;]Tests with unexpected results:
|
||||
##vso[task.logissue type=error;]$($unexpectedResultTest -join "$([Environment]::NewLine)##vso[task.logissue type=error;]")
|
||||
|
||||
"@
|
||||
}
|
||||
|
||||
if($totalTestsExecutedCount -lt $MinimumExpectedTestsExecutedCount)
|
||||
{
|
||||
Write-Host "Expected at least $MinimumExpectedTestsExecutedCount tests to be executed."
|
||||
Write-Host "Actual executed test count is: $totalTestsExecutedCount"
|
||||
Write-Host "##vso[task.complete result=Failed;]"
|
||||
}
|
||||
elseif ($failingTests.Count -gt 0)
|
||||
{
|
||||
Write-Host "At least one test failed."
|
||||
Write-Host "##vso[task.complete result=Failed;]"
|
||||
}
|
||||
elseif ($unreliableTests.Count -gt 0)
|
||||
{
|
||||
Write-Host "All tests eventually passed, but some initially failed."
|
||||
Write-Host "##vso[task.complete result=Succeeded;]"
|
||||
}
|
||||
else
|
||||
{
|
||||
Write-Host "All tests passed."
|
||||
Write-Host "##vso[task.complete result=Succeeded;]"
|
||||
}
|
||||
@@ -1,62 +0,0 @@
|
||||
[CmdLetBinding()]
|
||||
Param(
|
||||
[string]$Platform,
|
||||
[string]$Configuration,
|
||||
[string]$ArtifactName='drop'
|
||||
)
|
||||
|
||||
$payloadDir = "HelixPayload\$Configuration\$Platform"
|
||||
|
||||
$repoDirectory = Join-Path (Split-Path -Parent $script:MyInvocation.MyCommand.Path) "..\..\"
|
||||
$nugetPackagesDir = Join-Path (Split-Path -Parent $script:MyInvocation.MyCommand.Path) "packages"
|
||||
|
||||
# Create the payload directory. Remove it if it already exists.
|
||||
If(test-path $payloadDir)
|
||||
{
|
||||
Remove-Item $payloadDir -Recurse
|
||||
}
|
||||
New-Item -ItemType Directory -Force -Path $payloadDir
|
||||
|
||||
# Copy files from nuget packages
|
||||
Copy-Item "$nugetPackagesDir\microsoft.windows.apps.test.1.0.181203002\lib\netcoreapp2.1\*.dll" $payloadDir
|
||||
Copy-Item "$nugetPackagesDir\Microsoft.Taef.10.60.210621002\build\Binaries\$Platform\*" $payloadDir
|
||||
Copy-Item "$nugetPackagesDir\Microsoft.Taef.10.60.210621002\build\Binaries\$Platform\NetFx4.5\*" $payloadDir
|
||||
New-Item -ItemType Directory -Force -Path "$payloadDir\.NETCoreApp2.1\"
|
||||
Copy-Item "$nugetPackagesDir\runtime.win-$Platform.microsoft.netcore.app.2.1.0\runtimes\win-$Platform\lib\netcoreapp2.1\*" "$payloadDir\.NETCoreApp2.1\"
|
||||
Copy-Item "$nugetPackagesDir\runtime.win-$Platform.microsoft.netcore.app.2.1.0\runtimes\win-$Platform\native\*" "$payloadDir\.NETCoreApp2.1\"
|
||||
New-Item -ItemType Directory -Force -Path "$payloadDir\content\"
|
||||
Copy-Item "$nugetPackagesDir\Microsoft.Internal.Windows.Terminal.TestContent.1.0.1\content\*" "$payloadDir\content\"
|
||||
|
||||
function Copy-If-Exists
|
||||
{
|
||||
Param($source, $destinationDir)
|
||||
|
||||
if (Test-Path $source)
|
||||
{
|
||||
Write-Host "Copy from '$source' to '$destinationDir'"
|
||||
Copy-Item -Force $source $destinationDir
|
||||
}
|
||||
else
|
||||
{
|
||||
Write-Host "'$source' does not exist."
|
||||
}
|
||||
}
|
||||
|
||||
# Copy files from the 'drop' artifact dir
|
||||
Copy-Item "$repoDirectory\Artifacts\$ArtifactName\$Configuration\$Platform\Test\*" $payloadDir -Recurse
|
||||
|
||||
# Copy files from the repo
|
||||
New-Item -ItemType Directory -Force -Path "$payloadDir"
|
||||
Copy-Item "build\helix\ConvertWttLogToXUnit.ps1" "$payloadDir"
|
||||
Copy-Item "build\helix\OutputFailedTestQuery.ps1" "$payloadDir"
|
||||
Copy-Item "build\helix\OutputSubResultsJsonFiles.ps1" "$payloadDir"
|
||||
Copy-Item "build\helix\HelixTestHelpers.cs" "$payloadDir"
|
||||
Copy-Item "build\helix\runtests.cmd" $payloadDir
|
||||
Copy-Item "build\helix\InstallTestAppDependencies.ps1" "$payloadDir"
|
||||
Copy-Item "build\Helix\EnsureMachineState.ps1" "$payloadDir"
|
||||
|
||||
# Extract the unpackaged distribution of Windows Terminal to the payload directory,
|
||||
# where it will create a subdirectory named terminal-0.0.1.0
|
||||
# This is referenced in TerminalApp.cs later as part of the test harness.
|
||||
& tar -x -v -f "$repoDirectory\Artifacts\$ArtifactName\unpackaged\WindowsTerminalDev_0.0.1.0_x64.zip" -C "$payloadDir"
|
||||
Copy-Item "res\fonts\*.ttf" "$payloadDir\terminal-0.0.1.0"
|
||||
@@ -1,130 +0,0 @@
|
||||
Param(
|
||||
[string]$AccessToken = $env:SYSTEM_ACCESSTOKEN,
|
||||
[string]$HelixAccessToken = $env:HelixAccessToken,
|
||||
[string]$CollectionUri = $env:SYSTEM_COLLECTIONURI,
|
||||
[string]$TeamProject = $env:SYSTEM_TEAMPROJECT,
|
||||
[string]$BuildUri = $env:BUILD_BUILDURI,
|
||||
[string]$OutputFolder = "HelixOutput"
|
||||
)
|
||||
|
||||
$helixLinkFile = "$OutputFolder\LinksToHelixTestFiles.html"
|
||||
|
||||
|
||||
function Generate-File-Links
|
||||
{
|
||||
Param ([Array[]]$files,[string]$sectionName)
|
||||
if($files.Count -gt 0)
|
||||
{
|
||||
Out-File -FilePath $helixLinkFile -Append -InputObject "<div class=$sectionName>"
|
||||
Out-File -FilePath $helixLinkFile -Append -InputObject "<h4>$sectionName</h4>"
|
||||
Out-File -FilePath $helixLinkFile -Append -InputObject "<ul>"
|
||||
foreach($file in $files)
|
||||
{
|
||||
$url = Append-HelixAccessTokenToUrl $file.Link "{Your-Helix-Access-Token-Here}"
|
||||
Out-File -FilePath $helixLinkFile -Append -InputObject "<li>$($url)</li>"
|
||||
}
|
||||
Out-File -FilePath $helixLinkFile -Append -InputObject "</ul>"
|
||||
Out-File -FilePath $helixLinkFile -Append -InputObject "</div>"
|
||||
}
|
||||
}
|
||||
|
||||
function Append-HelixAccessTokenToUrl
|
||||
{
|
||||
Param ([string]$url, [string]$token)
|
||||
if($token)
|
||||
{
|
||||
if($url.Contains("?"))
|
||||
{
|
||||
$url = "$($url)&access_token=$($token)"
|
||||
}
|
||||
else
|
||||
{
|
||||
$url = "$($url)?access_token=$($token)"
|
||||
}
|
||||
}
|
||||
return $url
|
||||
}
|
||||
|
||||
#Create output directory
|
||||
New-Item $OutputFolder -ItemType Directory
|
||||
|
||||
$azureDevOpsRestApiHeaders = @{
|
||||
"Accept"="application/json"
|
||||
"Authorization"="Basic $([System.Convert]::ToBase64String([System.Text.ASCIIEncoding]::ASCII.GetBytes(":$AccessToken")))"
|
||||
}
|
||||
|
||||
. "$PSScriptRoot/AzurePipelinesHelperScripts.ps1"
|
||||
|
||||
$queryUri = GetQueryTestRunsUri -CollectionUri $CollectionUri -TeamProject $TeamProject -BuildUri $BuildUri -IncludeRunDetails
|
||||
Write-Host "queryUri = $queryUri"
|
||||
|
||||
$testRuns = Invoke-RestMethodWithRetries $queryUri -Headers $azureDevOpsRestApiHeaders
|
||||
$webClient = New-Object System.Net.WebClient
|
||||
[System.Collections.Generic.List[string]]$workItems = @()
|
||||
|
||||
foreach ($testRun in $testRuns.value)
|
||||
{
|
||||
Write-Host "testRunUri = $testRun.url"
|
||||
$testResults = Invoke-RestMethodWithRetries "$($testRun.url)/results?api-version=5.0" -Headers $azureDevOpsRestApiHeaders
|
||||
$isTestRunNameShown = $false
|
||||
|
||||
foreach ($testResult in $testResults.value)
|
||||
{
|
||||
$info = ConvertFrom-Json ([System.Web.HttpUtility]::HtmlDecode($testResult.comment))
|
||||
$helixJobId = $info.HelixJobId
|
||||
$helixWorkItemName = $info.HelixWorkItemName
|
||||
|
||||
$workItem = "$helixJobId-$helixWorkItemName"
|
||||
|
||||
Write-Host "Helix Work Item = $workItem"
|
||||
|
||||
if (-not $workItems.Contains($workItem))
|
||||
{
|
||||
$workItems.Add($workItem)
|
||||
$filesQueryUri = "https://helix.dot.net/api/2019-06-17/jobs/$helixJobId/workitems/$helixWorkItemName/files"
|
||||
$filesQueryUri = Append-HelixAccessTokenToUrl $filesQueryUri $helixAccessToken
|
||||
$files = Invoke-RestMethodWithRetries $filesQueryUri
|
||||
|
||||
$screenShots = $files | where { $_.Name.EndsWith(".jpg") }
|
||||
$dumps = $files | where { $_.Name.EndsWith(".dmp") }
|
||||
$pgcFiles = $files | where { $_.Name.EndsWith(".pgc") }
|
||||
if ($screenShots.Count + $dumps.Count + $pgcFiles.Count -gt 0)
|
||||
{
|
||||
if(-Not $isTestRunNameShown)
|
||||
{
|
||||
Out-File -FilePath $helixLinkFile -Append -InputObject "<h2>$($testRun.name)</h2>"
|
||||
$isTestRunNameShown = $true
|
||||
}
|
||||
Out-File -FilePath $helixLinkFile -Append -InputObject "<h3>$helixWorkItemName</h3>"
|
||||
Generate-File-Links $screenShots "Screenshots"
|
||||
Generate-File-Links $dumps "CrashDumps"
|
||||
Generate-File-Links $pgcFiles "PGC files"
|
||||
$misc = $files | where { ($screenShots -NotContains $_) -And ($dumps -NotContains $_) -And ($visualTreeVerificationFiles -NotContains $_) -And ($pgcFiles -NotContains $_) }
|
||||
Generate-File-Links $misc "Misc"
|
||||
|
||||
foreach($pgcFile in $pgcFiles)
|
||||
{
|
||||
$flavorPath = $testResult.automatedTestName.Split('.')[0]
|
||||
$archPath = $testResult.automatedTestName.Split('.')[1]
|
||||
$fileName = $pgcFile.Name
|
||||
$fullPath = "$OutputFolder\PGO\$flavorPath\$archPath"
|
||||
$destination = "$fullPath\$fileName"
|
||||
|
||||
Write-Host "Copying $($pgcFile.Name) to $destination"
|
||||
|
||||
if (-Not (Test-Path $fullPath))
|
||||
{
|
||||
New-Item $fullPath -ItemType Directory
|
||||
}
|
||||
|
||||
$link = $pgcFile.Link
|
||||
|
||||
Write-Host "Downloading $link to $destination"
|
||||
|
||||
$link = Append-HelixAccessTokenToUrl $link $HelixAccessToken
|
||||
Download-FileWithRetries $link $destination
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
<Project Sdk="Microsoft.DotNet.Helix.Sdk" DefaultTargets="Test">
|
||||
<PropertyGroup>
|
||||
<HelixSource>pr/terminal/$(BUILD_SOURCEBRANCH)/</HelixSource>
|
||||
<EnableXUnitReporter>true</EnableXUnitReporter>
|
||||
<EnableAzurePipelinesReporter>true</EnableAzurePipelinesReporter>
|
||||
<FailOnMissionControlTestFailure>true</FailOnMissionControlTestFailure>
|
||||
<HelixPreCommands>$(HelixPreCommands);set testnameprefix=$(Configuration).$(Platform);set testbuildplatform=$(Platform);set rerunPassesRequiredToAvoidFailure=$(rerunPassesRequiredToAvoidFailure)</HelixPreCommands>
|
||||
<OutputPath>..\..\bin\$(Platform)\$(Configuration)\</OutputPath>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<HelixCorrelationPayload Include="..\..\HelixPayload\$(Configuration)\$(Platform)" />
|
||||
</ItemGroup>
|
||||
|
||||
<!-- These .proj files are generated by the build machine prior to running tests via GenerateTestProjFile.ps1. -->
|
||||
<Import Project="$(ProjFilesPath)\$(Configuration)\$(Platform)\RunTestsInHelix-TerminalAppLocalTests.proj" Condition=" '$(TestSuite)'=='DevTestSuite' " />
|
||||
<Import Project="$(ProjFilesPath)\$(Configuration)\$(Platform)\RunTestsInHelix-SettingsModelLocalTests.proj" Condition=" '$(TestSuite)'=='DevTestSuite' " />
|
||||
<Import Project="$(ProjFilesPath)\$(Configuration)\$(Platform)\RunTestsInHelix-HostTestsUIA.proj" Condition=" '$(TestSuite)'=='DevTestSuite' " />
|
||||
<Import Project="$(ProjFilesPath)\$(Configuration)\$(Platform)\RunTestsInHelix-WindowsTerminalUIATests.proj" Condition=" '$(TestSuite)'=='PgoInstrumentationSuite' " />
|
||||
</Project>
|
||||
@@ -1,136 +0,0 @@
|
||||
[CmdLetBinding()]
|
||||
Param(
|
||||
[Parameter(Mandatory = $true)]
|
||||
[int]$RerunPassesRequiredToAvoidFailure,
|
||||
|
||||
[string]$AccessToken = $env:SYSTEM_ACCESSTOKEN,
|
||||
[string]$CollectionUri = $env:SYSTEM_COLLECTIONURI,
|
||||
[string]$TeamProject = $env:SYSTEM_TEAMPROJECT,
|
||||
[string]$BuildUri = $env:BUILD_BUILDURI
|
||||
)
|
||||
|
||||
. "$PSScriptRoot/AzurePipelinesHelperScripts.ps1"
|
||||
|
||||
|
||||
$azureDevOpsRestApiHeaders = @{
|
||||
"Accept"="application/json"
|
||||
"Authorization"="Basic $([System.Convert]::ToBase64String([System.Text.ASCIIEncoding]::ASCII.GetBytes(":$AccessToken")))"
|
||||
}
|
||||
|
||||
$queryUri = GetQueryTestRunsUri -CollectionUri $CollectionUri -TeamProject $TeamProject -BuildUri $BuildUri
|
||||
Write-Host "queryUri = $queryUri"
|
||||
|
||||
# To account for unreliable tests, we'll iterate through all of the tests associated with this build, check to see any tests that were unreliable
|
||||
# (denoted by being marked as "skipped"), and if so, we'll instead mark those tests with a warning and enumerate all of the attempted runs
|
||||
# with their pass/fail states as well as any relevant error messages for failed attempts.
|
||||
$testRuns = Invoke-RestMethodWithRetries $queryUri -Headers $azureDevOpsRestApiHeaders
|
||||
|
||||
$timesSeenByRunName = @{}
|
||||
|
||||
foreach ($testRun in $testRuns.value)
|
||||
{
|
||||
$testRunResultsUri = "$($testRun.url)/results?api-version=5.0"
|
||||
|
||||
Write-Host "Marking test run `"$($testRun.name)`" as in progress so we can change its results to account for unreliable tests."
|
||||
Invoke-RestMethod "$($testRun.url)?api-version=5.0" -Method Patch -Body (ConvertTo-Json @{ "state" = "InProgress" }) -Headers $azureDevOpsRestApiHeaders -ContentType "application/json" | Out-Null
|
||||
|
||||
Write-Host "Retrieving test results..."
|
||||
$testResults = Invoke-RestMethodWithRetries $testRunResultsUri -Headers $azureDevOpsRestApiHeaders
|
||||
|
||||
foreach ($testResult in $testResults.value)
|
||||
{
|
||||
$testNeedsSubResultProcessing = $false
|
||||
if ($testResult.outcome -eq "NotExecuted")
|
||||
{
|
||||
$testNeedsSubResultProcessing = $true
|
||||
}
|
||||
elseif($testResult.outcome -eq "Failed")
|
||||
{
|
||||
$testNeedsSubResultProcessing = $testResult.errorMessage -like "*_subresults.json*"
|
||||
}
|
||||
|
||||
if ($testNeedsSubResultProcessing)
|
||||
{
|
||||
Write-Host " Test $($testResult.testCaseTitle) was detected as unreliable. Updating..."
|
||||
|
||||
# The errorMessage field contains a link to the JSON-encoded rerun result data.
|
||||
$resultsJson = Download-StringWithRetries "Error results" $testResult.errorMessage
|
||||
$rerunResults = ConvertFrom-Json $resultsJson
|
||||
[System.Collections.Generic.List[System.Collections.Hashtable]]$rerunDataList = @()
|
||||
$attemptCount = 0
|
||||
$passCount = 0
|
||||
$totalDuration = 0
|
||||
|
||||
foreach ($rerun in $rerunResults.results)
|
||||
{
|
||||
$rerunData = @{
|
||||
"displayName" = "Attempt #$($attemptCount + 1) - $($testResult.testCaseTitle)";
|
||||
"durationInMs" = $rerun.duration;
|
||||
"outcome" = $rerun.outcome;
|
||||
}
|
||||
|
||||
if ($rerun.outcome -eq "Passed")
|
||||
{
|
||||
$passCount++
|
||||
}
|
||||
|
||||
if ($attemptCount -gt 0)
|
||||
{
|
||||
$rerunData["sequenceId"] = $attemptCount
|
||||
}
|
||||
|
||||
Write-Host " Attempt #$($attemptCount + 1): $($rerun.outcome)"
|
||||
|
||||
if ($rerun.outcome -ne "Passed")
|
||||
{
|
||||
$screenshots = "$($rerunResults.blobPrefix)/$($rerun.screenshots -join @"
|
||||
$($rerunResults.blobSuffix)
|
||||
$($rerunResults.blobPrefix)
|
||||
"@)$($rerunResults.blobSuffix)"
|
||||
|
||||
# We subtract 1 from the error index because we added 1 so we could use 0
|
||||
# as a default value not injected into the JSON in order to keep its size down.
|
||||
# We did this because there's a maximum size enforced for the errorMessage parameter
|
||||
# in the Azure DevOps REST API.
|
||||
$fullErrorMessage = @"
|
||||
Log: $($rerunResults.blobPrefix)/$($rerun.log)$($rerunResults.blobSuffix)
|
||||
|
||||
Screenshots:
|
||||
$screenshots
|
||||
|
||||
Error log:
|
||||
$($rerunResults.errors[$rerun.errorIndex - 1])
|
||||
"@
|
||||
|
||||
$rerunData["errorMessage"] = $fullErrorMessage
|
||||
}
|
||||
|
||||
$attemptCount++
|
||||
$totalDuration += $rerun.duration
|
||||
$rerunDataList.Add($rerunData)
|
||||
}
|
||||
|
||||
$overallOutcome = "Warning"
|
||||
|
||||
if ($attemptCount -eq 2)
|
||||
{
|
||||
Write-Host " Test $($testResult.testCaseTitle) passed on the immediate rerun, so we'll mark it as unreliable."
|
||||
}
|
||||
elseif ($passCount -gt $RerunPassesRequiredToAvoidFailure)
|
||||
{
|
||||
Write-Host " Test $($testResult.testCaseTitle) passed on $passCount of $attemptCount attempts, which is greater than or equal to the $RerunPassesRequiredToAvoidFailure passes required to avoid being marked as failed. Marking as unreliable."
|
||||
}
|
||||
else
|
||||
{
|
||||
Write-Host " Test $($testResult.testCaseTitle) passed on only $passCount of $attemptCount attempts, which is less than the $RerunPassesRequiredToAvoidFailure passes required to avoid being marked as failed. Marking as failed."
|
||||
$overallOutcome = "Failed"
|
||||
}
|
||||
|
||||
$updateBody = ConvertTo-Json @(@{ "id" = $testResult.id; "outcome" = $overallOutcome; "errorMessage" = " "; "durationInMs" = $totalDuration; "subResults" = $rerunDataList; "resultGroupType" = "rerun" }) -Depth 5
|
||||
Invoke-RestMethod -Uri $testRunResultsUri -Method Patch -Headers $azureDevOpsRestApiHeaders -Body $updateBody -ContentType "application/json" | Out-Null
|
||||
}
|
||||
}
|
||||
|
||||
Write-Host "Finished updates. Re-marking test run `"$($testRun.name)`" as completed."
|
||||
Invoke-RestMethod -Uri "$($testRun.url)?api-version=5.0" -Method Patch -Body (ConvertTo-Json @{ "state" = "Completed" }) -Headers $azureDevOpsRestApiHeaders -ContentType "application/json" | Out-Null
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
{
|
||||
"msbuild-sdks": {
|
||||
"Microsoft.DotNet.Helix.Sdk": "6.0.0-beta.22525.5"
|
||||
}
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="MUXCustomBuildTasks" version="1.0.48" targetFramework="native" />
|
||||
<package id="Microsoft.Internal.Windows.Terminal.TestContent" version="1.0.1" />
|
||||
<package id="Microsoft.Taef" version="10.60.210621002" targetFramework="native" />
|
||||
<package id="microsoft.windows.apps.test" version="1.0.181203002" targetFramework="native" />
|
||||
<package id="runtime.win-x86.microsoft.netcore.app" version="2.1.0" targetFramework="native" />
|
||||
<package id="runtime.win-x64.microsoft.netcore.app" version="2.1.0" targetFramework="native" />
|
||||
</packages>
|
||||
@@ -1,32 +0,0 @@
|
||||
This directory contains code and configuration files to run WinUI tests in Helix.
|
||||
|
||||
Helix is a cloud hosted test execution environment which is accessed via the Arcade SDK.
|
||||
More details:
|
||||
* [Arcade](https://github.com/dotnet/arcade)
|
||||
* [Helix](https://github.com/dotnet/arcade/tree/master/src/Microsoft.DotNet.Helix/Sdk)
|
||||
|
||||
WinUI tests are scheduled in Helix by the Azure DevOps Pipeline: [RunHelixTests.yml](../RunHelixTests.yml).
|
||||
|
||||
The workflow is as follows:
|
||||
1. NuGet Restore is called on the packages.config in this directory. This downloads any runtime dependencies
|
||||
that are needed to run tests.
|
||||
2. PrepareHelixPayload.ps1 is called. This copies the necessary files from various locations into a Helix
|
||||
payload directory. This directory is what will get sent to the Helix machines.
|
||||
3. RunTestsInHelix.proj is executed. This proj has a dependency on
|
||||
[Microsoft.DotNet.Helix.Sdk](https://github.com/dotnet/arcade/tree/master/src/Microsoft.DotNet.Helix/Sdk)
|
||||
which it uses to publish the Helix payload directory and to schedule the Helix Work Items. The WinUI tests
|
||||
are parallelized into multiple Helix Work Items.
|
||||
4. Each Helix Work Item calls [runtests.cmd](runtests.cmd) with a specific query to pass to
|
||||
[TAEF](https://docs.microsoft.com/en-us/windows-hardware/drivers/taef/) which runs the tests.
|
||||
5. If a test is detected to have failed, we run it again, first once, then eight more times if it fails again.
|
||||
If it fails all ten times, we report the test as failed; otherwise, we report it as unreliable,
|
||||
which will show up as a warning, but which will not fail the build. When a test is reported as unreliable,
|
||||
we include the results for each individual run via a JSON string in the original test's errorMessage field.
|
||||
6. TAEF produces logs in WTT format. Helix is able to process logs in XUnit format. We run
|
||||
[ConvertWttLogToXUnit.ps1](ConvertWttLogToXUnit.ps1) to convert the logs into the necessary format.
|
||||
7. RunTestsInHelix.proj has EnableAzurePipelinesReporter set to true. This allows the XUnit formatted test
|
||||
results to be reported back to the Azure DevOps Pipeline.
|
||||
8. We process unreliable tests once all tests have been reported by reading the JSON string from the
|
||||
errorMessage field and calling the Azure DevOps REST API to modify the unreliable tests to have sub-results
|
||||
added to the test and to mark the test as "warning", which will enable people to see exactly how the test
|
||||
failed in runs where it did.
|
||||
@@ -1,105 +0,0 @@
|
||||
setlocal ENABLEDELAYEDEXPANSION
|
||||
|
||||
echo %TIME%
|
||||
|
||||
robocopy %HELIX_CORRELATION_PAYLOAD% . /s /NP > NUL
|
||||
|
||||
echo %TIME%
|
||||
|
||||
reg add HKLM\Software\Policies\Microsoft\Windows\Appx /v AllowAllTrustedApps /t REG_DWORD /d 1 /f
|
||||
|
||||
rem enable dump collection for our test apps:
|
||||
rem note, this script is run from a 32-bit cmd, but we need to set the native reg-key
|
||||
FOR %%A IN (TestHostApp.exe,te.exe,te.processhost.exe,conhost.exe,OpenConsole.exe,WindowsTerminal.exe) DO (
|
||||
%systemroot%\sysnative\cmd.exe /c reg add "HKLM\Software\Microsoft\Windows\Windows Error Reporting\LocalDumps\%%A" /v DumpFolder /t REG_EXPAND_SZ /d %HELIX_DUMP_FOLDER% /f
|
||||
%systemroot%\sysnative\cmd.exe /c reg add "HKLM\Software\Microsoft\Windows\Windows Error Reporting\LocalDumps\%%A" /v DumpType /t REG_DWORD /d 2 /f
|
||||
%systemroot%\sysnative\cmd.exe /c reg add "HKLM\Software\Microsoft\Windows\Windows Error Reporting\LocalDumps\%%A" /v DumpCount /t REG_DWORD /d 10 /f
|
||||
)
|
||||
|
||||
echo %TIME%
|
||||
|
||||
:: kill dhandler, which is a tool designed to handle unexpected windows appearing. But since our tests are
|
||||
:: expected to show UI we don't want it running.
|
||||
taskkill -f -im dhandler.exe
|
||||
|
||||
echo %TIME%
|
||||
powershell -ExecutionPolicy Bypass .\EnsureMachineState.ps1
|
||||
echo %TIME%
|
||||
powershell -ExecutionPolicy Bypass .\InstallTestAppDependencies.ps1
|
||||
echo %TIME%
|
||||
|
||||
set testBinaryCandidates=TerminalApp.LocalTests.dll SettingsModel.LocalTests.dll Conhost.UIA.Tests.dll WindowsTerminal.UIA.Tests.dll
|
||||
set testBinaries=
|
||||
for %%B in (%testBinaryCandidates%) do (
|
||||
if exist %%B (
|
||||
set "testBinaries=!testBinaries! %%B"
|
||||
)
|
||||
)
|
||||
|
||||
echo %TIME%
|
||||
te.exe %testBinaries% /enablewttlogging /unicodeOutput:false /sessionTimeout:0:15 /testtimeout:0:10 /screenCaptureOnError %*
|
||||
echo %TIME%
|
||||
|
||||
powershell -ExecutionPolicy Bypass Get-Process
|
||||
|
||||
move te.wtl te_original.wtl
|
||||
|
||||
copy /y te_original.wtl %HELIX_WORKITEM_UPLOAD_ROOT%
|
||||
copy /y WexLogFileOutput\*.jpg %HELIX_WORKITEM_UPLOAD_ROOT%
|
||||
copy /y *.pgc %HELIX_WORKITEM_UPLOAD_ROOT%
|
||||
|
||||
set FailedTestQuery=
|
||||
for /F "tokens=* usebackq" %%I IN (`powershell -ExecutionPolicy Bypass .\OutputFailedTestQuery.ps1 te_original.wtl`) DO (
|
||||
set FailedTestQuery=%%I
|
||||
)
|
||||
|
||||
rem The first time, we'll just re-run failed tests once. In many cases, tests fail very rarely, such that
|
||||
rem a single re-run will be sufficient to detect many unreliable tests.
|
||||
if "%FailedTestQuery%" == "" goto :SkipReruns
|
||||
|
||||
echo %TIME%
|
||||
te.exe %testBinaries% /enablewttlogging /unicodeOutput:false /sessionTimeout:0:15 /testtimeout:0:10 /screenCaptureOnError /select:"%FailedTestQuery%"
|
||||
echo %TIME%
|
||||
|
||||
move te.wtl te_rerun.wtl
|
||||
|
||||
copy /y te_rerun.wtl %HELIX_WORKITEM_UPLOAD_ROOT%
|
||||
copy /y WexLogFileOutput\*.jpg %HELIX_WORKITEM_UPLOAD_ROOT%
|
||||
|
||||
rem If there are still failing tests remaining, we'll run them eight more times, so they'll have been run a total of ten times.
|
||||
rem If any tests fail all ten times, we can be pretty confident that these are actual test failures rather than unreliable tests.
|
||||
if not exist te_rerun.wtl goto :SkipReruns
|
||||
|
||||
set FailedTestQuery=
|
||||
for /F "tokens=* usebackq" %%I IN (`powershell -ExecutionPolicy Bypass .\OutputFailedTestQuery.ps1 te_rerun.wtl`) DO (
|
||||
set FailedTestQuery=%%I
|
||||
)
|
||||
|
||||
if "%FailedTestQuery%" == "" goto :SkipReruns
|
||||
|
||||
echo %TIME%
|
||||
te.exe %testBinaries% /enablewttlogging /unicodeOutput:false /sessionTimeout:0:15 /testtimeout:0:10 /screenCaptureOnError /testmode:Loop /LoopTest:8 /select:"%FailedTestQuery%"
|
||||
echo %TIME%
|
||||
|
||||
powershell -ExecutionPolicy Bypass Get-Process
|
||||
|
||||
move te.wtl te_rerun_multiple.wtl
|
||||
|
||||
copy /y te_rerun_multiple.wtl %HELIX_WORKITEM_UPLOAD_ROOT%
|
||||
copy /y WexLogFileOutput\*.jpg %HELIX_WORKITEM_UPLOAD_ROOT%
|
||||
powershell -ExecutionPolicy Bypass .\CopyVisualTreeVerificationFiles.ps1
|
||||
|
||||
:SkipReruns
|
||||
|
||||
powershell -ExecutionPolicy Bypass Get-Process
|
||||
|
||||
echo %TIME%
|
||||
powershell -ExecutionPolicy Bypass .\OutputSubResultsJsonFiles.ps1 te_original.wtl te_rerun.wtl te_rerun_multiple.wtl %testnameprefix%
|
||||
powershell -ExecutionPolicy Bypass .\ConvertWttLogToXUnit.ps1 te_original.wtl te_rerun.wtl te_rerun_multiple.wtl testResults.xml %testnameprefix%
|
||||
echo %TIME%
|
||||
|
||||
copy /y *_subresults.json %HELIX_WORKITEM_UPLOAD_ROOT%
|
||||
|
||||
type testResults.xml
|
||||
|
||||
echo %TIME%
|
||||
@@ -1,51 +0,0 @@
|
||||
{
|
||||
"Version": "1.0.0",
|
||||
"UseMinimatch": false,
|
||||
"SignBatches": [
|
||||
{
|
||||
"MatchedPath": [
|
||||
"conpty.dll",
|
||||
"OpenConsole.exe"
|
||||
],
|
||||
"SigningInfo": {
|
||||
"Operations": [
|
||||
{
|
||||
"KeyCode": "CP-230012",
|
||||
"OperationSetCode": "SigntoolSign",
|
||||
"Parameters": [
|
||||
{
|
||||
"parameterName": "OpusName",
|
||||
"parameterValue": "Microsoft"
|
||||
},
|
||||
{
|
||||
"parameterName": "OpusInfo",
|
||||
"parameterValue": "http://www.microsoft.com"
|
||||
},
|
||||
{
|
||||
"parameterName": "FileDigest",
|
||||
"parameterValue": "/fd \"SHA256\""
|
||||
},
|
||||
{
|
||||
"parameterName": "PageHash",
|
||||
"parameterValue": "/NPH"
|
||||
},
|
||||
{
|
||||
"parameterName": "TimeStamp",
|
||||
"parameterValue": "/tr \"http://rfc3161.gtm.corp.microsoft.com/TSS/HttpTspServer\" /td sha256"
|
||||
}
|
||||
],
|
||||
"ToolName": "sign",
|
||||
"ToolVersion": "1.0"
|
||||
},
|
||||
{
|
||||
"KeyCode": "CP-230012",
|
||||
"OperationSetCode": "SigntoolVerify",
|
||||
"Parameters": [],
|
||||
"ToolName": "sign",
|
||||
"ToolVersion": "1.0"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,72 +0,0 @@
|
||||
{
|
||||
"Version": "1.0.0",
|
||||
"UseMinimatch": false,
|
||||
"SignBatches": [
|
||||
{
|
||||
"MatchedPath": [
|
||||
// Namespaced DLLs
|
||||
"Microsoft.Terminal.*.dll",
|
||||
"Microsoft.Terminal.*.winmd",
|
||||
|
||||
// ConPTY and DefTerm
|
||||
"OpenConsole.exe",
|
||||
"OpenConsoleProxy.dll",
|
||||
|
||||
// VCRT Forwarders
|
||||
"*_app.dll",
|
||||
|
||||
// Legacy DLLs with old names
|
||||
"TerminalApp.dll",
|
||||
"TerminalApp.winmd",
|
||||
"TerminalConnection.dll",
|
||||
"TerminalThemeHelpers.dll",
|
||||
"WindowsTerminalShellExt.dll",
|
||||
|
||||
// The rest
|
||||
"TerminalAzBridge.exe",
|
||||
"wt.exe",
|
||||
"WindowsTerminal.exe",
|
||||
"elevate-shim.exe"
|
||||
],
|
||||
"SigningInfo": {
|
||||
"Operations": [
|
||||
{
|
||||
"KeyCode": "CP-230012",
|
||||
"OperationSetCode": "SigntoolSign",
|
||||
"Parameters": [
|
||||
{
|
||||
"parameterName": "OpusName",
|
||||
"parameterValue": "Microsoft"
|
||||
},
|
||||
{
|
||||
"parameterName": "OpusInfo",
|
||||
"parameterValue": "http://www.microsoft.com"
|
||||
},
|
||||
{
|
||||
"parameterName": "FileDigest",
|
||||
"parameterValue": "/fd \"SHA256\""
|
||||
},
|
||||
{
|
||||
"parameterName": "PageHash",
|
||||
"parameterValue": "/NPH"
|
||||
},
|
||||
{
|
||||
"parameterName": "TimeStamp",
|
||||
"parameterValue": "/tr \"http://rfc3161.gtm.corp.microsoft.com/TSS/HttpTspServer\" /td sha256"
|
||||
}
|
||||
],
|
||||
"ToolName": "sign",
|
||||
"ToolVersion": "1.0"
|
||||
},
|
||||
{
|
||||
"KeyCode": "CP-230012",
|
||||
"OperationSetCode": "SigntoolVerify",
|
||||
"Parameters": [],
|
||||
"ToolName": "sign",
|
||||
"ToolVersion": "1.0"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
47
build/config/esrp.build.batch.conpty.json
Normal file
47
build/config/esrp.build.batch.conpty.json
Normal file
@@ -0,0 +1,47 @@
|
||||
[
|
||||
{
|
||||
"MatchedPath": [
|
||||
"conpty.dll",
|
||||
"OpenConsole.exe"
|
||||
],
|
||||
"SigningInfo": {
|
||||
"Operations": [
|
||||
{
|
||||
"KeyCode": "CP-230012",
|
||||
"OperationSetCode": "SigntoolSign",
|
||||
"Parameters": [
|
||||
{
|
||||
"parameterName": "OpusName",
|
||||
"parameterValue": "Microsoft"
|
||||
},
|
||||
{
|
||||
"parameterName": "OpusInfo",
|
||||
"parameterValue": "http://www.microsoft.com"
|
||||
},
|
||||
{
|
||||
"parameterName": "FileDigest",
|
||||
"parameterValue": "/fd \"SHA256\""
|
||||
},
|
||||
{
|
||||
"parameterName": "PageHash",
|
||||
"parameterValue": "/NPH"
|
||||
},
|
||||
{
|
||||
"parameterName": "TimeStamp",
|
||||
"parameterValue": "/tr \"http://rfc3161.gtm.corp.microsoft.com/TSS/HttpTspServer\" /td sha256"
|
||||
}
|
||||
],
|
||||
"ToolName": "sign",
|
||||
"ToolVersion": "1.0"
|
||||
},
|
||||
{
|
||||
"KeyCode": "CP-230012",
|
||||
"OperationSetCode": "SigntoolVerify",
|
||||
"Parameters": [],
|
||||
"ToolName": "sign",
|
||||
"ToolVersion": "1.0"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
65
build/config/esrp.build.batch.terminal_constituents.json
Normal file
65
build/config/esrp.build.batch.terminal_constituents.json
Normal file
@@ -0,0 +1,65 @@
|
||||
[
|
||||
{
|
||||
"MatchedPath": [
|
||||
// Namespaced DLLs
|
||||
"PackageContents/Microsoft.Terminal.*.dll",
|
||||
"PackageContents/Microsoft.Terminal.*.winmd",
|
||||
|
||||
// ConPTY and DefTerm
|
||||
"PackageContents/OpenConsole.exe",
|
||||
"PackageContents/OpenConsoleProxy.dll",
|
||||
|
||||
// Legacy DLLs with old names
|
||||
"PackageContents/TerminalApp.dll",
|
||||
"PackageContents/TerminalApp.winmd",
|
||||
"PackageContents/TerminalConnection.dll",
|
||||
"PackageContents/TerminalThemeHelpers.dll",
|
||||
"PackageContents/WindowsTerminalShellExt.dll",
|
||||
|
||||
// The rest
|
||||
"PackageContents/TerminalAzBridge.exe",
|
||||
"PackageContents/wt.exe",
|
||||
"PackageContents/WindowsTerminal.exe",
|
||||
"PackageContents/elevate-shim.exe"
|
||||
],
|
||||
"SigningInfo": {
|
||||
"Operations": [
|
||||
{
|
||||
"KeyCode": "CP-230012",
|
||||
"OperationSetCode": "SigntoolSign",
|
||||
"Parameters": [
|
||||
{
|
||||
"parameterName": "OpusName",
|
||||
"parameterValue": "Microsoft"
|
||||
},
|
||||
{
|
||||
"parameterName": "OpusInfo",
|
||||
"parameterValue": "http://www.microsoft.com"
|
||||
},
|
||||
{
|
||||
"parameterName": "FileDigest",
|
||||
"parameterValue": "/fd \"SHA256\""
|
||||
},
|
||||
{
|
||||
"parameterName": "PageHash",
|
||||
"parameterValue": "/NPH"
|
||||
},
|
||||
{
|
||||
"parameterName": "TimeStamp",
|
||||
"parameterValue": "/tr \"http://rfc3161.gtm.corp.microsoft.com/TSS/HttpTspServer\" /td sha256"
|
||||
}
|
||||
],
|
||||
"ToolName": "sign",
|
||||
"ToolVersion": "1.0"
|
||||
},
|
||||
{
|
||||
"KeyCode": "CP-230012",
|
||||
"OperationSetCode": "SigntoolVerify",
|
||||
"Parameters": [],
|
||||
"ToolName": "sign",
|
||||
"ToolVersion": "1.0"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
46
build/config/esrp.build.batch.wpf.json
Normal file
46
build/config/esrp.build.batch.wpf.json
Normal file
@@ -0,0 +1,46 @@
|
||||
[
|
||||
{
|
||||
"MatchedPath": [
|
||||
"Microsoft.Terminal.Control/Microsoft.Terminal.Control.dll"
|
||||
],
|
||||
"SigningInfo": {
|
||||
"Operations": [
|
||||
{
|
||||
"KeyCode": "CP-230012",
|
||||
"OperationSetCode": "SigntoolSign",
|
||||
"Parameters": [
|
||||
{
|
||||
"parameterName": "OpusName",
|
||||
"parameterValue": "Microsoft"
|
||||
},
|
||||
{
|
||||
"parameterName": "OpusInfo",
|
||||
"parameterValue": "http://www.microsoft.com"
|
||||
},
|
||||
{
|
||||
"parameterName": "FileDigest",
|
||||
"parameterValue": "/fd \"SHA256\""
|
||||
},
|
||||
{
|
||||
"parameterName": "PageHash",
|
||||
"parameterValue": "/NPH"
|
||||
},
|
||||
{
|
||||
"parameterName": "TimeStamp",
|
||||
"parameterValue": "/tr \"http://rfc3161.gtm.corp.microsoft.com/TSS/HttpTspServer\" /td sha256"
|
||||
}
|
||||
],
|
||||
"ToolName": "sign",
|
||||
"ToolVersion": "1.0"
|
||||
},
|
||||
{
|
||||
"KeyCode": "CP-230012",
|
||||
"OperationSetCode": "SigntoolVerify",
|
||||
"Parameters": [],
|
||||
"ToolName": "sign",
|
||||
"ToolVersion": "1.0"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
47
build/config/esrp.build.batch.wpfdotnet.json
Normal file
47
build/config/esrp.build.batch.wpfdotnet.json
Normal file
@@ -0,0 +1,47 @@
|
||||
[
|
||||
{
|
||||
"MatchedPath": [
|
||||
"WpfTerminalControl/net472/Microsoft.Terminal.Wpf.dll",
|
||||
"WpfTerminalControl/net6.0-windows/Microsoft.Terminal.Wpf.dll"
|
||||
],
|
||||
"SigningInfo": {
|
||||
"Operations": [
|
||||
{
|
||||
"KeyCode": "CP-230012",
|
||||
"OperationSetCode": "SigntoolSign",
|
||||
"Parameters": [
|
||||
{
|
||||
"parameterName": "OpusName",
|
||||
"parameterValue": "Microsoft"
|
||||
},
|
||||
{
|
||||
"parameterName": "OpusInfo",
|
||||
"parameterValue": "http://www.microsoft.com"
|
||||
},
|
||||
{
|
||||
"parameterName": "FileDigest",
|
||||
"parameterValue": "/fd \"SHA256\""
|
||||
},
|
||||
{
|
||||
"parameterName": "PageHash",
|
||||
"parameterValue": "/NPH"
|
||||
},
|
||||
{
|
||||
"parameterName": "TimeStamp",
|
||||
"parameterValue": "/tr \"http://rfc3161.gtm.corp.microsoft.com/TSS/HttpTspServer\" /td sha256"
|
||||
}
|
||||
],
|
||||
"ToolName": "sign",
|
||||
"ToolVersion": "1.0"
|
||||
},
|
||||
{
|
||||
"KeyCode": "CP-230012",
|
||||
"OperationSetCode": "SigntoolVerify",
|
||||
"Parameters": [],
|
||||
"ToolName": "sign",
|
||||
"ToolVersion": "1.0"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
1127
build/config/release.gdnbaselines
Normal file
1127
build/config/release.gdnbaselines
Normal file
File diff suppressed because it is too large
Load Diff
38
build/config/template.appinstaller
Normal file
38
build/config/template.appinstaller
Normal file
@@ -0,0 +1,38 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<AppInstaller
|
||||
xmlns="http://schemas.microsoft.com/appx/appinstaller/2017/2"
|
||||
Version="1.0.0.0"
|
||||
Uri="$$ROOT$$$$NAME$$.appinstaller">
|
||||
|
||||
<MainBundle
|
||||
Name="$$NAME$$"
|
||||
Publisher="CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US"
|
||||
Version="$$VERSION$$"
|
||||
Uri="$$ROOT$$$$PACKAGE$$" />
|
||||
|
||||
<Dependencies>
|
||||
<Package
|
||||
Name="Microsoft.UI.Xaml.2.8"
|
||||
Publisher="CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US"
|
||||
Version="8.2305.5001.0"
|
||||
ProcessorArchitecture="x64"
|
||||
Uri="https://github.com/microsoft/microsoft-ui-xaml/releases/download/v2.8.4/Microsoft.UI.Xaml.2.8.x64.appx" />
|
||||
<Package
|
||||
Name="Microsoft.UI.Xaml.2.8"
|
||||
Publisher="CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US"
|
||||
Version="8.2305.5001.0"
|
||||
ProcessorArchitecture="x86"
|
||||
Uri="https://github.com/microsoft/microsoft-ui-xaml/releases/download/v2.8.4/Microsoft.UI.Xaml.2.8.x86.appx" />
|
||||
<Package
|
||||
Name="Microsoft.UI.Xaml.2.8"
|
||||
Publisher="CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US"
|
||||
Version="8.2305.5001.0"
|
||||
ProcessorArchitecture="arm64"
|
||||
Uri="https://github.com/microsoft/microsoft-ui-xaml/releases/download/v2.8.4/Microsoft.UI.Xaml.2.8.arm64.appx" />
|
||||
</Dependencies>
|
||||
|
||||
<UpdateSettings>
|
||||
<OnLaunch
|
||||
HoursBetweenUpdateChecks="6" />
|
||||
</UpdateSettings>
|
||||
</AppInstaller>
|
||||
6
build/config/tsa.json
Normal file
6
build/config/tsa.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"instanceUrl": "https://microsoft.visualstudio.com",
|
||||
"projectName": "OS",
|
||||
"areaPath": "OS\\Windows Client and Services\\ADEPT\\E4D-Engineered for Developers\\SHINE\\Terminal",
|
||||
"notificationAliases": ["condev@microsoft.com", "duhowett@microsoft.com"]
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="Terminal.PGO.props" />
|
||||
<Import Project="$(PkgMicrosoft_PGO_Helpers_Cpp)\build\Microsoft.PGO-Helpers.Cpp.props" />
|
||||
<Import Project="$(PkgMicrosoft_PGO_Helpers_Cpp)\build\Microsoft.PGO-Helpers.Cpp.targets" />
|
||||
</Project>
|
||||
</Project>
|
||||
|
||||
@@ -12,5 +12,6 @@
|
||||
<files>
|
||||
<!-- The target directories for pgd files need to remain as is. PGO optimization pass will rely on this exact directory layout. -->
|
||||
<file src="x64\*.pgd" target="tools\x64"/>
|
||||
<file src="arm64\*.pgd" target="tools\arm64"/>
|
||||
</files>
|
||||
</package>
|
||||
|
||||
@@ -46,6 +46,5 @@
|
||||
<PGOCopyRuntime Condition="'$(PGOBuildMode)' == 'Instrument'">true</PGOCopyRuntime>
|
||||
</PropertyGroup>
|
||||
|
||||
<!-- Import PGO-Helpers -->
|
||||
<Import Project="$(PkgMicrosoft_PGO_Helpers_Cpp)\build\Microsoft.PGO-Helpers.Cpp.props" />
|
||||
<!-- Do not import PGO-Helpers props here, as it is too early to detect the C++ tools directory -->
|
||||
</Project>
|
||||
|
||||
@@ -29,76 +29,80 @@ variables:
|
||||
# 0.0.1904.0900
|
||||
name: 0.0.$(Date:yyMM).$(Date:dd)$(Rev:rr)
|
||||
|
||||
parameters:
|
||||
- name: auditMode
|
||||
displayName: "Build in Audit Mode (x64)"
|
||||
type: boolean
|
||||
default: true
|
||||
- name: runTests
|
||||
displayName: "Run Tests"
|
||||
type: boolean
|
||||
default: true
|
||||
- name: buildPlatforms
|
||||
type: object
|
||||
default:
|
||||
- x64
|
||||
- x86
|
||||
- arm64
|
||||
|
||||
stages:
|
||||
- stage: Audit_x64
|
||||
displayName: Audit Mode
|
||||
dependsOn: []
|
||||
condition: succeeded()
|
||||
jobs:
|
||||
- template: ./templates/build-console-audit-job.yml
|
||||
parameters:
|
||||
platform: x64
|
||||
- ${{ if eq(parameters.auditMode, true) }}:
|
||||
- stage: Audit_x64
|
||||
displayName: Audit Mode
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- template: ./templates-v2/job-build-project.yml
|
||||
parameters:
|
||||
pool:
|
||||
${{ if eq(variables['System.CollectionUri'], 'https://dev.azure.com/ms/') }}:
|
||||
name: SHINE-OSS-L
|
||||
${{ if ne(variables['System.CollectionUri'], 'https://dev.azure.com/ms/') }}:
|
||||
name: SHINE-INT-L
|
||||
buildPlatforms: [x64]
|
||||
buildConfigurations: [AuditMode]
|
||||
buildEverything: true
|
||||
keepAllExpensiveBuildOutputs: false
|
||||
|
||||
- stage: Build_x64
|
||||
displayName: Build x64
|
||||
dependsOn: []
|
||||
condition: succeeded()
|
||||
jobs:
|
||||
- template: ./templates/build-console-ci.yml
|
||||
parameters:
|
||||
platform: x64
|
||||
- stage: Build_x86
|
||||
displayName: Build x86
|
||||
- stage: CodeHealth
|
||||
displayName: Code Health
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- template: ./templates/build-console-ci.yml
|
||||
parameters:
|
||||
platform: x86
|
||||
- stage: Build_ARM64
|
||||
displayName: Build ARM64
|
||||
dependsOn: []
|
||||
condition: not(eq(variables['Build.Reason'], 'PullRequest'))
|
||||
jobs:
|
||||
- template: ./templates/build-console-ci.yml
|
||||
parameters:
|
||||
platform: ARM64
|
||||
- template: ./templates-v2/job-check-code-format.yml
|
||||
|
||||
- stage: Test_x64
|
||||
displayName: Test x64
|
||||
dependsOn: [Build_x64]
|
||||
condition: succeeded()
|
||||
jobs:
|
||||
- template: ./templates/test-console-ci.yml
|
||||
parameters:
|
||||
platform: x64
|
||||
- stage: Test_x86
|
||||
displayName: Test x86
|
||||
dependsOn: [Build_x86]
|
||||
jobs:
|
||||
- template: ./templates/test-console-ci.yml
|
||||
parameters:
|
||||
platform: x86
|
||||
- ${{ each platform in parameters.buildPlatforms }}:
|
||||
- stage: Build_${{ platform }}
|
||||
displayName: Build ${{ platform }}
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- template: ./templates-v2/job-build-project.yml
|
||||
parameters:
|
||||
pool:
|
||||
${{ if eq(variables['System.CollectionUri'], 'https://dev.azure.com/ms/') }}:
|
||||
name: SHINE-OSS-L
|
||||
${{ if ne(variables['System.CollectionUri'], 'https://dev.azure.com/ms/') }}:
|
||||
name: SHINE-INT-L
|
||||
buildPlatforms:
|
||||
- ${{ platform }}
|
||||
buildConfigurations: [Release]
|
||||
buildEverything: true
|
||||
keepAllExpensiveBuildOutputs: false
|
||||
|
||||
- stage: Helix_x64
|
||||
displayName: Helix x64
|
||||
dependsOn: [Build_x64]
|
||||
condition: and(succeeded(), not(eq(variables['Build.Reason'], 'PullRequest')))
|
||||
jobs:
|
||||
- template: ./templates/console-ci-helix-job.yml
|
||||
parameters:
|
||||
platform: x64
|
||||
- ${{ if eq(parameters.runTests, true) }}:
|
||||
- stage: Test_${{ platform }}
|
||||
displayName: Test ${{ platform }}
|
||||
dependsOn:
|
||||
- Build_${{ platform }}
|
||||
condition: succeeded()
|
||||
jobs:
|
||||
- template: ./templates-v2/job-test-project.yml
|
||||
parameters:
|
||||
platform: ${{ platform }}
|
||||
# The tests might be run more than once; log one artifact per attempt.
|
||||
outputArtifactStem: -$(System.JobAttempt)
|
||||
|
||||
- stage: Scripts
|
||||
displayName: Code Health Scripts
|
||||
dependsOn: []
|
||||
condition: succeeded()
|
||||
jobs:
|
||||
- template: ./templates/check-formatting.yml
|
||||
|
||||
|
||||
- stage: CodeIndexer
|
||||
displayName: Github CodeNav Indexer
|
||||
dependsOn: [Build_x64]
|
||||
condition: and(succeeded(), not(eq(variables['Build.Reason'], 'PullRequest')))
|
||||
jobs:
|
||||
- template: ./templates/codenav-indexer.yml
|
||||
- ${{ if ne(variables['Build.Reason'], 'PullRequest') }}:
|
||||
- stage: CodeIndexer
|
||||
displayName: Github CodeNav Indexer
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- template: ./templates-v2/job-index-github-codenav.yml
|
||||
|
||||
@@ -27,6 +27,7 @@ steps:
|
||||
clean: true
|
||||
submodules: false
|
||||
fetchDepth: 1 # Don't need a deep checkout for loc files!
|
||||
fetchTags: false # Tags still result in depth > 1 fetch; we don't need them here
|
||||
persistCredentials: true
|
||||
path: s # Adding a second repo made Azure DevOps change where we're checked out.
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ pr:
|
||||
paths:
|
||||
include:
|
||||
- src/features.xml
|
||||
- build/pipelines/feature-flag-ci.yml
|
||||
|
||||
variables:
|
||||
- name: runCodesignValidationInjectionBG
|
||||
@@ -21,9 +22,19 @@ parameters:
|
||||
# Dev is built automatically
|
||||
# WindowsInbox does not typically build with VS.
|
||||
|
||||
jobs:
|
||||
stages:
|
||||
- ${{ each branding in parameters.buildBrandings }}:
|
||||
- template: ./templates/build-console-ci.yml
|
||||
parameters:
|
||||
platform: x64
|
||||
branding: ${{ branding }}
|
||||
- stage: Build_${{ branding }}
|
||||
dependsOn: []
|
||||
displayName: Build ${{ branding }}
|
||||
jobs:
|
||||
- template: ./templates-v2/job-build-project.yml
|
||||
parameters:
|
||||
pool: # This only runs in CI
|
||||
name: SHINE-OSS-L
|
||||
buildPlatforms: [x64]
|
||||
buildConfigurations: [Release]
|
||||
buildEverything: true
|
||||
branding: ${{ branding }}
|
||||
keepAllExpensiveBuildOutputs: false
|
||||
artifactStem: -${{ branding }} # Disambiguate artifacts with the same config/platform
|
||||
|
||||
@@ -16,44 +16,52 @@ pr: none
|
||||
name: 0.0.$(Date:yyMM).$(Date:dd)$(Rev:rr)
|
||||
|
||||
stages:
|
||||
- stage: Build_Fuzz_Config
|
||||
displayName: Build Fuzzers
|
||||
- stage: Build
|
||||
displayName: Fuzzing Build
|
||||
dependsOn: []
|
||||
condition: succeeded()
|
||||
jobs:
|
||||
- template: ./templates/build-console-fuzzing.yml
|
||||
parameters:
|
||||
platform: x64
|
||||
- stage: OneFuzz
|
||||
displayName: Submit OneFuzz Job
|
||||
dependsOn: ['Build_Fuzz_Config']
|
||||
- template: ./templates-v2/job-build-project.yml
|
||||
parameters:
|
||||
pool:
|
||||
${{ if eq(variables['System.CollectionUri'], 'https://dev.azure.com/ms/') }}:
|
||||
name: SHINE-OSS-L
|
||||
${{ if ne(variables['System.CollectionUri'], 'https://dev.azure.com/ms/') }}:
|
||||
name: SHINE-INT-L
|
||||
buildPlatforms: [x64]
|
||||
buildConfigurations: [Fuzzing]
|
||||
buildEverything: true
|
||||
keepAllExpensiveBuildOutputs: false
|
||||
|
||||
- stage: Submit
|
||||
displayName: Submit to OneFuzz
|
||||
dependsOn: [Build]
|
||||
condition: succeeded()
|
||||
pool:
|
||||
vmImage: 'ubuntu-latest'
|
||||
variables:
|
||||
artifactName: fuzzingBuildOutput
|
||||
jobs:
|
||||
- job:
|
||||
steps:
|
||||
- task: DownloadBuildArtifacts@0
|
||||
inputs:
|
||||
artifactName: $(artifactName)
|
||||
downloadPath: $(Build.ArtifactStagingDirectory)
|
||||
- task: UsePythonVersion@0
|
||||
inputs:
|
||||
versionSpec: '3.x'
|
||||
addToPath: true
|
||||
architecture: 'x64'
|
||||
- bash: |
|
||||
set -ex
|
||||
pip -q install onefuzz
|
||||
onefuzz config --endpoint $(endpoint) --client_id $(client_id) --authority $(authority) --tenant_domain $(tenant_domain) --client_secret $(client_secret)
|
||||
sed -i s/INSERT_PAT_HERE/$(ado_pat)/ build/Fuzz/notifications-ado.json
|
||||
sed -i s/INSERT_ASSIGNED_HERE/$(ado_assigned_to)/ build/Fuzz/notifications-ado.json
|
||||
displayName: Configure OneFuzz
|
||||
- bash: |
|
||||
onefuzz template libfuzzer basic --colocate_all_tasks --vm_count 1 --target_exe $target_exe_path --notification_config @./build/Fuzz/notifications-ado.json OpenConsole $test_name $(Build.SourceVersion) default
|
||||
displayName: Submit OneFuzz Job
|
||||
env:
|
||||
target_exe_path: $(Build.ArtifactStagingDirectory)/$(artifactName)/Fuzzing/x64/test/OpenConsoleFuzzer.exe
|
||||
test_name: WriteCharsLegacy
|
||||
- job:
|
||||
pool:
|
||||
vmImage: 'ubuntu-latest'
|
||||
steps:
|
||||
- task: DownloadPipelineArtifact@2
|
||||
displayName: Download artifacts
|
||||
inputs:
|
||||
artifactName: build-x64-Fuzzing
|
||||
downloadPath: $(Build.ArtifactStagingDirectory)
|
||||
- task: UsePythonVersion@0
|
||||
inputs:
|
||||
versionSpec: '3.x'
|
||||
addToPath: true
|
||||
architecture: 'x64'
|
||||
- bash: |
|
||||
set -ex
|
||||
pip -q install onefuzz
|
||||
onefuzz config --endpoint $(endpoint) --client_id $(client_id) --authority $(authority) --tenant_domain $(tenant_domain) --client_secret $(client_secret)
|
||||
sed -i s/INSERT_PAT_HERE/$(ado_pat)/ build/Fuzz/notifications-ado.json
|
||||
sed -i s/INSERT_ASSIGNED_HERE/$(ado_assigned_to)/ build/Fuzz/notifications-ado.json
|
||||
displayName: Configure OneFuzz
|
||||
- bash: |
|
||||
onefuzz template libfuzzer basic --colocate_all_tasks --vm_count 1 --target_exe $target_exe_path --notification_config @./build/Fuzz/notifications-ado.json OpenConsole $test_name $(Build.SourceVersion) default
|
||||
displayName: Submit OneFuzz Job
|
||||
env:
|
||||
target_exe_path: $(Build.ArtifactStagingDirectory)/OpenConsoleFuzzer.exe
|
||||
test_name: WriteCharsLegacy
|
||||
|
||||
53
build/pipelines/ob-nightly.yml
Normal file
53
build/pipelines/ob-nightly.yml
Normal file
@@ -0,0 +1,53 @@
|
||||
trigger: none
|
||||
pr: none
|
||||
schedules:
|
||||
- cron: "30 3 * * 2-6" # Run at 03:30 UTC Tuesday through Saturday (After the work day in Pacific, Mon-Fri)
|
||||
displayName: "Nightly Terminal Build"
|
||||
branches:
|
||||
include:
|
||||
- main
|
||||
always: false # only run if there's code changes!
|
||||
|
||||
parameters:
|
||||
- name: publishToAzure
|
||||
displayName: "Deploy to **PUBLIC** Azure Storage"
|
||||
type: boolean
|
||||
default: true
|
||||
|
||||
name: $(BuildDefinitionName)_$(date:yyMM).$(date:dd)$(rev:rrr)
|
||||
|
||||
variables:
|
||||
- template: templates-v2/variables-nuget-package-version.yml
|
||||
parameters:
|
||||
branding: Canary
|
||||
- template: templates-v2/variables-onebranch-config.yml
|
||||
|
||||
extends:
|
||||
template: templates-v2/pipeline-onebranch-full-release-build.yml
|
||||
parameters:
|
||||
official: true
|
||||
branding: Canary
|
||||
buildTerminal: true
|
||||
pgoBuildMode: Optimize
|
||||
codeSign: true
|
||||
publishSymbolsToPublic: true
|
||||
publishVpackToWindows: false
|
||||
symbolExpiryTime: 15
|
||||
${{ if eq(true, parameters.publishToAzure) }}:
|
||||
extraPublishJobs:
|
||||
- template: build/pipelines/templates-v2/job-deploy-to-azure-storage.yml@self
|
||||
parameters:
|
||||
pool: { type: windows }
|
||||
variables:
|
||||
ob_git_checkout: false # This job checks itself out
|
||||
ob_git_skip_checkout_none: true
|
||||
ob_outputDirectory: "$(Build.SourcesDirectory)/_none"
|
||||
dependsOn: [PublishSymbols]
|
||||
storagePublicRootURL: $(AppInstallerRootURL)
|
||||
subscription: $(AzureSubscriptionName)
|
||||
storageAccount: $(AzureStorageAccount)
|
||||
storageContainer: $(AzureStorageContainer)
|
||||
buildConfiguration: Release
|
||||
buildPlatforms: [x64, x86, arm64]
|
||||
environment: production-canary
|
||||
|
||||
83
build/pipelines/ob-release.yml
Normal file
83
build/pipelines/ob-release.yml
Normal file
@@ -0,0 +1,83 @@
|
||||
trigger: none
|
||||
pr: none
|
||||
|
||||
# Expose all of these parameters for user configuration.
|
||||
parameters:
|
||||
- name: branding
|
||||
displayName: "Branding (Build Type)"
|
||||
type: string
|
||||
default: Release
|
||||
values:
|
||||
- Release
|
||||
- Preview
|
||||
- Canary
|
||||
- Dev
|
||||
- name: buildTerminal
|
||||
displayName: "Build Windows Terminal MSIX"
|
||||
type: boolean
|
||||
default: true
|
||||
- name: buildConPTY
|
||||
displayName: "Build ConPTY NuGet"
|
||||
type: boolean
|
||||
default: false
|
||||
- name: buildWPF
|
||||
displayName: "Build Terminal WPF Control"
|
||||
type: boolean
|
||||
default: false
|
||||
- name: pgoBuildMode
|
||||
displayName: "PGO Build Mode"
|
||||
type: string
|
||||
default: Optimize
|
||||
values:
|
||||
- Optimize
|
||||
- Instrument
|
||||
- None
|
||||
- name: buildConfigurations
|
||||
displayName: "Build Configurations"
|
||||
type: object
|
||||
default:
|
||||
- Release
|
||||
- name: buildPlatforms
|
||||
displayName: "Build Platforms"
|
||||
type: object
|
||||
default:
|
||||
- x64
|
||||
- x86
|
||||
- arm64
|
||||
- name: terminalInternalPackageVersion
|
||||
displayName: "Terminal Internal Package Version"
|
||||
type: string
|
||||
default: '0.0.8'
|
||||
|
||||
- name: publishSymbolsToPublic
|
||||
displayName: "Publish Symbols to MSDL"
|
||||
type: boolean
|
||||
default: true
|
||||
- name: publishVpackToWindows
|
||||
displayName: "Publish VPack to Windows"
|
||||
type: boolean
|
||||
default: false
|
||||
|
||||
name: $(BuildDefinitionName)_$(date:yyMM).$(date:dd)$(rev:rrr)
|
||||
|
||||
variables:
|
||||
- template: templates-v2/variables-nuget-package-version.yml
|
||||
parameters:
|
||||
branding: ${{ parameters.branding }}
|
||||
- template: templates-v2/variables-onebranch-config.yml
|
||||
|
||||
extends:
|
||||
template: templates-v2/pipeline-onebranch-full-release-build.yml
|
||||
parameters:
|
||||
official: true
|
||||
branding: ${{ parameters.branding }}
|
||||
buildTerminal: ${{ parameters.buildTerminal }}
|
||||
buildConPTY: ${{ parameters.buildConPTY }}
|
||||
buildWPF: ${{ parameters.buildWPF }}
|
||||
pgoBuildMode: ${{ parameters.pgoBuildMode }}
|
||||
buildConfigurations: ${{ parameters.buildConfigurations }}
|
||||
buildPlatforms: ${{ parameters.buildPlatforms }}
|
||||
codeSign: true
|
||||
terminalInternalPackageVersion: ${{ parameters.terminalInternalPackageVersion }}
|
||||
publishSymbolsToPublic: ${{ parameters.publishSymbolsToPublic }}
|
||||
publishVpackToWindows: ${{ parameters.publishVpackToWindows }}
|
||||
@@ -1,5 +1,27 @@
|
||||
trigger: none
|
||||
pr: none
|
||||
schedules:
|
||||
- cron: "0 5 * * 2-6" # Run at 05:00 UTC Tuesday through Saturday (Even later than Localization, after the work day in Pacific, Mon-Fri)
|
||||
displayName: "Nightly Instrumentation Build"
|
||||
branches:
|
||||
include:
|
||||
- main
|
||||
always: false # only run if there's code changes!
|
||||
|
||||
parameters:
|
||||
- name: branding
|
||||
displayName: "Branding (Build Type)"
|
||||
type: string
|
||||
default: Preview # By default, we'll PGO the Preview builds to get max coverage
|
||||
values:
|
||||
- Release
|
||||
- Preview
|
||||
- Dev
|
||||
- name: buildPlatforms
|
||||
type: object
|
||||
default:
|
||||
- x64
|
||||
- arm64
|
||||
|
||||
variables:
|
||||
- name: runCodesignValidationInjectionBG
|
||||
@@ -10,18 +32,57 @@ variables:
|
||||
name: 0.0.$(Date:yyMM).$(Date:dd)$(Rev:rr)
|
||||
|
||||
stages:
|
||||
- stage: Build_x64
|
||||
displayName: Build x64
|
||||
- stage: Build
|
||||
displayName: Build
|
||||
dependsOn: []
|
||||
condition: succeeded()
|
||||
jobs:
|
||||
- template: ./templates/build-console-pgo.yml
|
||||
- template: ./templates-v2/job-build-project.yml
|
||||
parameters:
|
||||
platform: x64
|
||||
- stage: Publish_PGO_Databases
|
||||
displayName: Publish PGO databases
|
||||
dependsOn: ['Build_x64']
|
||||
pool:
|
||||
${{ if eq(variables['System.CollectionUri'], 'https://dev.azure.com/ms/') }}:
|
||||
name: SHINE-OSS-L
|
||||
${{ if ne(variables['System.CollectionUri'], 'https://dev.azure.com/ms/') }}:
|
||||
name: SHINE-INT-L
|
||||
branding: ${{ parameters.branding }}
|
||||
buildPlatforms: ${{ parameters.buildPlatforms }}
|
||||
buildConfigurations: [Release]
|
||||
buildEverything: true
|
||||
pgoBuildMode: Instrument
|
||||
artifactStem: -instrumentation
|
||||
|
||||
- stage: RunPGO
|
||||
displayName: Run PGO
|
||||
dependsOn: [Build]
|
||||
condition: succeeded()
|
||||
jobs:
|
||||
- template: ./templates/pgo-build-and-publish-nuget-job.yml
|
||||
- ${{ each platform in parameters.buildPlatforms }}:
|
||||
- template: ./templates-v2/job-run-pgo-tests.yml
|
||||
parameters:
|
||||
# This job chooses its own pools based on platform
|
||||
buildPlatform: ${{ platform }}
|
||||
buildConfiguration: Release
|
||||
artifactStem: -instrumentation
|
||||
|
||||
- stage: FinalizePGO
|
||||
displayName: Finalize PGO and Publish
|
||||
dependsOn: [RunPGO]
|
||||
condition: succeeded()
|
||||
jobs:
|
||||
# This job takes multiple platforms and fans them back in to a single artifact.
|
||||
- template: ./templates-v2/job-pgo-merge-pgd.yml
|
||||
parameters:
|
||||
pgoArtifact: 'PGO'
|
||||
jobName: MergePGD
|
||||
pool:
|
||||
vmImage: 'windows-2022'
|
||||
buildConfiguration: Release
|
||||
buildPlatforms: ${{ parameters.buildPlatforms }}
|
||||
artifactStem: -instrumentation
|
||||
|
||||
- template: ./templates-v2/job-pgo-build-nuget-and-publish.yml
|
||||
parameters:
|
||||
pool:
|
||||
vmImage: 'windows-2022'
|
||||
dependsOn: MergePGD
|
||||
buildConfiguration: Release
|
||||
artifactStem: -instrumentation
|
||||
|
||||
@@ -1,751 +0,0 @@
|
||||
# This build should never run as CI or against a pull request.
|
||||
trigger: none
|
||||
pr: none
|
||||
|
||||
pool:
|
||||
name: WinDevPool-L
|
||||
demands: ImageOverride -equals WinDevVS17-latest
|
||||
|
||||
parameters:
|
||||
- name: branding
|
||||
displayName: "Branding (Build Type)"
|
||||
type: string
|
||||
default: Release
|
||||
values:
|
||||
- Release
|
||||
- Preview
|
||||
- name: buildTerminal
|
||||
displayName: "Build Windows Terminal MSIX"
|
||||
type: boolean
|
||||
default: true
|
||||
- name: runCompliance
|
||||
displayName: "Run Compliance and Security Build"
|
||||
type: boolean
|
||||
default: true
|
||||
- name: publishSymbolsToPublic
|
||||
displayName: "Publish Symbols to MSDL"
|
||||
type: boolean
|
||||
default: true
|
||||
- name: buildTerminalVPack
|
||||
displayName: "Build Windows Terminal VPack"
|
||||
type: boolean
|
||||
default: false
|
||||
- name: buildConPTY
|
||||
displayName: "Build ConPTY NuGet"
|
||||
type: boolean
|
||||
default: false
|
||||
- name: buildWPF
|
||||
displayName: "Build Terminal WPF Control"
|
||||
type: boolean
|
||||
default: false
|
||||
- name: pgoBuildMode
|
||||
displayName: "PGO Build Mode"
|
||||
type: string
|
||||
default: Optimize
|
||||
values:
|
||||
- Optimize
|
||||
- Instrument
|
||||
- None
|
||||
- name: buildConfigurations
|
||||
type: object
|
||||
default:
|
||||
- Release
|
||||
- name: buildPlatforms
|
||||
type: object
|
||||
default:
|
||||
- x64
|
||||
- x86
|
||||
- arm64
|
||||
|
||||
variables:
|
||||
MakeAppxPath: 'C:\Program Files (x86)\Windows Kits\10\bin\10.0.22621.0\x86\MakeAppx.exe'
|
||||
TerminalInternalPackageVersion: "0.0.8"
|
||||
# If we are building a branch called "release-*", change the NuGet suffix
|
||||
# to "preview". If we don't do that, XES will set the suffix to "release1"
|
||||
# because it truncates the value after the first period.
|
||||
# We also want to disable the suffix entirely if we're Release branded while
|
||||
# on a release branch.
|
||||
# main is special, however. XES ignores main. Since we never produce actual
|
||||
# shipping builds from main, we want to force it to have a beta label as
|
||||
# well.
|
||||
#
|
||||
# In effect:
|
||||
# BRANCH / BRANDING | Release | Preview
|
||||
# ------------------|----------------------------|-----------------------------
|
||||
# release-* | 1.12.20220427 | 1.13.20220427-preview
|
||||
# main | 1.14.20220427-experimental | 1.14.20220427-experimental
|
||||
# all others | 1.14.20220427-mybranch | 1.14.20220427-mybranch
|
||||
${{ if startsWith(variables['Build.SourceBranchName'], 'release-') }}:
|
||||
${{ if eq(parameters.branding, 'Release') }}:
|
||||
NoNuGetPackBetaVersion: true
|
||||
${{ else }}:
|
||||
NuGetPackBetaVersion: preview
|
||||
${{ elseif eq(variables['Build.SourceBranchName'], 'main') }}:
|
||||
NuGetPackBetaVersion: experimental
|
||||
|
||||
name: $(BuildDefinitionName)_$(date:yyMM).$(date:dd)$(rev:rrr)
|
||||
resources:
|
||||
repositories:
|
||||
- repository: self
|
||||
type: git
|
||||
ref: main
|
||||
jobs:
|
||||
- job: Build
|
||||
strategy:
|
||||
matrix:
|
||||
${{ each config in parameters.buildConfigurations }}:
|
||||
${{ each platform in parameters.buildPlatforms }}:
|
||||
${{ config }}_${{ platform }}:
|
||||
BuildConfiguration: ${{ config }}
|
||||
BuildPlatform: ${{ platform }}
|
||||
displayName: Build
|
||||
timeoutInMinutes: 240
|
||||
cancelTimeoutInMinutes: 1
|
||||
steps:
|
||||
- checkout: self
|
||||
clean: true
|
||||
submodules: true
|
||||
persistCredentials: True
|
||||
- task: PkgESSetupBuild@12
|
||||
displayName: Package ES - Setup Build
|
||||
inputs:
|
||||
disableOutputRedirect: true
|
||||
- task: PowerShell@2
|
||||
displayName: Rationalize Build Platform
|
||||
inputs:
|
||||
targetType: inline
|
||||
script: >-
|
||||
$Arch = "$(BuildPlatform)"
|
||||
|
||||
If ($Arch -Eq "x86") { $Arch = "Win32" }
|
||||
|
||||
Write-Host "##vso[task.setvariable variable=RationalizedBuildPlatform]${Arch}"
|
||||
- template: .\templates\restore-nuget-steps.yml
|
||||
- task: UniversalPackages@0
|
||||
displayName: Download terminal-internal Universal Package
|
||||
inputs:
|
||||
feedListDownload: 2b3f8893-a6e8-411f-b197-a9e05576da48
|
||||
packageListDownload: e82d490c-af86-4733-9dc4-07b772033204
|
||||
versionListDownload: $(TerminalInternalPackageVersion)
|
||||
- task: TouchdownBuildTask@1
|
||||
displayName: Download Localization Files
|
||||
inputs:
|
||||
teamId: 7105
|
||||
authId: $(TouchdownAppId)
|
||||
authKey: $(TouchdownAppKey)
|
||||
resourceFilePath: >-
|
||||
src\cascadia\TerminalApp\Resources\en-US\Resources.resw
|
||||
|
||||
src\cascadia\TerminalApp\Resources\en-US\ContextMenu.resw
|
||||
|
||||
src\cascadia\TerminalControl\Resources\en-US\Resources.resw
|
||||
|
||||
src\cascadia\TerminalConnection\Resources\en-US\Resources.resw
|
||||
|
||||
src\cascadia\TerminalSettingsModel\Resources\en-US\Resources.resw
|
||||
|
||||
src\cascadia\TerminalSettingsEditor\Resources\en-US\Resources.resw
|
||||
|
||||
src\cascadia\CascadiaPackage\Resources\en-US\Resources.resw
|
||||
appendRelativeDir: true
|
||||
localizationTarget: false
|
||||
pseudoSetting: Included
|
||||
- task: PowerShell@2
|
||||
displayName: Move Loc files one level up
|
||||
inputs:
|
||||
targetType: inline
|
||||
script: >-
|
||||
$Files = Get-ChildItem . -R -Filter 'Resources.resw' | ? FullName -Like '*en-US\*\Resources.resw'
|
||||
|
||||
$Files | % { Move-Item -Verbose $_.Directory $_.Directory.Parent.Parent -EA:Ignore }
|
||||
pwsh: true
|
||||
- task: PowerShell@2
|
||||
displayName: Copy the Context Menu Loc Resources to CascadiaPackage
|
||||
inputs:
|
||||
filePath: ./build/scripts/Copy-ContextMenuResourcesToCascadiaPackage.ps1
|
||||
pwsh: true
|
||||
- task: PowerShell@2
|
||||
displayName: Generate NOTICE.html from NOTICE.md
|
||||
inputs:
|
||||
filePath: .\build\scripts\Generate-ThirdPartyNotices.ps1
|
||||
arguments: -MarkdownNoticePath .\NOTICE.md -OutputPath .\src\cascadia\CascadiaPackage\NOTICE.html
|
||||
pwsh: true
|
||||
- ${{ if eq(parameters.buildTerminal, true) }}:
|
||||
- task: VSBuild@1
|
||||
displayName: Build solution **\OpenConsole.sln
|
||||
condition: true
|
||||
inputs:
|
||||
solution: '**\OpenConsole.sln'
|
||||
msbuildArgs: /p:WindowsTerminalOfficialBuild=true /p:WindowsTerminalBranding=${{ parameters.branding }};PGOBuildMode=${{ parameters.pgoBuildMode }} /t:Terminal\CascadiaPackage /p:WindowsTerminalReleaseBuild=true /bl:$(Build.SourcesDirectory)\msbuild.binlog
|
||||
platform: $(BuildPlatform)
|
||||
configuration: $(BuildConfiguration)
|
||||
clean: true
|
||||
maximumCpuCount: true
|
||||
- task: PublishBuildArtifacts@1
|
||||
displayName: 'Publish Artifact: binlog'
|
||||
condition: failed()
|
||||
continueOnError: True
|
||||
inputs:
|
||||
PathtoPublish: $(Build.SourcesDirectory)\msbuild.binlog
|
||||
ArtifactName: binlog-$(BuildPlatform)
|
||||
- task: PowerShell@2
|
||||
displayName: Check MSIX for common regressions
|
||||
inputs:
|
||||
targetType: inline
|
||||
script: >-
|
||||
$Package = Get-ChildItem -Recurse -Filter "CascadiaPackage_*.msix"
|
||||
|
||||
.\build\scripts\Test-WindowsTerminalPackage.ps1 -Verbose -Path $Package.FullName
|
||||
pwsh: true
|
||||
- ${{ if eq(parameters.buildWPF, true) }}:
|
||||
- task: VSBuild@1
|
||||
displayName: Build solution **\OpenConsole.sln for PublicTerminalCore
|
||||
inputs:
|
||||
solution: '**\OpenConsole.sln'
|
||||
msbuildArgs: /p:WindowsTerminalOfficialBuild=true /p:WindowsTerminalBranding=${{ parameters.branding }};PGOBuildMode=${{ parameters.pgoBuildMode }} /p:WindowsTerminalReleaseBuild=true /t:Terminal\wpf\PublicTerminalCore
|
||||
platform: $(BuildPlatform)
|
||||
configuration: $(BuildConfiguration)
|
||||
- ${{ if eq(parameters.buildConPTY, true) }}:
|
||||
- task: VSBuild@1
|
||||
displayName: Build solution **\OpenConsole.sln for ConPTY
|
||||
inputs:
|
||||
solution: '**\OpenConsole.sln'
|
||||
msbuildArgs: /p:WindowsTerminalOfficialBuild=true /p:WindowsTerminalBranding=${{ parameters.branding }};PGOBuildMode=${{ parameters.pgoBuildMode }} /p:WindowsTerminalReleaseBuild=true /t:Conhost\Host_EXE;Conhost\winconpty_DLL
|
||||
platform: $(BuildPlatform)
|
||||
configuration: $(BuildConfiguration)
|
||||
- task: PowerShell@2
|
||||
displayName: Source Index PDBs
|
||||
inputs:
|
||||
filePath: build\scripts\Index-Pdbs.ps1
|
||||
arguments: -SearchDir '$(Build.SourcesDirectory)' -SourceRoot '$(Build.SourcesDirectory)' -recursive -Verbose -CommitId $(Build.SourceVersion)
|
||||
errorActionPreference: silentlyContinue
|
||||
pwsh: true
|
||||
- task: PowerShell@2
|
||||
displayName: Run Unit Tests
|
||||
condition: and(succeeded(), or(eq(variables['BuildPlatform'], 'x64'), eq(variables['BuildPlatform'], 'x86')))
|
||||
enabled: False
|
||||
inputs:
|
||||
filePath: build\scripts\Run-Tests.ps1
|
||||
arguments: -MatchPattern '*unit.test*.dll' -Platform '$(RationalizedBuildPlatform)' -Configuration '$(BuildConfiguration)'
|
||||
- task: PowerShell@2
|
||||
displayName: Run Feature Tests
|
||||
condition: and(succeeded(), eq(variables['BuildPlatform'], 'x64'))
|
||||
enabled: False
|
||||
inputs:
|
||||
filePath: build\scripts\Run-Tests.ps1
|
||||
arguments: -MatchPattern '*feature.test*.dll' -Platform '$(RationalizedBuildPlatform)' -Configuration '$(BuildConfiguration)'
|
||||
- ${{ if eq(parameters.buildTerminal, true) }}:
|
||||
- task: CopyFiles@2
|
||||
displayName: Copy *.msix and symbols to Artifacts
|
||||
inputs:
|
||||
Contents: >-
|
||||
**/*.msix
|
||||
|
||||
**/*.appxsym
|
||||
TargetFolder: $(Build.ArtifactStagingDirectory)/appx
|
||||
OverWrite: true
|
||||
flattenFolders: true
|
||||
|
||||
- pwsh: |-
|
||||
$Package = (Get-ChildItem "$(Build.ArtifactStagingDirectory)/appx" -Recurse -Filter "Cascadia*.msix" | Select -First 1)
|
||||
$PackageFilename = $Package.FullName
|
||||
Write-Host "##vso[task.setvariable variable=WindowsTerminalPackagePath]${PackageFilename}"
|
||||
& "$(MakeAppxPath)" unpack /p $PackageFilename /d "$(Build.SourcesDirectory)\UnpackedTerminalPackage"
|
||||
displayName: Unpack the new Terminal package for signing
|
||||
|
||||
- task: EsrpCodeSigning@1
|
||||
displayName: Submit Terminal's binaries for signing
|
||||
inputs:
|
||||
ConnectedServiceName: 9d6d2960-0793-4d59-943e-78dcb434840a
|
||||
FolderPath: '$(Build.SourcesDirectory)\UnpackedTerminalPackage'
|
||||
signType: batchSigning
|
||||
batchSignPolicyFile: '$(Build.SourcesDirectory)\build\config\ESRPSigning_Terminal.json'
|
||||
|
||||
- pwsh: |-
|
||||
$PackageFilename = "$(WindowsTerminalPackagePath)"
|
||||
Remove-Item "$(Build.SourcesDirectory)\UnpackedTerminalPackage\CodeSignSummary*"
|
||||
& "$(MakeAppxPath)" pack /h SHA256 /o /p $PackageFilename /d "$(Build.SourcesDirectory)\UnpackedTerminalPackage"
|
||||
displayName: Re-pack the new Terminal package after signing
|
||||
|
||||
- pwsh: |-
|
||||
$XamlAppxPath = (Get-Item "src\cascadia\CascadiaPackage\AppPackages\*\Dependencies\$(BuildPlatform)\Microsoft.UI.Xaml*.appx").FullName
|
||||
& .\build\scripts\New-UnpackagedTerminalDistribution.ps1 -TerminalAppX $(WindowsTerminalPackagePath) -XamlAppX $XamlAppxPath -Destination "$(Build.ArtifactStagingDirectory)/appx"
|
||||
displayName: Build Unpackaged Distribution
|
||||
|
||||
- task: AzureArtifacts.manifest-generator-task.manifest-generator-task.ManifestGeneratorTask@0
|
||||
displayName: 'Generate SBOM manifest (application)'
|
||||
inputs:
|
||||
BuildDropPath: '$(System.ArtifactsDirectory)/appx'
|
||||
|
||||
- task: DropValidatorTask@0
|
||||
displayName: 'Validate application SBOM manifest'
|
||||
inputs:
|
||||
BuildDropPath: '$(System.ArtifactsDirectory)/appx'
|
||||
OutputPath: 'output.json'
|
||||
ValidateSignature: true
|
||||
Verbosity: 'Verbose'
|
||||
|
||||
- task: PublishBuildArtifacts@1
|
||||
displayName: Publish Artifact (Terminal app)
|
||||
inputs:
|
||||
PathtoPublish: $(Build.ArtifactStagingDirectory)/appx
|
||||
ArtifactName: terminal-$(BuildPlatform)-$(BuildConfiguration)
|
||||
|
||||
- ${{ if eq(parameters.buildConPTY, true) }}:
|
||||
- task: CopyFiles@2
|
||||
displayName: Copy ConPTY to Artifacts
|
||||
inputs:
|
||||
Contents: |-
|
||||
$(Build.SourcesDirectory)/bin/**/conpty.dll
|
||||
$(Build.SourcesDirectory)/bin/**/conpty.lib
|
||||
$(Build.SourcesDirectory)/bin/**/conpty.pdb
|
||||
$(Build.SourcesDirectory)/bin/**/OpenConsole.exe
|
||||
$(Build.SourcesDirectory)/bin/**/OpenConsole.pdb
|
||||
TargetFolder: $(Build.ArtifactStagingDirectory)/conpty
|
||||
OverWrite: true
|
||||
flattenFolders: true
|
||||
- task: PublishBuildArtifacts@1
|
||||
displayName: Publish Artifact (ConPTY)
|
||||
inputs:
|
||||
PathtoPublish: $(Build.ArtifactStagingDirectory)/conpty
|
||||
ArtifactName: conpty-dll-$(BuildPlatform)-$(BuildConfiguration)
|
||||
- ${{ if eq(parameters.buildWPF, true) }}:
|
||||
- task: CopyFiles@2
|
||||
displayName: Copy PublicTerminalCore.dll to Artifacts
|
||||
inputs:
|
||||
Contents: >-
|
||||
**/PublicTerminalCore.dll
|
||||
TargetFolder: $(Build.ArtifactStagingDirectory)/wpf
|
||||
OverWrite: true
|
||||
flattenFolders: true
|
||||
- task: PublishBuildArtifacts@1
|
||||
displayName: Publish Artifact (PublicTerminalCore)
|
||||
inputs:
|
||||
PathtoPublish: $(Build.ArtifactStagingDirectory)/wpf
|
||||
ArtifactName: wpf-dll-$(BuildPlatform)-$(BuildConfiguration)
|
||||
|
||||
- task: PublishSymbols@2
|
||||
displayName: Publish symbols path
|
||||
continueOnError: True
|
||||
inputs:
|
||||
SearchPattern: |
|
||||
$(Build.SourcesDirectory)/bin/**/*.pdb
|
||||
$(Build.SourcesDirectory)/bin/**/*.exe
|
||||
$(Build.SourcesDirectory)/bin/**/*.dll
|
||||
IndexSources: false
|
||||
SymbolServerType: TeamServices
|
||||
|
||||
- ${{ if eq(parameters.runCompliance, true) }}:
|
||||
- template: ./templates/build-console-compliance-job.yml
|
||||
|
||||
- ${{ if eq(parameters.buildTerminal, true) }}:
|
||||
- job: BundleAndSign
|
||||
displayName: Create and sign AppX/MSIX bundles
|
||||
variables:
|
||||
${{ if eq(parameters.branding, 'Release') }}:
|
||||
BundleStemName: Microsoft.WindowsTerminal
|
||||
${{ elseif eq(parameters.branding, 'Preview') }}:
|
||||
BundleStemName: Microsoft.WindowsTerminalPreview
|
||||
${{ else }}:
|
||||
BundleStemName: WindowsTerminalDev
|
||||
dependsOn: Build
|
||||
steps:
|
||||
- checkout: self
|
||||
clean: true
|
||||
fetchDepth: 1
|
||||
submodules: true
|
||||
persistCredentials: True
|
||||
- task: PkgESSetupBuild@12
|
||||
displayName: Package ES - Setup Build
|
||||
inputs:
|
||||
disableOutputRedirect: true
|
||||
- ${{ each platform in parameters.buildPlatforms }}:
|
||||
- task: DownloadBuildArtifacts@1
|
||||
displayName: Download Artifacts ${{ platform }}
|
||||
inputs:
|
||||
# Make sure to download the entire artifact, because it includes the SPDX SBOM
|
||||
artifactName: terminal-${{ platform }}-Release
|
||||
# Downloading to the source directory should ensure that the later SBOM generator can see the earlier SBOMs.
|
||||
downloadPath: '$(Build.SourcesDirectory)/appx-artifacts'
|
||||
# Add 3000 to the major version component, but only for the bundle.
|
||||
# This is to ensure that it is newer than "2022.xx.yy.zz" or whatever the original bundle versions were before
|
||||
# we switched to uniform naming.
|
||||
- pwsh: |-
|
||||
$VersionEpoch = 3000
|
||||
$Components = "$(XES_APPXMANIFESTVERSION)" -Split "\."
|
||||
$Components[0] = ([int]$Components[0] + $VersionEpoch)
|
||||
$BundleVersion = $Components -Join "."
|
||||
New-Item -Type Directory "$(System.ArtifactsDirectory)\bundle"
|
||||
.\build\scripts\Create-AppxBundle.ps1 -InputPath "$(Build.SourcesDirectory)/appx-artifacts" -ProjectName CascadiaPackage -BundleVersion $BundleVersion -OutputPath "$(System.ArtifactsDirectory)\bundle\$(BundleStemName)_$(XES_APPXMANIFESTVERSION)_8wekyb3d8bbwe.msixbundle"
|
||||
displayName: Create WindowsTerminal*.msixbundle
|
||||
- task: EsrpCodeSigning@1
|
||||
displayName: Submit *.msixbundle to ESRP for code signing
|
||||
inputs:
|
||||
ConnectedServiceName: 9d6d2960-0793-4d59-943e-78dcb434840a
|
||||
FolderPath: $(System.ArtifactsDirectory)\bundle
|
||||
Pattern: $(BundleStemName)*.msixbundle
|
||||
UseMinimatch: true
|
||||
signConfigType: inlineSignParams
|
||||
inlineOperation: >-
|
||||
[
|
||||
{
|
||||
"KeyCode": "Dynamic",
|
||||
"CertTemplateName": "WINMSAPP1ST",
|
||||
"CertSubjectName": "CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US",
|
||||
"OperationCode": "SigntoolSign",
|
||||
"Parameters": {
|
||||
"OpusName": "Microsoft",
|
||||
"OpusInfo": "http://www.microsoft.com",
|
||||
"FileDigest": "/fd \"SHA256\"",
|
||||
"TimeStamp": "/tr \"http://rfc3161.gtm.corp.microsoft.com/TSS/HttpTspServer\" /td sha256"
|
||||
},
|
||||
"ToolName": "sign",
|
||||
"ToolVersion": "1.0"
|
||||
},
|
||||
{
|
||||
"KeyCode": "Dynamic",
|
||||
"CertTemplateName": "WINMSAPP1ST",
|
||||
"CertSubjectName": "CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US",
|
||||
"OperationCode": "SigntoolVerify",
|
||||
"Parameters": {},
|
||||
"ToolName": "sign",
|
||||
"ToolVersion": "1.0"
|
||||
}
|
||||
]
|
||||
|
||||
- task: AzureArtifacts.manifest-generator-task.manifest-generator-task.ManifestGeneratorTask@0
|
||||
displayName: 'Generate SBOM manifest (bundle)'
|
||||
inputs:
|
||||
BuildDropPath: '$(System.ArtifactsDirectory)/bundle'
|
||||
BuildComponentPath: '$(Build.SourcesDirectory)/appx-artifacts'
|
||||
|
||||
- task: DropValidatorTask@0
|
||||
displayName: 'Validate bundle SBOM manifest'
|
||||
inputs:
|
||||
BuildDropPath: '$(System.ArtifactsDirectory)/bundle'
|
||||
OutputPath: 'output.json'
|
||||
ValidateSignature: true
|
||||
Verbosity: 'Verbose'
|
||||
|
||||
- task: PublishBuildArtifacts@1
|
||||
displayName: 'Publish Artifact: appxbundle-signed'
|
||||
inputs:
|
||||
PathtoPublish: $(System.ArtifactsDirectory)\bundle
|
||||
ArtifactName: appxbundle-signed
|
||||
|
||||
- ${{ if eq(parameters.buildConPTY, true) }}:
|
||||
- job: PackageAndSignConPTY
|
||||
strategy:
|
||||
matrix:
|
||||
${{ each config in parameters.buildConfigurations }}:
|
||||
${{ config }}:
|
||||
BuildConfiguration: ${{ config }}
|
||||
displayName: Create NuGet Package (ConPTY)
|
||||
dependsOn: Build
|
||||
steps:
|
||||
- checkout: self
|
||||
clean: true
|
||||
fetchDepth: 1
|
||||
submodules: true
|
||||
persistCredentials: True
|
||||
- task: PkgESSetupBuild@12
|
||||
displayName: Package ES - Setup Build
|
||||
inputs:
|
||||
disableOutputRedirect: true
|
||||
- ${{ each platform in parameters.buildPlatforms }}:
|
||||
- task: DownloadBuildArtifacts@1
|
||||
displayName: Download ${{ platform }} ConPTY binaries
|
||||
inputs:
|
||||
artifactName: conpty-dll-${{ platform }}-$(BuildConfiguration)
|
||||
downloadPath: bin\${{ platform }}\$(BuildConfiguration)\
|
||||
extractTars: false
|
||||
- task: PowerShell@2
|
||||
displayName: Move downloaded artifacts around
|
||||
inputs:
|
||||
targetType: inline
|
||||
# Find all artifact files and move them up a directory. Ugh.
|
||||
script: |-
|
||||
Get-ChildItem bin -Recurse -Directory -Filter conpty-dll-* | % {
|
||||
$_ | Get-ChildItem -Recurse -File | % {
|
||||
Move-Item -Verbose $_.FullName $_.Directory.Parent.FullName
|
||||
}
|
||||
}
|
||||
Move-Item bin\x86 bin\Win32
|
||||
|
||||
- task: EsrpCodeSigning@1
|
||||
displayName: Submit ConPTY libraries and OpenConsole for code signing
|
||||
inputs:
|
||||
ConnectedServiceName: 9d6d2960-0793-4d59-943e-78dcb434840a
|
||||
FolderPath: '$(Build.SourcesDirectory)/bin'
|
||||
signType: batchSigning
|
||||
batchSignPolicyFile: '$(Build.SourcesDirectory)\build\config\ESRPSigning_ConPTY.json'
|
||||
|
||||
- task: NuGetToolInstaller@1
|
||||
displayName: Use NuGet 5.10.0
|
||||
inputs:
|
||||
versionSpec: 5.10.0
|
||||
- task: NuGetCommand@2
|
||||
displayName: NuGet pack
|
||||
inputs:
|
||||
command: pack
|
||||
packagesToPack: $(Build.SourcesDirectory)\src\winconpty\package\winconpty.nuspec
|
||||
packDestination: '$(Build.ArtifactStagingDirectory)/nupkg'
|
||||
versioningScheme: byEnvVar
|
||||
versionEnvVar: XES_PACKAGEVERSIONNUMBER
|
||||
- task: EsrpCodeSigning@1
|
||||
displayName: Submit *.nupkg to ESRP for code signing
|
||||
inputs:
|
||||
ConnectedServiceName: 9d6d2960-0793-4d59-943e-78dcb434840a
|
||||
FolderPath: $(Build.ArtifactStagingDirectory)/nupkg
|
||||
Pattern: '*.nupkg'
|
||||
UseMinimatch: true
|
||||
signConfigType: inlineSignParams
|
||||
inlineOperation: >-
|
||||
[
|
||||
{
|
||||
"KeyCode": "CP-401405",
|
||||
"OperationCode": "NuGetSign",
|
||||
"Parameters": {},
|
||||
"ToolName": "sign",
|
||||
"ToolVersion": "1.0"
|
||||
},
|
||||
{
|
||||
"KeyCode": "CP-401405",
|
||||
"OperationCode": "NuGetVerify",
|
||||
"Parameters": {},
|
||||
"ToolName": "sign",
|
||||
"ToolVersion": "1.0"
|
||||
}
|
||||
]
|
||||
- task: PublishBuildArtifacts@1
|
||||
displayName: Publish Artifact (nupkg)
|
||||
inputs:
|
||||
PathtoPublish: $(Build.ArtifactStagingDirectory)\nupkg
|
||||
ArtifactName: conpty-nupkg-$(BuildConfiguration)
|
||||
|
||||
|
||||
- ${{ if eq(parameters.buildWPF, true) }}:
|
||||
- job: PackageAndSignWPF
|
||||
strategy:
|
||||
matrix:
|
||||
${{ each config in parameters.buildConfigurations }}:
|
||||
${{ config }}:
|
||||
BuildConfiguration: ${{ config }}
|
||||
displayName: Create NuGet Package (WPF Terminal Control)
|
||||
dependsOn: Build
|
||||
steps:
|
||||
- checkout: self
|
||||
clean: true
|
||||
fetchDepth: 1
|
||||
submodules: true
|
||||
persistCredentials: True
|
||||
- task: PkgESSetupBuild@12
|
||||
displayName: Package ES - Setup Build
|
||||
inputs:
|
||||
disableOutputRedirect: true
|
||||
- ${{ each platform in parameters.buildPlatforms }}:
|
||||
- task: DownloadBuildArtifacts@1
|
||||
displayName: Download ${{ platform }} PublicTerminalCore
|
||||
inputs:
|
||||
artifactName: wpf-dll-${{ platform }}-$(BuildConfiguration)
|
||||
itemPattern: '**/*.dll'
|
||||
downloadPath: bin\${{ platform }}\$(BuildConfiguration)\
|
||||
extractTars: false
|
||||
- task: PowerShell@2
|
||||
displayName: Move downloaded artifacts around
|
||||
inputs:
|
||||
targetType: inline
|
||||
# Find all artifact files and move them up a directory. Ugh.
|
||||
script: |-
|
||||
Get-ChildItem bin -Recurse -Directory -Filter wpf-dll-* | % {
|
||||
$_ | Get-ChildItem -Recurse -File | % {
|
||||
Move-Item -Verbose $_.FullName $_.Directory.Parent.FullName
|
||||
}
|
||||
}
|
||||
Move-Item bin\x86 bin\Win32
|
||||
- task: NuGetToolInstaller@1
|
||||
displayName: Use NuGet 5.10.0
|
||||
inputs:
|
||||
versionSpec: 5.10.0
|
||||
- task: NuGetCommand@2
|
||||
displayName: NuGet restore copy
|
||||
inputs:
|
||||
selectOrConfig: config
|
||||
nugetConfigPath: NuGet.Config
|
||||
- task: VSBuild@1
|
||||
displayName: Build solution **\OpenConsole.sln for WPF Control
|
||||
inputs:
|
||||
solution: '**\OpenConsole.sln'
|
||||
msbuildArgs: /p:WindowsTerminalReleaseBuild=$(UseReleaseBranding);Version=$(XES_PACKAGEVERSIONNUMBER) /t:Pack
|
||||
platform: Any CPU
|
||||
configuration: $(BuildConfiguration)
|
||||
maximumCpuCount: true
|
||||
- task: PublishSymbols@2
|
||||
displayName: Publish symbols path
|
||||
continueOnError: True
|
||||
inputs:
|
||||
SearchPattern: |
|
||||
$(Build.SourcesDirectory)/bin/**/*.pdb
|
||||
$(Build.SourcesDirectory)/bin/**/*.exe
|
||||
$(Build.SourcesDirectory)/bin/**/*.dll
|
||||
IndexSources: false
|
||||
SymbolServerType: TeamServices
|
||||
SymbolsArtifactName: Symbols_WPF_$(BuildConfiguration)
|
||||
- task: CopyFiles@2
|
||||
displayName: Copy *.nupkg to Artifacts
|
||||
inputs:
|
||||
Contents: '**/*Wpf*.nupkg'
|
||||
TargetFolder: $(Build.ArtifactStagingDirectory)/nupkg
|
||||
OverWrite: true
|
||||
flattenFolders: true
|
||||
- task: EsrpCodeSigning@1
|
||||
displayName: Submit *.nupkg to ESRP for code signing
|
||||
inputs:
|
||||
ConnectedServiceName: 9d6d2960-0793-4d59-943e-78dcb434840a
|
||||
FolderPath: $(Build.ArtifactStagingDirectory)/nupkg
|
||||
Pattern: '*.nupkg'
|
||||
UseMinimatch: true
|
||||
signConfigType: inlineSignParams
|
||||
inlineOperation: >-
|
||||
[
|
||||
{
|
||||
"KeyCode": "CP-401405",
|
||||
"OperationCode": "NuGetSign",
|
||||
"Parameters": {},
|
||||
"ToolName": "sign",
|
||||
"ToolVersion": "1.0"
|
||||
},
|
||||
{
|
||||
"KeyCode": "CP-401405",
|
||||
"OperationCode": "NuGetVerify",
|
||||
"Parameters": {},
|
||||
"ToolName": "sign",
|
||||
"ToolVersion": "1.0"
|
||||
}
|
||||
]
|
||||
- task: PublishBuildArtifacts@1
|
||||
displayName: Publish Artifact (nupkg)
|
||||
inputs:
|
||||
PathtoPublish: $(Build.ArtifactStagingDirectory)\nupkg
|
||||
ArtifactName: wpf-nupkg-$(BuildConfiguration)
|
||||
|
||||
- ${{ if eq(parameters.publishSymbolsToPublic, true) }}:
|
||||
- job: PublishSymbols
|
||||
displayName: Publish Symbols
|
||||
dependsOn: BundleAndSign
|
||||
steps:
|
||||
- checkout: self
|
||||
clean: true
|
||||
fetchDepth: 1
|
||||
submodules: true
|
||||
- task: PkgESSetupBuild@12
|
||||
displayName: Package ES - Setup Build
|
||||
|
||||
- template: .\templates\restore-nuget-steps.yml
|
||||
|
||||
# Download the terminal-PLATFORM-CONFIG-VERSION artifact for every platform/version combo
|
||||
- ${{ each platform in parameters.buildPlatforms }}:
|
||||
- task: DownloadBuildArtifacts@1
|
||||
displayName: Download Symbols ${{ platform }}
|
||||
inputs:
|
||||
artifactName: terminal-${{ platform }}-Release
|
||||
itemPattern: '**/*.appxsym'
|
||||
|
||||
# It seems easier to do this -- download every appxsym -- then enumerate all the PDBs in the build directory for the
|
||||
# public symbol push. Otherwise, we would have to list all of the PDB files one by one.
|
||||
- pwsh: |-
|
||||
mkdir $(Build.SourcesDirectory)/appxsym-temp
|
||||
Get-ChildItem "$(System.ArtifactsDirectory)" -Filter *.appxsym -Recurse | % {
|
||||
$src = $_.FullName
|
||||
$dest = Join-Path "$(Build.SourcesDirectory)/appxsym-temp/" $_.Name
|
||||
|
||||
mkdir $dest
|
||||
Write-Host "Extracting $src to $dest..."
|
||||
tar -x -v -f $src -C $dest
|
||||
}
|
||||
displayName: Extract symbols for public consumption
|
||||
|
||||
- task: PowerShell@2
|
||||
displayName: Source Index PDBs (the public ones)
|
||||
inputs:
|
||||
filePath: build\scripts\Index-Pdbs.ps1
|
||||
arguments: -SearchDir '$(Build.SourcesDirectory)/appxsym-temp' -SourceRoot '$(Build.SourcesDirectory)' -recursive -Verbose -CommitId $(Build.SourceVersion)
|
||||
pwsh: true
|
||||
|
||||
# Publish the app symbols to the public MSDL symbol server
|
||||
# accessible via https://msdl.microsoft.com/download/symbols
|
||||
- task: PublishSymbols@2
|
||||
displayName: 'Publish app symbols to MSDL'
|
||||
inputs:
|
||||
symbolsFolder: '$(Build.SourcesDirectory)/appxsym-temp'
|
||||
searchPattern: '**/*.pdb'
|
||||
SymbolsMaximumWaitTime: 30
|
||||
SymbolServerType: 'TeamServices'
|
||||
SymbolsProduct: 'Windows Terminal Application Binaries'
|
||||
SymbolsVersion: '$(XES_APPXMANIFESTVERSION)'
|
||||
# The ADO task does not support indexing of GitHub sources.
|
||||
indexSources: false
|
||||
detailedLog: true
|
||||
# There is a bug which causes this task to fail if LIB includes an inaccessible path (even though it does not depend on it).
|
||||
# To work around this issue, we just force LIB to be any dir that we know exists.
|
||||
# Copied from https://github.com/microsoft/icu/blob/f869c214adc87415dfe751d81f42f1bca55dcf5f/build/azure-nuget.yml#L564-L583
|
||||
env:
|
||||
LIB: $(Build.SourcesDirectory)
|
||||
ArtifactServices_Symbol_AccountName: microsoftpublicsymbols
|
||||
ArtifactServices_Symbol_PAT: $(ADO_microsoftpublicsymbols_PAT)
|
||||
|
||||
|
||||
- ${{ if eq(parameters.buildTerminalVPack, true) }}:
|
||||
- job: VPack
|
||||
displayName: Create Windows vPack
|
||||
dependsOn: BundleAndSign
|
||||
steps:
|
||||
- checkout: self
|
||||
clean: true
|
||||
fetchDepth: 1
|
||||
submodules: true
|
||||
- task: PkgESSetupBuild@12
|
||||
displayName: Package ES - Setup Build
|
||||
- task: DownloadBuildArtifacts@1
|
||||
displayName: Download Build Artifacts
|
||||
inputs:
|
||||
artifactName: appxbundle-signed
|
||||
extractTars: false
|
||||
- task: PowerShell@2
|
||||
displayName: Rename and stage packages for vpack
|
||||
inputs:
|
||||
targetType: inline
|
||||
script: >-
|
||||
# Rename to known/fixed name for Windows build system
|
||||
|
||||
Get-ChildItem Microsoft.WindowsTerminal_*.msixbundle | Rename-Item -NewName { 'Microsoft.WindowsTerminal_8wekyb3d8bbwe.msixbundle' }
|
||||
|
||||
|
||||
# Create vpack directory and place item inside
|
||||
|
||||
mkdir WindowsTerminal.app
|
||||
|
||||
mv Microsoft.WindowsTerminal_8wekyb3d8bbwe.msixbundle .\WindowsTerminal.app\
|
||||
workingDirectory: $(System.ArtifactsDirectory)\appxbundle-signed
|
||||
- task: PkgESVPack@12
|
||||
displayName: 'Package ES - VPack'
|
||||
env:
|
||||
SYSTEM_ACCESSTOKEN: $(System.AccessToken)
|
||||
inputs:
|
||||
sourceDirectory: $(System.ArtifactsDirectory)\appxbundle-signed\WindowsTerminal.app
|
||||
description: VPack for the Windows Terminal Application
|
||||
pushPkgName: WindowsTerminal.app
|
||||
owner: conhost
|
||||
githubToken: $(GitHubTokenForVpackProvenance)
|
||||
- task: PublishPipelineArtifact@1
|
||||
displayName: 'Copy VPack Manifest to Drop'
|
||||
inputs:
|
||||
targetPath: $(XES_VPACKMANIFESTDIRECTORY)
|
||||
artifactName: VPackManifest
|
||||
- task: PkgESFCIBGit@12
|
||||
displayName: 'Submit VPack Manifest to Windows'
|
||||
inputs:
|
||||
configPath: '$(Build.SourcesDirectory)\build\config\GitCheckin.json'
|
||||
artifactsDirectory: $(XES_VPACKMANIFESTDIRECTORY)
|
||||
prTimeOut: 5
|
||||
...
|
||||
144
build/pipelines/templates-v2/job-build-package-wpf.yml
Normal file
144
build/pipelines/templates-v2/job-build-package-wpf.yml
Normal file
@@ -0,0 +1,144 @@
|
||||
parameters:
|
||||
- name: buildConfigurations
|
||||
type: object
|
||||
- name: buildPlatforms
|
||||
type: object
|
||||
- name: generateSbom
|
||||
type: boolean
|
||||
default: false
|
||||
- name: codeSign
|
||||
type: boolean
|
||||
default: false
|
||||
- name: pool
|
||||
type: object
|
||||
default: []
|
||||
- name: dependsOn
|
||||
type: object
|
||||
default: null
|
||||
- name: artifactStem
|
||||
type: string
|
||||
default: ''
|
||||
- name: jobName
|
||||
type: string
|
||||
default: PackWPF
|
||||
- name: variables
|
||||
type: object
|
||||
default: {}
|
||||
- name: publishArtifacts
|
||||
type: boolean
|
||||
default: true
|
||||
|
||||
jobs:
|
||||
- job: ${{ parameters.jobName }}
|
||||
${{ if ne(length(parameters.pool), 0) }}:
|
||||
pool: ${{ parameters.pool }}
|
||||
${{ if eq(parameters.codeSign, true) }}:
|
||||
displayName: Pack and Sign Microsoft.Terminal.Wpf
|
||||
${{ else }}:
|
||||
displayName: Pack Microsoft.Terminal.Wpf
|
||||
strategy:
|
||||
matrix:
|
||||
${{ each config in parameters.buildConfigurations }}:
|
||||
${{ config }}:
|
||||
BuildConfiguration: ${{ config }}
|
||||
dependsOn: ${{ parameters.dependsOn }}
|
||||
variables:
|
||||
OutputBuildPlatform: AnyCPU
|
||||
Terminal.BinDir: $(Build.SourcesDirectory)/bin/$(OutputBuildPlatform)/$(BuildConfiguration)
|
||||
JobOutputDirectory: $(Build.ArtifactStagingDirectory)\nupkg
|
||||
JobOutputArtifactName: wpf-nupkg-$(BuildConfiguration)${{ parameters.artifactStem }}
|
||||
${{ insert }}: ${{ parameters.variables }}
|
||||
steps:
|
||||
- checkout: self
|
||||
clean: true
|
||||
fetchDepth: 1
|
||||
fetchTags: false # Tags still result in depth > 1 fetch; we don't need them here
|
||||
submodules: true
|
||||
persistCredentials: True
|
||||
|
||||
- task: PkgESSetupBuild@12
|
||||
displayName: Package ES - Setup Build
|
||||
inputs:
|
||||
disableOutputRedirect: true
|
||||
|
||||
- template: steps-download-bin-dir-artifact.yml
|
||||
parameters:
|
||||
buildPlatforms:
|
||||
- ${{ parameters.buildPlatforms }}
|
||||
- Any CPU # Make sure we grab the precompiled WPF bits
|
||||
# This build is already matrix'd on configuration, so
|
||||
# just pass a single config into the download template.
|
||||
buildConfigurations:
|
||||
- $(BuildConfiguration)
|
||||
artifactStem: ${{ parameters.artifactStem }}
|
||||
|
||||
- template: .\steps-restore-nuget.yml
|
||||
|
||||
- task: VSBuild@1
|
||||
displayName: Build solution OpenConsole.sln for WPF Control (Pack)
|
||||
inputs:
|
||||
solution: 'OpenConsole.sln'
|
||||
msbuildArgs: >-
|
||||
/p:WindowsTerminalReleaseBuild=true;Version=$(XES_PACKAGEVERSIONNUMBER)
|
||||
/p:NoBuild=true
|
||||
/p:IncludeSymbols=true
|
||||
/t:Terminal\wpf\WpfTerminalControl:Pack
|
||||
platform: Any CPU
|
||||
configuration: $(BuildConfiguration)
|
||||
maximumCpuCount: true
|
||||
clean: false
|
||||
|
||||
- task: CopyFiles@2
|
||||
displayName: Copy *.nupkg to Artifacts
|
||||
inputs:
|
||||
Contents: 'bin/**/*Wpf*.nupkg'
|
||||
TargetFolder: $(Build.ArtifactStagingDirectory)/nupkg
|
||||
OverWrite: true
|
||||
flattenFolders: true
|
||||
|
||||
- ${{ if eq(parameters.codeSign, true) }}:
|
||||
- task: EsrpCodeSigning@3
|
||||
displayName: Submit *.nupkg to ESRP for code signing
|
||||
inputs:
|
||||
ConnectedServiceName: 9d6d2960-0793-4d59-943e-78dcb434840a
|
||||
FolderPath: $(Build.ArtifactStagingDirectory)/nupkg
|
||||
Pattern: '*.nupkg'
|
||||
UseMinimatch: true
|
||||
signConfigType: inlineSignParams
|
||||
inlineOperation: >-
|
||||
[
|
||||
{
|
||||
"KeyCode": "CP-401405",
|
||||
"OperationCode": "NuGetSign",
|
||||
"Parameters": {},
|
||||
"ToolName": "sign",
|
||||
"ToolVersion": "1.0"
|
||||
},
|
||||
{
|
||||
"KeyCode": "CP-401405",
|
||||
"OperationCode": "NuGetVerify",
|
||||
"Parameters": {},
|
||||
"ToolName": "sign",
|
||||
"ToolVersion": "1.0"
|
||||
}
|
||||
]
|
||||
|
||||
- ${{ if eq(parameters.generateSbom, true) }}:
|
||||
- task: AzureArtifacts.manifest-generator-task.manifest-generator-task.ManifestGeneratorTask@0
|
||||
displayName: 'Generate SBOM manifest (wpf)'
|
||||
inputs:
|
||||
BuildDropPath: '$(System.ArtifactsDirectory)/nupkg'
|
||||
BuildComponentPath: '$(Build.SourcesDirectory)/bin'
|
||||
|
||||
- task: DropValidatorTask@0
|
||||
displayName: 'Validate wpf SBOM manifest'
|
||||
inputs:
|
||||
BuildDropPath: '$(System.ArtifactsDirectory)/nupkg'
|
||||
OutputPath: 'output.json'
|
||||
ValidateSignature: true
|
||||
Verbosity: 'Verbose'
|
||||
|
||||
- ${{ if eq(parameters.publishArtifacts, true) }}:
|
||||
- publish: $(JobOutputDirectory)
|
||||
artifact: $(JobOutputArtifactName)
|
||||
displayName: Publish nupkg
|
||||
298
build/pipelines/templates-v2/job-build-project.yml
Normal file
298
build/pipelines/templates-v2/job-build-project.yml
Normal file
@@ -0,0 +1,298 @@
|
||||
parameters:
|
||||
- name: branding
|
||||
type: string
|
||||
default: Dev
|
||||
- name: additionalBuildOptions
|
||||
type: string
|
||||
default: ''
|
||||
- name: buildTerminal
|
||||
type: boolean
|
||||
default: true
|
||||
- name: buildConPTY
|
||||
type: boolean
|
||||
default: false
|
||||
- name: buildWPF
|
||||
type: boolean
|
||||
default: false
|
||||
- name: buildWPFDotNetComponents # This weird hack is to make sure we sign and source index the .NET pieces
|
||||
type: boolean
|
||||
default: false
|
||||
- name: buildEverything
|
||||
displayName: "Build Everything (Overrides all other build options)"
|
||||
type: boolean
|
||||
default: false
|
||||
- name: pgoBuildMode
|
||||
type: string
|
||||
default: None
|
||||
values: [Optimize, Instrument, None]
|
||||
- name: buildConfigurations
|
||||
type: object
|
||||
default:
|
||||
- Release
|
||||
- name: buildPlatforms
|
||||
type: object
|
||||
default:
|
||||
- x64
|
||||
- x86
|
||||
- arm64
|
||||
- name: generateSbom
|
||||
type: boolean
|
||||
default: false
|
||||
- name: codeSign
|
||||
type: boolean
|
||||
default: false
|
||||
- name: keepAllExpensiveBuildOutputs
|
||||
type: boolean
|
||||
default: true
|
||||
- name: artifactStem
|
||||
type: string
|
||||
default: ''
|
||||
- name: jobName
|
||||
type: string
|
||||
default: 'Build'
|
||||
- name: pool
|
||||
type: object
|
||||
default: []
|
||||
- name: beforeBuildSteps
|
||||
type: stepList
|
||||
default: []
|
||||
- name: variables
|
||||
type: object
|
||||
default: {}
|
||||
- name: publishArtifacts
|
||||
type: boolean
|
||||
default: true
|
||||
- name: removeAllNonSignedFiles
|
||||
type: boolean
|
||||
default: false
|
||||
|
||||
jobs:
|
||||
- job: ${{ parameters.jobName }}
|
||||
${{ if ne(length(parameters.pool), 0) }}:
|
||||
pool: ${{ parameters.pool }}
|
||||
strategy:
|
||||
matrix:
|
||||
${{ each config in parameters.buildConfigurations }}:
|
||||
${{ each platform in parameters.buildPlatforms }}:
|
||||
${{ config }}_${{ platform }}:
|
||||
BuildConfiguration: ${{ config }}
|
||||
BuildPlatform: ${{ platform }}
|
||||
${{ if eq(platform, 'x86') }}:
|
||||
OutputBuildPlatform: Win32
|
||||
${{ elseif eq(platform, 'Any CPU') }}:
|
||||
OutputBuildPlatform: AnyCPU
|
||||
${{ else }}:
|
||||
OutputBuildPlatform: ${{ platform }}
|
||||
variables:
|
||||
MakeAppxPath: 'C:\Program Files (x86)\Windows Kits\10\bin\10.0.22621.0\x86\MakeAppx.exe'
|
||||
Terminal.BinDir: $(Build.SourcesDirectory)/bin/$(OutputBuildPlatform)/$(BuildConfiguration)
|
||||
# Azure DevOps abhors a vacuum
|
||||
# If these are blank, expansion will fail later on... which will result in direct substitution of the variable *names*
|
||||
# later on. We'll just... set them to a single space and if we need to, check IsNullOrWhiteSpace.
|
||||
# Yup.
|
||||
BuildTargetParameter: ' '
|
||||
SelectedSigningFragments: ' '
|
||||
# When building the unpackaged distribution, build it in portable mode if it's Canary-branded
|
||||
${{ if eq(parameters.branding, 'Canary') }}:
|
||||
UnpackagedBuildArguments: -PortableMode
|
||||
${{ else }}:
|
||||
UnpackagedBuildArguments: ' '
|
||||
JobOutputDirectory: $(Terminal.BinDir)
|
||||
JobOutputArtifactName: build-$(BuildPlatform)-$(BuildConfiguration)${{ parameters.artifactStem }}
|
||||
${{ insert }}: ${{ parameters.variables }}
|
||||
displayName: Build
|
||||
timeoutInMinutes: 240
|
||||
cancelTimeoutInMinutes: 1
|
||||
steps:
|
||||
- checkout: self
|
||||
clean: true
|
||||
submodules: true
|
||||
persistCredentials: True
|
||||
# This generates either nothing for BuildTargetParameter, or /t:X;Y;Z, to control targets later.
|
||||
- pwsh: |-
|
||||
If (-Not [bool]::Parse("${{ parameters.buildEverything }}")) {
|
||||
$BuildTargets = @()
|
||||
$SignFragments = @()
|
||||
If ([bool]::Parse("${{ parameters.buildTerminal }}")) {
|
||||
$BuildTargets += "Terminal\CascadiaPackage"
|
||||
$SignFragments += "terminal_constituents"
|
||||
}
|
||||
If ([bool]::Parse("${{ parameters.buildWPFDotNetComponents }}")) {
|
||||
$BuildTargets += "Terminal\wpf\WpfTerminalControl"
|
||||
$SignFragments += "wpfdotnet"
|
||||
}
|
||||
If ([bool]::Parse("${{ parameters.buildWPF }}")) {
|
||||
$BuildTargets += "Terminal\Control\Microsoft_Terminal_Control"
|
||||
$SignFragments += "wpf"
|
||||
}
|
||||
If ([bool]::Parse("${{ parameters.buildConPTY }}")) {
|
||||
$BuildTargets += "Conhost\Host_EXE;Conhost\winconpty_DLL"
|
||||
$SignFragments += "conpty"
|
||||
}
|
||||
Write-Host "Targets: $($BuildTargets -Join ";")"
|
||||
Write-Host "Sign targets: $($SignFragments -Join ";")"
|
||||
Write-Host "##vso[task.setvariable variable=BuildTargetParameter]/t:$($BuildTargets -Join ";")"
|
||||
Write-Host "##vso[task.setvariable variable=SelectedSigningFragments]$($SignFragments -Join ";")"
|
||||
}
|
||||
displayName: Prepare Build and Sign Targets
|
||||
|
||||
- pwsh: |-
|
||||
.\build\scripts\Generate-ThirdPartyNotices.ps1 -MarkdownNoticePath .\NOTICE.md -OutputPath .\src\cascadia\CascadiaPackage\NOTICE.html
|
||||
displayName: Generate NOTICE.html from NOTICE.md
|
||||
|
||||
- template: .\steps-restore-nuget.yml
|
||||
|
||||
- ${{ parameters.beforeBuildSteps }}
|
||||
|
||||
- task: VSBuild@1
|
||||
displayName: Build OpenConsole.sln
|
||||
inputs:
|
||||
solution: 'OpenConsole.sln'
|
||||
msbuildArgs: >-
|
||||
/p:WindowsTerminalOfficialBuild=true;WindowsTerminalBranding=${{ parameters.branding }};PGOBuildMode=${{ parameters.pgoBuildMode }}
|
||||
${{ parameters.additionalBuildOptions }}
|
||||
/bl:$(Build.SourcesDirectory)\msbuild.binlog
|
||||
$(BuildTargetParameter)
|
||||
platform: $(BuildPlatform)
|
||||
configuration: $(BuildConfiguration)
|
||||
maximumCpuCount: true
|
||||
|
||||
- ${{ if eq(parameters.publishArtifacts, true) }}:
|
||||
- publish: $(Build.SourcesDirectory)/msbuild.binlog
|
||||
artifact: logs-$(BuildPlatform)-$(BuildConfiguration)${{ parameters.artifactStem }}
|
||||
condition: always()
|
||||
displayName: Publish Build Log
|
||||
- ${{ else }}:
|
||||
- task: CopyFiles@2
|
||||
displayName: Copy Build Log
|
||||
inputs:
|
||||
contents: $(Build.SourcesDirectory)/msbuild.binlog
|
||||
TargetFolder: $(Terminal.BinDir)
|
||||
|
||||
# This saves ~2GiB per architecture. We won't need these later.
|
||||
# Removes:
|
||||
# - All .lib that do not have an associated .exp (which would indicate that they are import libs)
|
||||
# - All .pdbs from those .libs (which were only used during linking)
|
||||
# - Directories ending in Lib (static lib projects that we fully linked into DLLs which may also contain unnecessary resources)
|
||||
# - All LocalTests_ project outputs, as they were subsumed into TestHostApp
|
||||
# - All PDB files inside the WindowsTerminal/ output, which do not belong there.
|
||||
# - console.dll, which apparently breaks XFGCheck? lol.
|
||||
- pwsh: |-
|
||||
$binDir = '$(Terminal.BinDir)'
|
||||
$ImportLibs = Get-ChildItem $binDir -Recurse -File -Filter '*.exp' | ForEach-Object { $_.FullName -Replace "exp$","lib" }
|
||||
$StaticLibs = Get-ChildItem $binDir -Recurse -File -Filter '*.lib' | Where-Object FullName -NotIn $ImportLibs
|
||||
|
||||
$Items = @()
|
||||
$Items += $StaticLibs
|
||||
$Items += Get-Item ($StaticLibs.FullName -Replace "lib$","pdb") -ErrorAction:Ignore
|
||||
$Items += Get-ChildItem $binDir -Directory -Filter '*Lib'
|
||||
$Items += Get-ChildItem $binDir -Directory -Filter 'LocalTests_*'
|
||||
$Items += Get-ChildItem "${$binDir}\WindowsTerminal" -Filter '*.pdb' -ErrorAction:Ignore
|
||||
|
||||
If (-Not [bool]::Parse('${{ parameters.keepAllExpensiveBuildOutputs }}')) {
|
||||
$Items += Get-ChildItem '$(Terminal.BinDir)' -Filter '*.pdb' -Recurse
|
||||
}
|
||||
|
||||
$Items += Get-ChildItem $binDir -Filter 'console.dll'
|
||||
|
||||
$Items | Remove-Item -Recurse -Force -Verbose -ErrorAction:Ignore
|
||||
displayName: Clean up static libs and extra symbols
|
||||
errorActionPreference: silentlyContinue # It's OK if this silently fails
|
||||
|
||||
# We cannot index PDBs that we have deleted!
|
||||
- ${{ if eq(parameters.keepAllExpensiveBuildOutputs, true) }}:
|
||||
- pwsh: |-
|
||||
build\scripts\Index-Pdbs.ps1 -SearchDir '$(Terminal.BinDir)' -SourceRoot '$(Build.SourcesDirectory)' -recursive -Verbose -CommitId $(Build.SourceVersion)
|
||||
displayName: Source Index PDBs
|
||||
errorActionPreference: silentlyContinue
|
||||
|
||||
- ${{ if or(parameters.buildTerminal, parameters.buildEverything) }}:
|
||||
- pwsh: |-
|
||||
$Package = (Get-ChildItem -Recurse -Filter "CascadiaPackage*.msix" | Select -First 1)
|
||||
$PackageFilename = $Package.FullName
|
||||
Write-Host "##vso[task.setvariable variable=WindowsTerminalPackagePath]${PackageFilename}"
|
||||
displayName: Locate the MSIX
|
||||
|
||||
# CHECK EXCEPTION
|
||||
# PGO requires a desktop CRT
|
||||
- ${{ if ne(parameters.pgoBuildMode, 'Instrument') }}:
|
||||
- pwsh: |-
|
||||
.\build\scripts\Test-WindowsTerminalPackage.ps1 -Verbose -Path "$(WindowsTerminalPackagePath)"
|
||||
displayName: Check MSIX for common regressions
|
||||
condition: and(succeeded(), ne(variables.WindowsTerminalPackagePath, ''))
|
||||
|
||||
- ${{ if eq(parameters.codeSign, true) }}:
|
||||
- pwsh: |-
|
||||
& "$(MakeAppxPath)" unpack /p "$(WindowsTerminalPackagePath)" /d "$(Terminal.BinDir)/PackageContents"
|
||||
displayName: Unpack the MSIX for signing
|
||||
|
||||
- ${{ if eq(parameters.codeSign, true) }}:
|
||||
- template: steps-create-signing-config.yml
|
||||
parameters:
|
||||
outFile: '$(Build.SourcesDirectory)/ESRPSigningConfig.json'
|
||||
stage: build
|
||||
fragments: $(SelectedSigningFragments)
|
||||
|
||||
# Code-sign everything we just put together.
|
||||
# We run the signing in Terminal.BinDir, because all of the signing batches are relative to the final architecture/configuration output folder.
|
||||
- task: EsrpCodeSigning@3
|
||||
displayName: Submit Signing Request
|
||||
inputs:
|
||||
ConnectedServiceName: 9d6d2960-0793-4d59-943e-78dcb434840a
|
||||
FolderPath: '$(Terminal.BinDir)'
|
||||
signType: batchSigning
|
||||
batchSignPolicyFile: '$(Build.SourcesDirectory)/ESRPSigningConfig.json'
|
||||
|
||||
# We only need to re-pack the MSIX if we actually signed, so this can stay in the codeSign conditional
|
||||
- ${{ if or(parameters.buildTerminal, parameters.buildEverything) }}:
|
||||
- pwsh: |-
|
||||
$outDir = New-Item -Type Directory "$(Terminal.BinDir)/_appx" -ErrorAction:Ignore
|
||||
$PackageFilename = Join-Path $outDir.FullName (Split-Path -Leaf "$(WindowsTerminalPackagePath)")
|
||||
& "$(MakeAppxPath)" pack /h SHA256 /o /p $PackageFilename /d "$(Terminal.BinDir)/PackageContents"
|
||||
Write-Host "##vso[task.setvariable variable=WindowsTerminalPackagePath]${PackageFilename}"
|
||||
displayName: Re-pack the new Terminal package after signing
|
||||
|
||||
# Some of our governed pipelines explicitly fail builds that have *any* non-codesigned filed (!)
|
||||
- ${{ if eq(parameters.removeAllNonSignedFiles, true) }}:
|
||||
- pwsh: |-
|
||||
Get-ChildItem "$(Terminal.BinDir)" -Recurse -Include "*.dll","*.exe" |
|
||||
Where-Object { (Get-AuthenticodeSignature $_).Status -Ne "Valid" } |
|
||||
Remove-Item -Verbose -Force
|
||||
displayName: Remove all non-signed output files
|
||||
|
||||
- ${{ else }}: # No Signing
|
||||
- ${{ if or(parameters.buildTerminal, parameters.buildEverything) }}:
|
||||
- pwsh: |-
|
||||
$outDir = New-Item -Type Directory "$(Terminal.BinDir)/_appx" -ErrorAction:Ignore
|
||||
$PackageFilename = Join-Path $outDir.FullName (Split-Path -Leaf "$(WindowsTerminalPackagePath)")
|
||||
Copy-Item "$(WindowsTerminalPackagePath)" $PackageFilename
|
||||
Write-Host "##vso[task.setvariable variable=WindowsTerminalPackagePath]${PackageFilename}"
|
||||
displayName: Stage the package (unsigned)
|
||||
condition: and(succeeded(), ne(variables.WindowsTerminalPackagePath, ''))
|
||||
|
||||
- ${{ if or(parameters.buildTerminal, parameters.buildEverything) }}:
|
||||
- pwsh: |-
|
||||
$XamlAppxPath = (Get-Item "src\cascadia\CascadiaPackage\AppPackages\*\Dependencies\$(BuildPlatform)\Microsoft.UI.Xaml*.appx").FullName
|
||||
$outDir = New-Item -Type Directory "$(Terminal.BinDir)/_unpackaged" -ErrorAction:Ignore
|
||||
& .\build\scripts\New-UnpackagedTerminalDistribution.ps1 $(UnpackagedBuildArguments) -TerminalAppX $(WindowsTerminalPackagePath) -XamlAppX $XamlAppxPath -Destination $outDir.FullName
|
||||
displayName: Build Unpackaged Distribution (from MSIX)
|
||||
condition: and(succeeded(), ne(variables.WindowsTerminalPackagePath, ''))
|
||||
|
||||
- ${{ if eq(parameters.generateSbom, true) }}:
|
||||
- task: AzureArtifacts.manifest-generator-task.manifest-generator-task.ManifestGeneratorTask@0
|
||||
displayName: 'Generate SBOM manifest'
|
||||
inputs:
|
||||
BuildDropPath: '$(Terminal.BinDir)'
|
||||
|
||||
- task: DropValidatorTask@0
|
||||
displayName: 'Validate SBOM manifest'
|
||||
inputs:
|
||||
BuildDropPath: '$(Terminal.BinDir)'
|
||||
OutputPath: 'output.json'
|
||||
ValidateSignature: true
|
||||
Verbosity: 'Verbose'
|
||||
|
||||
- ${{ if eq(parameters.publishArtifacts, true) }}:
|
||||
- publish: $(Terminal.BinDir)
|
||||
artifact: $(JobOutputArtifactName)
|
||||
displayName: Publish All Outputs
|
||||
15
build/pipelines/templates-v2/job-check-code-format.yml
Normal file
15
build/pipelines/templates-v2/job-check-code-format.yml
Normal file
@@ -0,0 +1,15 @@
|
||||
jobs:
|
||||
- job: CodeFormatCheck
|
||||
displayName: Check Code Format
|
||||
pool: { vmImage: windows-2022 }
|
||||
|
||||
steps:
|
||||
- checkout: self
|
||||
fetchDepth: 1
|
||||
fetchTags: false # Tags still result in depth > 1 fetch; we don't need them here
|
||||
submodules: false
|
||||
clean: true
|
||||
|
||||
- powershell: |-
|
||||
.\build\scripts\Invoke-FormattingCheck.ps1
|
||||
displayName: 'Run formatters'
|
||||
92
build/pipelines/templates-v2/job-deploy-to-azure-storage.yml
Normal file
92
build/pipelines/templates-v2/job-deploy-to-azure-storage.yml
Normal file
@@ -0,0 +1,92 @@
|
||||
parameters:
|
||||
- name: buildConfiguration
|
||||
type: string
|
||||
- name: buildPlatforms
|
||||
type: object
|
||||
- name: pool
|
||||
type: object
|
||||
default: []
|
||||
- name: dependsOn
|
||||
type: object
|
||||
default: null
|
||||
- name: artifactStem
|
||||
type: string
|
||||
default: ''
|
||||
- name: variables
|
||||
type: object
|
||||
default: {}
|
||||
- name: environment
|
||||
type: string
|
||||
- name: storagePublicRootURL
|
||||
type: string
|
||||
- name: subscription
|
||||
type: string
|
||||
- name: storageAccount
|
||||
type: string
|
||||
- name: storageContainer
|
||||
type: string
|
||||
|
||||
jobs:
|
||||
- job: DeployAzure
|
||||
${{ if ne(length(parameters.pool), 0) }}:
|
||||
pool: ${{ parameters.pool }}
|
||||
displayName: Publish to Azure Storage (Prod)
|
||||
dependsOn: ${{ parameters.dependsOn }}
|
||||
variables:
|
||||
${{ insert }}: ${{ parameters.variables }}
|
||||
steps:
|
||||
- download: none
|
||||
|
||||
- checkout: self
|
||||
clean: true
|
||||
fetchDepth: 1
|
||||
fetchTags: false # Tags still result in depth > 1 fetch; we don't need them here
|
||||
submodules: true
|
||||
persistCredentials: True
|
||||
|
||||
- task: DownloadPipelineArtifact@2
|
||||
displayName: Download MSIX Bundle Artifact
|
||||
inputs:
|
||||
artifactName: appxbundle-${{ parameters.buildConfiguration }}${{ parameters.artifactStem }}
|
||||
downloadPath: '$(Build.SourcesDirectory)/_out'
|
||||
itemPattern: '**/*.msixbundle'
|
||||
|
||||
- ${{ each platform in parameters.buildPlatforms }}:
|
||||
- task: DownloadPipelineArtifact@2
|
||||
displayName: Download unpackaged build for ${{ platform }} ${{ parameters.buildConfiguration }}
|
||||
inputs:
|
||||
artifactName: build-${{ platform }}-${{ parameters.buildConfiguration }}${{ parameters.artifactStem }}
|
||||
downloadPath: '$(Build.SourcesDirectory)/_unpackaged'
|
||||
itemPattern: '**/_unpackaged/*.zip'
|
||||
|
||||
- pwsh: |-
|
||||
$b = Get-Item _out/*.msixbundle
|
||||
./build/scripts/New-AppInstallerFromTemplateAndBundle.ps1 -BundlePath $b.FullName -AppInstallerTemplatePath ./build/config/template.appinstaller -AppInstallerRoot "${{ parameters.storagePublicRootURL }}" -OutputPath _out/Microsoft.WindowsTerminalCanary.appinstaller
|
||||
displayName: "Produce AppInstaller for MSIX bundle"
|
||||
|
||||
- pwsh: |-
|
||||
$zips = Get-ChildItem -Recurse -Filter *.zip _unpackaged
|
||||
$zips | ForEach-Object {
|
||||
$name = $_.Name
|
||||
$parts = $name.Split('_')
|
||||
$parts[1] = "latest"
|
||||
$name = [String]::Join('_', $parts)
|
||||
$_ | Move-Item -Destination (Join-Path "_out" $name)
|
||||
}
|
||||
displayName: "Wrangle Unpackaged builds into place, rename"
|
||||
|
||||
- powershell: |-
|
||||
Get-PackageProvider -Name NuGet -ForceBootstrap
|
||||
Install-Module -Verbose -AllowClobber -Force Az.Accounts, Az.Storage, Az.Network, Az.Resources, Az.Compute
|
||||
displayName: Install Azure Module Dependencies
|
||||
|
||||
- task: AzureFileCopy@5
|
||||
displayName: Publish to Storage Account
|
||||
inputs:
|
||||
sourcePath: _out/*
|
||||
Destination: AzureBlob
|
||||
azureSubscription: ${{ parameters.subscription }}
|
||||
storage: ${{ parameters.storageAccount }}
|
||||
ContainerName: ${{ parameters.storageContainer }}
|
||||
AdditionalArgumentsForBlobCopy: "--content-type application/octet-stream"
|
||||
|
||||
@@ -1,21 +1,15 @@
|
||||
parameters:
|
||||
artifactName: 'drop'
|
||||
|
||||
jobs:
|
||||
- job: CodeNavIndexer
|
||||
displayName: Run Github CodeNav Indexer
|
||||
pool: { vmImage: windows-2019 }
|
||||
pool: { vmImage: windows-2022 }
|
||||
|
||||
steps:
|
||||
- checkout: self
|
||||
fetchDepth: 1
|
||||
fetchTags: false # Tags still result in depth > 1 fetch; we don't need them here
|
||||
submodules: false
|
||||
clean: true
|
||||
|
||||
- task: DownloadBuildArtifacts@0
|
||||
inputs:
|
||||
artifactName: ${{ parameters.artifactName }}
|
||||
|
||||
- task: RichCodeNavIndexer@0
|
||||
inputs:
|
||||
languages: 'cpp,csharp'
|
||||
152
build/pipelines/templates-v2/job-merge-msix-into-bundle.yml
Normal file
152
build/pipelines/templates-v2/job-merge-msix-into-bundle.yml
Normal file
@@ -0,0 +1,152 @@
|
||||
parameters:
|
||||
- name: branding
|
||||
type: string
|
||||
- name: buildConfigurations
|
||||
type: object
|
||||
- name: buildPlatforms
|
||||
type: object
|
||||
- name: generateSbom
|
||||
type: boolean
|
||||
default: false
|
||||
- name: codeSign
|
||||
type: boolean
|
||||
default: false
|
||||
- name: pool
|
||||
type: object
|
||||
default: []
|
||||
- name: dependsOn
|
||||
type: object
|
||||
default: null
|
||||
- name: artifactStem
|
||||
type: string
|
||||
default: ''
|
||||
- name: jobName
|
||||
type: string
|
||||
default: Bundle
|
||||
- name: variables
|
||||
type: object
|
||||
default: {}
|
||||
- name: publishArtifacts
|
||||
type: boolean
|
||||
default: true
|
||||
- name: afterBuildSteps
|
||||
type: stepList
|
||||
default: []
|
||||
|
||||
jobs:
|
||||
- job: ${{ parameters.jobName }}
|
||||
${{ if ne(length(parameters.pool), 0) }}:
|
||||
pool: ${{ parameters.pool }}
|
||||
${{ if eq(parameters.codeSign, true) }}:
|
||||
displayName: Pack and Sign Terminal MSIXBundle
|
||||
${{ else }}:
|
||||
displayName: Pack Terminal MSIXBundle
|
||||
strategy:
|
||||
matrix:
|
||||
${{ each config in parameters.buildConfigurations }}:
|
||||
${{ config }}:
|
||||
BuildConfiguration: ${{ config }}
|
||||
variables:
|
||||
${{ if eq(parameters.branding, 'Release') }}:
|
||||
BundleStemName: Microsoft.WindowsTerminal
|
||||
${{ elseif eq(parameters.branding, 'Preview') }}:
|
||||
BundleStemName: Microsoft.WindowsTerminalPreview
|
||||
${{ elseif eq(parameters.branding, 'Canary') }}:
|
||||
BundleStemName: Microsoft.WindowsTerminalCanary
|
||||
${{ else }}:
|
||||
BundleStemName: WindowsTerminalDev
|
||||
JobOutputDirectory: '$(System.ArtifactsDirectory)/bundle'
|
||||
JobOutputArtifactName: appxbundle-$(BuildConfiguration)${{ parameters.artifactStem }}
|
||||
${{ insert }}: ${{ parameters.variables }}
|
||||
dependsOn: ${{ parameters.dependsOn }}
|
||||
steps:
|
||||
- checkout: self
|
||||
clean: true
|
||||
fetchDepth: 1
|
||||
fetchTags: false # Tags still result in depth > 1 fetch; we don't need them here
|
||||
submodules: true
|
||||
persistCredentials: True
|
||||
- task: PkgESSetupBuild@12
|
||||
displayName: Package ES - Setup Build
|
||||
inputs:
|
||||
disableOutputRedirect: true
|
||||
- template: steps-download-bin-dir-artifact.yml
|
||||
parameters:
|
||||
buildPlatforms: ${{ parameters.buildPlatforms }}
|
||||
# This build is already matrix'd on configuration, so
|
||||
# just pass a single config into the download template.
|
||||
buildConfigurations:
|
||||
- $(BuildConfiguration)
|
||||
artifactStem: ${{ parameters.artifactStem }}
|
||||
|
||||
# Add 3000 to the major version component, but only for the bundle.
|
||||
# This is to ensure that it is newer than "2022.xx.yy.zz" or whatever the original bundle versions were before
|
||||
# we switched to uniform naming.
|
||||
- pwsh: |-
|
||||
$VersionEpoch = 3000
|
||||
$Components = "$(XES_APPXMANIFESTVERSION)" -Split "\."
|
||||
$Components[0] = ([int]$Components[0] + $VersionEpoch)
|
||||
$BundleVersion = $Components -Join "."
|
||||
New-Item -Type Directory "$(System.ArtifactsDirectory)/bundle"
|
||||
$BundlePath = "$(System.ArtifactsDirectory)\bundle\$(BundleStemName)_$(XES_APPXMANIFESTVERSION)_8wekyb3d8bbwe.msixbundle"
|
||||
.\build\scripts\Create-AppxBundle.ps1 -InputPath 'bin/' -ProjectName CascadiaPackage -BundleVersion $BundleVersion -OutputPath $BundlePath
|
||||
Write-Host "##vso[task.setvariable variable=MsixBundlePath]${BundlePath}"
|
||||
displayName: Create msixbundle
|
||||
|
||||
- ${{ if eq(parameters.codeSign, true) }}:
|
||||
- task: EsrpCodeSigning@3
|
||||
displayName: Submit *.msixbundle to ESRP for code signing
|
||||
inputs:
|
||||
ConnectedServiceName: 9d6d2960-0793-4d59-943e-78dcb434840a
|
||||
FolderPath: $(System.ArtifactsDirectory)\bundle
|
||||
Pattern: $(BundleStemName)*.msixbundle
|
||||
UseMinimatch: true
|
||||
signConfigType: inlineSignParams
|
||||
inlineOperation: >-
|
||||
[
|
||||
{
|
||||
"KeyCode": "Dynamic",
|
||||
"CertTemplateName": "WINMSAPP1ST",
|
||||
"CertSubjectName": "CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US",
|
||||
"OperationCode": "SigntoolSign",
|
||||
"Parameters": {
|
||||
"OpusName": "Microsoft",
|
||||
"OpusInfo": "http://www.microsoft.com",
|
||||
"FileDigest": "/fd \"SHA256\"",
|
||||
"TimeStamp": "/tr \"http://rfc3161.gtm.corp.microsoft.com/TSS/HttpTspServer\" /td sha256"
|
||||
},
|
||||
"ToolName": "sign",
|
||||
"ToolVersion": "1.0"
|
||||
},
|
||||
{
|
||||
"KeyCode": "Dynamic",
|
||||
"CertTemplateName": "WINMSAPP1ST",
|
||||
"CertSubjectName": "CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US",
|
||||
"OperationCode": "SigntoolVerify",
|
||||
"Parameters": {},
|
||||
"ToolName": "sign",
|
||||
"ToolVersion": "1.0"
|
||||
}
|
||||
]
|
||||
|
||||
- ${{ if eq(parameters.generateSbom, true) }}:
|
||||
- task: AzureArtifacts.manifest-generator-task.manifest-generator-task.ManifestGeneratorTask@0
|
||||
displayName: 'Generate SBOM manifest (bundle)'
|
||||
inputs:
|
||||
BuildDropPath: '$(System.ArtifactsDirectory)/bundle'
|
||||
BuildComponentPath: '$(Build.SourcesDirectory)/bin'
|
||||
|
||||
- task: DropValidatorTask@0
|
||||
displayName: 'Validate bundle SBOM manifest'
|
||||
inputs:
|
||||
BuildDropPath: '$(System.ArtifactsDirectory)/bundle'
|
||||
OutputPath: 'output.json'
|
||||
ValidateSignature: true
|
||||
Verbosity: 'Verbose'
|
||||
|
||||
- ${{ parameters.afterBuildSteps }}
|
||||
|
||||
- ${{ if eq(parameters.publishArtifacts, true) }}:
|
||||
- publish: $(JobOutputDirectory)
|
||||
artifact: $(JobOutputArtifactName)
|
||||
displayName: Publish msixbundle
|
||||
129
build/pipelines/templates-v2/job-package-conpty.yml
Normal file
129
build/pipelines/templates-v2/job-package-conpty.yml
Normal file
@@ -0,0 +1,129 @@
|
||||
parameters:
|
||||
- name: buildConfigurations
|
||||
type: object
|
||||
- name: buildPlatforms
|
||||
type: object
|
||||
- name: generateSbom
|
||||
type: boolean
|
||||
default: false
|
||||
- name: codeSign
|
||||
type: boolean
|
||||
default: false
|
||||
- name: pool
|
||||
type: object
|
||||
default: []
|
||||
- name: dependsOn
|
||||
type: object
|
||||
default: null
|
||||
- name: artifactStem
|
||||
type: string
|
||||
default: ''
|
||||
- name: jobName
|
||||
type: string
|
||||
default: PackConPTY
|
||||
- name: variables
|
||||
type: object
|
||||
default: {}
|
||||
- name: publishArtifacts
|
||||
type: boolean
|
||||
default: true
|
||||
|
||||
jobs:
|
||||
- job: ${{ parameters.jobName }}
|
||||
${{ if ne(length(parameters.pool), 0) }}:
|
||||
pool: ${{ parameters.pool }}
|
||||
${{ if eq(parameters.codeSign, true) }}:
|
||||
displayName: Pack and Sign Microsoft.Windows.Console.ConPTY
|
||||
${{ else }}:
|
||||
displayName: Pack Microsoft.Windows.Console.ConPTY
|
||||
strategy:
|
||||
matrix:
|
||||
${{ each config in parameters.buildConfigurations }}:
|
||||
${{ config }}:
|
||||
BuildConfiguration: ${{ config }}
|
||||
dependsOn: ${{ parameters.dependsOn }}
|
||||
variables:
|
||||
JobOutputDirectory: $(Build.ArtifactStagingDirectory)\nupkg
|
||||
JobOutputArtifactName: conpty-nupkg-$(BuildConfiguration)${{ parameters.artifactStem }}
|
||||
${{ insert }}: ${{ parameters.variables }}
|
||||
steps:
|
||||
- checkout: self
|
||||
clean: true
|
||||
fetchDepth: 1
|
||||
fetchTags: false # Tags still result in depth > 1 fetch; we don't need them here
|
||||
submodules: true
|
||||
persistCredentials: True
|
||||
|
||||
- task: PkgESSetupBuild@12
|
||||
displayName: Package ES - Setup Build
|
||||
inputs:
|
||||
disableOutputRedirect: true
|
||||
|
||||
- template: steps-download-bin-dir-artifact.yml
|
||||
parameters:
|
||||
buildPlatforms: ${{ parameters.buildPlatforms }}
|
||||
# This build is already matrix'd on configuration, so
|
||||
# just pass a single config into the download template.
|
||||
buildConfigurations:
|
||||
- $(BuildConfiguration)
|
||||
artifactStem: ${{ parameters.artifactStem }}
|
||||
|
||||
- template: steps-ensure-nuget-version.yml
|
||||
|
||||
# In the Microsoft Azure DevOps tenant, NuGetCommand is ambiguous.
|
||||
# This should be `task: NuGetCommand@2`
|
||||
- task: 333b11bd-d341-40d9-afcf-b32d5ce6f23b@2
|
||||
displayName: NuGet pack
|
||||
inputs:
|
||||
command: pack
|
||||
packagesToPack: $(Build.SourcesDirectory)\src\winconpty\package\winconpty.nuspec
|
||||
packDestination: '$(Build.ArtifactStagingDirectory)/nupkg'
|
||||
versioningScheme: byEnvVar
|
||||
versionEnvVar: XES_PACKAGEVERSIONNUMBER
|
||||
|
||||
- ${{ if eq(parameters.codeSign, true) }}:
|
||||
- task: EsrpCodeSigning@3
|
||||
displayName: Submit *.nupkg to ESRP for code signing
|
||||
inputs:
|
||||
ConnectedServiceName: 9d6d2960-0793-4d59-943e-78dcb434840a
|
||||
FolderPath: $(Build.ArtifactStagingDirectory)/nupkg
|
||||
Pattern: '*.nupkg'
|
||||
UseMinimatch: true
|
||||
signConfigType: inlineSignParams
|
||||
inlineOperation: >-
|
||||
[
|
||||
{
|
||||
"KeyCode": "CP-401405",
|
||||
"OperationCode": "NuGetSign",
|
||||
"Parameters": {},
|
||||
"ToolName": "sign",
|
||||
"ToolVersion": "1.0"
|
||||
},
|
||||
{
|
||||
"KeyCode": "CP-401405",
|
||||
"OperationCode": "NuGetVerify",
|
||||
"Parameters": {},
|
||||
"ToolName": "sign",
|
||||
"ToolVersion": "1.0"
|
||||
}
|
||||
]
|
||||
|
||||
- ${{ if eq(parameters.generateSbom, true) }}:
|
||||
- task: AzureArtifacts.manifest-generator-task.manifest-generator-task.ManifestGeneratorTask@0
|
||||
displayName: 'Generate SBOM manifest (conpty)'
|
||||
inputs:
|
||||
BuildDropPath: '$(System.ArtifactsDirectory)/nupkg'
|
||||
BuildComponentPath: '$(Build.SourcesDirectory)/bin'
|
||||
|
||||
- task: DropValidatorTask@0
|
||||
displayName: 'Validate conpty SBOM manifest'
|
||||
inputs:
|
||||
BuildDropPath: '$(System.ArtifactsDirectory)/nupkg'
|
||||
OutputPath: 'output.json'
|
||||
ValidateSignature: true
|
||||
Verbosity: 'Verbose'
|
||||
|
||||
- ${{ if eq(parameters.publishArtifacts, true) }}:
|
||||
- publish: $(JobOutputDirectory)
|
||||
artifact: $(JobOutputArtifactName)
|
||||
displayName: Publish nupkg
|
||||
@@ -1,14 +1,26 @@
|
||||
# From our friends at MUX: https://github.com/microsoft/microsoft-ui-xaml/blob/main/build/AzurePipelinesTemplates/MUX-BuildAndPublishPGONuGet-Job.yml
|
||||
|
||||
parameters:
|
||||
dependsOn: ''
|
||||
pgoArtifact: PGO
|
||||
- name: buildConfiguration
|
||||
type: string
|
||||
- name: pool
|
||||
type: object
|
||||
default: []
|
||||
- name: dependsOn
|
||||
type: object
|
||||
default: null
|
||||
- name: artifactStem
|
||||
type: string
|
||||
default: ''
|
||||
- name: jobName
|
||||
type: string
|
||||
default: BuildAndPublishPGONuget
|
||||
|
||||
jobs:
|
||||
- job: BuildAndPublishPGONuGet
|
||||
- job: ${{ parameters.jobName }}
|
||||
${{ if ne(length(parameters.pool), 0) }}:
|
||||
pool: ${{ parameters.pool }}
|
||||
dependsOn: ${{ parameters.dependsOn }}
|
||||
pool:
|
||||
vmImage: 'windows-2019'
|
||||
displayName: Package and Publish PGO Databases
|
||||
|
||||
variables:
|
||||
artifactsPath: $(Build.SourcesDirectory)\Artifacts
|
||||
pgoToolsPath: $(Build.SourcesDirectory)\build\PGO
|
||||
@@ -16,20 +28,25 @@ jobs:
|
||||
nuspecFilename: PGO.nuspec
|
||||
|
||||
steps:
|
||||
- task: DownloadBuildArtifacts@0
|
||||
- checkout: self
|
||||
clean: true
|
||||
# It is important that this be 0, otherwise git will not fetch the branch ref names that the PGO rules require.
|
||||
fetchDepth: 0
|
||||
submodules: false
|
||||
persistCredentials: false
|
||||
|
||||
- task: DownloadPipelineArtifact@2
|
||||
displayName: Download Final PGO Databases
|
||||
inputs:
|
||||
artifactName: ${{ parameters.pgoArtifact }}
|
||||
artifact: pgd-merged-${{ parameters.buildConfiguration }}${{ parameters.artifactStem }}
|
||||
downloadPath: $(artifactsPath)
|
||||
|
||||
- template: steps-ensure-nuget-version.yml
|
||||
|
||||
- task: NuGetAuthenticate@0
|
||||
inputs:
|
||||
nuGetServiceConnections: 'Terminal Public Artifact Feed'
|
||||
|
||||
- task: NuGetToolInstaller@0
|
||||
displayName: 'Use NuGet 5.8.0'
|
||||
inputs:
|
||||
versionSpec: 5.8.0
|
||||
|
||||
# In the Microsoft Azure DevOps tenant, NuGetCommand is ambiguous.
|
||||
# This should be `task: NuGetCommand@2`
|
||||
- task: 333b11bd-d341-40d9-afcf-b32d5ce6f23b@2
|
||||
@@ -45,12 +62,11 @@ jobs:
|
||||
displayName: 'Create PGO Nuget'
|
||||
inputs:
|
||||
solution: $(pgoToolsPath)\PGO.DB.proj
|
||||
msbuildArguments: '/t:CreatePGONuGet /p:PGOBuildMode=Instrument /p:PGDPathForAllArch=$(artifactsPath)\${{ parameters.pgoArtifact }} /p:PGOOutputPath=$(Build.ArtifactStagingDirectory)'
|
||||
msbuildArguments: '/t:CreatePGONuGet /p:PGOBuildMode=Instrument /p:PGDPathForAllArch=$(artifactsPath) /p:PGOOutputPath=$(Build.ArtifactStagingDirectory)'
|
||||
|
||||
- task: PublishBuildArtifacts@1
|
||||
inputs:
|
||||
pathToPublish: $(Build.ArtifactStagingDirectory)
|
||||
artifactName: ${{ parameters.pgoArtifact }}
|
||||
- publish: $(Build.ArtifactStagingDirectory)
|
||||
artifact: pgo-nupkg-${{ parameters.buildConfiguration }}${{ parameters.artifactStem }}
|
||||
displayName: "Publish Pipeline Artifact"
|
||||
|
||||
- task: 333b11bd-d341-40d9-afcf-b32d5ce6f23b@2
|
||||
displayName: 'NuGet push'
|
||||
75
build/pipelines/templates-v2/job-pgo-merge-pgd.yml
Normal file
75
build/pipelines/templates-v2/job-pgo-merge-pgd.yml
Normal file
@@ -0,0 +1,75 @@
|
||||
parameters:
|
||||
- name: buildConfiguration
|
||||
type: string
|
||||
- name: buildPlatforms
|
||||
type: object
|
||||
- name: pool
|
||||
type: object
|
||||
default: []
|
||||
- name: dependsOn
|
||||
type: object
|
||||
default: null
|
||||
- name: artifactStem
|
||||
type: string
|
||||
default: ''
|
||||
- name: jobName
|
||||
type: string
|
||||
default: MergePGD
|
||||
|
||||
jobs:
|
||||
- job: ${{ parameters.jobName }}
|
||||
${{ if ne(length(parameters.pool), 0) }}:
|
||||
pool: ${{ parameters.pool }}
|
||||
dependsOn: ${{ parameters.dependsOn }}
|
||||
displayName: Merge PGO Counts for ${{ parameters.buildConfiguration }}
|
||||
|
||||
steps:
|
||||
# The environment variable VCToolsInstallDir isn't defined on lab machines, so we need to retrieve it ourselves.
|
||||
- script: |
|
||||
"%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe" -Latest -requires Microsoft.Component.MSBuild -property InstallationPath > %TEMP%\vsinstalldir.txt
|
||||
set /p _VSINSTALLDIR15=<%TEMP%\vsinstalldir.txt
|
||||
del %TEMP%\vsinstalldir.txt
|
||||
call "%_VSINSTALLDIR15%\Common7\Tools\VsDevCmd.bat"
|
||||
echo VCToolsInstallDir = %VCToolsInstallDir%
|
||||
echo ##vso[task.setvariable variable=VCToolsInstallDir]%VCToolsInstallDir%
|
||||
displayName: 'Retrieve VC tools directory'
|
||||
|
||||
- ${{ each platform in parameters.buildPlatforms }}:
|
||||
- task: DownloadPipelineArtifact@2
|
||||
displayName: Download PGO Databases for ${{ platform }}
|
||||
inputs:
|
||||
artifactName: build-${{ platform }}-${{ parameters.buildConfiguration }}${{ parameters.artifactStem }}
|
||||
itemPattern: '**/*.pgd'
|
||||
downloadPath: '$(Build.SourcesDirectory)/pgd/${{ platform }}/${{ parameters.buildConfiguration }}'
|
||||
- task: DownloadPipelineArtifact@2
|
||||
displayName: Download PGO Counts for ${{ platform }}
|
||||
inputs:
|
||||
artifactName: pgc-intermediates-${{ platform }}-${{ parameters.buildConfiguration }}${{ parameters.artifactStem }}
|
||||
downloadPath: '$(Build.SourcesDirectory)/pgc/${{ platform }}/${{ parameters.buildConfiguration }}'
|
||||
- pwsh: |-
|
||||
$Arch = '${{ platform }}'
|
||||
$Conf = '${{ parameters.buildConfiguration }}'
|
||||
$PGCDir = '$(Build.SourcesDirectory)/pgc/${{ platform }}/${{ parameters.buildConfiguration }}'
|
||||
$PGDDir = '$(Build.SourcesDirectory)/pgd/${{ platform }}/${{ parameters.buildConfiguration }}'
|
||||
# Flatten the PGD directory
|
||||
Get-ChildItem $PGDDir -Recurse -Filter *.pgd | Move-Item -Destination $PGDDir -Verbose
|
||||
Get-ChildItem $PGCDir -Filter *.pgc |
|
||||
ForEach-Object {
|
||||
$Parts = $_.Name -Split "!";
|
||||
$_ | Add-Member Module $Parts[0] -PassThru
|
||||
} |
|
||||
Group-Object Module |
|
||||
ForEach-Object {
|
||||
& "$(VCToolsInstallDir)\bin\Hostx64\${{ platform }}\pgomgr.exe" /merge $_.Group.FullName "$PGDDir\$($_.Name).pgd"
|
||||
}
|
||||
displayName: Merge PGO Counts for ${{ platform }}
|
||||
- task: CopyFiles@2
|
||||
displayName: 'Copy merged pgds to artifact staging'
|
||||
inputs:
|
||||
sourceFolder: '$(Build.SourcesDirectory)/pgd/${{ platform }}/${{ parameters.buildConfiguration }}'
|
||||
contents: '**\*.pgd'
|
||||
targetFolder: '$(Build.ArtifactStagingDirectory)\out-pgd\${{ platform }}'
|
||||
|
||||
- publish: $(Build.ArtifactStagingDirectory)\out-pgd
|
||||
artifact: pgd-merged-${{ parameters.buildConfiguration }}${{ parameters.artifactStem }}
|
||||
displayName: "Publish merged PGDs"
|
||||
97
build/pipelines/templates-v2/job-publish-symbols.yml
Normal file
97
build/pipelines/templates-v2/job-publish-symbols.yml
Normal file
@@ -0,0 +1,97 @@
|
||||
parameters:
|
||||
- name: includePublicSymbolServer
|
||||
type: boolean
|
||||
default: false
|
||||
- name: pool
|
||||
type: object
|
||||
default: []
|
||||
- name: dependsOn
|
||||
type: object
|
||||
default: null
|
||||
- name: artifactStem
|
||||
type: string
|
||||
default: ''
|
||||
- name: jobName
|
||||
type: string
|
||||
default: PublishSymbols
|
||||
- name: symbolExpiryTime
|
||||
type: string
|
||||
default: 36530 # This is the default from PublishSymbols@2
|
||||
- name: variables
|
||||
type: object
|
||||
default: {}
|
||||
- name: symbolPatGoesInTaskInputs
|
||||
type: boolean
|
||||
default: false
|
||||
|
||||
jobs:
|
||||
- job: ${{ parameters.jobName }}
|
||||
${{ if ne(length(parameters.pool), 0) }}:
|
||||
pool: ${{ parameters.pool }}
|
||||
${{ if eq(parameters.includePublicSymbolServer, true) }}:
|
||||
displayName: Publish Symbols to Internal and MSDL
|
||||
${{ else }}:
|
||||
displayName: Publish Symbols Internally
|
||||
dependsOn: ${{ parameters.dependsOn }}
|
||||
variables:
|
||||
${{ insert }}: ${{ parameters.variables }}
|
||||
steps:
|
||||
- checkout: self
|
||||
clean: true
|
||||
fetchDepth: 1
|
||||
fetchTags: false # Tags still result in depth > 1 fetch; we don't need them here
|
||||
submodules: true
|
||||
persistCredentials: True
|
||||
|
||||
- task: PkgESSetupBuild@12
|
||||
displayName: Package ES - Setup Build
|
||||
inputs:
|
||||
disableOutputRedirect: true
|
||||
|
||||
- task: DownloadPipelineArtifact@2
|
||||
displayName: Download all PDBs from all prior build phases
|
||||
inputs:
|
||||
itemPattern: '**/*.pdb'
|
||||
targetPath: '$(Build.SourcesDirectory)/bin'
|
||||
|
||||
- task: PublishSymbols@2
|
||||
displayName: Publish Symbols (to current Azure DevOps tenant)
|
||||
continueOnError: True
|
||||
inputs:
|
||||
SymbolsFolder: '$(Build.SourcesDirectory)/bin'
|
||||
SearchPattern: '**/*.pdb'
|
||||
IndexSources: false
|
||||
DetailedLog: true
|
||||
SymbolsMaximumWaitTime: 30
|
||||
SymbolServerType: 'TeamServices'
|
||||
SymbolsProduct: 'Windows Terminal Converged Symbols'
|
||||
SymbolsVersion: '$(XES_APPXMANIFESTVERSION)'
|
||||
SymbolExpirationInDays: ${{ parameters.symbolExpiryTime }}
|
||||
env:
|
||||
LIB: $(Build.SourcesDirectory)
|
||||
|
||||
- ${{ if eq(parameters.includePublicSymbolServer, true) }}:
|
||||
- task: PublishSymbols@2
|
||||
displayName: 'Publish symbols to MSDL'
|
||||
continueOnError: True
|
||||
inputs:
|
||||
SymbolsFolder: '$(Build.SourcesDirectory)/bin'
|
||||
SearchPattern: '**/*.pdb'
|
||||
IndexSources: false
|
||||
DetailedLog: true
|
||||
SymbolsMaximumWaitTime: 30
|
||||
SymbolServerType: 'TeamServices'
|
||||
SymbolsProduct: 'Windows Terminal Converged Symbols'
|
||||
SymbolsVersion: '$(XES_APPXMANIFESTVERSION)'
|
||||
SymbolExpirationInDays: ${{ parameters.symbolExpiryTime }}
|
||||
${{ if eq(parameters.symbolPatGoesInTaskInputs, true) }}:
|
||||
Pat: $(ADO_microsoftpublicsymbols_PAT)
|
||||
# The ADO task does not support indexing of GitHub sources.
|
||||
# There is a bug which causes this task to fail if LIB includes an inaccessible path (even though it does not depend on it).
|
||||
# To work around this issue, we just force LIB to be any dir that we know exists.
|
||||
# Copied from https://github.com/microsoft/icu/blob/f869c214adc87415dfe751d81f42f1bca55dcf5f/build/azure-nuget.yml#L564-L583
|
||||
env:
|
||||
LIB: $(Build.SourcesDirectory)
|
||||
ArtifactServices_Symbol_AccountName: microsoftpublicsymbols
|
||||
${{ if ne(parameters.symbolPatGoesInTaskInputs, true) }}:
|
||||
ArtifactServices_Symbol_PAT: $(ADO_microsoftpublicsymbols_PAT)
|
||||
82
build/pipelines/templates-v2/job-run-pgo-tests.yml
Normal file
82
build/pipelines/templates-v2/job-run-pgo-tests.yml
Normal file
@@ -0,0 +1,82 @@
|
||||
parameters:
|
||||
buildConfiguration: 'Release'
|
||||
buildPlatform: ''
|
||||
artifactStem: ''
|
||||
testLogPath: '$(Build.BinariesDirectory)\$(BuildPlatform)\$(BuildConfiguration)\testsOnBuildMachine.wtl'
|
||||
|
||||
jobs:
|
||||
- job: PGO${{ parameters.buildPlatform }}${{ parameters.buildConfiguration }}
|
||||
displayName: PGO ${{ parameters.buildPlatform }} ${{ parameters.buildConfiguration }}
|
||||
variables:
|
||||
BuildConfiguration: ${{ parameters.buildConfiguration }}
|
||||
BuildPlatform: ${{ parameters.buildPlatform }}
|
||||
OutputBuildPlatform: ${{ parameters.buildPlatform }}
|
||||
Terminal.BinDir: $(Build.SourcesDirectory)/bin/$(OutputBuildPlatform)/$(BuildConfiguration)
|
||||
pool:
|
||||
${{ if eq(variables['System.CollectionUri'], 'https://dev.azure.com/ms/') }}:
|
||||
${{ if ne(parameters.buildPlatform, 'ARM64') }}:
|
||||
name: SHINE-OSS-Testing-x64
|
||||
${{ else }}:
|
||||
name: SHINE-OSS-Testing-arm64
|
||||
${{ if ne(variables['System.CollectionUri'], 'https://dev.azure.com/ms/') }}:
|
||||
${{ if ne(parameters.buildPlatform, 'ARM64') }}:
|
||||
name: SHINE-INT-Testing-x64
|
||||
${{ else }}:
|
||||
name: SHINE-INT-Testing-arm64
|
||||
|
||||
steps:
|
||||
- checkout: self
|
||||
submodules: false
|
||||
clean: true
|
||||
fetchDepth: 1
|
||||
fetchTags: false # Tags still result in depth > 1 fetch; we don't need them here
|
||||
|
||||
- task: DownloadPipelineArtifact@2
|
||||
displayName: Download artifacts
|
||||
inputs:
|
||||
artifactName: build-${{ parameters.buildPlatform }}-$(BuildConfiguration)${{ parameters.artifactStem }}
|
||||
downloadPath: $(Terminal.BinDir)
|
||||
|
||||
# The tests expect Terminal to be an unpackaged distribution named terminal-0.0.1.0 (after the dev build version scheme)
|
||||
# Extract to that folder explicitly and strip the embedded folder name from the unpackaged archive.
|
||||
- powershell: |-
|
||||
$TargetDirectory = New-Item -Type Directory (Join-Path "$(Terminal.BinDir)" "terminal-0.0.1.0")
|
||||
& tar.exe -x -v -f (Get-Item "$(Terminal.BinDir)/_unpackaged/*.zip") -C $TargetDirectory.FullName --strip-components=1
|
||||
displayName: Extract the unpackaged build for PGO
|
||||
|
||||
- template: steps-ensure-nuget-version.yml
|
||||
|
||||
- powershell: |-
|
||||
$Package = 'Microsoft.Internal.Windows.Terminal.TestContent'
|
||||
$Version = '1.0.1'
|
||||
& nuget.exe install $Package -Version $Version
|
||||
Write-Host "##vso[task.setvariable variable=TerminalTestContentPath]$(Build.SourcesDirectory)\packages\${Package}.${Version}\content"
|
||||
displayName: Install Test Content
|
||||
|
||||
- task: PowerShell@2
|
||||
displayName: 'Run PGO Tests'
|
||||
inputs:
|
||||
targetType: filePath
|
||||
filePath: build\scripts\Run-Tests.ps1
|
||||
arguments: >-
|
||||
-MatchPattern '*UIA.Tests.dll'
|
||||
-Platform '$(OutputBuildPlatform)'
|
||||
-Configuration '$(BuildConfiguration)'
|
||||
-LogPath '${{ parameters.testLogPath }}'
|
||||
-Root "$(Terminal.BinDir)"
|
||||
-AdditionalTaefArguments '/select:(@IsPGO=true)','/p:WTTestContent=$(TerminalTestContentPath)'
|
||||
|
||||
- task: CopyFiles@2
|
||||
displayName: 'Copy PGO outputs to Artifacts'
|
||||
condition: always()
|
||||
inputs:
|
||||
Contents: |
|
||||
**/*.pgc
|
||||
${{ parameters.testLogPath }}
|
||||
TargetFolder: '$(Build.ArtifactStagingDirectory)/$(BuildConfiguration)/$(BuildPlatform)/pgc'
|
||||
OverWrite: true
|
||||
flattenFolders: true
|
||||
|
||||
- publish: '$(Build.ArtifactStagingDirectory)/$(BuildConfiguration)/$(BuildPlatform)/pgc'
|
||||
artifact: pgc-intermediates-$(BuildPlatform)-$(BuildConfiguration)${{ parameters.artifactStem }}
|
||||
condition: always()
|
||||
81
build/pipelines/templates-v2/job-submit-windows-vpack.yml
Normal file
81
build/pipelines/templates-v2/job-submit-windows-vpack.yml
Normal file
@@ -0,0 +1,81 @@
|
||||
parameters:
|
||||
- name: buildConfiguration
|
||||
type: string
|
||||
- name: generateSbom
|
||||
type: boolean
|
||||
default: false
|
||||
- name: pool
|
||||
type: object
|
||||
default: []
|
||||
- name: dependsOn
|
||||
type: object
|
||||
default: null
|
||||
- name: artifactStem
|
||||
type: string
|
||||
default: ''
|
||||
- name: variables
|
||||
type: object
|
||||
default: {}
|
||||
- name: publishArtifacts
|
||||
type: boolean
|
||||
default: true
|
||||
|
||||
jobs:
|
||||
- job: VPack
|
||||
${{ if ne(length(parameters.pool), 0) }}:
|
||||
pool: ${{ parameters.pool }}
|
||||
displayName: Create and Submit Windows vPack
|
||||
dependsOn: ${{ parameters.dependsOn }}
|
||||
variables:
|
||||
JobOutputDirectory: $(XES_VPACKMANIFESTDIRECTORY)
|
||||
JobOutputArtifactName: vpack-manifest${{ parameters.artifactStem }}
|
||||
${{ insert }}: ${{ parameters.variables }}
|
||||
steps:
|
||||
- checkout: self
|
||||
clean: true
|
||||
fetchDepth: 1
|
||||
fetchTags: false # Tags still result in depth > 1 fetch; we don't need them here
|
||||
submodules: true
|
||||
persistCredentials: True
|
||||
|
||||
- task: PkgESSetupBuild@12
|
||||
displayName: Package ES - Setup Build
|
||||
inputs:
|
||||
disableOutputRedirect: true
|
||||
|
||||
- task: DownloadPipelineArtifact@2
|
||||
displayName: Download MSIX Bundle Artifact
|
||||
inputs:
|
||||
artifactName: appxbundle-${{ parameters.buildConfiguration }}${{ parameters.artifactStem }}
|
||||
downloadPath: '$(Build.SourcesDirectory)/bundle'
|
||||
|
||||
# Rename to known/fixed name for Windows build system
|
||||
- powershell: |-
|
||||
# Create vpack directory and place item inside
|
||||
$TargetFolder = New-Item -Type Directory '$(Build.SourcesDirectory)/WindowsTerminal.app'
|
||||
Get-ChildItem bundle/Microsoft.WindowsTerminal_*.msixbundle | Move-Item (Join-Path $TargetFolder.FullName 'Microsoft.WindowsTerminal_8wekyb3d8bbwe.msixbundle') -Verbose
|
||||
displayName: Stage packages for vpack
|
||||
|
||||
- task: PkgESVPack@12
|
||||
displayName: 'Package ES - VPack'
|
||||
env:
|
||||
SYSTEM_ACCESSTOKEN: $(System.AccessToken)
|
||||
inputs:
|
||||
sourceDirectory: '$(Build.SourcesDirectory)/WindowsTerminal.app'
|
||||
description: VPack for the Windows Terminal Application
|
||||
pushPkgName: WindowsTerminal.app
|
||||
owner: conhost
|
||||
githubToken: $(GitHubTokenForVpackProvenance)
|
||||
|
||||
- ${{ if eq(parameters.publishArtifacts, true) }}:
|
||||
- publish: $(JobOutputDirectory)
|
||||
artifact: $(JobOutputArtifactName)
|
||||
displayName: 'Publish VPack Manifest to Drop'
|
||||
|
||||
- task: PkgESFCIBGit@12
|
||||
displayName: 'Submit VPack Manifest to Windows'
|
||||
inputs:
|
||||
configPath: '$(Build.SourcesDirectory)\build\config\GitCheckin.json'
|
||||
artifactsDirectory: $(XES_VPACKMANIFESTDIRECTORY)
|
||||
prTimeOut: 5
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
parameters:
|
||||
configuration: 'Release'
|
||||
platform: ''
|
||||
additionalBuildArguments: ''
|
||||
artifactName: 'drop'
|
||||
testLogPath: '$(Build.BinariesDirectory)\$(BuildPlatform)\$(BuildConfiguration)\testsOnBuildMachine.wtl'
|
||||
inputArtifactStem: ''
|
||||
outputArtifactStem: ''
|
||||
|
||||
jobs:
|
||||
- job: Test${{ parameters.platform }}${{ parameters.configuration }}
|
||||
@@ -11,72 +11,80 @@ jobs:
|
||||
variables:
|
||||
BuildConfiguration: ${{ parameters.configuration }}
|
||||
BuildPlatform: ${{ parameters.platform }}
|
||||
${{ if eq(parameters.platform, 'x86') }}:
|
||||
OutputBuildPlatform: Win32
|
||||
${{ else }}:
|
||||
OutputBuildPlatform: ${{ parameters.platform }}
|
||||
Terminal.BinDir: $(Build.SourcesDirectory)/bin/$(OutputBuildPlatform)/$(BuildConfiguration)
|
||||
pool:
|
||||
${{ if eq(variables['System.CollectionUri'], 'https://dev.azure.com/ms/') }}:
|
||||
name: WinDevPoolOSS-L
|
||||
${{ if ne(parameters.platform, 'ARM64') }}:
|
||||
name: SHINE-OSS-Testing-x64
|
||||
${{ else }}:
|
||||
name: SHINE-OSS-Testing-arm64
|
||||
${{ if ne(variables['System.CollectionUri'], 'https://dev.azure.com/ms/') }}:
|
||||
name: WinDevPool-L
|
||||
demands: ImageOverride -equals WinDevVS17-latest
|
||||
${{ if ne(parameters.platform, 'ARM64') }}:
|
||||
name: SHINE-INT-Testing-x64
|
||||
${{ else }}:
|
||||
name: SHINE-INT-Testing-arm64
|
||||
|
||||
steps:
|
||||
- checkout: self
|
||||
submodules: true
|
||||
submodules: false
|
||||
clean: true
|
||||
fetchDepth: 1
|
||||
fetchTags: false # Tags still result in depth > 1 fetch; we don't need them here
|
||||
|
||||
- task: DownloadBuildArtifacts@0
|
||||
- task: DownloadPipelineArtifact@2
|
||||
displayName: Download artifacts
|
||||
inputs:
|
||||
artifactName: ${{ parameters.artifactName }}
|
||||
|
||||
- task: PowerShell@2
|
||||
displayName: 'Rationalize build platform'
|
||||
inputs:
|
||||
targetType: inline
|
||||
script: |
|
||||
$Arch = "$(BuildPlatform)"
|
||||
If ($Arch -Eq "x86") { $Arch = "Win32" }
|
||||
Write-Host "##vso[task.setvariable variable=RationalizedBuildPlatform]${Arch}"
|
||||
artifactName: build-${{ parameters.platform }}-$(BuildConfiguration)${{ parameters.inputArtifactStem }}
|
||||
downloadPath: $(Terminal.BinDir)
|
||||
|
||||
- task: PowerShell@2
|
||||
displayName: 'Run Unit Tests'
|
||||
inputs:
|
||||
targetType: filePath
|
||||
filePath: build\scripts\Run-Tests.ps1
|
||||
arguments: -MatchPattern '*unit.test*.dll' -Platform '$(RationalizedBuildPlatform)' -Configuration '$(BuildConfiguration)' -LogPath '${{ parameters.testLogPath }}' -Root "$(System.ArtifactsDirectory)\\${{ parameters.artifactName }}\\$(BuildConfiguration)\\$(BuildPlatform)\\test"
|
||||
condition: and(and(succeeded(), ne(variables['PGOBuildMode'], 'Instrument')), or(eq(variables['BuildPlatform'], 'x64'), eq(variables['BuildPlatform'], 'x86')))
|
||||
arguments: -MatchPattern '*unit.test*.dll' -Platform '$(OutputBuildPlatform)' -Configuration '$(BuildConfiguration)' -LogPath '${{ parameters.testLogPath }}' -Root "$(Terminal.BinDir)"
|
||||
|
||||
- task: PowerShell@2
|
||||
displayName: 'Run Feature Tests (x64 only)'
|
||||
inputs:
|
||||
targetType: filePath
|
||||
filePath: build\scripts\Run-Tests.ps1
|
||||
arguments: -MatchPattern '*feature.test*.dll' -Platform '$(RationalizedBuildPlatform)' -Configuration '$(BuildConfiguration)' -LogPath '${{ parameters.testLogPath }}' -Root "$(System.ArtifactsDirectory)\\${{ parameters.artifactName }}\\$(BuildConfiguration)\\$(BuildPlatform)\\test"
|
||||
condition: and(and(succeeded(), ne(variables['PGOBuildMode'], 'Instrument')), eq(variables['BuildPlatform'], 'x64'))
|
||||
- ${{ if or(eq(parameters.platform, 'x64'), eq(parameters.platform, 'arm64')) }}:
|
||||
- task: PowerShell@2
|
||||
displayName: 'Run Feature Tests'
|
||||
inputs:
|
||||
targetType: filePath
|
||||
filePath: build\scripts\Run-Tests.ps1
|
||||
arguments: -MatchPattern '*feature.test*.dll' -Platform '$(OutputBuildPlatform)' -Configuration '$(BuildConfiguration)' -LogPath '${{ parameters.testLogPath }}' -Root "$(Terminal.BinDir)"
|
||||
|
||||
- task: PowerShell@2
|
||||
displayName: 'Convert Test Logs from WTL to xUnit format'
|
||||
condition: always()
|
||||
inputs:
|
||||
targetType: filePath
|
||||
filePath: build\Helix\ConvertWttLogToXUnit.ps1
|
||||
arguments: -WttInputPath '${{ parameters.testLogPath }}' -WttSingleRerunInputPath 'unused.wtl' -WttMultipleRerunInputPath 'unused2.wtl' -XUnitOutputPath 'onBuildMachineResults.xml' -TestNamePrefix '$(BuildConfiguration).$(BuildPlatform)'
|
||||
condition: and(ne(variables['PGOBuildMode'], 'Instrument'),or(eq(variables['BuildPlatform'], 'x64'), eq(variables['BuildPlatform'], 'x86')))
|
||||
|
||||
- task: PowerShell@2
|
||||
displayName: 'Manually log test failures'
|
||||
condition: always()
|
||||
inputs:
|
||||
targetType: filePath
|
||||
filePath: build\Helix\OutputTestErrorsForAzureDevops.ps1
|
||||
arguments: -XUnitOutputPath 'onBuildMachineResults.xml'
|
||||
|
||||
- task: PublishTestResults@2
|
||||
displayName: 'Upload converted test logs'
|
||||
condition: ne(variables['PGOBuildMode'], 'Instrument')
|
||||
condition: always()
|
||||
inputs:
|
||||
testResultsFormat: 'xUnit' # Options: JUnit, NUnit, VSTest, xUnit, cTest
|
||||
testResultsFiles: '**/onBuildMachineResults.xml'
|
||||
#searchFolder: '$(System.DefaultWorkingDirectory)' # Optional
|
||||
#mergeTestResults: false # Optional
|
||||
#failTaskOnFailedTests: false # Optional
|
||||
testRunTitle: 'On Build Machine Tests' # Optional
|
||||
buildPlatform: $(BuildPlatform) # Optional
|
||||
buildConfiguration: $(BuildConfiguration) # Optional
|
||||
#publishRunAttachments: true # Optional
|
||||
|
||||
- task: CopyFiles@2
|
||||
displayName: 'Copy result logs to Artifacts'
|
||||
condition: always()
|
||||
inputs:
|
||||
Contents: |
|
||||
**/*.wtl
|
||||
@@ -87,4 +95,5 @@ jobs:
|
||||
flattenFolders: true
|
||||
|
||||
- publish: '$(Build.ArtifactStagingDirectory)/$(BuildConfiguration)/$(BuildPlatform)/test-logs'
|
||||
artifact: TestLogs$(BuildPlatform)$(BuildConfiguration)
|
||||
artifact: test-logs-$(BuildPlatform)-$(BuildConfiguration)${{ parameters.outputArtifactStem }}
|
||||
condition: always()
|
||||
181
build/pipelines/templates-v2/pipeline-full-release-build.yml
Normal file
181
build/pipelines/templates-v2/pipeline-full-release-build.yml
Normal file
@@ -0,0 +1,181 @@
|
||||
# This build should never run as CI or against a pull request.
|
||||
trigger: none
|
||||
|
||||
parameters:
|
||||
- name: branding
|
||||
type: string
|
||||
default: Release
|
||||
- name: buildTerminal
|
||||
type: boolean
|
||||
default: true
|
||||
- name: buildConPTY
|
||||
type: boolean
|
||||
default: false
|
||||
- name: buildWPF
|
||||
type: boolean
|
||||
default: false
|
||||
- name: pgoBuildMode
|
||||
type: string
|
||||
default: Optimize
|
||||
values:
|
||||
- Optimize
|
||||
- Instrument
|
||||
- None
|
||||
- name: buildConfigurations
|
||||
type: object
|
||||
default:
|
||||
- Release
|
||||
- name: buildPlatforms
|
||||
type: object
|
||||
default:
|
||||
- x64
|
||||
- x86
|
||||
- arm64
|
||||
- name: codeSign
|
||||
type: boolean
|
||||
default: true
|
||||
- name: generateSbom
|
||||
type: boolean
|
||||
default: true
|
||||
- name: terminalInternalPackageVersion
|
||||
type: string
|
||||
default: '0.0.8'
|
||||
|
||||
- name: publishSymbolsToPublic
|
||||
type: boolean
|
||||
default: true
|
||||
- name: symbolExpiryTime
|
||||
type: string
|
||||
default: 36530 # This is the default from PublishSymbols@2
|
||||
- name: publishVpackToWindows
|
||||
type: boolean
|
||||
default: false
|
||||
|
||||
- name: extraPublishJobs
|
||||
type: object
|
||||
default: []
|
||||
- name: pool
|
||||
type: object
|
||||
default:
|
||||
name: SHINE-INT-S # By default, send jobs to the small agent pool.
|
||||
demands: ImageOverride -equals SHINE-VS17-Latest
|
||||
|
||||
variables:
|
||||
- template: variables-nuget-package-version.yml
|
||||
parameters:
|
||||
branding: ${{ parameters.branding }}
|
||||
|
||||
resources:
|
||||
repositories:
|
||||
- repository: self
|
||||
type: git
|
||||
ref: main
|
||||
|
||||
stages:
|
||||
- stage: Build
|
||||
displayName: Build
|
||||
pool: ${{ parameters.pool }}
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- template: ./job-build-project.yml
|
||||
parameters:
|
||||
pool:
|
||||
name: SHINE-INT-L # Run the compilation on the large agent pool, rather than the default small one.
|
||||
demands: ImageOverride -equals SHINE-VS17-Latest
|
||||
branding: ${{ parameters.branding }}
|
||||
buildTerminal: ${{ parameters.buildTerminal }}
|
||||
buildConPTY: ${{ parameters.buildConPTY }}
|
||||
buildWPF: ${{ parameters.buildWPF }}
|
||||
pgoBuildMode: ${{ parameters.pgoBuildMode }}
|
||||
buildConfigurations: ${{ parameters.buildConfigurations }}
|
||||
buildPlatforms: ${{ parameters.buildPlatforms }}
|
||||
generateSbom: ${{ parameters.generateSbom }}
|
||||
codeSign: ${{ parameters.codeSign }}
|
||||
beforeBuildSteps: # Right before we build, lay down the universal package and localizations
|
||||
- task: PkgESSetupBuild@12
|
||||
displayName: Package ES - Setup Build
|
||||
inputs:
|
||||
disableOutputRedirect: true
|
||||
|
||||
- task: UniversalPackages@0
|
||||
displayName: Download terminal-internal Universal Package
|
||||
inputs:
|
||||
feedListDownload: 2b3f8893-a6e8-411f-b197-a9e05576da48
|
||||
packageListDownload: e82d490c-af86-4733-9dc4-07b772033204
|
||||
versionListDownload: ${{ parameters.terminalInternalPackageVersion }}
|
||||
|
||||
- template: ./steps-fetch-and-prepare-localizations.yml
|
||||
parameters:
|
||||
includePseudoLoc: true
|
||||
|
||||
- ${{ if eq(parameters.buildWPF, true) }}:
|
||||
# Add an Any CPU build flavor for the WPF control bits
|
||||
- template: ./job-build-project.yml
|
||||
parameters:
|
||||
# This job is allowed to run on the default small pool.
|
||||
jobName: BuildWPF
|
||||
branding: ${{ parameters.branding }}
|
||||
buildTerminal: false
|
||||
buildWPFDotNetComponents: true
|
||||
buildConfigurations: ${{ parameters.buildConfigurations }}
|
||||
buildPlatforms:
|
||||
- Any CPU
|
||||
generateSbom: ${{ parameters.generateSbom }}
|
||||
codeSign: ${{ parameters.codeSign }}
|
||||
beforeBuildSteps:
|
||||
- task: PkgESSetupBuild@12
|
||||
displayName: Package ES - Setup Build
|
||||
inputs:
|
||||
disableOutputRedirect: true
|
||||
# WPF doesn't need the localizations or the universal package, but if it does... put them here.
|
||||
|
||||
- stage: Package
|
||||
displayName: Package
|
||||
pool: ${{ parameters.pool }}
|
||||
dependsOn: [Build]
|
||||
jobs:
|
||||
- ${{ if eq(parameters.buildTerminal, true) }}:
|
||||
- template: ./job-merge-msix-into-bundle.yml
|
||||
parameters:
|
||||
jobName: Bundle
|
||||
branding: ${{ parameters.branding }}
|
||||
buildConfigurations: ${{ parameters.buildConfigurations }}
|
||||
buildPlatforms: ${{ parameters.buildPlatforms }}
|
||||
generateSbom: ${{ parameters.generateSbom }}
|
||||
codeSign: ${{ parameters.codeSign }}
|
||||
|
||||
- ${{ if eq(parameters.buildConPTY, true) }}:
|
||||
- template: ./job-package-conpty.yml
|
||||
parameters:
|
||||
buildConfigurations: ${{ parameters.buildConfigurations }}
|
||||
buildPlatforms: ${{ parameters.buildPlatforms }}
|
||||
generateSbom: ${{ parameters.generateSbom }}
|
||||
codeSign: ${{ parameters.codeSign }}
|
||||
|
||||
- ${{ if eq(parameters.buildWPF, true) }}:
|
||||
- template: ./job-build-package-wpf.yml
|
||||
parameters:
|
||||
buildConfigurations: ${{ parameters.buildConfigurations }}
|
||||
buildPlatforms: ${{ parameters.buildPlatforms }}
|
||||
generateSbom: ${{ parameters.generateSbom }}
|
||||
codeSign: ${{ parameters.codeSign }}
|
||||
|
||||
- stage: Publish
|
||||
displayName: Publish
|
||||
pool: ${{ parameters.pool }}
|
||||
dependsOn: [Build, Package]
|
||||
jobs:
|
||||
# We only support the vpack for Release builds that include Terminal
|
||||
- ${{ if and(containsValue(parameters.buildConfigurations, 'Release'), parameters.buildTerminal, parameters.publishVpackToWindows) }}:
|
||||
- template: ./job-submit-windows-vpack.yml
|
||||
parameters:
|
||||
buildConfiguration: Release
|
||||
generateSbom: ${{ parameters.generateSbom }}
|
||||
|
||||
- template: ./job-publish-symbols.yml
|
||||
parameters:
|
||||
includePublicSymbolServer: ${{ parameters.publishSymbolsToPublic }}
|
||||
symbolExpiryTime: ${{ parameters.symbolExpiryTime }}
|
||||
|
||||
- ${{ parameters.extraPublishJobs }}
|
||||
...
|
||||
@@ -0,0 +1,265 @@
|
||||
parameters:
|
||||
- name: official
|
||||
type: boolean
|
||||
default: false
|
||||
- name: branding
|
||||
type: string
|
||||
default: Release
|
||||
values:
|
||||
- Release
|
||||
- Preview
|
||||
- Canary
|
||||
- Dev
|
||||
- name: buildTerminal
|
||||
type: boolean
|
||||
default: true
|
||||
- name: buildConPTY
|
||||
type: boolean
|
||||
default: false
|
||||
- name: buildWPF
|
||||
type: boolean
|
||||
default: false
|
||||
- name: pgoBuildMode
|
||||
type: string
|
||||
default: Optimize
|
||||
values:
|
||||
- Optimize
|
||||
- Instrument
|
||||
- None
|
||||
- name: buildConfigurations
|
||||
type: object
|
||||
default:
|
||||
- Release
|
||||
- name: buildPlatforms
|
||||
type: object
|
||||
default:
|
||||
- x64
|
||||
- x86
|
||||
- arm64
|
||||
- name: codeSign
|
||||
type: boolean
|
||||
default: true
|
||||
- name: terminalInternalPackageVersion
|
||||
type: string
|
||||
default: '0.0.8'
|
||||
|
||||
- name: publishSymbolsToPublic
|
||||
type: boolean
|
||||
default: true
|
||||
- name: symbolExpiryTime
|
||||
type: string
|
||||
default: 36530 # This is the default from PublishSymbols@2
|
||||
- name: publishVpackToWindows
|
||||
type: boolean
|
||||
default: false
|
||||
|
||||
- name: extraPublishJobs
|
||||
type: object
|
||||
default: []
|
||||
|
||||
resources:
|
||||
repositories:
|
||||
- repository: templates
|
||||
type: git
|
||||
name: OneBranch.Pipelines/GovernedTemplates
|
||||
ref: refs/heads/main
|
||||
|
||||
extends:
|
||||
${{ if eq(parameters.official, true) }}:
|
||||
template: v2/Microsoft.Official.yml@templates # https://aka.ms/obpipelines/templates
|
||||
${{ else }}:
|
||||
template: v2/Microsoft.NonOfficial.yml@templates
|
||||
parameters:
|
||||
featureFlags:
|
||||
WindowsHostVersion: 1ESWindows2022
|
||||
platform:
|
||||
name: 'windows_undocked'
|
||||
product: 'Windows Terminal'
|
||||
cloudvault: # https://aka.ms/obpipelines/cloudvault
|
||||
enabled: false
|
||||
globalSdl: # https://aka.ms/obpipelines/sdl
|
||||
tsa:
|
||||
enabled: true
|
||||
configFile: '$(Build.SourcesDirectory)\build\config\tsa.json'
|
||||
binskim:
|
||||
break: false
|
||||
scanOutputDirectoryOnly: true
|
||||
policheck:
|
||||
break: false
|
||||
severity: Note
|
||||
baseline:
|
||||
baselineFile: '$(Build.SourcesDirectory)\build\config\release.gdnbaselines'
|
||||
suppressionSet: default
|
||||
|
||||
stages:
|
||||
- stage: Build
|
||||
displayName: Build
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- template: ./build/pipelines/templates-v2/job-build-project.yml@self
|
||||
parameters:
|
||||
pool: { type: windows }
|
||||
variables:
|
||||
ob_git_checkout: false # This job checks itself out
|
||||
ob_git_skip_checkout_none: true
|
||||
ob_outputDirectory: $(JobOutputDirectory)
|
||||
ob_artifactBaseName: $(JobOutputArtifactName)
|
||||
publishArtifacts: false # Handled by OneBranch
|
||||
branding: ${{ parameters.branding }}
|
||||
buildTerminal: ${{ parameters.buildTerminal }}
|
||||
buildConPTY: ${{ parameters.buildConPTY }}
|
||||
buildWPF: ${{ parameters.buildWPF }}
|
||||
pgoBuildMode: ${{ parameters.pgoBuildMode }}
|
||||
buildConfigurations: ${{ parameters.buildConfigurations }}
|
||||
buildPlatforms: ${{ parameters.buildPlatforms }}
|
||||
generateSbom: false # this is handled by onebranch
|
||||
removeAllNonSignedFiles: true # appease the overlords
|
||||
codeSign: ${{ parameters.codeSign }}
|
||||
beforeBuildSteps: # Right before we build, lay down the universal package and localizations
|
||||
- task: PkgESSetupBuild@12
|
||||
displayName: Package ES - Setup Build
|
||||
inputs:
|
||||
disableOutputRedirect: true
|
||||
|
||||
- task: UniversalPackages@0
|
||||
displayName: Download terminal-internal Universal Package
|
||||
inputs:
|
||||
feedListDownload: 2b3f8893-a6e8-411f-b197-a9e05576da48
|
||||
packageListDownload: e82d490c-af86-4733-9dc4-07b772033204
|
||||
versionListDownload: ${{ parameters.terminalInternalPackageVersion }}
|
||||
|
||||
- template: ./build/pipelines/templates-v2/steps-fetch-and-prepare-localizations.yml@self
|
||||
parameters:
|
||||
includePseudoLoc: true
|
||||
|
||||
- ${{ if eq(parameters.buildWPF, true) }}:
|
||||
# Add an Any CPU build flavor for the WPF control bits
|
||||
- template: ./build/pipelines/templates-v2/job-build-project.yml@self
|
||||
parameters:
|
||||
pool: { type: windows }
|
||||
variables:
|
||||
ob_git_checkout: false # This job checks itself out
|
||||
ob_git_skip_checkout_none: true
|
||||
ob_outputDirectory: $(JobOutputDirectory)
|
||||
ob_artifactBaseName: $(JobOutputArtifactName)
|
||||
publishArtifacts: false # Handled by OneBranch
|
||||
jobName: BuildWPF
|
||||
branding: ${{ parameters.branding }}
|
||||
buildTerminal: false
|
||||
buildWPFDotNetComponents: true
|
||||
buildConfigurations: ${{ parameters.buildConfigurations }}
|
||||
buildPlatforms:
|
||||
- Any CPU
|
||||
generateSbom: false # this is handled by onebranch
|
||||
removeAllNonSignedFiles: true # appease the overlords
|
||||
codeSign: ${{ parameters.codeSign }}
|
||||
beforeBuildSteps:
|
||||
- task: PkgESSetupBuild@12
|
||||
displayName: Package ES - Setup Build
|
||||
inputs:
|
||||
disableOutputRedirect: true
|
||||
# WPF doesn't need the localizations or the universal package, but if it does... put them here.
|
||||
|
||||
- stage: Package
|
||||
displayName: Package
|
||||
dependsOn: [Build]
|
||||
jobs:
|
||||
- ${{ if eq(parameters.buildTerminal, true) }}:
|
||||
- template: ./build/pipelines/templates-v2/job-merge-msix-into-bundle.yml@self
|
||||
parameters:
|
||||
pool: { type: windows }
|
||||
variables:
|
||||
ob_git_checkout: false # This job checks itself out
|
||||
ob_git_skip_checkout_none: true
|
||||
ob_outputDirectory: $(JobOutputDirectory)
|
||||
ob_artifactBaseName: $(JobOutputArtifactName)
|
||||
### This job is also in charge of submitting the vpack to Windows if it's enabled
|
||||
ob_createvpack_enabled: ${{ and(parameters.buildTerminal, parameters.publishVpackToWindows) }}
|
||||
ob_updateOSManifest_enabled: ${{ and(parameters.buildTerminal, parameters.publishVpackToWindows) }}
|
||||
### If enabled above, these options are in play.
|
||||
ob_createvpack_packagename: 'WindowsTerminal.app'
|
||||
ob_createvpack_owneralias: 'conhost@microsoft.com'
|
||||
ob_createvpack_description: 'VPack for the Windows Terminal Application'
|
||||
ob_createvpack_targetDestinationDirectory: '$(Destination)'
|
||||
ob_createvpack_propsFile: false
|
||||
ob_createvpack_provData: true
|
||||
ob_createvpack_metadata: '$(Build.SourceVersion)'
|
||||
ob_createvpack_topLevelRetries: 0
|
||||
ob_createvpack_failOnStdErr: true
|
||||
ob_createvpack_taskLogVerbosity: Detailed
|
||||
ob_createvpack_verbose: true
|
||||
ob_createvpack_vpackdirectory: '$(JobOutputDirectory)\vpack'
|
||||
ob_updateOSManifest_gitcheckinConfigPath: '$(Build.SourcesDirectory)\build\config\GitCheckin.json'
|
||||
# We're skipping the 'fetch' part of the OneBranch rules, but that doesn't mean
|
||||
# that it doesn't expect to have downloaded a manifest directly to some 'destination'
|
||||
# folder that it can then update and upload.
|
||||
# Effectively: it says "destination" but it means "source"
|
||||
# DH: Don't ask why.
|
||||
ob_updateOSManifest_destination: $(XES_VPACKMANIFESTDIRECTORY)
|
||||
ob_updateOSManifest_skipFetch: true
|
||||
publishArtifacts: false # Handled by OneBranch
|
||||
jobName: Bundle
|
||||
branding: ${{ parameters.branding }}
|
||||
buildConfigurations: ${{ parameters.buildConfigurations }}
|
||||
buildPlatforms: ${{ parameters.buildPlatforms }}
|
||||
generateSbom: false # Handled by onebranch
|
||||
codeSign: ${{ parameters.codeSign }}
|
||||
afterBuildSteps:
|
||||
# This directory has to exist, even if we aren't using createvpack, because the Guardian rules demand it.
|
||||
- pwsh: |-
|
||||
New-Item "$(JobOutputDirectory)/vpack" -Type Directory
|
||||
displayName: Make sure the vpack directory exists
|
||||
|
||||
- ${{ if parameters.publishVpackToWindows }}:
|
||||
- pwsh: |-
|
||||
Copy-Item -Verbose -Path "$(MsixBundlePath)" -Destination (Join-Path "$(JobOutputDirectory)/vpack" 'Microsoft.WindowsTerminal_8wekyb3d8bbwe.msixbundle')
|
||||
displayName: Stage msixbundle for vpack
|
||||
|
||||
- ${{ if eq(parameters.buildConPTY, true) }}:
|
||||
- template: ./build/pipelines/templates-v2/job-package-conpty.yml@self
|
||||
parameters:
|
||||
pool: { type: windows }
|
||||
variables:
|
||||
ob_git_checkout: false # This job checks itself out
|
||||
ob_git_skip_checkout_none: true
|
||||
ob_outputDirectory: $(JobOutputDirectory)
|
||||
ob_artifactBaseName: $(JobOutputArtifactName)
|
||||
publishArtifacts: false # Handled by OneBranch
|
||||
buildConfigurations: ${{ parameters.buildConfigurations }}
|
||||
buildPlatforms: ${{ parameters.buildPlatforms }}
|
||||
generateSbom: false # this is handled by onebranch
|
||||
codeSign: ${{ parameters.codeSign }}
|
||||
|
||||
- ${{ if eq(parameters.buildWPF, true) }}:
|
||||
- template: ./build/pipelines/templates-v2/job-build-package-wpf.yml@self
|
||||
parameters:
|
||||
pool: { type: windows }
|
||||
variables:
|
||||
ob_git_checkout: false # This job checks itself out
|
||||
ob_git_skip_checkout_none: true
|
||||
ob_outputDirectory: $(JobOutputDirectory)
|
||||
ob_artifactBaseName: $(JobOutputArtifactName)
|
||||
publishArtifacts: false # Handled by OneBranch
|
||||
buildConfigurations: ${{ parameters.buildConfigurations }}
|
||||
buildPlatforms: ${{ parameters.buildPlatforms }}
|
||||
generateSbom: false # this is handled by onebranch
|
||||
codeSign: ${{ parameters.codeSign }}
|
||||
|
||||
- stage: Publish
|
||||
displayName: Publish
|
||||
dependsOn: [Build, Package]
|
||||
jobs:
|
||||
- template: ./build/pipelines/templates-v2/job-publish-symbols.yml@self
|
||||
parameters:
|
||||
pool: { type: windows }
|
||||
includePublicSymbolServer: ${{ parameters.publishSymbolsToPublic }}
|
||||
symbolPatGoesInTaskInputs: true # onebranch tries to muck with the PAT variable, so we need to change how it get the PAT
|
||||
symbolExpiryTime: ${{ parameters.symbolExpiryTime }}
|
||||
variables:
|
||||
ob_git_checkout: false # This job checks itself out
|
||||
ob_git_skip_checkout_none: true
|
||||
ob_outputDirectory: $(Build.ArtifactStagingDirectory)
|
||||
# Without this, OneBranch will nerf our symbol tasks
|
||||
ob_symbolsPublishing_enabled: true
|
||||
|
||||
- ${{ parameters.extraPublishJobs }}
|
||||
35
build/pipelines/templates-v2/steps-create-signing-config.yml
Normal file
35
build/pipelines/templates-v2/steps-create-signing-config.yml
Normal file
@@ -0,0 +1,35 @@
|
||||
parameters:
|
||||
- name: stage
|
||||
type: string
|
||||
- name: outFile
|
||||
type: string
|
||||
- name: fragments
|
||||
type: string
|
||||
|
||||
# This build step template takes all files named "esrp.STAGE.batch.*.json"
|
||||
# and merges them into a single output signing config.
|
||||
#
|
||||
# We generate the batch signing config by sticking together multiple "batches".
|
||||
# The filter below (with Fragments) works by splitting the filename, esrp.s.batch.x.json,
|
||||
# to get 'x' and then checking whether x is in Fragments.
|
||||
# We have to manually strip comments out of the batch fragments due to https://github.com/PowerShell/PowerShell/issues/14553
|
||||
|
||||
steps:
|
||||
- pwsh: |-
|
||||
$SignBatchFiles = (Get-Item build/config/esrp.${{ parameters.stage }}.batch.*.json)
|
||||
$Fragments = "${{ parameters.fragments }}"
|
||||
If (-Not [String]::IsNullOrWhiteSpace($Fragments)) {
|
||||
$FragmentList = $Fragments -Split ";"
|
||||
If ($FragmentList.Length -Gt 0) {
|
||||
$SignBatchFiles = $SignBatchFiles | Where-Object { ($_.Name -Split '\.')[3] -In $FragmentList }
|
||||
}
|
||||
}
|
||||
Write-Host "Found $(@($SignBatchFiles).Length) Signing Configs"
|
||||
Write-Host ($SignBatchFiles.Name -Join ";")
|
||||
$FinalSignConfig = @{
|
||||
Version = "1.0.0";
|
||||
UseMinimatch = $false;
|
||||
SignBatches = @($SignBatchFiles | ForEach-Object { Get-Content $_ | Where-Object { $_ -NotMatch "^\s*\/\/" } | ConvertFrom-Json -Depth 10 });
|
||||
}
|
||||
$FinalSignConfig | ConvertTo-Json -Depth 10 | Out-File -Encoding utf8 "${{ parameters.outFile }}"
|
||||
displayName: Merge ${{ parameters.stage }} signing configs (${{ parameters.outFile }})
|
||||
@@ -0,0 +1,24 @@
|
||||
parameters:
|
||||
- name: buildConfigurations
|
||||
type: object
|
||||
- name: buildPlatforms
|
||||
type: object
|
||||
- name: artifactStem
|
||||
type: string
|
||||
default: ''
|
||||
|
||||
steps:
|
||||
- ${{ each configuration in parameters.buildConfigurations }}:
|
||||
- ${{ each platform in parameters.buildPlatforms }}:
|
||||
- task: DownloadPipelineArtifact@2
|
||||
displayName: Download artifacts for ${{ platform }} ${{ configuration }}
|
||||
inputs:
|
||||
# Make sure to download the entire artifact, because it includes the SPDX SBOM
|
||||
artifactName: build-${{ platform }}-${{ configuration }}${{ parameters.artifactStem }}
|
||||
# Downloading to the source directory should ensure that the later SBOM generator can see the earlier SBOMs.
|
||||
${{ if eq(platform, 'x86') }}:
|
||||
downloadPath: '$(Build.SourcesDirectory)/bin/Win32/${{ configuration }}'
|
||||
${{ elseif eq(platform, 'Any CPU') }}:
|
||||
downloadPath: '$(Build.SourcesDirectory)/bin/AnyCPU/${{ configuration }}'
|
||||
${{ else }}:
|
||||
downloadPath: '$(Build.SourcesDirectory)/bin/${{ platform }}/${{ configuration }}'
|
||||
@@ -0,0 +1,5 @@
|
||||
steps:
|
||||
- task: NuGetToolInstaller@1
|
||||
displayName: Use NuGet 6.6.1
|
||||
inputs:
|
||||
versionSpec: 6.6.1
|
||||
@@ -0,0 +1,27 @@
|
||||
parameters:
|
||||
- name: includePseudoLoc
|
||||
type: boolean
|
||||
default: true
|
||||
|
||||
steps:
|
||||
- task: TouchdownBuildTask@1
|
||||
displayName: Download Localization Files
|
||||
inputs:
|
||||
teamId: 7105
|
||||
authId: $(TouchdownAppId)
|
||||
authKey: $(TouchdownAppKey)
|
||||
resourceFilePath: |
|
||||
src\cascadia\**\en-US\*.resw
|
||||
appendRelativeDir: true
|
||||
localizationTarget: false
|
||||
${{ if eq(parameters.includePseudoLoc, true) }}:
|
||||
pseudoSetting: Included
|
||||
|
||||
- pwsh: |-
|
||||
$Files = Get-ChildItem . -R -Filter 'Resources.resw' | ? FullName -Like '*en-US\*\Resources.resw'
|
||||
$Files | % { Move-Item -Verbose $_.Directory $_.Directory.Parent.Parent -EA:Ignore }
|
||||
displayName: Move Loc files into final locations
|
||||
|
||||
- pwsh: |-
|
||||
./build/scripts/Copy-ContextMenuResourcesToCascadiaPackage.ps1
|
||||
displayName: Copy the Context Menu Loc Resources to CascadiaPackage
|
||||
@@ -1,14 +1,12 @@
|
||||
steps:
|
||||
- task: NuGetToolInstaller@0
|
||||
displayName: 'Use NuGet 6.3.0'
|
||||
inputs:
|
||||
versionSpec: 6.3.0
|
||||
- template: steps-ensure-nuget-version.yml
|
||||
|
||||
- task: NuGetAuthenticate@0
|
||||
|
||||
- script: |-
|
||||
echo ##vso[task.setvariable variable=NUGET_RESTORE_MSBUILD_ARGS]/p:Platform=$(BuildPlatform)
|
||||
displayName: Ensure NuGet restores for $(BuildPlatform)
|
||||
condition: and(succeeded(), ne(variables['BuildPlatform'], 'Any CPU'))
|
||||
|
||||
# In the Microsoft Azure DevOps tenant, NuGetCommand is ambiguous.
|
||||
# This should be `task: NuGetCommand@2`
|
||||
@@ -0,0 +1,27 @@
|
||||
parameters:
|
||||
- name: branding
|
||||
type: string
|
||||
|
||||
variables:
|
||||
# If we are building a branch called "release-*", change the NuGet suffix
|
||||
# to "preview". If we don't do that, XES will set the suffix to "release1"
|
||||
# because it truncates the value after the first period.
|
||||
# We also want to disable the suffix entirely if we're Release branded while
|
||||
# on a release branch.
|
||||
# main is special, however. XES ignores main. Since we never produce actual
|
||||
# shipping builds from main, we want to force it to have a beta label as
|
||||
# well.
|
||||
#
|
||||
# In effect:
|
||||
# BRANCH / BRANDING | Release | Preview
|
||||
# ------------------|----------------------------|-----------------------------
|
||||
# release-* | 1.12.20220427 | 1.13.20220427-preview
|
||||
# main | 1.14.20220427-experimental | 1.14.20220427-experimental
|
||||
# all others | 1.14.20220427-mybranch | 1.14.20220427-mybranch
|
||||
${{ if startsWith(variables['Build.SourceBranchName'], 'release-') }}:
|
||||
${{ if eq(parameters.branding, 'Release') }}:
|
||||
NoNuGetPackBetaVersion: true
|
||||
${{ else }}:
|
||||
NuGetPackBetaVersion: preview
|
||||
${{ elseif eq(variables['Build.SourceBranchName'], 'main') }}:
|
||||
NuGetPackBetaVersion: experimental
|
||||
@@ -0,0 +1,2 @@
|
||||
variables:
|
||||
WindowsContainerImage: 'onebranch.azurecr.io/windows/ltsc2022/vse2022:latest'
|
||||
@@ -1,34 +0,0 @@
|
||||
parameters:
|
||||
platform: ''
|
||||
additionalBuildArguments: ''
|
||||
|
||||
jobs:
|
||||
- job: Build${{ parameters.platform }}AuditMode
|
||||
displayName: Static Analysis Build ${{ parameters.platform }}
|
||||
variables:
|
||||
BuildConfiguration: AuditMode
|
||||
BuildPlatform: ${{ parameters.platform }}
|
||||
pool:
|
||||
${{ if eq(variables['System.CollectionUri'], 'https://dev.azure.com/ms/') }}:
|
||||
name: WinDevPoolOSS-L
|
||||
${{ if ne(variables['System.CollectionUri'], 'https://dev.azure.com/ms/') }}:
|
||||
name: WinDevPool-L
|
||||
demands: ImageOverride -equals WinDevVS17-latest
|
||||
|
||||
steps:
|
||||
- checkout: self
|
||||
submodules: true
|
||||
clean: true
|
||||
fetchDepth: 1
|
||||
|
||||
- template: restore-nuget-steps.yml
|
||||
|
||||
- task: VSBuild@1
|
||||
displayName: 'Build solution **\OpenConsole.sln'
|
||||
inputs:
|
||||
solution: '**\OpenConsole.sln'
|
||||
platform: '$(BuildPlatform)'
|
||||
configuration: '$(BuildConfiguration)'
|
||||
msbuildArgs: ${{ parameters.additionalBuildArguments }}
|
||||
clean: true
|
||||
maximumCpuCount: true
|
||||
@@ -1,31 +0,0 @@
|
||||
parameters:
|
||||
configuration: 'Release'
|
||||
branding: 'Dev'
|
||||
platform: ''
|
||||
additionalBuildArguments: ''
|
||||
|
||||
jobs:
|
||||
- job: Build${{ parameters.platform }}${{ parameters.configuration }}${{ parameters.branding }}
|
||||
displayName: Build ${{ parameters.platform }} ${{ parameters.configuration }} ${{ parameters.branding }}
|
||||
variables:
|
||||
BuildConfiguration: ${{ parameters.configuration }}
|
||||
BuildPlatform: ${{ parameters.platform }}
|
||||
WindowsTerminalBranding: ${{ parameters.branding }}
|
||||
EnableRichCodeNavigation: true
|
||||
pool:
|
||||
${{ if eq(variables['System.CollectionUri'], 'https://dev.azure.com/ms/') }}:
|
||||
name: WinDevPoolOSS-L
|
||||
${{ if ne(variables['System.CollectionUri'], 'https://dev.azure.com/ms/') }}:
|
||||
name: WinDevPool-L
|
||||
demands: ImageOverride -equals WinDevVS17-latest
|
||||
|
||||
steps:
|
||||
- template: build-console-steps.yml
|
||||
parameters:
|
||||
additionalBuildArguments: ${{ parameters.additionalBuildArguments }}
|
||||
|
||||
# It appears that the Component Governance build task that gets automatically injected stopped working
|
||||
# when we renamed our main branch.
|
||||
- task: ms.vss-governance-buildtask.governance-build-task-component-detection.ComponentGovernanceComponentDetection@0
|
||||
displayName: 'Component Detection'
|
||||
condition: and(succeededOrFailed(), not(eq(variables['Build.Reason'], 'PullRequest')))
|
||||
@@ -1,203 +0,0 @@
|
||||
jobs:
|
||||
- job: Compliance
|
||||
# We don't *need* a matrix but there's no other way to set parameters on a "job"
|
||||
# in the AzDO YAML syntax. It would have to be a "stage" or a "template".
|
||||
# Doesn't matter. We're going to do compliance on Release x64 because
|
||||
# that's the one all the tooling works against for sure.
|
||||
strategy:
|
||||
matrix:
|
||||
Release_x64:
|
||||
BuildConfiguration: Release
|
||||
BuildPlatform: x64
|
||||
displayName: Validate Security and Compliance
|
||||
timeoutInMinutes: 240
|
||||
steps:
|
||||
- checkout: self
|
||||
clean: true
|
||||
submodules: true
|
||||
persistCredentials: True
|
||||
- task: PkgESSetupBuild@12
|
||||
displayName: Package ES - Setup Build
|
||||
inputs:
|
||||
disableOutputRedirect: true
|
||||
- task: PowerShell@2
|
||||
displayName: Rationalize Build Platform
|
||||
inputs:
|
||||
targetType: inline
|
||||
script: >-
|
||||
$Arch = "$(BuildPlatform)"
|
||||
|
||||
If ($Arch -Eq "x86") { $Arch = "Win32" }
|
||||
|
||||
Write-Host "##vso[task.setvariable variable=RationalizedBuildPlatform]${Arch}"
|
||||
- template: restore-nuget-steps.yml
|
||||
- task: UniversalPackages@0
|
||||
displayName: Download terminal-internal Universal Package
|
||||
inputs:
|
||||
feedListDownload: 2b3f8893-a6e8-411f-b197-a9e05576da48
|
||||
packageListDownload: e82d490c-af86-4733-9dc4-07b772033204
|
||||
versionListDownload: $(TerminalInternalPackageVersion)
|
||||
- task: TouchdownBuildTask@1
|
||||
displayName: Download Localization Files
|
||||
inputs:
|
||||
teamId: 7105
|
||||
authId: $(TouchdownAppId)
|
||||
authKey: $(TouchdownAppKey)
|
||||
resourceFilePath: >-
|
||||
src\cascadia\TerminalApp\Resources\en-US\Resources.resw
|
||||
|
||||
src\cascadia\TerminalControl\Resources\en-US\Resources.resw
|
||||
|
||||
src\cascadia\TerminalConnection\Resources\en-US\Resources.resw
|
||||
|
||||
src\cascadia\TerminalSettingsModel\Resources\en-US\Resources.resw
|
||||
|
||||
src\cascadia\TerminalSettingsEditor\Resources\en-US\Resources.resw
|
||||
|
||||
src\cascadia\CascadiaPackage\Resources\en-US\Resources.resw
|
||||
appendRelativeDir: true
|
||||
localizationTarget: false
|
||||
pseudoSetting: Included
|
||||
- task: PowerShell@2
|
||||
displayName: Move Loc files one level up
|
||||
inputs:
|
||||
targetType: inline
|
||||
script: >-
|
||||
$Files = Get-ChildItem . -R -Filter 'Resources.resw' | ? FullName -Like '*en-US\*\Resources.resw'
|
||||
|
||||
$Files | % { Move-Item -Verbose $_.Directory $_.Directory.Parent.Parent -EA:Ignore }
|
||||
pwsh: true
|
||||
|
||||
# 1ES Component Governance onboarding (Detects open source components). See https://docs.opensource.microsoft.com/tools/cg.html
|
||||
- task: ms.vss-governance-buildtask.governance-build-task-component-detection.ComponentGovernanceComponentDetection@0
|
||||
displayName: Component Detection
|
||||
|
||||
# # PREfast and PoliCheck need Node. Install that first.
|
||||
- task: NodeTool@0
|
||||
|
||||
# !!! NOTE !!! Run PREfast first. Some of the other tasks are going to run on a completed build.
|
||||
# PREfast is going to build the code as a part of its analysis and the generated sources
|
||||
# and output binaries will be sufficient for the rest of the analysis.
|
||||
# If you disable this, the other tasks won't likely work. You would have to add a build
|
||||
# step instead that builds the code normally before calling them.
|
||||
# Also... PREfast will rebuild anyway so that's why we're not running a normal build first.
|
||||
# Waste of time to build twice.
|
||||
# PREfast. See https://www.1eswiki.com/wiki/SDL_Native_Rules_Build_Task
|
||||
|
||||
# The following 1ES tasks all operate completely differently and have a different syntax for usage.
|
||||
# Most notable is every one of them has a different way of excluding things.
|
||||
# Go see their 1eswiki.com pages to figure out how to exclude things.
|
||||
# When writing exclusions, try to make them narrow so when new projects/binaries are added, they
|
||||
# cause an error here and have to be explicitly pulled out. Don't write an exclusion so broad
|
||||
# that it will catch other new stuff.
|
||||
|
||||
# https://www.1eswiki.com/wiki/PREfast_Build_Task
|
||||
# Builds the project with C/C++ static analysis tools to find coding flaws and vulnerabilities
|
||||
# !!! WARNING !!! It doesn't work with WAPPROJ packaging projects. Build the sub-projects instead.
|
||||
- task: securedevelopmentteam.vss-secure-development-tools.build-task-prefast.SDLNativeRules@3
|
||||
displayName: 'Run the PREfast SDL Native Rules for MSBuild'
|
||||
condition: succeededOrFailed()
|
||||
inputs:
|
||||
setupCommandlines: '"C:\Program Files\Microsoft Visual Studio\2022\Enterprise\Common7\Tools\VsMSBuildCmd.bat"'
|
||||
msBuildCommandline: msbuild.exe /nologo /m /p:WindowsTerminalOfficialBuild=true /p:WindowsTerminalBranding=${{ parameters.branding }} /p:WindowsTerminalReleaseBuild=true /p:platform=$(BuildPlatform) /p:configuration=$(BuildConfiguration) /t:Terminal\Window\WindowsTerminal /p:VisualStudioVersion=17.0 $(Build.SourcesDirectory)\OpenConsole.sln
|
||||
msBuildVersion: "17.0"
|
||||
|
||||
# Copies output from PREfast SDL Native Rules task to expected location for consumption by PkgESSecComp
|
||||
- task: CopyFiles@1
|
||||
displayName: 'Copy PREfast xml files to SDLNativeRulesDir'
|
||||
inputs:
|
||||
SourceFolder: '$(Agent.BuildDirectory)'
|
||||
Contents: |
|
||||
**\*.nativecodeanalysis.xml
|
||||
TargetFolder: '$(Agent.BuildDirectory)\_sdt\logs\SDLNativeRules'
|
||||
|
||||
# https://www.1eswiki.com/index.php?title=PoliCheck_Build_Task
|
||||
# Scans the text of source code, comments, and content for terminology that could be sensitive for legal, cultural, or geopolitical reasons.
|
||||
# (Also finds vulgarities... takes all the fun out of everything.)
|
||||
- task: securedevelopmentteam.vss-secure-development-tools.build-task-policheck.PoliCheck@2
|
||||
displayName: 'Run PoliCheck'
|
||||
inputs:
|
||||
targetType: F
|
||||
targetArgument: $(Build.SourcesDirectory)
|
||||
result: PoliCheck.xml
|
||||
optionsFC: 1
|
||||
optionsXS: 1
|
||||
optionsUEPath: $(Build.SourcesDirectory)\build\config\PolicheckExclusions.xml
|
||||
optionsHMENABLE: 0
|
||||
continueOnError: true
|
||||
|
||||
# https://www.1eswiki.com/wiki/CredScan_Azure_DevOps_Build_Task
|
||||
# Searches through source code and build outputs for a credential left behind in the open
|
||||
- task: securedevelopmentteam.vss-secure-development-tools.build-task-credscan.CredScan@3
|
||||
displayName: 'Run CredScan'
|
||||
inputs:
|
||||
outputFormat: pre
|
||||
# suppressionsFile: LocalSuppressions.json
|
||||
batchSize: 20
|
||||
debugMode: false
|
||||
continueOnError: true
|
||||
|
||||
# https://www.1eswiki.com/wiki/BinSkim_Build_Task
|
||||
# Searches managed and unmanaged binaries for known security vulnerabilities.
|
||||
- task: securedevelopmentteam.vss-secure-development-tools.build-task-binskim.BinSkim@4
|
||||
displayName: 'Run BinSkim'
|
||||
inputs:
|
||||
TargetPattern: guardianGlob
|
||||
# See https://aka.ms/gdn-globs for how to do match patterns
|
||||
AnalyzeTargetGlob: $(Build.SourcesDirectory)\bin\**\*.dll;$(Build.SourcesDirectory)\bin\**\*.exe;-:file|**\Microsoft.UI.Xaml.dll;-:file|**\Microsoft.Toolkit.Win32.UI.XamlHost.dll;-:file|**\vcruntime*.dll;-:file|**\vcomp*.dll;-:file|**\vccorlib*.dll;-:file|**\vcamp*.dll;-:file|**\msvcp*.dll;-:file|**\concrt*.dll;-:file|**\TerminalThemeHelpers*.dll
|
||||
continueOnError: true
|
||||
|
||||
# Set XES_SERIALPOSTBUILDREADY to run Security and Compliance task once per build
|
||||
- powershell: Write-Host "##vso[task.setvariable variable=XES_SERIALPOSTBUILDREADY;]true"
|
||||
displayName: 'Set XES_SERIALPOSTBUILDREADY Vars'
|
||||
|
||||
# https://www.osgwiki.com/wiki/Package_ES_Security_and_Compliance
|
||||
# Does a few things:
|
||||
# - Ensures that Windows-required compliance tasks are run either inside this task
|
||||
# or were run as a previous step prior to this one
|
||||
# (PREfast, PoliCheck, Credscan)
|
||||
# - Runs Windows-specific compliance tasks inside the task
|
||||
# + CheckCFlags - ensures that compiler and linker flags meet Windows standards
|
||||
# + CFGCheck/XFGCheck - ensures that Control Flow Guard (CFG) or
|
||||
# eXtended Flow Guard (XFG) are enabled on binaries
|
||||
# NOTE: CFG is deprecated and XFG isn't fully ready yet.
|
||||
# NOTE2: CFG fails on an XFG'd binary
|
||||
# - Brokers all security/compliance task logs to "Trust Services Automation (TSA)" (https://aka.ms/tsa)
|
||||
# which is a system that maps all errors into the appropriate bug database
|
||||
# template for each organization since they all vary. It should also suppress
|
||||
# new bugs when one already exists for the product.
|
||||
# This one is set up to go to the OS repository and use the given parameters
|
||||
# to file bugs to our AzDO product path.
|
||||
# If we don't use PkgESSecComp to do this for us, we need to install the TSA task
|
||||
# ourselves in this pipeline to finalize data upload and bug creation.
|
||||
# !!! NOTE !!! This task goes *LAST* after any other compliance tasks so it catches their logs
|
||||
- task: PkgESSecComp@10
|
||||
displayName: 'Security and Compliance tasks'
|
||||
inputs:
|
||||
fileNewBugs: false
|
||||
areaPath: 'OS\WDX\DXP\WinDev\Terminal'
|
||||
teamProject: 'OS'
|
||||
iterationPath: 'OS\Future'
|
||||
bugTags: 'TerminalReleaseCompliance'
|
||||
scanAll: true
|
||||
errOnBugs: false
|
||||
failOnStdErr: true
|
||||
taskLogVerbosity: Diagnostic
|
||||
secCompConfigFromTask: |
|
||||
# Overrides default build sources directory
|
||||
sourceTargetOverrideAll: $(Build.SourcesDirectory)
|
||||
# Overrides default build binaries directory when "Scan all" option is specified
|
||||
binariesTargetOverrideAll: $(Build.SourcesDirectory)\bin
|
||||
|
||||
# Set the tools to false if they should not run in the build
|
||||
tools:
|
||||
- toolName: CheckCFlags
|
||||
enable: true
|
||||
- toolName: CFGCheck
|
||||
enable: true
|
||||
- toolName: Policheck
|
||||
enable: false
|
||||
- toolName: CredScan
|
||||
enable: false
|
||||
- toolName: XFGCheck
|
||||
enable: false
|
||||
@@ -1,90 +0,0 @@
|
||||
parameters:
|
||||
configuration: 'Fuzzing'
|
||||
platform: ''
|
||||
additionalBuildArguments: ''
|
||||
|
||||
jobs:
|
||||
- job: Build${{ parameters.platform }}${{ parameters.configuration }}
|
||||
displayName: Build ${{ parameters.platform }} ${{ parameters.configuration }}
|
||||
variables:
|
||||
BuildConfiguration: ${{ parameters.configuration }}
|
||||
BuildPlatform: ${{ parameters.platform }}
|
||||
pool:
|
||||
${{ if eq(variables['System.CollectionUri'], 'https://dev.azure.com/ms/') }}:
|
||||
name: WinDevPoolOSS-L
|
||||
${{ if ne(variables['System.CollectionUri'], 'https://dev.azure.com/ms/') }}:
|
||||
name: WinDevPool-L
|
||||
demands: ImageOverride -equals WinDevVS17-latest
|
||||
|
||||
steps:
|
||||
- checkout: self
|
||||
submodules: true
|
||||
clean: true
|
||||
|
||||
- template: restore-nuget-steps.yml
|
||||
|
||||
# The environment variable VCToolsInstallDir isn't defined on lab machines, so we need to retrieve it ourselves.
|
||||
- script: |
|
||||
"%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe" -Latest -requires Microsoft.Component.MSBuild -property InstallationPath > %TEMP%\vsinstalldir.txt
|
||||
set /p _VSINSTALLDIR15=<%TEMP%\vsinstalldir.txt
|
||||
del %TEMP%\vsinstalldir.txt
|
||||
call "%_VSINSTALLDIR15%\Common7\Tools\VsDevCmd.bat"
|
||||
echo VCToolsInstallDir = %VCToolsInstallDir%
|
||||
echo ##vso[task.setvariable variable=VCToolsInstallDir]%VCToolsInstallDir%
|
||||
displayName: 'Retrieve VC tools directory'
|
||||
|
||||
- task: VSBuild@1
|
||||
displayName: 'Build solution **\OpenConsole.sln'
|
||||
inputs:
|
||||
solution: '**\OpenConsole.sln'
|
||||
platform: '$(BuildPlatform)'
|
||||
configuration: '$(BuildConfiguration)'
|
||||
msbuildArgs: "${{ parameters.additionalBuildArguments }}"
|
||||
clean: true
|
||||
maximumCpuCount: true
|
||||
|
||||
- task: PowerShell@2
|
||||
displayName: 'Rationalize build platform'
|
||||
inputs:
|
||||
targetType: inline
|
||||
script: |
|
||||
$Arch = "$(BuildPlatform)"
|
||||
If ($Arch -Eq "x86") { $Arch = "Win32" }
|
||||
Write-Host "##vso[task.setvariable variable=RationalizedBuildPlatform]${Arch}"
|
||||
|
||||
- task: CopyFiles@2
|
||||
displayName: 'Copy result logs to Artifacts'
|
||||
inputs:
|
||||
Contents: |
|
||||
**/*.wtl
|
||||
**/*onBuildMachineResults.xml
|
||||
${{ parameters.testLogPath }}
|
||||
TargetFolder: '$(Build.ArtifactStagingDirectory)/$(BuildConfiguration)/$(BuildPlatform)/test'
|
||||
OverWrite: true
|
||||
flattenFolders: true
|
||||
|
||||
- task: CopyFiles@2
|
||||
displayName: 'Copy outputs needed for test runs to Artifacts'
|
||||
inputs:
|
||||
Contents: |
|
||||
$(Build.SourcesDirectory)/bin/$(RationalizedBuildPlatform)/$(BuildConfiguration)/*.exe
|
||||
$(Build.SourcesDirectory)/bin/$(RationalizedBuildPlatform)/$(BuildConfiguration)/*.dll
|
||||
$(Build.SourcesDirectory)/bin/$(RationalizedBuildPlatform)/$(BuildConfiguration)/*.xml
|
||||
**/Microsoft.VCLibs.*.appx
|
||||
**/TestHostApp/*.exe
|
||||
**/TestHostApp/*.dll
|
||||
**/TestHostApp/*.xml
|
||||
!**/*.pdb
|
||||
!**/*.ipdb
|
||||
!**/*.obj
|
||||
!**/*.pch
|
||||
TargetFolder: '$(Build.ArtifactStagingDirectory)/$(BuildConfiguration)/$(BuildPlatform)/test'
|
||||
OverWrite: true
|
||||
flattenFolders: true
|
||||
condition: succeeded()
|
||||
|
||||
- task: PublishBuildArtifacts@1
|
||||
displayName: 'Publish All Build Artifacts'
|
||||
inputs:
|
||||
PathtoPublish: '$(Build.ArtifactStagingDirectory)'
|
||||
ArtifactName: 'fuzzingBuildOutput'
|
||||
@@ -1,55 +0,0 @@
|
||||
parameters:
|
||||
configuration: 'Release'
|
||||
platform: ''
|
||||
additionalBuildArguments: ''
|
||||
minimumExpectedTestsExecutedCount: 1 # Sanity check for minimum expected tests to be reported
|
||||
rerunPassesRequiredToAvoidFailure: 5
|
||||
|
||||
jobs:
|
||||
- job: Build${{ parameters.platform }}${{ parameters.configuration }}
|
||||
displayName: Build ${{ parameters.platform }} ${{ parameters.configuration }}
|
||||
variables:
|
||||
BuildConfiguration: ${{ parameters.configuration }}
|
||||
BuildPlatform: ${{ parameters.platform }}
|
||||
PGOBuildMode: 'Instrument'
|
||||
pool:
|
||||
${{ if eq(variables['System.CollectionUri'], 'https://dev.azure.com/ms/') }}:
|
||||
name: WinDevPoolOSS-L
|
||||
${{ if ne(variables['System.CollectionUri'], 'https://dev.azure.com/ms/') }}:
|
||||
name: WinDevPool-L
|
||||
demands: ImageOverride -equals WinDevVS17-latest
|
||||
|
||||
steps:
|
||||
- template: build-console-steps.yml
|
||||
parameters:
|
||||
additionalBuildArguments: '${{ parameters.additionalBuildArguments }}'
|
||||
|
||||
- template: helix-runtests-job.yml
|
||||
parameters:
|
||||
name: 'RunTestsInHelix'
|
||||
dependsOn: Build${{ parameters.platform }}${{ parameters.configuration }}
|
||||
condition: succeeded()
|
||||
testSuite: 'PgoInstrumentationSuite'
|
||||
taefQuery: '@IsPgo=true'
|
||||
configuration: ${{ parameters.configuration }}
|
||||
platform: ${{ parameters.platform }}
|
||||
rerunPassesRequiredToAvoidFailure: ${{ parameters.rerunPassesRequiredToAvoidFailure }}
|
||||
|
||||
- template: helix-processtestresults-job.yml
|
||||
parameters:
|
||||
name: 'ProcessTestResults'
|
||||
pgoArtifact: 'PGO'
|
||||
dependsOn:
|
||||
- RunTestsInHelix
|
||||
condition: succeededOrFailed()
|
||||
rerunPassesRequiredToAvoidFailure: ${{ parameters.rerunPassesRequiredToAvoidFailure }}
|
||||
minimumExpectedTestsExecutedCount: ${{ parameters.minimumExpectedTestsExecutedCount }}
|
||||
|
||||
- template: pgo-merge-pgd-job.yml
|
||||
parameters:
|
||||
name: 'MergePGD'
|
||||
dependsOn:
|
||||
- ProcessTestResults
|
||||
pgoArtifact: 'PGO'
|
||||
platform: ${{ parameters.platform }}
|
||||
configuration: ${{ parameters.configuration }}
|
||||
@@ -1,137 +0,0 @@
|
||||
parameters:
|
||||
additionalBuildArguments: ''
|
||||
|
||||
steps:
|
||||
- checkout: self
|
||||
submodules: true
|
||||
clean: true
|
||||
fetchDepth: 1
|
||||
|
||||
- template: restore-nuget-steps.yml
|
||||
|
||||
# The environment variable VCToolsInstallDir isn't defined on lab machines, so we need to retrieve it ourselves.
|
||||
- script: |
|
||||
"%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe" -Latest -requires Microsoft.Component.MSBuild -property InstallationPath > %TEMP%\vsinstalldir.txt
|
||||
set /p _VSINSTALLDIR15=<%TEMP%\vsinstalldir.txt
|
||||
del %TEMP%\vsinstalldir.txt
|
||||
call "%_VSINSTALLDIR15%\Common7\Tools\VsDevCmd.bat"
|
||||
echo VCToolsInstallDir = %VCToolsInstallDir%
|
||||
echo ##vso[task.setvariable variable=VCToolsInstallDir]%VCToolsInstallDir%
|
||||
displayName: 'Retrieve VC tools directory'
|
||||
|
||||
- task: CmdLine@1
|
||||
displayName: 'Display build machine environment variables'
|
||||
inputs:
|
||||
filename: 'set'
|
||||
|
||||
- task: VSBuild@1
|
||||
displayName: 'Build solution **\OpenConsole.sln'
|
||||
inputs:
|
||||
solution: '**\OpenConsole.sln'
|
||||
platform: '$(BuildPlatform)'
|
||||
configuration: '$(BuildConfiguration)'
|
||||
msbuildArgs: "${{ parameters.additionalBuildArguments }} /p:PGOBuildMode=$(PGOBuildMode) /bl:$(Build.SourcesDirectory)\\msbuild.binlog"
|
||||
clean: true
|
||||
maximumCpuCount: true
|
||||
|
||||
- task: PowerShell@2
|
||||
displayName: 'Check MSIX for common regressions'
|
||||
# PGO runtime needs its own CRT and it's in the package for convenience.
|
||||
# That will make this script mad so skip since we're not shipping the PGO Instrumentation one anyway.
|
||||
condition: ne(variables['PGOBuildMode'], 'Instrument')
|
||||
inputs:
|
||||
targetType: inline
|
||||
script: |
|
||||
$Package = Get-ChildItem -Recurse -Filter "CascadiaPackage_*.msix"
|
||||
.\build\scripts\Test-WindowsTerminalPackage.ps1 -Verbose -Path $Package.FullName
|
||||
|
||||
- task: powershell@2
|
||||
displayName: 'Source Index PDBs'
|
||||
condition: ne(variables['PGOBuildMode'], 'Instrument')
|
||||
inputs:
|
||||
targetType: filePath
|
||||
filePath: build\scripts\Index-Pdbs.ps1
|
||||
arguments: -SearchDir '$(Build.SourcesDirectory)' -SourceRoot '$(Build.SourcesDirectory)' -recursive -Verbose -CommitId $(Build.SourceVersion)
|
||||
errorActionPreference: silentlyContinue
|
||||
|
||||
- task: PowerShell@2
|
||||
displayName: 'Rationalize build platform'
|
||||
inputs:
|
||||
targetType: inline
|
||||
script: |
|
||||
$Arch = "$(BuildPlatform)"
|
||||
If ($Arch -Eq "x86") { $Arch = "Win32" }
|
||||
Write-Host "##vso[task.setvariable variable=RationalizedBuildPlatform]${Arch}"
|
||||
|
||||
- task: CopyFiles@2
|
||||
displayName: 'Copy *.msix to Artifacts'
|
||||
inputs:
|
||||
Contents: |
|
||||
**/*.msix
|
||||
**/*.appxsym
|
||||
TargetFolder: '$(Build.ArtifactStagingDirectory)/appx'
|
||||
OverWrite: true
|
||||
flattenFolders: true
|
||||
|
||||
- pwsh: |-
|
||||
$TerminalMsixPath = (Get-Item "$(Build.ArtifactStagingDirectory)\appx\Cascadia*.msix").FullName
|
||||
$XamlAppxPath = (Get-Item "src\cascadia\CascadiaPackage\AppPackages\*\Dependencies\$(BuildPlatform)\Microsoft.UI.Xaml*.appx").FullName
|
||||
& .\build\scripts\New-UnpackagedTerminalDistribution.ps1 -TerminalAppX $TerminalMsixPath -XamlAppX $XamlAppxPath -Destination "$(Build.ArtifactStagingDirectory)/unpackaged"
|
||||
displayName: Build Unpackaged Distribution
|
||||
|
||||
- publish: $(Build.ArtifactStagingDirectory)/unpackaged
|
||||
artifact: unpackaged-$(BuildPlatform)-$(BuildConfiguration)
|
||||
displayName: Publish Artifact (unpackaged)
|
||||
|
||||
- task: CopyFiles@2
|
||||
displayName: 'Copy outputs needed for test runs to Artifacts'
|
||||
inputs:
|
||||
Contents: |
|
||||
$(Build.SourcesDirectory)/bin/$(RationalizedBuildPlatform)/$(BuildConfiguration)/*.exe
|
||||
$(Build.SourcesDirectory)/bin/$(RationalizedBuildPlatform)/$(BuildConfiguration)/*.dll
|
||||
$(Build.SourcesDirectory)/bin/$(RationalizedBuildPlatform)/$(BuildConfiguration)/*.xml
|
||||
**/Microsoft.VCLibs.*.appx
|
||||
**/*unit.test*.dll
|
||||
**/*unit.test*.manifest
|
||||
**/TestHostApp/*.exe
|
||||
**/TestHostApp/*.dll
|
||||
**/TestHostApp/*.xml
|
||||
!**/*.pdb
|
||||
!**/*.ipdb
|
||||
!**/*.obj
|
||||
!**/*.pch
|
||||
TargetFolder: '$(Build.ArtifactStagingDirectory)/$(BuildConfiguration)/$(BuildPlatform)/test'
|
||||
OverWrite: true
|
||||
flattenFolders: true
|
||||
condition: succeeded()
|
||||
|
||||
- task: PublishBuildArtifacts@1
|
||||
displayName: 'Publish All Build Artifacts'
|
||||
inputs:
|
||||
PathtoPublish: '$(Build.ArtifactStagingDirectory)'
|
||||
ArtifactName: 'drop'
|
||||
|
||||
- task: CopyFiles@2
|
||||
displayName: 'Copy PGO databases needed for PGO instrumentation run'
|
||||
inputs:
|
||||
Contents: |
|
||||
**/*.pgd
|
||||
TargetFolder: '$(Build.ArtifactStagingDirectory)/$(BuildConfiguration)/PGO/$(BuildPlatform)'
|
||||
OverWrite: true
|
||||
flattenFolders: true
|
||||
condition: and(succeeded(), eq(variables['PGOBuildMode'], 'Instrument'))
|
||||
|
||||
- task: PublishBuildArtifacts@1
|
||||
displayName: 'Publish All PGO Artifacts'
|
||||
inputs:
|
||||
PathtoPublish: '$(Build.ArtifactStagingDirectory)/$(BuildConfiguration)/PGO'
|
||||
ArtifactName: 'PGO'
|
||||
condition: and(succeeded(), eq(variables['PGOBuildMode'], 'Instrument'))
|
||||
|
||||
- task: PublishBuildArtifacts@1
|
||||
displayName: 'Publish Artifact: binlog'
|
||||
condition: always()
|
||||
continueOnError: True
|
||||
inputs:
|
||||
PathtoPublish: $(Build.SourcesDirectory)\msbuild.binlog
|
||||
ArtifactName: binlog-$(BuildPlatform)
|
||||
@@ -1,17 +0,0 @@
|
||||
|
||||
jobs:
|
||||
- job: CodeFormatCheck
|
||||
displayName: Proper Code Formatting Check
|
||||
pool: { vmImage: windows-2022 }
|
||||
|
||||
steps:
|
||||
- checkout: self
|
||||
fetchDepth: 1
|
||||
submodules: false
|
||||
clean: true
|
||||
|
||||
- task: PowerShell@2
|
||||
displayName: 'Code Formatting Check'
|
||||
inputs:
|
||||
targetType: filePath
|
||||
filePath: '.\build\scripts\Invoke-FormattingCheck.ps1'
|
||||
@@ -1,25 +0,0 @@
|
||||
parameters:
|
||||
configuration: 'Release'
|
||||
platform: ''
|
||||
minimumExpectedTestsExecutedCount: 10 # Sanity check for minimum expected tests to be reported
|
||||
rerunPassesRequiredToAvoidFailure: 5
|
||||
|
||||
jobs:
|
||||
- template: helix-runtests-job.yml
|
||||
parameters:
|
||||
name: 'RunTestsInHelix'
|
||||
# We're not setting dependsOn as we want to rely on the "stage" dependency above us
|
||||
testSuite: 'DevTestSuite'
|
||||
platform: ${{ parameters.platform }}
|
||||
configuration: ${{ parameters.configuration }}
|
||||
rerunPassesRequiredToAvoidFailure: ${{ parameters.rerunPassesRequiredToAvoidFailure }}
|
||||
|
||||
- template: helix-processtestresults-job.yml
|
||||
parameters:
|
||||
dependsOn:
|
||||
- RunTestsInHelix
|
||||
# the default condition is succeededOrFailed(), and the "stage" condition ensures we only run as needed
|
||||
platform: ${{ parameters.platform }}
|
||||
configuration: ${{ parameters.configuration }}
|
||||
rerunPassesRequiredToAvoidFailure: ${{ parameters.rerunPassesRequiredToAvoidFailure }}
|
||||
minimumExpectedTestsExecutedCount: ${{ parameters.minimumExpectedTestsExecutedCount }}
|
||||
@@ -1,15 +0,0 @@
|
||||
parameters:
|
||||
condition: ''
|
||||
testFilePath: ''
|
||||
outputProjFileName: ''
|
||||
testSuite: ''
|
||||
taefQuery: ''
|
||||
|
||||
steps:
|
||||
- task: powershell@2
|
||||
displayName: 'Create ${{ parameters.outputProjFileName }}'
|
||||
condition: ${{ parameters.condition }}
|
||||
inputs:
|
||||
targetType: filePath
|
||||
filePath: build\Helix\GenerateTestProjFile.ps1
|
||||
arguments: -TestFile '${{ parameters.testFilePath }}' -OutputProjFile '$(Build.ArtifactStagingDirectory)\$(BuildConfiguration)\$(BuildPlatform)\${{ parameters.outputProjFileName }}' -JobTestSuiteName '${{ parameters.testSuite }}' -TaefPath '$(Build.SourcesDirectory)\build\Helix\packages\Microsoft.Taef.10.60.210621002\build\Binaries\x86' -TaefQuery '${{ parameters.taefQuery }}'
|
||||
@@ -1,71 +0,0 @@
|
||||
parameters:
|
||||
condition: 'succeededOrFailed()'
|
||||
dependsOn: ''
|
||||
rerunPassesRequiredToAvoidFailure: 5
|
||||
minimumExpectedTestsExecutedCount: 10
|
||||
checkJobAttempt: false
|
||||
pgoArtifact: ''
|
||||
|
||||
jobs:
|
||||
- job: ProcessTestResults
|
||||
displayName: Process Helix Results ${{ parameters.platform }} ${{ parameters.configuration }}
|
||||
condition: ${{ parameters.condition }}
|
||||
dependsOn: ${{ parameters.dependsOn }}
|
||||
pool:
|
||||
vmImage: 'windows-2019'
|
||||
timeoutInMinutes: 120
|
||||
variables:
|
||||
helixOutputFolder: $(Build.SourcesDirectory)\HelixOutput
|
||||
|
||||
steps:
|
||||
- task: powershell@2
|
||||
displayName: 'UpdateUnreliableTests.ps1'
|
||||
condition: succeededOrFailed()
|
||||
env:
|
||||
SYSTEM_ACCESSTOKEN: $(System.AccessToken)
|
||||
HelixAccessToken: $(HelixApiAccessToken)
|
||||
inputs:
|
||||
targetType: filePath
|
||||
filePath: build\Helix\UpdateUnreliableTests.ps1
|
||||
arguments: -RerunPassesRequiredToAvoidFailure '${{ parameters.rerunPassesRequiredToAvoidFailure }}'
|
||||
|
||||
- task: powershell@2
|
||||
displayName: 'OutputTestResults.ps1'
|
||||
condition: succeededOrFailed()
|
||||
env:
|
||||
SYSTEM_ACCESSTOKEN: $(System.AccessToken)
|
||||
HelixAccessToken: $(HelixApiAccessToken)
|
||||
inputs:
|
||||
targetType: filePath
|
||||
filePath: build\Helix\OutputTestResults.ps1
|
||||
arguments: -MinimumExpectedTestsExecutedCount '${{ parameters.minimumExpectedTestsExecutedCount }}' -CheckJobAttempt $${{ parameters.checkJobAttempt }}
|
||||
|
||||
- task: powershell@2
|
||||
displayName: 'ProcessHelixFiles.ps1'
|
||||
condition: succeededOrFailed()
|
||||
env:
|
||||
SYSTEM_ACCESSTOKEN: $(System.AccessToken)
|
||||
HelixAccessToken: $(HelixApiAccessToken)
|
||||
inputs:
|
||||
targetType: filePath
|
||||
filePath: build\Helix\ProcessHelixFiles.ps1
|
||||
arguments: -OutputFolder '$(helixOutputFolder)'
|
||||
|
||||
- ${{if ne(parameters.pgoArtifact, '') }}:
|
||||
- script: move /y $(helixOutputFolder)\PGO $(Build.ArtifactStagingDirectory)
|
||||
displayName: 'Move pgc files to PGO artifact'
|
||||
|
||||
- task: PublishBuildArtifacts@1
|
||||
displayName: 'Publish Helix files'
|
||||
condition: succeededOrFailed()
|
||||
inputs:
|
||||
PathtoPublish: $(helixOutputFolder)
|
||||
artifactName: drop
|
||||
|
||||
- ${{if ne(parameters.pgoArtifact, '') }}:
|
||||
- task: PublishBuildArtifacts@1
|
||||
displayName: 'Publish pgc files'
|
||||
condition: succeededOrFailed()
|
||||
inputs:
|
||||
PathtoPublish: $(Build.ArtifactStagingDirectory)\PGO\Release
|
||||
artifactName: ${{ parameters.pgoArtifact }}
|
||||
@@ -1,164 +0,0 @@
|
||||
parameters:
|
||||
name: 'RunTestsInHelix'
|
||||
dependsOn: ''
|
||||
condition: ''
|
||||
testSuite: ''
|
||||
# If a Pipeline runs this template more than once, this parameter should be unique per build flavor to differentiate the
|
||||
# the different test runs:
|
||||
helixType: 'test/devtest'
|
||||
artifactName: 'drop'
|
||||
maxParallel: 4
|
||||
rerunPassesRequiredToAvoidFailure: 5
|
||||
taefQuery: ''
|
||||
configuration: ''
|
||||
platform: ''
|
||||
# if 'useBuildOutputFromBuildId' is set, we will default to using a build from this pipeline:
|
||||
useBuildOutputFromPipeline: $(System.DefinitionId)
|
||||
openHelixTargetQueues: 'windows.11.amd64.client.open.reunion'
|
||||
closedHelixTargetQueues: 'windows.11.amd64.client.reunion'
|
||||
|
||||
jobs:
|
||||
- job: ${{ parameters.name }}
|
||||
displayName: Submit Helix ${{ parameters.platform }} ${{ parameters.configuration }}
|
||||
dependsOn: ${{ parameters.dependsOn }}
|
||||
condition: ${{ parameters.condition }}
|
||||
pool:
|
||||
vmImage: 'windows-2019'
|
||||
timeoutInMinutes: 120
|
||||
strategy:
|
||||
maxParallel: ${{ parameters.maxParallel }}
|
||||
variables:
|
||||
buildConfiguration: ${{ parameters.configuration }}
|
||||
buildPlatform: ${{ parameters.platform }}
|
||||
openHelixTargetQueues: ${{ parameters.openHelixTargetQueues }}
|
||||
closedHelixTargetQueues: ${{ parameters.closedHelixTargetQueues }}
|
||||
artifactsDir: $(Build.SourcesDirectory)\Artifacts
|
||||
taefPath: $(Build.SourcesDirectory)\build\Helix\packages\Microsoft.Taef.10.60.210621002\build\Binaries\$(buildPlatform)
|
||||
helixCommonArgs: '/binaryLogger:$(Build.SourcesDirectory)/${{parameters.name}}.$(buildPlatform).$(buildConfiguration).binlog /p:HelixBuild=$(Build.BuildId).$(buildPlatform).$(buildConfiguration) /p:Platform=$(buildPlatform) /p:Configuration=$(buildConfiguration) /p:HelixType=${{parameters.helixType}} /p:TestSuite=${{parameters.testSuite}} /p:ProjFilesPath=$(Build.ArtifactStagingDirectory) /p:rerunPassesRequiredToAvoidFailure=${{parameters.rerunPassesRequiredToAvoidFailure}}'
|
||||
|
||||
steps:
|
||||
- task: CmdLine@1
|
||||
displayName: 'Display build machine environment variables'
|
||||
inputs:
|
||||
filename: 'set'
|
||||
|
||||
- task: NuGetToolInstaller@0
|
||||
displayName: 'Use NuGet 6.3.0'
|
||||
inputs:
|
||||
versionSpec: 6.3.0
|
||||
|
||||
- task: 333b11bd-d341-40d9-afcf-b32d5ce6f23b@2
|
||||
displayName: 'NuGet restore build/Helix/packages.config'
|
||||
inputs:
|
||||
restoreSolution: build/Helix/packages.config
|
||||
feedsToUse: config
|
||||
nugetConfigPath: nuget.config
|
||||
restoreDirectory: packages
|
||||
|
||||
- task: DownloadBuildArtifacts@0
|
||||
condition:
|
||||
and(succeeded(),eq(variables['useBuildOutputFromBuildId'],''))
|
||||
inputs:
|
||||
artifactName: ${{ parameters.artifactName }}
|
||||
downloadPath: '$(artifactsDir)'
|
||||
|
||||
- task: DownloadBuildArtifacts@0
|
||||
condition:
|
||||
and(succeeded(),ne(variables['useBuildOutputFromBuildId'],''))
|
||||
inputs:
|
||||
buildType: specific
|
||||
buildVersionToDownload: specific
|
||||
project: $(System.TeamProjectId)
|
||||
pipeline: ${{ parameters.useBuildOutputFromPipeline }}
|
||||
buildId: $(useBuildOutputFromBuildId)
|
||||
artifactName: ${{ parameters.artifactName }}
|
||||
downloadPath: '$(artifactsDir)'
|
||||
|
||||
- task: CmdLine@1
|
||||
displayName: 'Display Artifact Directory payload contents'
|
||||
inputs:
|
||||
filename: 'dir'
|
||||
arguments: '/s $(artifactsDir)'
|
||||
|
||||
- task: powershell@2
|
||||
displayName: 'PrepareHelixPayload.ps1'
|
||||
inputs:
|
||||
targetType: filePath
|
||||
filePath: build\Helix\PrepareHelixPayload.ps1
|
||||
arguments: -Platform '$(buildPlatform)' -Configuration '$(buildConfiguration)' -ArtifactName '${{ parameters.artifactName }}'
|
||||
|
||||
- task: CmdLine@1
|
||||
displayName: 'Display Helix payload contents'
|
||||
inputs:
|
||||
filename: 'dir'
|
||||
arguments: '/s $(Build.SourcesDirectory)\HelixPayload'
|
||||
|
||||
- task: PowerShell@2
|
||||
displayName: 'Make artifact directories'
|
||||
inputs:
|
||||
targetType: inline
|
||||
script: |
|
||||
New-Item -ItemType Directory -Force -Path "$(Build.ArtifactStagingDirectory)\$(BuildConfiguration)\"
|
||||
New-Item -ItemType Directory -Force -Path "$(Build.ArtifactStagingDirectory)\$(BuildConfiguration)\$(BuildPlatform)\"
|
||||
|
||||
- template: helix-createprojfile-steps.yml
|
||||
parameters:
|
||||
condition: and(succeeded(),eq('${{ parameters.testSuite }}','DevTestSuite'))
|
||||
testFilePath: '$(artifactsDir)\${{ parameters.artifactName }}\$(buildConfiguration)\$(buildPlatform)\Test\TerminalApp.LocalTests.dll'
|
||||
outputProjFileName: 'RunTestsInHelix-TerminalAppLocalTests.proj'
|
||||
testSuite: '${{ parameters.testSuite }}'
|
||||
taefQuery: ${{ parameters.taefQuery }}
|
||||
|
||||
- template: helix-createprojfile-steps.yml
|
||||
parameters:
|
||||
condition: and(succeeded(),eq('${{ parameters.testSuite }}','DevTestSuite'))
|
||||
testFilePath: '$(artifactsDir)\${{ parameters.artifactName }}\$(buildConfiguration)\$(buildPlatform)\Test\SettingsModel.LocalTests.dll'
|
||||
outputProjFileName: 'RunTestsInHelix-SettingsModelLocalTests.proj'
|
||||
testSuite: '${{ parameters.testSuite }}'
|
||||
taefQuery: ${{ parameters.taefQuery }}
|
||||
|
||||
|
||||
- template: helix-createprojfile-steps.yml
|
||||
parameters:
|
||||
condition: and(succeeded(),eq('${{ parameters.testSuite }}','DevTestSuite'))
|
||||
testFilePath: '$(artifactsDir)\${{ parameters.artifactName }}\$(buildConfiguration)\$(buildPlatform)\Test\Conhost.UIA.Tests.dll'
|
||||
outputProjFileName: 'RunTestsInHelix-HostTestsUIA.proj'
|
||||
testSuite: '${{ parameters.testSuite }}'
|
||||
taefQuery: ${{ parameters.taefQuery }}
|
||||
|
||||
- template: helix-createprojfile-steps.yml
|
||||
parameters:
|
||||
condition: and(succeeded(),or(eq('${{ parameters.testSuite }}','PgoInstrumentationSuite'),eq('${{ parameters.testSuite }}','DevTestSuite')))
|
||||
testFilePath: '$(artifactsDir)\${{ parameters.artifactName }}\$(buildConfiguration)\$(buildPlatform)\Test\WindowsTerminal.UIA.Tests.dll'
|
||||
outputProjFileName: 'RunTestsInHelix-WindowsTerminalUIATests.proj'
|
||||
testSuite: '${{ parameters.testSuite }}'
|
||||
taefQuery: ${{ parameters.taefQuery }}
|
||||
|
||||
- task: PublishBuildArtifacts@1
|
||||
displayName: 'Publish generated .proj files'
|
||||
inputs:
|
||||
PathtoPublish: $(Build.ArtifactStagingDirectory)
|
||||
artifactName: ${{ parameters.artifactName }}
|
||||
|
||||
- task: DotNetCoreCLI@2
|
||||
displayName: 'Run tests in Helix (open queues)'
|
||||
condition: and(succeeded(),eq(variables['System.CollectionUri'],'https://dev.azure.com/ms/'))
|
||||
env:
|
||||
SYSTEM_ACCESSTOKEN: $(System.AccessToken)
|
||||
inputs:
|
||||
command: custom
|
||||
projects: build\Helix\RunTestsInHelix.proj
|
||||
custom: msbuild
|
||||
arguments: '$(helixCommonArgs) /p:IsExternal=true /p:Creator=Terminal /p:HelixTargetQueues=$(openHelixTargetQueues)'
|
||||
|
||||
- task: DotNetCoreCLI@2
|
||||
displayName: 'Run tests in Helix (closed queues)'
|
||||
condition: and(succeeded(),ne(variables['System.CollectionUri'],'https://dev.azure.com/ms/'))
|
||||
env:
|
||||
SYSTEM_ACCESSTOKEN: $(System.AccessToken)
|
||||
HelixAccessToken: $(HelixApiAccessToken)
|
||||
inputs:
|
||||
command: custom
|
||||
projects: build\Helix\RunTestsInHelix.proj
|
||||
custom: msbuild
|
||||
arguments: '$(helixCommonArgs) /p:HelixTargetQueues=$(closedHelixTargetQueues)'
|
||||
@@ -1,70 +0,0 @@
|
||||
parameters:
|
||||
dependsOn: ''
|
||||
pgoArtifact: PGO
|
||||
platform: ''
|
||||
configuration: ''
|
||||
|
||||
jobs:
|
||||
- job: MergePGD
|
||||
dependsOn: ${{ parameters.dependsOn }}
|
||||
pool:
|
||||
vmImage: 'windows-2019'
|
||||
variables:
|
||||
artifactsPath: $(Build.SourcesDirectory)\Artifacts
|
||||
pgoArtifactsPath: $(artifactsPath)\${{ parameters.pgoArtifact }}
|
||||
buildPlatform: ${{ parameters.platform }}
|
||||
buildConfiguration: ${{ parameters.configuration }}
|
||||
|
||||
steps:
|
||||
# The environment variable VCToolsInstallDir isn't defined on lab machines, so we need to retrieve it ourselves.
|
||||
- script: |
|
||||
"%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe" -Latest -requires Microsoft.Component.MSBuild -property InstallationPath > %TEMP%\vsinstalldir.txt
|
||||
set /p _VSINSTALLDIR15=<%TEMP%\vsinstalldir.txt
|
||||
del %TEMP%\vsinstalldir.txt
|
||||
call "%_VSINSTALLDIR15%\Common7\Tools\VsDevCmd.bat"
|
||||
echo VCToolsInstallDir = %VCToolsInstallDir%
|
||||
echo ##vso[task.setvariable variable=VCToolsInstallDir]%VCToolsInstallDir%
|
||||
displayName: 'Retrieve VC tools directory'
|
||||
|
||||
- task: NuGetToolInstaller@0
|
||||
displayName: 'Use NuGet 6.3.0'
|
||||
inputs:
|
||||
versionSpec: 6.3.0
|
||||
|
||||
- task: NuGetAuthenticate@0
|
||||
|
||||
# In the Microsoft Azure DevOps tenant, NuGetCommand is ambiguous.
|
||||
# This should be `task: NuGetCommand@2`
|
||||
- task: 333b11bd-d341-40d9-afcf-b32d5ce6f23b@2
|
||||
displayName: Restore NuGet packages for extraneous build actions
|
||||
inputs:
|
||||
command: restore
|
||||
feedsToUse: config
|
||||
configPath: NuGet.config
|
||||
restoreSolution: build/packages.config
|
||||
restoreDirectory: '$(Build.SourcesDirectory)\packages'
|
||||
|
||||
- task: DownloadBuildArtifacts@0
|
||||
inputs:
|
||||
artifactName: ${{ parameters.pgoArtifact }}
|
||||
downloadPath: $(artifactsPath)
|
||||
|
||||
- task: MSBuild@1
|
||||
displayName: Merge counts into PGD
|
||||
inputs:
|
||||
solution: $(Build.SourcesDirectory)\OpenConsole.sln
|
||||
platform: $(buildPlatform)
|
||||
configuration: $(buildConfiguration)
|
||||
msbuildArguments: '/t:MergePGOCounts /p:PGOBuildMode=Instrument /p:PGDPath=$(pgoArtifactsPath)\$(buildPlatform) /p:PGCRootPath=$(pgoArtifactsPath)\$(buildPlatform)'
|
||||
|
||||
- task: CopyFiles@2
|
||||
displayName: 'Copy merged pgd to artifact staging'
|
||||
inputs:
|
||||
sourceFolder: $(pgoArtifactsPath)
|
||||
contents: '**\$(buildPlatform)\*.pgd'
|
||||
targetFolder: $(Build.ArtifactStagingDirectory)
|
||||
|
||||
- task: PublishBuildArtifacts@1
|
||||
inputs:
|
||||
pathToPublish: $(Build.ArtifactStagingDirectory)
|
||||
artifactName: ${{ parameters.pgoArtifact }}
|
||||
@@ -1,6 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<_WTBrandingPreprocessorToken Condition="'$(WindowsTerminalBranding)'=='Canary'">WT_BRANDING_CANARY</_WTBrandingPreprocessorToken>
|
||||
<_WTBrandingPreprocessorToken Condition="'$(WindowsTerminalBranding)'=='Preview'">WT_BRANDING_PREVIEW</_WTBrandingPreprocessorToken>
|
||||
<_WTBrandingPreprocessorToken Condition="'$(WindowsTerminalBranding)'=='Release'">WT_BRANDING_RELEASE</_WTBrandingPreprocessorToken>
|
||||
<_WTBrandingPreprocessorToken Condition="'$(_WTBrandingPreprocessorToken)'==''">WT_BRANDING_DEV</_WTBrandingPreprocessorToken>
|
||||
|
||||
42
build/scripts/New-AppInstallerFromTemplateAndBundle.ps1
Normal file
42
build/scripts/New-AppInstallerFromTemplateAndBundle.ps1
Normal file
@@ -0,0 +1,42 @@
|
||||
[CmdletBinding()]
|
||||
Param(
|
||||
[Parameter(Mandatory,
|
||||
HelpMessage="Path to the .msixbundle")]
|
||||
[string]
|
||||
$BundlePath,
|
||||
|
||||
[Parameter(Mandatory,
|
||||
HelpMessage="Path to the .appinstaller template")]
|
||||
[string]
|
||||
$AppInstallerTemplatePath,
|
||||
|
||||
[string]
|
||||
$AppInstallerRoot,
|
||||
|
||||
[Parameter(Mandatory,
|
||||
HelpMessage="Output Path")]
|
||||
[string]
|
||||
$OutputPath
|
||||
)
|
||||
|
||||
$ErrorActionPreference = "Stop"
|
||||
|
||||
$sentinelFile = New-TemporaryFile
|
||||
$directory = New-Item -Type Directory "$($sentinelFile.FullName)_Package"
|
||||
Remove-Item $sentinelFile -Force -EA:Ignore
|
||||
|
||||
$bundle = (Get-Item $BundlePath)
|
||||
& tar.exe -x -f $bundle.FullName -C $directory AppxMetadata/AppxBundleManifest.xml
|
||||
|
||||
$xml = [xml](Get-Content (Join-Path $directory "AppxMetadata\AppxBundleManifest.xml"))
|
||||
$name = $xml.Bundle.Identity.Name
|
||||
$version = $xml.Bundle.Identity.Version
|
||||
|
||||
$doc = (Get-Content -ReadCount 0 $AppInstallerTemplatePath)
|
||||
$doc = $doc -Replace '\$\$ROOT\$\$',$AppInstallerRoot
|
||||
$doc = $doc -Replace '\$\$NAME\$\$',$name
|
||||
$doc = $doc -Replace '\$\$VERSION\$\$',$version
|
||||
$doc = $doc -Replace '\$\$PACKAGE\$\$',$bundle.Name
|
||||
$doc | Out-File -Encoding utf8NoBOM $OutputPath
|
||||
|
||||
Get-Item $OutputPath
|
||||
@@ -25,7 +25,12 @@ Param(
|
||||
[Parameter(HelpMessage="Path to makeappx.exe", ParameterSetName='Layout')]
|
||||
[ValidateScript({Test-Path $_ -Type Leaf})]
|
||||
[string]
|
||||
$MakeAppxPath = "C:\Program Files (x86)\Windows Kits\10\bin\10.0.22621.0\x64\MakeAppx.exe"
|
||||
$MakeAppxPath = "C:\Program Files (x86)\Windows Kits\10\bin\10.0.22621.0\x64\MakeAppx.exe",
|
||||
|
||||
[Parameter(HelpMessage="Include the portable mode marker file by default", ParameterSetName='AppX')]
|
||||
[Parameter(HelpMessage="Include the portable mode marker file by default", ParameterSetName='Layout')]
|
||||
[switch]
|
||||
$PortableMode = $PSCmdlet.ParameterSetName -eq 'Layout'
|
||||
)
|
||||
|
||||
$filesToRemove = @("*.xml", "*.winmd", "Appx*", "Images/*Tile*", "Images/*Logo*") # Remove from Terminal
|
||||
@@ -128,6 +133,11 @@ $finalTerminalPriFile = Join-Path $terminalAppPath "resources.pri"
|
||||
# Packaging
|
||||
########
|
||||
|
||||
$portableModeMarkerFile = Join-Path $terminalAppPath ".portable"
|
||||
If ($PortableMode) {
|
||||
"" | Out-File $portableModeMarkerFile
|
||||
}
|
||||
|
||||
If ($PSCmdlet.ParameterSetName -Eq "AppX") {
|
||||
# We only produce a ZIP when we're combining two AppX directories.
|
||||
New-Item -ItemType Directory -Path $Destination -ErrorAction:SilentlyContinue | Out-Null
|
||||
|
||||
@@ -9,7 +9,8 @@ Param(
|
||||
[Parameter(Mandatory=$false, Position=3)]
|
||||
[string]$LogPath,
|
||||
[Parameter(Mandatory=$false)]
|
||||
[string]$Root = ".\bin\$Platform\$Configuration"
|
||||
[string]$Root = ".\bin\$Platform\$Configuration",
|
||||
[string[]]$AdditionalTaefArguments
|
||||
)
|
||||
|
||||
# Find test DLLs based on the provided root, match pattern, and recursion
|
||||
@@ -26,7 +27,7 @@ if ($LogPath) {
|
||||
}
|
||||
|
||||
# Invoke the te.exe executable with arguments and test DLLs
|
||||
& "$Root\te.exe" $args $testDlls.FullName
|
||||
& "$Root\te.exe" $args $testDlls.FullName $AdditionalTaefArguments
|
||||
|
||||
# Check the exit code of the te.exe process and exit accordingly
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<XesUseOneStoreVersioning>true</XesUseOneStoreVersioning>
|
||||
<XesBaseYearForStoreVersion>2023</XesBaseYearForStoreVersion>
|
||||
<VersionMajor>1</VersionMajor>
|
||||
<VersionMinor>19</VersionMinor>
|
||||
<VersionMinor>20</VersionMinor>
|
||||
<VersionInfoProductName>Windows Terminal</VersionInfoProductName>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
<package id="Microsoft.VisualStudio.Setup.Configuration.Native" version="2.3.2262" targetFramework="native" developmentDependency="true" />
|
||||
<package id="Microsoft.UI.Xaml" version="2.8.4" targetFramework="native" />
|
||||
<package id="Microsoft.Web.WebView2" version="1.0.1661.34" targetFramework="native" />
|
||||
<package id="Microsoft.Windows.ImplementationLibrary" version="1.0.220201.1" targetFramework="native" developmentDependency="true" />
|
||||
<package id="Microsoft.Windows.ImplementationLibrary" version="1.0.230824.2" targetFramework="native" developmentDependency="true" />
|
||||
|
||||
<!-- Managed packages -->
|
||||
<package id="Appium.WebDriver" version="3.0.0.2" targetFramework="net45" />
|
||||
|
||||
90
doc/COOKED_READ_DATA.md
Normal file
90
doc/COOKED_READ_DATA.md
Normal file
@@ -0,0 +1,90 @@
|
||||
# COOKED_READ_DATA, aka conhost's readline implementation
|
||||
|
||||
## Test instructions
|
||||
|
||||
All of the following ✅ marks must be fulfilled during manual testing:
|
||||
* ASCII input
|
||||
* Chinese input (中文維基百科) ❔
|
||||
* Resizing the window properly wraps/unwraps wide glyphs ❌
|
||||
Broken due to `TextBuffer::Reflow` bugs
|
||||
* Surrogate pair input (🙂) ❔
|
||||
* Resizing the window properly wraps/unwraps surrogate pairs ❌
|
||||
Broken due to `TextBuffer::Reflow` bugs
|
||||
* In cmd.exe
|
||||
* Create 2 file: "a😊b.txt" and "a😟b.txt"
|
||||
* Press tab: Autocomplete to "a😊b.txt" ✅
|
||||
* Navigate the cursor right past the "a"
|
||||
* Press tab twice: Autocomplete to "a😟b.txt" ✅
|
||||
* Backspace deletes preceding glyphs ✅
|
||||
* Ctrl+Backspace deletes preceding words ✅
|
||||
* Escape clears input ✅
|
||||
* Home navigates to start ✅
|
||||
* Ctrl+Home deletes text between cursor and start ✅
|
||||
* End navigates to end ✅
|
||||
* Ctrl+End deletes text between cursor and end ✅
|
||||
* Left navigates over previous code points ✅
|
||||
* Ctrl+Left navigates to previous word-starts ✅
|
||||
* Right and F1 navigate over next code points ✅
|
||||
* Pressing right at the end of input copies characters
|
||||
from the previous command ✅
|
||||
* Ctrl+Right navigates to next word-ends ✅
|
||||
* Insert toggles overwrite mode ✅
|
||||
* Delete deletes next code point ✅
|
||||
* Up and F5 cycle through history ✅
|
||||
* Doesn't crash with no history ✅
|
||||
* Stops at first entry ✅
|
||||
* Down cycles through history ✅
|
||||
* Doesn't crash with no history ✅
|
||||
* Stops at last entry ✅
|
||||
* PageUp retrieves the oldest command ✅
|
||||
* PageDown retrieves the newest command ✅
|
||||
* F2 starts "copy to char" prompt ✅
|
||||
* Escape dismisses prompt ✅
|
||||
* Typing a character copies text from the previous command up
|
||||
until that character into the current buffer (acts identical
|
||||
to F3, but with automatic character search) ✅
|
||||
* F3 copies the previous command into the current buffer,
|
||||
starting at the current cursor position,
|
||||
for as many characters as possible ✅
|
||||
* Doesn't erase trailing text if the current buffer
|
||||
is longer than the previous command ✅
|
||||
* Puts the cursor at the end of the copied text ✅
|
||||
* F4 starts "copy from char" prompt ✅
|
||||
* Escape dismisses prompt ✅
|
||||
* Erases text between the current cursor position and the
|
||||
first instance of a given char (but not including it) ✅
|
||||
* F6 inserts Ctrl+Z ✅
|
||||
* F7 without modifiers starts "command list" prompt ✅
|
||||
* Escape dismisses prompt ✅
|
||||
* Minimum size of 40x10 characters ✅
|
||||
* Width expands to fit the widest history command ✅
|
||||
* Height expands up to 20 rows with longer histories ✅
|
||||
* F9 starts "command number" prompt ✅
|
||||
* Left/Right paste replace the buffer with the given command ✅
|
||||
* And put cursor at the end of the buffer ✅
|
||||
* Up/Down navigate selection through history ✅
|
||||
* Stops at start/end with <10 entries ✅
|
||||
* Stops at start/end with >20 entries ✅
|
||||
* Wide text rendering during pagination with >20 entries ✅
|
||||
* Shift+Up/Down moves history items around ✅
|
||||
* Home navigates to first entry ✅
|
||||
* End navigates to last entry ✅
|
||||
* PageUp navigates by 20 items at a time or to first ✅
|
||||
* PageDown navigates by 20 items at a time or to last ✅
|
||||
* Alt+F7 clears command history ✅
|
||||
* F8 cycles through commands that start with the same text as
|
||||
the current buffer up until the current cursor position ✅
|
||||
* Doesn't crash with no history ✅
|
||||
* F9 starts "command number" prompt ✅
|
||||
* Escape dismisses prompt ✅
|
||||
* Ignores non-ASCII-decimal characters ✅
|
||||
* Allows entering between 1 and 5 digits ✅
|
||||
* Pressing Enter fetches the given command from the history ✅
|
||||
* Alt+F10 clears doskey aliases ✅
|
||||
* In cmd.exe, with an empty prompt in an empty directory:
|
||||
Pressing tab produces an audible bing and prints no text ✅
|
||||
* When Narrator is enabled, in cmd.exe:
|
||||
* Typing individual characters announces only
|
||||
exactly each character that is being typed ✅
|
||||
* Backspacing at the end of a prompt announces
|
||||
only exactly each deleted character ✅
|
||||
@@ -27,6 +27,8 @@ I would highly recommend that Gulp convert to using PowerShell scripts and that
|
||||
|
||||
Original Source: https://github.com/microsoft/terminal/issues/217#issuecomment-404240443
|
||||
|
||||
_Addendum_: cmd.exe is the literal embodiment of [xkcd#1172]([url](https://xkcd.com/1172/)). Every change, no matter how small, will break _someone_.
|
||||
|
||||
## <a name="screenPerf"></a>Why is typing-to-screen performance better than every other app?
|
||||
|
||||
I really do not mind when someone comes by and decides to tell us that we're doing a good job at something. We hear so many complaints every day that a post like this is a breath of fresh air. Thanks for your thanks!
|
||||
|
||||
@@ -32,7 +32,6 @@
|
||||
* `/src/cascadia/TerminalApp` - This DLL represents the implementation of the Windows Terminal application. This includes parsing settings, hosting tabs & panes with Terminals in them, and displaying other UI elements. This DLL is almost entirely UWP-like code, and shouldn't be doing any Win32-like UI work.
|
||||
* `/src/cascadia/WindowsTerminal` - This EXE provides Win32 hosting for the TerminalApp. It will set up XAML islands, and is responsible for drawing the window, either as a standard window or with content in the titlebar (non-client area).
|
||||
* `/src/cascadia/CascadiaPackage` - This is a project for packaging the Windows Terminal and its dependencies into an .appx/.msix for deploying to the machine.
|
||||
* `/src/cascadia/PublicTerminalCore` - This is a DLL wrapper for the TerminalCore and Renderer, similar to `TermControl`, which exposes some exported functions that so the Terminal can be used from C#.
|
||||
* `/src/cascadia/WpfTerminalControl` - A DLL implementing a WPF version of the Terminal Control.
|
||||
* `/src/host` – The meat of the windows console host. This includes buffer, input, output, windowing, server management, clipboard, and most interactions with the console host window that aren’t stated anywhere else. We’re trying to pull things out that are reusable into other libraries, but it’s a work in progress
|
||||
* `/src/host/lib` – Builds the reusable LIB copy of the host
|
||||
|
||||
@@ -85,6 +85,41 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
"BuiltinSuggestionSource": {
|
||||
"type": "string",
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"enum": [
|
||||
"commandHistory",
|
||||
"tasks",
|
||||
"all"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"SuggestionSource": {
|
||||
"default": "all",
|
||||
"description": "Either a single suggestion source, or an array of sources to concatenate. Built-in sources include `commandHistory`, `directoryHistory`, and `tasks`. The special value `all` indicates all suggestion sources should be included",
|
||||
"$comment": "`tasks` and `local` are sources that would be added by the Tasks feature, as a follow-up",
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "null"
|
||||
},
|
||||
{
|
||||
"$ref": "#/$defs/BuiltinSuggestionSource"
|
||||
},
|
||||
{
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/$defs/BuiltinSuggestionSource"
|
||||
},
|
||||
"uniqueItems": true
|
||||
}
|
||||
]
|
||||
},
|
||||
"AppearanceConfig": {
|
||||
"properties": {
|
||||
"colorScheme": {
|
||||
@@ -175,10 +210,6 @@
|
||||
"desktopWallpaper"
|
||||
]
|
||||
}
|
||||
],
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"backgroundImageOpacity": {
|
||||
@@ -243,6 +274,17 @@
|
||||
"experimental.pixelShaderPath": {
|
||||
"description": "Use to set a path to a pixel shader to use with the Terminal when unfocused. Overrides `experimental.retroTerminalEffect`. This is an experimental feature, and its continued existence is not guaranteed.",
|
||||
"type": "string"
|
||||
},
|
||||
"useAcrylic": {
|
||||
"description": "When set to true, the window will have an acrylic material background when unfocused. When set to false, the window will have a plain, untextured background when unfocused.",
|
||||
"type": "boolean"
|
||||
},
|
||||
"opacity": {
|
||||
"default": 100,
|
||||
"description": "Sets the opacity of the window for the profile when unfocused. Accepts values from 0-100.",
|
||||
"maximum": 100,
|
||||
"minimum": 0,
|
||||
"type": "number"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
@@ -260,7 +302,8 @@
|
||||
"description": "Name of the scheme to use when the app is using dark theme",
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"FontConfig": {
|
||||
"properties": {
|
||||
@@ -347,8 +390,12 @@
|
||||
},
|
||||
"ShortcutActionName": {
|
||||
"enum": [
|
||||
"addMark",
|
||||
"adjustFontSize",
|
||||
"adjustOpacity",
|
||||
"clearAllMarks",
|
||||
"clearBuffer",
|
||||
"clearMark",
|
||||
"closeOtherPanes",
|
||||
"closeOtherTabs",
|
||||
"closePane",
|
||||
@@ -359,6 +406,7 @@
|
||||
"copy",
|
||||
"duplicateTab",
|
||||
"expandSelectionToWord",
|
||||
"experimental.colorSelection",
|
||||
"exportBuffer",
|
||||
"find",
|
||||
"findMatch",
|
||||
@@ -366,63 +414,60 @@
|
||||
"globalSummon",
|
||||
"identifyWindow",
|
||||
"identifyWindows",
|
||||
"markMode",
|
||||
"moveFocus",
|
||||
"movePane",
|
||||
"swapPane",
|
||||
"markMode",
|
||||
"moveTab",
|
||||
"multipleActions",
|
||||
"newTab",
|
||||
"newWindow",
|
||||
"nextTab",
|
||||
"openAbout",
|
||||
"openNewTabDropdown",
|
||||
"openSettings",
|
||||
"openSystemMenu",
|
||||
"openTabColorPicker",
|
||||
"openTabRenamer",
|
||||
"openWindowRenamer",
|
||||
"paste",
|
||||
"prevTab",
|
||||
"renameTab",
|
||||
"openSystemMenu",
|
||||
"openTabRenamer",
|
||||
"quakeMode",
|
||||
"quit",
|
||||
"renameTab",
|
||||
"renameWindow",
|
||||
"resetFontSize",
|
||||
"resizePane",
|
||||
"renameWindow",
|
||||
"restoreLastClosed",
|
||||
"scrollDown",
|
||||
"scrollDownPage",
|
||||
"scrollToBottom",
|
||||
"scrollToMark",
|
||||
"scrollToTop",
|
||||
"scrollUp",
|
||||
"scrollUpPage",
|
||||
"scrollToBottom",
|
||||
"scrollToTop",
|
||||
"searchWeb",
|
||||
"selectAll",
|
||||
"sendInput",
|
||||
"setColorScheme",
|
||||
"setFocusMode",
|
||||
"setFullScreen",
|
||||
"setMaximized",
|
||||
"setTabColor",
|
||||
"showSuggestions",
|
||||
"splitPane",
|
||||
"swapPane",
|
||||
"switchSelectionEndpoint",
|
||||
"switchToTab",
|
||||
"tabSearch",
|
||||
"toggleAlwaysOnTop",
|
||||
"toggleBlockSelection",
|
||||
"toggleFocusMode",
|
||||
"selectAll",
|
||||
"setFocusMode",
|
||||
"switchSelectionEndpoint",
|
||||
"toggleFullscreen",
|
||||
"setFullScreen",
|
||||
"setMaximized",
|
||||
"togglePaneZoom",
|
||||
"toggleSplitOrientation",
|
||||
"toggleReadOnlyMode",
|
||||
"toggleShaderEffects",
|
||||
"toggleSplitOrientation",
|
||||
"wt",
|
||||
"quit",
|
||||
"adjustOpacity",
|
||||
"restoreLastClosed",
|
||||
"addMark",
|
||||
"scrollToMark",
|
||||
"clearMark",
|
||||
"clearAllMarks",
|
||||
"searchWeb",
|
||||
"experimental.colorSelection",
|
||||
"unbound"
|
||||
],
|
||||
"type": "string"
|
||||
@@ -612,6 +657,7 @@
|
||||
"$ref": "#/$defs/NewTabMenuEntry"
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"type": {
|
||||
"type": "string",
|
||||
@@ -640,7 +686,7 @@
|
||||
},
|
||||
"allowEmpty": {
|
||||
"description": "Whether to render a folder without entries, or to hide it",
|
||||
"default": "false",
|
||||
"default": false,
|
||||
"type": "boolean"
|
||||
}
|
||||
}
|
||||
@@ -654,6 +700,7 @@
|
||||
"$ref": "#/$defs/NewTabMenuEntry"
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"type": {
|
||||
"type": "string",
|
||||
@@ -670,6 +717,7 @@
|
||||
"$ref": "#/$defs/NewTabMenuEntry"
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"type": {
|
||||
"type": "string",
|
||||
@@ -691,6 +739,7 @@
|
||||
"$ref": "#/$defs/NewTabMenuEntry"
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"type": {
|
||||
"type": "string",
|
||||
@@ -707,6 +756,7 @@
|
||||
"$ref": "#/$defs/NewTabMenuEntry"
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"type": {
|
||||
"type": "string",
|
||||
@@ -747,6 +797,7 @@
|
||||
]
|
||||
},
|
||||
"ShortcutAction": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"action": {
|
||||
"description": "The action to execute",
|
||||
@@ -755,8 +806,7 @@
|
||||
},
|
||||
"required": [
|
||||
"action"
|
||||
],
|
||||
"type": "object"
|
||||
]
|
||||
},
|
||||
"AdjustFontSizeAction": {
|
||||
"description": "Arguments corresponding to an Adjust Font Size Action",
|
||||
@@ -765,6 +815,7 @@
|
||||
"$ref": "#/$defs/ShortcutAction"
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"action": {
|
||||
"type": "string",
|
||||
@@ -789,6 +840,7 @@
|
||||
"$ref": "#/$defs/ShortcutAction"
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"action": {
|
||||
"type": "string",
|
||||
@@ -830,6 +882,7 @@
|
||||
"$ref": "#/$defs/NewTerminalArgs"
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"action": {
|
||||
"type": "string",
|
||||
@@ -846,6 +899,7 @@
|
||||
"$ref": "#/$defs/ShortcutAction"
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"action": {
|
||||
"type": "string",
|
||||
@@ -870,6 +924,7 @@
|
||||
"$ref": "#/$defs/ShortcutAction"
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"action": {
|
||||
"type": "string",
|
||||
@@ -894,6 +949,7 @@
|
||||
"$ref": "#/$defs/ShortcutAction"
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"action": {
|
||||
"type": "string",
|
||||
@@ -918,6 +974,7 @@
|
||||
"$ref": "#/$defs/ShortcutAction"
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"action": {
|
||||
"type": "string",
|
||||
@@ -942,6 +999,7 @@
|
||||
"$ref": "#/$defs/ShortcutAction"
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"action": {
|
||||
"type": "string",
|
||||
@@ -966,6 +1024,7 @@
|
||||
"$ref": "#/$defs/ShortcutAction"
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"action": {
|
||||
"type": "string",
|
||||
@@ -990,6 +1049,7 @@
|
||||
"$ref": "#/$defs/ShortcutAction"
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"action": {
|
||||
"type": "string",
|
||||
@@ -1017,6 +1077,7 @@
|
||||
"$ref": "#/$defs/NewTerminalArgs"
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"action": {
|
||||
"type": "string",
|
||||
@@ -1049,6 +1110,7 @@
|
||||
"$ref": "#/$defs/ShortcutAction"
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"action": {
|
||||
"type": "string",
|
||||
@@ -1086,6 +1148,7 @@
|
||||
"$ref": "#/$defs/ShortcutAction"
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"action": {
|
||||
"type": "string",
|
||||
@@ -1113,6 +1176,7 @@
|
||||
"$ref": "#/$defs/ShortcutAction"
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"action": {
|
||||
"type": "string",
|
||||
@@ -1134,6 +1198,7 @@
|
||||
"$ref": "#/$defs/ShortcutAction"
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"action": {
|
||||
"type": "string",
|
||||
@@ -1155,6 +1220,7 @@
|
||||
"$ref": "#/$defs/ShortcutAction"
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"action": {
|
||||
"type": "string",
|
||||
@@ -1179,6 +1245,7 @@
|
||||
"$ref": "#/$defs/ShortcutAction"
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"action": {
|
||||
"type": "string",
|
||||
@@ -1199,6 +1266,7 @@
|
||||
"$ref": "#/$defs/ShortcutAction"
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"action": {
|
||||
"type": "string",
|
||||
@@ -1219,6 +1287,7 @@
|
||||
"$ref": "#/$defs/ShortcutAction"
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"action": {
|
||||
"type": "string",
|
||||
@@ -1239,6 +1308,7 @@
|
||||
"$ref": "#/$defs/ShortcutAction"
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"action": {
|
||||
"type": "string",
|
||||
@@ -1263,6 +1333,7 @@
|
||||
"$ref": "#/$defs/ShortcutAction"
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"action": {
|
||||
"type": "string",
|
||||
@@ -1291,6 +1362,7 @@
|
||||
"$ref": "#/$defs/ShortcutAction"
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"action": {
|
||||
"type": "string",
|
||||
@@ -1319,6 +1391,7 @@
|
||||
"$ref": "#/$defs/ShortcutAction"
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"action": {
|
||||
"type": "string",
|
||||
@@ -1347,6 +1420,7 @@
|
||||
"$ref": "#/$defs/ShortcutAction"
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"action": {
|
||||
"type": "string",
|
||||
@@ -1371,6 +1445,7 @@
|
||||
"$ref": "#/$defs/ShortcutAction"
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"action": {
|
||||
"type": "string",
|
||||
@@ -1395,6 +1470,7 @@
|
||||
"$ref": "#/$defs/ShortcutAction"
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"action": {
|
||||
"type": "string",
|
||||
@@ -1418,6 +1494,7 @@
|
||||
"$ref": "#/$defs/ShortcutAction"
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"action": {
|
||||
"type": "string",
|
||||
@@ -1443,6 +1520,7 @@
|
||||
"$ref": "#/$defs/ShortcutAction"
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"action": {
|
||||
"type": "string",
|
||||
@@ -1464,6 +1542,7 @@
|
||||
"$ref": "#/$defs/ShortcutAction"
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"action": {
|
||||
"type": "string",
|
||||
@@ -1491,6 +1570,7 @@
|
||||
"$ref": "#/$defs/NewTerminalArgs"
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"action": {
|
||||
"type": "string",
|
||||
@@ -1507,6 +1587,7 @@
|
||||
"$ref": "#/$defs/ShortcutAction"
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"action": {
|
||||
"type": "string",
|
||||
@@ -1528,6 +1609,7 @@
|
||||
"$ref": "#/$defs/ShortcutAction"
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"action": {
|
||||
"type": "string",
|
||||
@@ -1549,6 +1631,7 @@
|
||||
"$ref": "#/$defs/ShortcutAction"
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"action": {
|
||||
"type": "string",
|
||||
@@ -1570,6 +1653,7 @@
|
||||
"$ref": "#/$defs/ShortcutAction"
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"action": {
|
||||
"type": "string",
|
||||
@@ -1591,6 +1675,7 @@
|
||||
"$ref": "#/$defs/ShortcutAction"
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"action": {
|
||||
"type": "string",
|
||||
@@ -1613,6 +1698,7 @@
|
||||
"$ref": "#/$defs/ShortcutAction"
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"action": {
|
||||
"type": "string",
|
||||
@@ -1634,6 +1720,7 @@
|
||||
"$ref": "#/$defs/ShortcutAction"
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"action": {
|
||||
"type": "string",
|
||||
@@ -1655,6 +1742,7 @@
|
||||
"$ref": "#/$defs/ShortcutAction"
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"action": {
|
||||
"type": "string",
|
||||
@@ -1706,6 +1794,7 @@
|
||||
"$ref": "#/$defs/ShortcutAction"
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"action": {
|
||||
"type": "string",
|
||||
@@ -1722,6 +1811,7 @@
|
||||
"$ref": "#/$defs/ShortcutAction"
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"action": {
|
||||
"type": "string",
|
||||
@@ -1745,6 +1835,7 @@
|
||||
"$ref": "#/$defs/ShortcutAction"
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"action": {
|
||||
"type": "string",
|
||||
@@ -1766,6 +1857,31 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
"ShowSuggestionsAction": {
|
||||
"description": "Arguments corresponding to a Open Suggestions Action",
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/$defs/ShortcutAction"
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"action": {
|
||||
"type": "string",
|
||||
"const": "showSuggestions"
|
||||
},
|
||||
"source": {
|
||||
"$ref": "#/$defs/SuggestionSource",
|
||||
"description": "Which suggestion sources to filter."
|
||||
},
|
||||
"useCommandline": {
|
||||
"default": false,
|
||||
"description": "When set to `true`, the current commandline the user has typed will pre-populate the filter of the Suggestions UI. This requires that the user has enabled shell integration in their shell's config. When set to false, the filter will start empty."
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"ShowCloseButton": {
|
||||
"enum": [
|
||||
"always",
|
||||
@@ -1835,7 +1951,11 @@
|
||||
"properties": {
|
||||
"applicationTheme": {
|
||||
"description": "Which UI theme the Terminal should use for controls",
|
||||
"enum": [ "light", "dark", "system" ],
|
||||
"enum": [
|
||||
"light",
|
||||
"dark",
|
||||
"system"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"useMica": {
|
||||
@@ -1866,7 +1986,11 @@
|
||||
"type": "string",
|
||||
"description": "The name of the theme. This will be displayed in the settings UI.",
|
||||
"not": {
|
||||
"enum": [ "light", "dark", "system" ]
|
||||
"enum": [
|
||||
"light",
|
||||
"dark",
|
||||
"system"
|
||||
]
|
||||
}
|
||||
},
|
||||
"tab": {
|
||||
@@ -1883,6 +2007,7 @@
|
||||
"ThemePair": {
|
||||
"additionalProperties": false,
|
||||
"description": "A pair of Theme names, to allow the Terminal to switch theme based on the OS theme",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"light": {
|
||||
"type": "string",
|
||||
@@ -2036,6 +2161,9 @@
|
||||
{
|
||||
"$ref": "#/$defs/SearchWebAction"
|
||||
},
|
||||
{
|
||||
"$ref": "#/$defs/ShowSuggestionsAction"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
@@ -2061,16 +2189,16 @@
|
||||
},
|
||||
"name": {
|
||||
"description": "The name that will appear in the command palette. If one isn't provided, the terminal will attempt to automatically generate a name.\nIf name is a string, it will be the name of the command.\nIf name is a object, the key property of the object will be used to lookup a localized string resource for the command",
|
||||
"properties": {
|
||||
"key": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"type": [
|
||||
"string",
|
||||
"object",
|
||||
"null"
|
||||
]
|
||||
],
|
||||
"properties": {
|
||||
"key": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"iterateOn": {
|
||||
"type": "string",
|
||||
@@ -2107,6 +2235,7 @@
|
||||
"Globals": {
|
||||
"additionalProperties": true,
|
||||
"description": "Properties that affect the entire window, regardless of the profile settings.",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"alwaysOnTop": {
|
||||
"default": false,
|
||||
@@ -2118,6 +2247,11 @@
|
||||
"description": "When set to true, tabs are always displayed. When set to false and \"showTabsInTitlebar\" is set to false, tabs only appear after opening a new tab.",
|
||||
"type": "boolean"
|
||||
},
|
||||
"compatibility.enableUnfocusedAcrylic": {
|
||||
"default": true,
|
||||
"description": "When set to true, unfocused windows can have acrylic instead of opaque.",
|
||||
"type": "boolean"
|
||||
},
|
||||
"centerOnLaunch": {
|
||||
"default": false,
|
||||
"description": "When set to `true`, the terminal window will auto-center itself on the display it opens on. The terminal will use the \"initialPosition\" to determine which display to open on.",
|
||||
@@ -2215,11 +2349,6 @@
|
||||
"description": "When set to true, the background image for the currently focused profile is expanded to encompass the entire window, beneath other panes.",
|
||||
"type": "boolean"
|
||||
},
|
||||
"compatibility.reloadEnvironmentVariables": {
|
||||
"default": true,
|
||||
"description": "When set to true, when opening a new tab or pane it will get reloaded environment variables.",
|
||||
"type": "boolean"
|
||||
},
|
||||
"initialCols": {
|
||||
"default": 120,
|
||||
"description": "The number of columns displayed in the window upon first load. If \"launchMode\" is set to \"maximized\" (or \"maximizedFocus\"), this property is ignored.",
|
||||
@@ -2321,10 +2450,17 @@
|
||||
"theme": {
|
||||
"default": "dark",
|
||||
"description": "Sets the theme of the application. This value should be the name of one of the themes defined in `themes`. The Terminal also includes the themes `dark`, `light`, and `system`.",
|
||||
"oneOf": [
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"enum": [
|
||||
"dark",
|
||||
"light",
|
||||
"system"
|
||||
]
|
||||
},
|
||||
{
|
||||
"$ref": "#/$defs/ThemePair"
|
||||
}
|
||||
@@ -2434,12 +2570,12 @@
|
||||
},
|
||||
"required": [
|
||||
"defaultProfile"
|
||||
],
|
||||
"type": "object"
|
||||
]
|
||||
},
|
||||
"Profile": {
|
||||
"description": "Properties specific to a unique profile.",
|
||||
"additionalProperties": false,
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"acrylicOpacity": {
|
||||
"default": 0.5,
|
||||
@@ -2468,6 +2604,11 @@
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"compatibility.reloadEnvironmentVariables": {
|
||||
"default": true,
|
||||
"description": "When set to true, when opening a new tab or pane it will get reloaded environment variables.",
|
||||
"type": "boolean"
|
||||
},
|
||||
"unfocusedAppearance": {
|
||||
"$ref": "#/$defs/AppearanceConfig",
|
||||
"description": "Sets the appearance of the terminal when it is unfocused.",
|
||||
@@ -2486,7 +2627,7 @@
|
||||
},
|
||||
"backgroundImage": {
|
||||
"description": "Sets the file location of the image to draw over the window background.",
|
||||
"oneOf": [
|
||||
"anyOf": [
|
||||
{
|
||||
"type": [
|
||||
"string",
|
||||
@@ -2498,10 +2639,6 @@
|
||||
"desktopWallpaper"
|
||||
]
|
||||
}
|
||||
],
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"backgroundImageAlignment": {
|
||||
@@ -2838,8 +2975,7 @@
|
||||
"description": "When set to true, the window will have an acrylic material background. When set to false, the window will have a plain, untextured background.",
|
||||
"type": "boolean"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
}
|
||||
},
|
||||
"ProfileList": {
|
||||
"description": "A list of profiles and the properties specific to each.",
|
||||
@@ -2854,6 +2990,7 @@
|
||||
},
|
||||
"ProfilesObject": {
|
||||
"description": "A list of profiles and default settings that apply to all of them",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"list": {
|
||||
"$ref": "#/$defs/ProfileList"
|
||||
@@ -2862,12 +2999,12 @@
|
||||
"description": "The default settings that apply to every profile.",
|
||||
"$ref": "#/$defs/Profile"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
}
|
||||
},
|
||||
"SchemeList": {
|
||||
"description": "Properties are specific to each color scheme. ColorTool is a great tool you can use to create and explore new color schemes. All colors use hex color format.",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"name": {
|
||||
@@ -2956,8 +3093,7 @@
|
||||
"$ref": "#/$defs/Color",
|
||||
"description": "Sets the color used as ANSI yellow."
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
}
|
||||
},
|
||||
"type": "array"
|
||||
}
|
||||
@@ -2967,6 +3103,7 @@
|
||||
"$ref": "#/$defs/Globals"
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"additionalItems": true,
|
||||
"properties": {
|
||||
"profiles": {
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
# Terminal 2022 Roadmap
|
||||
|
||||
> **NOTE**
|
||||
>
|
||||
> This document has been superseded by the [Terminal 2023 Roadmap]. Please refer to that document for the updated roadmap.
|
||||
|
||||
## Overview
|
||||
|
||||
This document outlines the roadmap of features we're planning for the Windows Terminal during 2022. This serves as a successor to the [Terminal v2 Roadmap], to reflect changes to our planning going forward.
|
||||
@@ -126,3 +130,5 @@ Incoming issues/asks/etc. are triaged several times a week, labeled appropriatel
|
||||
[Windows Terminal Preview 1.12 Release]: https://devblogs.microsoft.com/commandline/windows-terminal-preview-1-12-release/
|
||||
[Windows Terminal Preview 1.13 Release]: https://devblogs.microsoft.com/commandline/windows-terminal-preview-1-13-release/
|
||||
[Windows Terminal Preview 1.14 Release]: https://devblogs.microsoft.com/commandline/windows-terminal-preview-1-14-release/
|
||||
|
||||
[Terminal 2023 Roadmap]: https://github.com/microsoft/terminal/tree/main/doc/roadmap-2023.md
|
||||
|
||||
76
doc/roadmap-2023.md
Normal file
76
doc/roadmap-2023.md
Normal file
@@ -0,0 +1,76 @@
|
||||
# Terminal 2023 Roadmap
|
||||
|
||||
## Overview
|
||||
|
||||
This document outlines the roadmap of features we're planning for the Windows Terminal during 2023. This serves as a successor to the [2022 Roadmap], to reflect changes to our planning going forward.
|
||||
|
||||
## Release cadence
|
||||
|
||||
We've settled on a roughly quarterly release cycle - about once every three months. In May we released [Terminal 1.18]. We're targeting 1.19 for sometime in late September, and 1.20 likely in early January 2024. (These timelines are rough estimates, not strict rules. For example, 1.18's release was pushed back slightly to better align with Build 2023.)
|
||||
|
||||
New features will go into [Windows Terminal Preview](https://aka.ms/terminal-preview) first. Typically, one release after they've been in Preview, those features will move into [Windows Terminal](https://aka.ms/terminal) ("Terminal Stable"). In the case of some more risky or experimental features, we might hold them to only Preview builds for an extended period[^1].
|
||||
|
||||
|
||||
| Quarter | Date | Release Version | Preview Release Blog Post |
|
||||
| --------|------------|---------------- | ------------------------- |
|
||||
| CY23 Q1 | 2023-01-24 | [Terminal 1.17] | [Windows Terminal Preview 1.17 Release] |
|
||||
| CY23 Q2 | 2023-05-23 | [Terminal 1.18] | [Windows Terminal Preview 1.18 Release] |
|
||||
| CY23 Q3 | | [Terminal 1.19] | [Windows Terminal Preview 1.19 Release] |
|
||||
| CY23 Q4 | | [Terminal 1.20] | [Windows Terminal Preview 1.20 Release] |
|
||||
|
||||
Within a single milestone, we typically reserve the last month as "bake time", to polish off bugfixes and get the release ready to ship. In this last month, we'll likely slow down our ingestion of community PRs just to stabilize what's already in `main`. For example, a given release might look like:
|
||||
|
||||
```mermaid
|
||||
gantt
|
||||
title Proposed Terminal Releases 1.14-1.18
|
||||
dateFormat YYYY-MM-DD
|
||||
axisFormat %d %b
|
||||
section Terminal 1.18
|
||||
Lock down & bake :l18, 2023-05-09 , 2w
|
||||
Release 1.18 :milestone, 2023-05-23, 0
|
||||
1.18 becomes Stable :milestone, after l19, 0
|
||||
section Terminal 1.19
|
||||
Features :f19, after l18, 10w
|
||||
Bugfix :b19, after f19 , 4w
|
||||
Lock down & bake :l19, after b19 , 2w
|
||||
Release 1.19 :milestone, after l19, 0
|
||||
```
|
||||
|
||||
_informative, not normative_
|
||||
|
||||
## Up next in the Terminal
|
||||
|
||||
### Terminal 1.19
|
||||
|
||||
* Canary builds. Nightly builds of the Terminal from `main`. More unstable, but quicker access to experimental features.
|
||||
* Terminal AI. While this will only be shipping in Canary builds to begin with, the v0 implementation will be available roughly at the same time as 1.19.
|
||||
* The Suggestions UI. This is the starting point for shell completions [#3121], tasks [#1595], and probably Terminal AI at some point too.
|
||||
* Unicode input for `cmd.exe` (and any other console app using "cooked reads"). See [#15567]
|
||||
* Miscellaneous performance improvements. Conhost should be a _lot_ faster now.
|
||||
* Broadcast input mode, for sending text to multiple panes at once.
|
||||
|
||||
## Team member "north stars"
|
||||
|
||||
For a more fluid take on what each of the team's personal goals are, head on over to [Core team North Stars]. This has a list of more long-term goals that each team member is working towards, but not things that are necessarily committed work.
|
||||
|
||||
|
||||
[^1]: A conclusive list of these features can be found at https://github.com/microsoft/terminal/blob/main/src/features.xml. Note that this is a raw XML doc used to light up specific parts of the codebase, and not something authored for human consumption.
|
||||
|
||||
[2022 Roadmap]: https://github.com/microsoft/terminal/tree/main/doc/roadmap-2022.md
|
||||
|
||||
[Terminal 1.17]: https://github.com/microsoft/terminal/releases/tag/v1.17.1023
|
||||
[Terminal 1.18]: https://github.com/microsoft/terminal/releases/tag/v1.18.1462.0
|
||||
[Windows Terminal Preview 1.17 Release]: https://devblogs.microsoft.com/commandline/windows-terminal-preview-1-17-release/
|
||||
[Windows Terminal Preview 1.18 Release]: https://devblogs.microsoft.com/commandline/windows-terminal-preview-1-18-release/
|
||||
|
||||
[@DHowett]: https://github.com/DHowett
|
||||
[@zadjii-msft]: https://github.com/zadjii-msft
|
||||
[@lhecker]: https://github.com/lhecker
|
||||
[@carlos-zamora]: https://github.com/carlos-zamora
|
||||
[@PankajBhojwani]: https://github.com/PankajBhojwani
|
||||
|
||||
[Core team North Stars]: https://github.com/microsoft/terminal/wiki/Core-team-North-Stars
|
||||
|
||||
[#1595]: https://github.com/microsoft/terminal/issues/1595
|
||||
[#3121]: https://github.com/microsoft/terminal/issues/3121
|
||||
[#15567]: https://github.com/microsoft/terminal/issues/15567
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 585 KiB |
744
doc/specs/#1595 - Suggestions UI/Suggestions-UI.md
Normal file
744
doc/specs/#1595 - Suggestions UI/Suggestions-UI.md
Normal file
@@ -0,0 +1,744 @@
|
||||
---
|
||||
author: Mike Griese
|
||||
created on: 2022-08-22
|
||||
last updated: 2023-08-03
|
||||
issue id: 1595
|
||||
---
|
||||
|
||||
# Windows Terminal - Suggestions UI
|
||||
|
||||
## Abstract
|
||||
|
||||
Multiple related scenarios have come up where it would be beneficial to display
|
||||
actionable UI to the user within the context of the active terminal itself. This
|
||||
UI would be akin to the Intellisense UI in Visual Studio. It appears right where
|
||||
the user is typing, and can help provide immediate content for the user, based
|
||||
on some context. The "Suggestions UI" is this new ephemeral UI within the
|
||||
Windows Terminal that can display different types of actions, from different
|
||||
sources.
|
||||
|
||||
## Background
|
||||
|
||||
The Suggestions UI is the singular UI by which the Terminal can display a
|
||||
variety of suggestions to the user. These include:
|
||||
|
||||
* Recent commands the user has executed in this terminal, powered by shell integration.
|
||||
* Recent directories, similarly powered by shell integration
|
||||
* Completions from the shell itself (like the shell completions in PowerShell)
|
||||
* Tasks, which are `sendInput` actions from the user's settings
|
||||
* Buffer Completions, which is a dumb type of autocomplete based on words in the buffer
|
||||
* and more (as provided via extensions)
|
||||
|
||||
All of these scenarios are places where it makes sense to present the user a
|
||||
menu at the point of text insertion in the terminal control itself.
|
||||
|
||||
### Inspiration
|
||||
|
||||
Primarily, the inspiration is any Intellisense-like experience, in any app.
|
||||
Visual Studio, VsCode, PowerShell, vim, Sublime any JetBrains IDE - there's more
|
||||
than enough examples in the wild.
|
||||
|
||||
Ultimately, the inspiration for the Suggestions UI came from a bunch of places
|
||||
all at once. In the course of a few months though, it became clear that we'd
|
||||
need a unified UI for displaying a variety of suggestion-like experiences in the
|
||||
Terminal. Our work with the PowerShell and VsCode teams helped refine these
|
||||
requests all into the unified design below.
|
||||
|
||||
### User Stories
|
||||
|
||||
Size | Description
|
||||
-----------|--
|
||||
🐣 Crawl | The user can bring up the Suggestions UI with recent commands, powered by shell integration
|
||||
🐣 Crawl | [#12863] The user can bring up the Suggestions UI with recent directories, powered by shell integration
|
||||
🚶 Walk | The user can bring up the Suggestions UI with tasks from their settings
|
||||
🚶 Walk | CLI apps can invoke the Suggestions UI with a new VT sequence
|
||||
🚶 Walk | The Suggestions UI can be opened using the current typed commandline as a filter
|
||||
🚶 Walk | Recent commands and directories are stored in `state.json`, across sessions
|
||||
🏃♂️ Run | Suggestions can have descriptions presented in / alongside the UI
|
||||
🏃♂️ Run | The Suggestions UI can be opened without any nesting
|
||||
🏃♂️ Run | The Suggestions UI can be opened, nested by `source` of the suggestion
|
||||
🚀 Sprint | Extensions can provide suggestion sources for the Suggestions UI
|
||||
🚀 Sprint | The Suggestions UI can be opened in "inline" mode, only showing the text of the first suggestion
|
||||
|
||||
### Elevator Pitch
|
||||
|
||||
The Suggestions UI is a UI element displayed in the Terminal for providing
|
||||
different types of text suggestions to the user - anything from recently run
|
||||
commands, to saved commands, to tab-completion suggestions from the shell
|
||||
itself.
|
||||
|
||||
## Business Justification
|
||||
|
||||
It will delight developers.
|
||||
|
||||
Furthermore, our partners on the Visual Studio team have been requesting similar
|
||||
functionality for some time now. The way autocompletion menus in PowerShell
|
||||
currently interact with UIA clients leaves much to be desired. They'd like a way
|
||||
to provide richer context to screen readers. Something to enable the terminal to
|
||||
more specifically describe the context of what's being presented to the user.
|
||||
|
||||
## Scenario Details
|
||||
|
||||
### UI/UX Design
|
||||
|
||||
#### Prototypes
|
||||
|
||||
The following gif was a VsCode prototype of [shell-driven autocompletion]. This
|
||||
is the point of reference we're starting from when talking about what the
|
||||
suggestions UI might look like.
|
||||
|
||||

|
||||
|
||||
These suggestions are populated by logic within PowerShell itself, and
|
||||
communicated to the Terminal. The Terminal can then display them in the
|
||||
Suggestions UI.
|
||||
|
||||
The following demonstrate a prototype of what that might look like for the
|
||||
Terminal. These are meant to be informative, not normative, representations of
|
||||
what the UI would look like.
|
||||
|
||||

|
||||
|
||||
A prototype of the recent commands UI, powered by shell integration:
|
||||
|
||||

|
||||
|
||||
A prototype of the tasks UI, powered by the user's settings:
|
||||
|
||||

|
||||
|
||||
(admittedly, the `TeachingTip` in that gif is a prototype and was later replaced
|
||||
with a better version.)
|
||||
|
||||
In general, the Suggestions UI will present a list of elements to select from,
|
||||
near the text cursor. This control might be contain a text box for filtering
|
||||
these items (a "**palette**"), or it might not (a "**menu**").
|
||||
|
||||

|
||||
|
||||
#### Palette vs Menu
|
||||
|
||||
Depending on how the suggestions UI is invoked, we may or may not want to
|
||||
display a text box for filtering these suggestions. Consider the Intellisense
|
||||
menu in Visual Studio. That's a UI that only allows for up/down for navigation
|
||||
(and enter/tab for selecting the suggestion).
|
||||
|
||||
For suggestions driven by the Terminal, we'll display a filtering text box in
|
||||
the Suggestions UI. This is similar to the command palette's search - a fuzzy
|
||||
search to filter the contents. This is the "**palette**" style of the
|
||||
suggestions dialog.
|
||||
|
||||
For completions driven by the shell, we should probably not display the
|
||||
filtering text box. This is the "**menu**" style of the suggestion dialog. The
|
||||
user is primarily interacting with the shell here, not the Terminal.
|
||||
|
||||
> **Warning**
|
||||
> TODO! For discussion, possibly with a real UX designer.
|
||||
|
||||
How should we handle completions here? Tab? Enter? Right-Arrow? Should we have
|
||||
an element selected when we open the menu, or should tab/enter only work once
|
||||
the user has used the arrows at least once? Sublime allows for <kbd>tab</kbd> to
|
||||
complete the suggestion immediately.
|
||||
|
||||
Consider also that these suggestions might be provided by the shell, as the user
|
||||
is typing at a commandline shell. For something like PowerShell, the user might
|
||||
want to start typing a command and have it tab-complete based off the shell's
|
||||
tab expansion rules. PowerShell's inline suggestions use right-arrow to
|
||||
differentiate "use this suggestion" vs tab for "tab expand what I'm typing at
|
||||
the prompt". We should probably preserve this behavior.
|
||||
|
||||
We probably don't want to provide different experiences for the **menu** version
|
||||
of the Suggestions UI vs. the **palette** version. In the palette version, the
|
||||
user won't be pressing tab to tab-complete at the shell - the focus is out of
|
||||
the of terminal and in the Suggestions UI. With the menu version, the focus is
|
||||
still "in the terminal", and users would expect tab to tab-complete.
|
||||
|
||||
We will want to make sure that there's some semblance of consistency across our
|
||||
implementation for the Suggestions UI, our own Command Palette, VsCode's
|
||||
intellisense and their own implementation of shell-completions in the Terminal.
|
||||
|
||||
> **Note**
|
||||
> In my prototype, for the "Menu" mode, I accepted ALL of right-arrow, tab, and
|
||||
> enter as "accept completion", and any other key dismissed the UI. This _felt_
|
||||
> right for that mode. I'm not sure we could make the same call for "palette"
|
||||
> mode, where we'd need tab for navigating focus.
|
||||
|
||||
### Implementation Details
|
||||
|
||||
#### Fork the Command Palette
|
||||
|
||||
We're largely going to start with the Command Palette to build the Suggestions
|
||||
UI[[1](#footnote-1)]. The Command Palette is already a control we've built for displaying a
|
||||
transient list of commands and dispatching them to the rest of the app.
|
||||
|
||||
Currently, the Command Palette is a single static control, at the top-center of
|
||||
the Terminal window, and occupying a decent portion of the screen. For the
|
||||
Suggestions UI, we'll instead want to make sure that the control appears
|
||||
relative to the current cursor position.
|
||||
|
||||
We'll start by taking the command palette, and copying it over to a new control.
|
||||
This will allow us to remove large chunks of code dealing with different modes
|
||||
(i.e. the tab switcher), and code dealing with prefix characters to switch
|
||||
modes.
|
||||
|
||||
We'll need to make some small modifications to enable the Suggestions UI to
|
||||
* work as a text cursor-relative control
|
||||
* exist as a Flyout outside the bounds of the Terminal window
|
||||
* If the Suggestions UI is too close to the bottom of the screen, we'll need it to open
|
||||
"upwards", with the search box at the _bottom_ and the list extending above it
|
||||
* prevent it from switching to command-line mode
|
||||
* display tooltips / `TeachingTip`s / some secondary flyout with a description
|
||||
of the suggestion (if provided)
|
||||
|
||||
#### Completion sources
|
||||
|
||||
The Suggestions UI will support suggestions from a variety of different
|
||||
"sources". As an example, consider the following actions:
|
||||
|
||||
```json
|
||||
{ "command": { "action":"suggestions", "source": "commandHistory" } },
|
||||
{ "command": { "action":"suggestions", "source": "directoryHistory" } },
|
||||
|
||||
{ "command": { "action":"suggestions", "source": "tasks" } },
|
||||
{ "command": { "action":"suggestions", "source": "local" } },
|
||||
|
||||
{ "command": { "action":"suggestions", "source": ["local", "tasks", "commandHistory"] } },
|
||||
|
||||
{ "command": { "action":"suggestions", "source": "Microsoft.Terminal.Extensions.BufferComplete" } },
|
||||
```
|
||||
|
||||
Each of these `suggestions` actions would open the Suggestions UI with a
|
||||
different set of actions.
|
||||
|
||||
* `commandHistory`: Use commands from this session, as identified via shell
|
||||
integration. This won't be able to return any suggestions if the user has not
|
||||
configured their shell to support shell integration sequences yet.
|
||||
* `directoryHistory`: Populate the list with a series of `cd {path}` commands,
|
||||
where the paths are populated via shell integration. Paths are in MRU order.
|
||||
* `tasks`: Populate the list with all `sendInput` actions in the user's settings
|
||||
file. The command structure should remain unchanged. For example, if they have
|
||||
`sendInput` actions nested under a "git" command, then the "git" entry will
|
||||
remain in this tasks view with their `sendInput` actions nested inside it. For
|
||||
more details, see the [Tasks] spec.
|
||||
* `local`: Populate the list with tasks that are located in the CWD, in a file
|
||||
named `.wt.json`. For more details, see the [Tasks] spec.
|
||||
* `Microsoft.Terminal.Extensions.BufferComplete`: As an example, this
|
||||
demonstrates how an action might be authored to reference a suggestion source
|
||||
from an extension[[2](#footnote-2)].
|
||||
|
||||
Each of these different sources will build a different set of `Command`s,
|
||||
primarily populated with `sendInput` actions. We'll load those `Command`s into
|
||||
the Suggestions UI control, and open it at the text cursor.
|
||||
|
||||
To drill in on a single example - the `commandHistory` source. In that
|
||||
particular case, the TerminalPage will query the active TermControl for a list
|
||||
of its recent commands. If it knows these (via shell integration), then the
|
||||
TerminalPage will use that list of commands to build a list of `sendInput`
|
||||
actions. Those will then get fed to the suggestions UI.
|
||||
|
||||
Not listed above is [shell-driven autocompletion]. These aren't something that
|
||||
the Terminal can invoke all on its own - these are something the shell would
|
||||
need to invoke themselves.
|
||||
|
||||
#### Pre-populate the current commandline context
|
||||
|
||||
Consider the following scenario. A user has typed `git c` in their shell, and
|
||||
has [shell integration] enabled for their shell. They want to open the
|
||||
Suggestions UI filtered to their recent history, but starting with what they've
|
||||
already typed. To support this scenario, we'll add an additional property:
|
||||
|
||||
* `"useCommandline"`: `bool` (**default**: `true`)
|
||||
* `true`: the current commandline the user has typed will pre-populate the
|
||||
filter of the Suggestions UI. This requires that the user has enabled shell
|
||||
integration in their shell's config.
|
||||
* `false`: the filter will start empty, regardless of what the user has typed.
|
||||
|
||||
With that setting, the user can achieve their desired UX with the following action:
|
||||
|
||||
```json
|
||||
{ "command": { "action":"suggestions", "source": "commandHistory", "useCommandline": true } },
|
||||
```
|
||||
|
||||
Now, when they type `git c` and invoke the Suggestions UI, they can immediately
|
||||
start searching for recent commands that started with `git c`.
|
||||
|
||||
The primary use case for `useCommandline: false` was for `"nesting": "source"`.
|
||||
When filtering a list of ["Tasks...", "Recent commands...", "Recent
|
||||
directories...", "Docker...", "Git..."], then there's minimal value to start by
|
||||
filtering to "git c".
|
||||
|
||||
#### Default actions
|
||||
|
||||
I propose adding the following actions to the Terminal by default:
|
||||
|
||||
```json
|
||||
{ "command": { "action":"suggestions", "source": "commandHistory", "useCommandline": true } },
|
||||
{ "command": { "action":"suggestions", "source": "directoryHistory" } },
|
||||
{ "command": { "action":"suggestions", "source": ["local", "tasks", "commandHistory"], "useCommandline": true, "nesting": "disabled" } },
|
||||
{ "command": { "action":"suggestions", "source": ["all"], "useCommandline": false, "nesting": "source" } },
|
||||
```
|
||||
|
||||
These actions are colloquially:
|
||||
* Give me suggestions from my recent commands, using what I've typed
|
||||
* Give me suggestions of directories I've recently been in
|
||||
* _(After [Tasks] are implemented)_ Give me suggestions from recent commands,
|
||||
commands I've saved, and commands for this project. Don't nest any, so they're
|
||||
all in the top-level menu. Use what I've typed already to start filtering.
|
||||
* Just open the Suggestions UI with all suggestions sources, and group them by
|
||||
the source of the suggestions.
|
||||
|
||||
This should cover most of the basic use cases for suggestions.
|
||||
|
||||
#### Who owns this menu?
|
||||
|
||||
There was some discussion of who should own the suggestions menu. The control
|
||||
itself? Or the app hosting the control?
|
||||
|
||||
A main argument for hosting this UI in the control itself is that any consumer
|
||||
of the `TermControl` should be able to display the [shell-driven autocompletion]
|
||||
menu. And they should get the UI from us "for free". Consumers shouldn't need to
|
||||
reimplement it themselves. This probably could be done without many changes:
|
||||
* Instead of operating on `Command`s and actions from the terminal settings,
|
||||
the control could just know that all the entries in the menu are "send
|
||||
input" "actions".
|
||||
* The control could offer a method to manually invoke the Suggestions UI for a
|
||||
list of {suggestion, name, description} objects.
|
||||
* The app layer could easily translate between sendInput actions and these
|
||||
pseudo-actions.
|
||||
|
||||
A big argument in favor of having the app layer host the control: Consider an
|
||||
app like Visual Studio. When they embed the control, they'll want to style the
|
||||
shell-completions UI in their own way. They already have their own intellisense
|
||||
menu, and their own UI paradigm.
|
||||
|
||||
For now, we'll leave this as something that's owned by the app layer. When we
|
||||
get around to finalizing the [shell-driven autocompletion] design, we can
|
||||
iterate on ideas for supporting both consumers that want to use a pre-built
|
||||
suggestions control, or consumers who want to bring their own.
|
||||
|
||||
## Tenets
|
||||
|
||||
<table>
|
||||
|
||||
<tr><td><strong>Compatibility</strong></td><td>
|
||||
|
||||
This shouldn't break any existing flows. This is a general purpose UI element,
|
||||
to be extended in a variety of ways. Those customizations will all be opt-in by
|
||||
the user, so I'm not expecting any breaking compatibility changes here.
|
||||
|
||||
</td></tr>
|
||||
|
||||
<tr><td><strong>Accessibility</strong></td><td>
|
||||
|
||||
The Suggestions UI was designed with the goal of making commandline shell
|
||||
suggestions _more_ accessible. As Carlos previously wrote:
|
||||
|
||||
> Screen readers struggle with this because the entire menu is redrawn every time, making it harder to understand what exactly is "selected" (as the concept of selection in this instance is a shell-side concept represented by visual manipulation).
|
||||
>
|
||||
> ...
|
||||
>
|
||||
> _\[Shell driven suggestions\]_ can then be leveraged by Windows Terminal to create UI elements. Doing so leverages WinUI's accessible design.
|
||||
|
||||
This will allow the Terminal to provide more context-relevant information to
|
||||
screen readers.
|
||||
|
||||
</td></tr>
|
||||
|
||||
<tr><td><strong>Sustainability</strong></td><td>
|
||||
|
||||
No sustainability changes expected.
|
||||
|
||||
</td></tr>
|
||||
|
||||
<tr><td><strong>Localization</strong></td><td>
|
||||
|
||||
The localization needs of the Suggestions UI will be effectively the same as the
|
||||
needs of the Command Palette.
|
||||
|
||||
The Terminal will have no way to localize suggestions that are provided via
|
||||
[shell-driven autocompletion]. These are just verbatim strings that the shell
|
||||
told us to use. We don't consider this to be something to worry about, however.
|
||||
This is no different than the fact that Terminal cannot localize the `Get-Help`
|
||||
(or any other) output of PowerShell.
|
||||
|
||||
</td></tr>
|
||||
|
||||
</table>
|
||||
|
||||
## Implementation Plan
|
||||
|
||||
This is more of an informative outline, rather than a normative one. Many of the
|
||||
things from Crawl, Walk, and Run are all already in PRs as of the time of this
|
||||
spec's review.
|
||||
|
||||
### 🐣 Crawl
|
||||
|
||||
* [ ] Fork the Command palette to a new UI element, the `SuggestionsControl`
|
||||
* [ ] Enable previewing `sendInput` actions in the Command Palette and `SuggestionsControl`
|
||||
* [ ] Enable the `SuggestionsControl` to open top-down (aligned to the bottom of the cursor row) or bottom-up (aligned to the top of the cursor row).
|
||||
* [ ] Disable sorting on the `SuggestionsControl` - elements should presumably be pre-sorted by the source.
|
||||
* [ ] Expose the recent commands as a accessor on `TermControl`
|
||||
* [ ] Add a `suggestions` action which accepts a single option `recentCommands`. These should be fed in MRU order to the `SuggestionsControl`.
|
||||
* [ ] Expose the recent directories as an accessor on `TermControl`, and add a `recentDirectories` source.
|
||||
|
||||
### 🚶 Walk
|
||||
|
||||
* [ ] Add a `tasks` source to `suggestions` which opens the Suggestions UI with
|
||||
a tree of all `sendInput` commands
|
||||
* [ ] Enable the `SuggestionsControl` to open with or without a search box
|
||||
* [ ] Plumb support for shell-driven completions through the core up to the app
|
||||
* [ ] Expose the _current_ commandline from the `TermControl`
|
||||
* [ ] Add a `useCommandline` property to `suggestions`, to pre-populate the search with the current commandline.
|
||||
* [ ] Persist recent commands / directories accordingly
|
||||
|
||||
### 🏃♂️ Run
|
||||
|
||||
* [ ] Add a `description` field to `Command`
|
||||
* [ ] Add a `TeachingTip` (or similar) to the Suggestions UI to display
|
||||
descriptions (when available)
|
||||
* [ ] Use the `ToolTip` property of shell-driven suggestions as the description
|
||||
* [ ] Add a boolean `nesting` property which can be used to disable nesting on the `tasks` source.
|
||||
* [ ] Add the ability for `nesting` to accept `enabled`/`disabled` as `true`/`false` equivalents
|
||||
* [ ] Add the ability for `nesting` to accept `source`, which instead groups all
|
||||
commands to the Suggestions UI by the source of that suggestion.
|
||||
|
||||
### 🚀 Sprint
|
||||
|
||||
The two "sprint" tasks here are much more ambitious than the other listed
|
||||
scenarios, so breaking them down to atomic tasks sees less reasonable. We'd have
|
||||
to spend a considerable amount more time figuring out _how_ to do each of these
|
||||
first.
|
||||
|
||||
For example - extensions. We have yet to fully realize what extensions _are_.
|
||||
Determining how extensions will provide suggestions is left as something we'll
|
||||
need to do as a part of the Extensions spec.
|
||||
|
||||
## Conclusion
|
||||
|
||||
Here's a sample json schema for the settings discussed here.
|
||||
|
||||
```json
|
||||
"OpenSuggestionsAction": {
|
||||
"description": "Arguments corresponding to a Open Suggestions Action",
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/$defs/ShortcutAction"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"action": {
|
||||
"type": "string",
|
||||
"const": "suggestions"
|
||||
},
|
||||
"source": {
|
||||
"$ref": "#/$defs/SuggestionSource",
|
||||
"description": "Which suggestion sources to filter."
|
||||
},
|
||||
"useCommandline": {
|
||||
"default": false,
|
||||
"description": "When set to `true`, the current commandline the user has typed will pre-populate the filter of the Suggestions UI. This requires that the user has enabled shell integration in their shell's config. When set to false, the filter will start empty."
|
||||
},
|
||||
"nesting": {
|
||||
"default": true,
|
||||
"description": "When set to `true`, suggestions will follow the provided nesting structure. For Tasks, these will follow the structure of the Command Palette. When set to `false`, no nesting will be used (and all suggestions will be in the top-level menu.",
|
||||
"$comment": "This setting is a possible follow-up setting, not required for v1. "
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"BuiltinSuggestionSource": {
|
||||
"enum": [
|
||||
"commandHistory",
|
||||
"directoryHistory",
|
||||
"tasks",
|
||||
"local",
|
||||
"all"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"SuggestionSource": {
|
||||
"default": "all",
|
||||
"description": "Either a single suggestion source, or an array of sources to concatenate. Built-in sources include `commandHistory`, `directoryHistory`, `tasks`, and `local`. Extensions may provide additional values. The special value `all` indicates all suggestion sources should be included",
|
||||
"$comment": "`tasks` and `local` are sources that would be added by the Tasks feature, as a follow-up"
|
||||
"oneOf": [
|
||||
{
|
||||
"type": [ "string", "null", "BuiltinSuggestionSource" ]
|
||||
},
|
||||
{
|
||||
"type": "array",
|
||||
"items": { "type": "BuiltinSuggestionSource" }
|
||||
},
|
||||
{
|
||||
"type": "array",
|
||||
"items": { "type": "string" }
|
||||
}
|
||||
]
|
||||
},
|
||||
```
|
||||
|
||||
### Future Considerations
|
||||
|
||||
* Another extension idea: `WithFig.FigCompletions`. Imagine an extension that
|
||||
could parse existing [Fig] completion specs, and provide those as suggestions
|
||||
in this way.
|
||||
* This might be a good example of an async suggestion source. The current
|
||||
commandline is used as the starting filter, and the suggestions would be
|
||||
populated by some `fig` process / thread / async operation that returns the
|
||||
suggestions.
|
||||
* If the user hasn't enabled shell completion, we could add text to the
|
||||
`commandHistory` or `directoryHistory` menus to inform the user how they could
|
||||
go enable shell integration. We already have a docs page dedicated to this, so
|
||||
we could start by linking to that page. More notes on this in [Automatic shell
|
||||
integration](#Automatic-shell-integration).
|
||||
* Maybe there could be a per-profile setting for automatic suggestions after
|
||||
some timeout. Like, as you type, a menu version of the Suggestions UI appears.
|
||||
So you could just start typing `git c`, and it would automatically give you a
|
||||
menu with suggestions, implicitly using the typed command as the "filter".
|
||||
* Maybe we could do this as an `implicit` property on the `suggestions` action
|
||||
|
||||
|
||||
#### Description Tooltips
|
||||
|
||||
> **Note**: _This is left as a future consideration for the initial draft of
|
||||
> this spec. I'd like to flesh out [shell-driven autocompletion] more before
|
||||
> committing any plans here._
|
||||
|
||||
It would be beneficial for the Suggestions UI to display additional context to
|
||||
the user. Consider a extension that provides some commands for the user, like a
|
||||
hypothetical "Docker" extension. The extension author might be able to give the
|
||||
commands simplified names, but also want to expose a more detailed description
|
||||
of the commands to the user.
|
||||
|
||||
Or consider the Suggestions UI when invoked by [shell-driven autocompletion].
|
||||
The shell might want to provide help text to the user with each of the
|
||||
suggestions. This would allow a user to browse through the suggestions that they
|
||||
might not know about, and learn how they work before committing to one.
|
||||
|
||||
Only the help text for the currently hovered command should be presented to the
|
||||
user. To support this kind of UX, we'll add an optional flyout of some sort to
|
||||
display with the Suggestions UI. This flyout will only appear if there's more
|
||||
information provided to the Terminal.
|
||||
|
||||
This might be in the form of a `TeachingTip`, as in this example:
|
||||
|
||||

|
||||
|
||||
Actions in the settings could also accept an optional `description` property, to
|
||||
specify the string that would be presented in that flyout.
|
||||
|
||||
#### Automatic shell integration
|
||||
|
||||
A large portion of these features all rely on shell integration being enabled by
|
||||
the user. However, this is not a trivial thing for the Terminal to do on behalf
|
||||
of the user. Shell integration relies on changes to the user's shell config. If
|
||||
the Terminal were to try and configure those itself, we may accidentally destroy
|
||||
configuration that the user has already set up. Hence why the Terminal can't
|
||||
just have a "Light up all the bells and whistles" toggle in the Settings UI.
|
||||
|
||||
This is a non-trivial problem to solve, so it is being left as a future
|
||||
consideration, for a later spec. It deserves its own spec to sort out how we
|
||||
should expose this to users and safely implement it.
|
||||
|
||||
#### Pre-filtering the UI & filter by source
|
||||
|
||||
> **Note**: _This is a brainstorm I considered while writing this spec. I would
|
||||
> not include it in the v1 of this spec. Rather, I'd like to leave it for
|
||||
> where we might go with this UX in the future._
|
||||
|
||||
Do want to support different _types_ of nesting? So instead of just the default,
|
||||
there could be something like `nesting: "source"`, to create a menu structured
|
||||
like:
|
||||
|
||||
```
|
||||
Suggestions UI
|
||||
├─ Recent Commands...
|
||||
│ ├─ git checkout main
|
||||
│ ├─ git fetch
|
||||
│ └─ git pull
|
||||
├─ Recent Directories...
|
||||
│ ├─ d:\dev
|
||||
│ ├─ d:\dev\public
|
||||
│ └─ d:\dev\public\terminal
|
||||
├─ Saved tasks...
|
||||
│ ├─ Git...
|
||||
│ │ └─ git commit -m "
|
||||
│ │ └─ git log...
|
||||
│ └─ bx & runut
|
||||
└─ Docker
|
||||
├─ docker build --platform linux/amd64 <path>
|
||||
└─ docker logs -f --tail <lines_count> <container_name>
|
||||
```
|
||||
|
||||
> **Note**
|
||||
> I'm using `Docker` as an example fragment extension that provides
|
||||
> some `docker` commands. When grouping by `"source"`, we could pull those into
|
||||
> a separate top-level entry. When not grouping by `"source"`, those would still
|
||||
> show up with the rest of `tasks`. )
|
||||
|
||||
#### Store recent commands across sessions
|
||||
|
||||
> **Note**
|
||||
> _I'm not sure we really want to put this in this spec or not, hence
|
||||
> why it is in the "Future considerations" section. I think it is worth
|
||||
> mentioning. This might be better served in the [shell integration] doc._
|
||||
|
||||
We'll probably want a way for recent commands to be saved across sessions. That way, your `cmd.exe` command history could persist across sessions. We'd need:
|
||||
|
||||
* A setting to enable this behavior
|
||||
* A setting to control the context of these saved commandlines.
|
||||
* Do we want them saved per-profile, or globally?
|
||||
* If they're saved per-profile, maybe a profile can opt-in to loading all the commands?
|
||||
* How does defterm play with this? Do we "layer" by concatenating per-profile commands with `profiles.defaults` ones?
|
||||
* A button in the Settings UI for clearing these commands
|
||||
* Should fragments be able to pre-populate "recent commands"?
|
||||
* I'm just gonna say _no_. That would be a better idea for Tasks (aka just a `sendInput` Action that we load from the fragment normally as a Task), or a specific suggestion source for the fragment extension.
|
||||
|
||||
#### Inline mode
|
||||
|
||||
> **Note**
|
||||
> _This is a half-baked idea with some potential. However, I don't
|
||||
> think it needs to be a part of the v1 of the Suggestions UI, so I'm leaving it
|
||||
> under future considerations for a future revision._
|
||||
|
||||
Do we want to have a suggestions UI "mode", that's just **one** inline
|
||||
suggestion, "no" UI? Some UX ala the `PsReadline` recent command suggestion
|
||||
feature. Imagine, we just display the IME ghost text thing for the first result,
|
||||
given the current prompt?
|
||||
|
||||
Take the following action as an example:
|
||||
|
||||
```json
|
||||
{ "command": { "action":"suggestions", "source": "commandHistory", "useCommandline": true, "inline": true } },
|
||||
```
|
||||
|
||||
Type the start of some command at the prompt, and press that key. Presto, we do
|
||||
the `pwsh` thing. Ghost text appears for the first match in the `commandHistory`
|
||||
for what the user has typed. If they press another key, ~they've typed into the
|
||||
"hidden" Suggestions UI, which filters the (hidden) list more, and updates the
|
||||
one inline suggestion.~
|
||||
|
||||
Or, instead, typed keys go to the shell, and then we re-query the commandline,
|
||||
and update the filter accordingly. That would allow tab-completion to still
|
||||
work. We'd use <kbd>right arrow</kbd> to accept the suggestion (and dismiss the
|
||||
ghost text preview).
|
||||
|
||||
This would seemingly SUPER conflict with PowerShell's own handler. Probably not
|
||||
something someone should enable for PowerShell 7 profiles if they're using that
|
||||
feature.
|
||||
|
||||
### Rejected ideas
|
||||
|
||||
These are musings from earlier versions of the spec.
|
||||
* **Asynchronous prompting**: This was rejected because it was so fundamentally
|
||||
different from the rest of the UX of the Suggestions UI, it didn't make sense
|
||||
to try and also do that behavior.
|
||||
* ...
|
||||
|
||||
#### REJECTED: Asynchronous prompting
|
||||
|
||||
Certain suggestion sources might want to provide results asynchronously.
|
||||
Consider a source that might want to make a web request to populate what strings
|
||||
to suggest. That source might want to prompt the user for input first, then
|
||||
dispatch the request, then populate the UI. Or something like a `fig`-like
|
||||
suggestion source, which would need to parse some files from the disk to
|
||||
generate the list of suggestions.
|
||||
|
||||
The easiest way to do this would be to provide a secondary UI element for
|
||||
prompting the user for input, doing the request in the background, then opening
|
||||
the UI later. However, that feels a little disjointed. Could we instead provide
|
||||
a more continuous experience?
|
||||
|
||||
The following is a proposal for using the Suggestions UI itself as the control
|
||||
to prompt the user for input.
|
||||
|
||||
```c++
|
||||
TerminalPage::SetUpSuggestionsUI()
|
||||
{
|
||||
const auto& asyncSource{ AsyncSuggestions() };
|
||||
|
||||
suggestionsUI.OnInputChanged({ asyncSource, AsyncSuggestions::InputChangedHandler});
|
||||
// In this example, we don't want the UI to filter item based on the input
|
||||
// string - the source has already determined the list of relevant matches.
|
||||
suggestionsUI.FilterByInput(false);
|
||||
|
||||
asyncSource.SuggestionsChanged([](const auto& newCommands){
|
||||
suggestionsUI.Loading(false);
|
||||
suggestionsUI.Commands(newCommands);
|
||||
})
|
||||
}
|
||||
|
||||
void AsyncSuggestions::InputChangedHandler(FilterChangedArgs args)
|
||||
{
|
||||
// kick off a trailing ThrottledFunc to do a new query
|
||||
_loadNewResults->Run(args.NewInputText());
|
||||
// If we get another request, we might want to cancel the pending throttled
|
||||
// func entirely, and start the timeout fresh. Just so that we only make a
|
||||
// query for the final string they type.
|
||||
|
||||
args.RequestLoading(true); // pass a boolean back up in the args, so that
|
||||
// the Suggestions UI can clear out the current commands, and start displaying an
|
||||
// indeterminate progress wheel.
|
||||
}
|
||||
```
|
||||
|
||||
That would basically _have_ to be special cased for this source, at least for
|
||||
now. We could refactor that later to better deal with extensions.
|
||||
|
||||
Let's make sure this would work for something `fig`-like, where the "prompt" is
|
||||
literally the prompt, what the user has already typed at the commandline.
|
||||
|
||||
After some discussion:
|
||||
* How do we differentiate the prompting version of the Suggestions UI from the
|
||||
filtering version?
|
||||
* The prompting version _doesn't_ filter results
|
||||
* Async modes wouldn't work with sync ones at all. E.g. if you did `source:
|
||||
["tasks", "myAsyncSource"]`. It doesn't make sense to start with a list of
|
||||
`tasks`, then type, find no tasks, but then oh! the UI fills in some other
|
||||
suggestions too. That's weird.
|
||||
|
||||
## Resources
|
||||
|
||||
These are some other work streams that have a lot of tie-in to the Suggestions
|
||||
UI. These are all being spec'd at roughly the same time, so links may not be
|
||||
fully up to date.
|
||||
* [Shell integration]
|
||||
* [Shell-driven autocompletion]
|
||||
* [Tasks]
|
||||
|
||||
### Footnotes
|
||||
|
||||
<a name="footnote-1"><a>[1]: We've had discussion in the past ([#7285]) about
|
||||
possibly creating a more abstract "Live filtering list view" to replace the
|
||||
Command Palette. We could most certainly use that here too. We've decided to
|
||||
initially go with a fork for now.
|
||||
|
||||
<a name="footnote-2"><a>[2]: Obviously, we're not having a real discussion about
|
||||
extensions in this doc. This example is solely to show that there's room for
|
||||
extensions to work with the "source" property in this design. What the final
|
||||
shape of extensions will be is very much still to be determined.
|
||||
|
||||
|
||||
[Fig]: https://github.com/withfig/autocomplete
|
||||
[Warp]: https://www.warp.dev/
|
||||
[workflows]: https://docs.warp.dev/features/workflows
|
||||
[also working on workflows]: https://fig.io/user-manual/workflows
|
||||
[winget script]: https://github.com/microsoft/PowerToys/blob/main/.github/workflows/package-submissions.yml
|
||||
[#1595]: https://github.com/microsoft/terminal/issues/1595
|
||||
[#7039]: https://github.com/microsoft/terminal/issues/7039
|
||||
[#3121]: https://github.com/microsoft/terminal/issues/3121
|
||||
[#10436]: https://github.com/microsoft/terminal/issues/10436
|
||||
[#12927]: https://github.com/microsoft/terminal/issues/12927
|
||||
[#12863]: https://github.com/microsoft/terminal/issues/12863
|
||||
[#7285]: https://github.com/microsoft/terminal/issues/7285
|
||||
[#14939]: https://github.com/microsoft/terminal/issues/7285
|
||||
|
||||
[#keep]: https://github.com/zadjii/keep
|
||||
[VsCode Tasks]: https://github.com/microsoft/terminal/blob/main/.vscode/tasks.json
|
||||
|
||||
<!-- Note: This is its own spec in progress, but for the time being #12862 will do -->
|
||||
[Tasks]: https://github.com/microsoft/terminal/issues/12862
|
||||
<!-- Note: This is just a link to the PR that introduced the shell integration spec -->
|
||||
[shell integration]: https://github.com/microsoft/terminal/pull/14792
|
||||
<!-- Note: If I ever write a spec for this, go ahead and replace this link -->
|
||||
[shell-driven autocompletion]: https://github.com/microsoft/terminal/issues/3121
|
||||
BIN
doc/specs/#1595 - Suggestions UI/command-history-suggestions.gif
Normal file
BIN
doc/specs/#1595 - Suggestions UI/command-history-suggestions.gif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 965 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 1.0 MiB |
BIN
doc/specs/#1595 - Suggestions UI/tasks-suggestions.gif
Normal file
BIN
doc/specs/#1595 - Suggestions UI/tasks-suggestions.gif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.4 MiB |
BIN
doc/specs/#1595 - Suggestions UI/vscode-shell-suggestions.gif
Normal file
BIN
doc/specs/#1595 - Suggestions UI/vscode-shell-suggestions.gif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 431 KiB |
@@ -95,7 +95,7 @@
|
||||
#define HAVE_AVX512
|
||||
#endif
|
||||
|
||||
#if defined(X86_OR_X64)
|
||||
#if defined(X86_OR_X64) && !defined(_M_ARM64EC)
|
||||
/* MSVC compatible compilers (Windows) */
|
||||
#if defined(_MSC_VER)
|
||||
/* clang-cl (LLVM 10 from 2020) requires /arch:AVX2 or
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user