From 18a498b6cdbae130ed0871b06ad508b77b2a1b00 Mon Sep 17 00:00:00 2001 From: Patrick Meinecke Date: Thu, 15 Aug 2024 20:31:09 +0000 Subject: [PATCH 001/173] Merged PR 32128: Update third party notices #### AI description (iteration 1) #### PR Classification Documentation update #### PR Summary This pull request updates the third-party notices to reflect changes in dependencies and their respective licenses. - Updated `ThirdPartyNotices.txt` to reflect new versions and copyright holders for several dependencies. - Removed detailed Apache License text for `Microsoft.Extensions.ObjectPool` and replaced it with a summary. - Added new entries for `Microsoft.Extensions.ObjectPool 8.0.4` and updated versions for other dependencies like `Microsoft.Bcl.AsyncInterfaces`, `System.Security.AccessControl`, and various `Json` libraries. --- ThirdPartyNotices.txt | 307 ++++++++++++++++++------------------------ 1 file changed, 129 insertions(+), 178 deletions(-) diff --git a/ThirdPartyNotices.txt b/ThirdPartyNotices.txt index 4c6db295cec..27dd8ead268 100644 --- a/ThirdPartyNotices.txt +++ b/ThirdPartyNotices.txt @@ -17,125 +17,7 @@ required to debug changes to any libraries licensed under the GNU Lesser General --------------------------------------------------------- -Microsoft.Extensions.ObjectPool 5.0.10 - Apache-2.0 - - -(c) Microsoft Corporation -Copyright (c) Andrew Arnott -Copyright (c) 2019 David Fowler -Copyright (c) 2016 Richard Morris -Copyright (c) 2017 Yoshifumi Kawai -Copyright (c) Microsoft Corporation -Copyright (c) 2014-2018 Michael Daines -Copyright (c) 2013-2017, Milosz Krajewski -Copyright (c) .NET Foundation and Contributors -Copyright (c) 2019-2020 West Wind Technologies -Copyright (c) 2010-2019 Google LLC. http://angular.io/license -Copyright (c) Sindre Sorhus (https://sindresorhus.com) - -Apache License - -Version 2.0, January 2004 - -http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - - - "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. - - - - "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. - - - - "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. - - - - "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. - - - - "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. - - - - "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. - - - - "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). - - - - "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. - - - - "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." - - - - "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: - - (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. - - You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS - -APPENDIX: How to apply the Apache License to your work. - -To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. - -Copyright [yyyy] [name of copyright owner] - -Licensed under the Apache License, Version 2.0 (the "License"); - -you may not use this file except in compliance with the License. - -You may obtain a copy of the License at - -http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software - -distributed under the License is distributed on an "AS IS" BASIS, - -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - -See the License for the specific language governing permissions and - -limitations under the License. - ---------------------------------------------------------- - ---------------------------------------------------------- - -Markdig.Signed 0.34.0 - BSD-2-Clause +Markdig.Signed 0.37.0 - BSD-2-Clause @@ -173,15 +55,14 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI --------------------------------------------------------- -Json.More.Net 2.0.0 - MIT +Json.More.Net 2.0.1.2 - MIT -(c) Microsoft 2024 -Copyright (c) 2022 Greg Dennis +Copyright (c) 2024 Greg Dennis MIT License -Copyright (c) 2022 Greg Dennis +Copyright (c) 2024 Greg Dennis Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -206,15 +87,14 @@ SOFTWARE. --------------------------------------------------------- -JsonPointer.Net 4.0.0 - MIT +JsonPointer.Net 5.0.0 - MIT -(c) Microsoft 2024 -Copyright (c) 2022 Greg Dennis +Copyright (c) 2024 Greg Dennis MIT License -Copyright (c) 2022 Greg Dennis +Copyright (c) 2024 Greg Dennis Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -239,7 +119,7 @@ SOFTWARE. --------------------------------------------------------- -JsonSchema.Net 6.0.2 - MIT +JsonSchema.Net 7.0.1 - MIT @@ -276,45 +156,62 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI --------------------------------------------------------- -Microsoft.Bcl.AsyncInterfaces 5.0.0 - MIT +Microsoft.Bcl.AsyncInterfaces 8.0.0 - MIT -(c) Microsoft Corporation. +Copyright (c) Six Labors +(c) Microsoft Corporation Copyright (c) Andrew Arnott +Copyright 2019 LLVM Project Copyright 2018 Daniel Lemire -Copyright 2012 the V8 project -Copyright (c) .NET Foundation. +Copyright (c) .NET Foundation Copyright (c) 2011, Google Inc. +Copyright (c) 2020 Dan Shechter +(c) 1997-2005 Sean Eron Anderson Copyright (c) 1998 Microsoft. To -(c) 1997-2005 Sean Eron Anderson. +Copyright (c) 2022, Wojciech Mula Copyright (c) 2017 Yoshifumi Kawai +Copyright (c) 2022, Geoff Langdale +Copyright (c) 2005-2020 Rich Felker +Copyright (c) 2012-2021 Yann Collet Copyright (c) Microsoft Corporation Copyright (c) 2007 James Newton-King -Copyright (c) 2012-2014, Yann Collet +Copyright (c) 1991-2022 Unicode, Inc. Copyright (c) 2013-2017, Alfred Klomp +Copyright 2012 the V8 project authors +Copyright (c) 1999 Lucent Technologies +Copyright (c) 2008-2016, Wojciech Mula +Copyright (c) 2011-2020 Microsoft Corp Copyright (c) 2015-2017, Wojciech Mula +Copyright (c) 2021 csFastFloat authors Copyright (c) 2005-2007, Nick Galbreath +Copyright (c) 2015 The Chromium Authors Copyright (c) 2018 Alexander Chermyanin +Copyright (c) The Internet Society 1997 Portions (c) International Organization -Copyright (c) 2015 The Chromium Authors. -Copyright (c) The Internet Society 1997. Copyright (c) 2004-2006 Intel Corporation +Copyright (c) 2011-2015 Intel Corporation Copyright (c) 2013-2017, Milosz Krajewski Copyright (c) 2016-2017, Matthieu Darbois +Copyright (c) The Internet Society (2003) Copyright (c) .NET Foundation Contributors -Copyright (c) The Internet Society (2003). +Copyright (c) 2020 Mara Bos Copyright (c) .NET Foundation and Contributors +Copyright (c) 2012 - present, Victor Zverovich +Copyright (c) 2006 Jb Evain (jbevain@gmail.com) +Copyright (c) 2008-2020 Advanced Micro Devices, Inc. +Copyright (c) 2019 Microsoft Corporation, Daan Leijen Copyright (c) 2011 Novell, Inc (http://www.novell.com) -Copyright (c) 1995-2017 Jean-loup Gailly and Mark Adler +Copyright (c) 1995-2022 Jean-loup Gailly and Mark Adler Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com) -Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors. +Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc. -Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip. -Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers THIS WORK IS PROVIDED AS -Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California. -Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass. -Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass. To +Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers +Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip +Copyright (c) 1980, 1986, 1993 The Regents of the University of California +Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California +Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass The MIT License (MIT) @@ -345,7 +242,7 @@ SOFTWARE. --------------------------------------------------------- -Microsoft.CodeAnalysis.Common 4.8.0 - MIT +Microsoft.CodeAnalysis.Common 4.9.2 - MIT (c) Microsoft Corporation @@ -365,7 +262,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI --------------------------------------------------------- -Microsoft.CodeAnalysis.CSharp 4.8.0 - MIT +Microsoft.CodeAnalysis.CSharp 4.9.2 - MIT (c) Microsoft Corporation @@ -387,6 +284,56 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI --------------------------------------------------------- +Microsoft.Extensions.ObjectPool 8.0.4 - MIT + + +Copyright 2019 The gRPC +Copyright Jorn Zaefferer +(c) Microsoft Corporation +Copyright (c) Andrew Arnott +Copyright (c) 2015, Google Inc. +Copyright (c) 2019 David Fowler +Copyright (c) HTML5 Boilerplate +Copyright (c) 2016 Richard Morris +Copyright (c) 1998 John D. Polstra +Copyright (c) 2017 Yoshifumi Kawai +Copyright (c) Microsoft Corporation +Copyright (c) 2007 James Newton-King +Copyright (c) 2013 - 2018 AngleSharp +Copyright (c) 2000-2013 Julian Seward +Copyright (c) 2011-2021 Twitter, Inc. +Copyright (c) 2014-2018 Michael Daines +Copyright (c) 1996-1998 John D. Polstra +Copyright (c) 2013-2017, Milosz Krajewski +Copyright (c) .NET Foundation Contributors +Copyright (c) 2011-2021 The Bootstrap Authors +Copyright (c) 2019-2023 The Bootstrap Authors +Copyright (c) .NET Foundation and Contributors +Copyright (c) 2019-2020 West Wind Technologies +Copyright (c) 2007 John Birrell (jb@freebsd.org) +Copyright (c) 2011 Alex MacCaw (info@eribium.org) +Copyright (c) Nicolas Gallagher and Jonathan Neal +Copyright (c) 2010-2019 Google LLC. http://angular.io/license +Copyright (c) 2011 Nicolas Gallagher (nicolas@nicolasgallagher.com) +Copyright (c) 1989, 1993 The Regents of the University of California +Copyright (c) 1990, 1993 The Regents of the University of California +Copyright OpenJS Foundation and other contributors, https://openjsf.org +Copyright (c) Sindre Sorhus (https://sindresorhus.com) + +MIT License + +Copyright (c) + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +--------------------------------------------------------- + +--------------------------------------------------------- + Microsoft.PowerShell.MarkdownRender 7.2.1 - MIT @@ -652,7 +599,7 @@ SOFTWARE. --------------------------------------------------------- -Microsoft.Windows.Compatibility 8.0.2 - MIT +Microsoft.Windows.Compatibility 8.0.8 - MIT (c) Microsoft Corporation @@ -705,7 +652,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. --------------------------------------------------------- -runtime.android-arm.runtime.native.System.IO.Ports 9.0.0-preview.1.24080.9 - MIT +runtime.android-arm.runtime.native.System.IO.Ports 9.0.0-preview.3.24172.9 - MIT Copyright (c) Six Labors @@ -794,7 +741,7 @@ SOFTWARE. --------------------------------------------------------- -runtime.android-arm64.runtime.native.System.IO.Ports 9.0.0-preview.1.24080.9 - MIT +runtime.android-arm64.runtime.native.System.IO.Ports 9.0.0-preview.3.24172.9 - MIT Copyright (c) Six Labors @@ -883,7 +830,7 @@ SOFTWARE. --------------------------------------------------------- -runtime.android-x64.runtime.native.System.IO.Ports 9.0.0-preview.1.24080.9 - MIT +runtime.android-x64.runtime.native.System.IO.Ports 9.0.0-preview.3.24172.9 - MIT Copyright (c) Six Labors @@ -972,7 +919,7 @@ SOFTWARE. --------------------------------------------------------- -runtime.android-x86.runtime.native.System.IO.Ports 9.0.0-preview.1.24080.9 - MIT +runtime.android-x86.runtime.native.System.IO.Ports 9.0.0-preview.3.24172.9 - MIT Copyright (c) Six Labors @@ -1233,7 +1180,7 @@ SOFTWARE. --------------------------------------------------------- -runtime.linux-bionic-arm64.runtime.native.System.IO.Ports 9.0.0-preview.1.24080.9 - MIT +runtime.linux-bionic-arm64.runtime.native.System.IO.Ports 9.0.0-preview.3.24172.9 - MIT Copyright (c) Six Labors @@ -1322,7 +1269,7 @@ SOFTWARE. --------------------------------------------------------- -runtime.linux-bionic-x64.runtime.native.System.IO.Ports 9.0.0-preview.1.24080.9 - MIT +runtime.linux-bionic-x64.runtime.native.System.IO.Ports 9.0.0-preview.3.24172.9 - MIT Copyright (c) Six Labors @@ -1411,7 +1358,7 @@ SOFTWARE. --------------------------------------------------------- -runtime.linux-musl-arm.runtime.native.System.IO.Ports 9.0.0-preview.1.24080.9 - MIT +runtime.linux-musl-arm.runtime.native.System.IO.Ports 9.0.0-preview.3.24172.9 - MIT Copyright (c) Six Labors @@ -1500,7 +1447,7 @@ SOFTWARE. --------------------------------------------------------- -runtime.linux-musl-arm64.runtime.native.System.IO.Ports 9.0.0-preview.1.24080.9 - MIT +runtime.linux-musl-arm64.runtime.native.System.IO.Ports 9.0.0-preview.3.24172.9 - MIT Copyright (c) Six Labors @@ -1589,7 +1536,7 @@ SOFTWARE. --------------------------------------------------------- -runtime.linux-musl-x64.runtime.native.System.IO.Ports 9.0.0-preview.1.24080.9 - MIT +runtime.linux-musl-x64.runtime.native.System.IO.Ports 9.0.0-preview.3.24172.9 - MIT Copyright (c) Six Labors @@ -1764,7 +1711,7 @@ SOFTWARE. --------------------------------------------------------- -runtime.maccatalyst-arm64.runtime.native.System.IO.Ports 9.0.0-preview.1.24080.9 - MIT +runtime.maccatalyst-arm64.runtime.native.System.IO.Ports 9.0.0-preview.3.24172.9 - MIT Copyright (c) Six Labors @@ -1853,7 +1800,7 @@ SOFTWARE. --------------------------------------------------------- -runtime.maccatalyst-x64.runtime.native.System.IO.Ports 9.0.0-preview.1.24080.9 - MIT +runtime.maccatalyst-x64.runtime.native.System.IO.Ports 9.0.0-preview.3.24172.9 - MIT Copyright (c) Six Labors @@ -2908,7 +2855,7 @@ SOFTWARE. --------------------------------------------------------- -System.Diagnostics.DiagnosticSource 8.0.0 - MIT +System.Diagnostics.DiagnosticSource 8.0.1 - MIT Copyright (c) Six Labors @@ -3424,7 +3371,7 @@ SOFTWARE. --------------------------------------------------------- -System.Drawing.Common 8.0.2 - MIT +System.Drawing.Common 8.0.8 - MIT (c) Microsoft Corporation @@ -3459,7 +3406,7 @@ SOFTWARE. --------------------------------------------------------- -System.Formats.Asn1 8.0.0 - MIT +System.Formats.Asn1 8.0.1 - MIT Copyright (c) Six Labors @@ -3803,7 +3750,7 @@ SOFTWARE. --------------------------------------------------------- -System.Net.Http.WinHttpHandler 8.0.0 - MIT +System.Net.Http.WinHttpHandler 8.0.2 - MIT Copyright (c) Six Labors @@ -4360,45 +4307,50 @@ SOFTWARE. --------------------------------------------------------- -System.Security.AccessControl 6.0.0 - MIT +System.Security.AccessControl 6.0.1 - MIT -(c) Microsoft Corporation. +(c) Microsoft Corporation Copyright (c) Andrew Arnott +Copyright 2019 LLVM Project Copyright 2018 Daniel Lemire -Copyright 2012 the V8 project -Copyright (c) .NET Foundation. +Copyright (c) .NET Foundation Copyright (c) 2011, Google Inc. +Copyright (c) 2020 Dan Shechter +(c) 1997-2005 Sean Eron Anderson Copyright (c) 1998 Microsoft. To -(c) 1997-2005 Sean Eron Anderson. Copyright (c) 2017 Yoshifumi Kawai +Copyright (c) 2005-2020 Rich Felker Copyright (c) Microsoft Corporation Copyright (c) 2007 James Newton-King Copyright (c) 2012-2014, Yann Collet +Copyright (c) 1991-2020 Unicode, Inc. Copyright (c) 2013-2017, Alfred Klomp +Copyright 2012 the V8 project authors +Copyright (c) 2011-2020 Microsoft Corp Copyright (c) 2015-2017, Wojciech Mula Copyright (c) 2005-2007, Nick Galbreath +Copyright (c) 2015 The Chromium Authors Copyright (c) 2018 Alexander Chermyanin +Copyright (c) The Internet Society 1997 Portions (c) International Organization -Copyright (c) 2015 The Chromium Authors. -Copyright (c) The Internet Society 1997. Copyright (c) 2004-2006 Intel Corporation Copyright (c) 2013-2017, Milosz Krajewski Copyright (c) 2016-2017, Matthieu Darbois +Copyright (c) The Internet Society (2003) Copyright (c) .NET Foundation Contributors -Copyright (c) The Internet Society (2003). Copyright (c) .NET Foundation and Contributors Copyright (c) 2019 Microsoft Corporation, Daan Leijen Copyright (c) 2011 Novell, Inc (http://www.novell.com) -Copyright (c) 1995-2017 Jean-loup Gailly and Mark Adler +Copyright (c) 1995-2022 Jean-loup Gailly and Mark Adler Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com) -Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors. +Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc. -Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip. -Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers THIS WORK IS PROVIDED AS -Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California. -Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass. +Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers +Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip +Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California +Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass. To The MIT License (MIT) @@ -4602,7 +4554,7 @@ SOFTWARE. --------------------------------------------------------- -System.Security.Cryptography.Xml 8.0.0 - MIT +System.Security.Cryptography.Xml 8.0.1 - MIT Copyright (c) Six Labors @@ -5795,4 +5747,3 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - From 22285f5c423e7f3d8a243b786e93c9de7a20dc8e Mon Sep 17 00:00:00 2001 From: Patrick Meinecke Date: Wed, 21 Aug 2024 18:22:22 +0000 Subject: [PATCH 002/173] Merged PR 32244: Fix Validate SDK step by removing unncessary nuget file modification #### AI description (iteration 1) #### PR Classification Bug fix to remove unnecessary NuGet file modification in the Validate SDK step. #### PR Summary This pull request removes redundant modifications to the NuGet configuration file in the release validation pipeline. - `.pipelines/templates/release-validate-sdk.yml`: Commented out the code that modifies the NuGet configuration file to prevent unnecessary changes. --- .pipelines/templates/release-validate-sdk.yml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/.pipelines/templates/release-validate-sdk.yml b/.pipelines/templates/release-validate-sdk.yml index 4903f78d57f..3cd5425478e 100644 --- a/.pipelines/templates/release-validate-sdk.yml +++ b/.pipelines/templates/release-validate-sdk.yml @@ -87,11 +87,11 @@ jobs: Start-PSBootstrap $localLocation = "$(Pipeline.Workspace)/PSPackagesOfficial/drop_nupkg_build_nupkg" - $xmlElement = @" - - - - "@ + # $xmlElement = @" + # + # + # + # "@ $releaseVersion = '$(Version)' @@ -102,12 +102,12 @@ jobs: Get-ChildItem ## register the packages download directory in the nuget file - $nugetConfigContent = Get-Content ./NuGet.Config -Raw - $updateNugetContent = $nugetConfigContent.Replace("", $xmlElement) + # $nugetConfigContent = Get-Content ./NuGet.Config -Raw + # $updateNugetContent = $nugetConfigContent.Replace("", $xmlElement) - $updateNugetContent | Out-File ./NuGet.Config -Encoding ascii + # $updateNugetContent | Out-File ./NuGet.Config -Encoding ascii - Get-Content ./NuGet.Config + # Get-Content ./NuGet.Config # Add workaround to unblock xUnit testing see issue: https://github.com/dotnet/sdk/issues/26462 $dotnetPath = if ($IsWindows) { "$env:LocalAppData\Microsoft\dotnet" } else { "$env:HOME/.dotnet" } From 6695ffb6a80038753c8a8bec65eba7f760609d81 Mon Sep 17 00:00:00 2001 From: Patrick Meinecke Date: Wed, 21 Aug 2024 19:30:56 +0000 Subject: [PATCH 003/173] Merged PR 32255: Add `PSRedirectToVariable` to experimental features json file #### AI description (iteration 1) #### PR Classification New feature #### PR Summary This pull request adds a new experimental feature to the configuration files for both Linux and Windows platforms. - `experimental-feature-linux.json`: Added `PSRedirectToVariable` to the list of experimental features. - `experimental-feature-windows.json`: Added `PSRedirectToVariable` to the list of experimental features. --- experimental-feature-linux.json | 3 ++- experimental-feature-windows.json | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/experimental-feature-linux.json b/experimental-feature-linux.json index 291d28159e4..b5af1955d29 100644 --- a/experimental-feature-linux.json +++ b/experimental-feature-linux.json @@ -5,5 +5,6 @@ "PSLoadAssemblyFromNativeCode", "PSModuleAutoLoadSkipOfflineFiles", "PSNativeWindowsTildeExpansion", - "PSSubsystemPluginModel" + "PSSubsystemPluginModel", + "PSRedirectToVariable" ] diff --git a/experimental-feature-windows.json b/experimental-feature-windows.json index 291d28159e4..b5af1955d29 100644 --- a/experimental-feature-windows.json +++ b/experimental-feature-windows.json @@ -5,5 +5,6 @@ "PSLoadAssemblyFromNativeCode", "PSModuleAutoLoadSkipOfflineFiles", "PSNativeWindowsTildeExpansion", - "PSSubsystemPluginModel" + "PSSubsystemPluginModel", + "PSRedirectToVariable" ] From e00157e7aa439e3a14aff9f76b560154af55a24d Mon Sep 17 00:00:00 2001 From: Patrick Meinecke Date: Wed, 28 Aug 2024 18:24:04 +0000 Subject: [PATCH 004/173] Merged PR 32242: Update CHANGELOG for v7.5.0-preview.4 release #### AI description (iteration 1) #### PR Classification Documentation update for the v7.5.0-preview.4 release. #### PR Summary This pull request updates the changelog to document the changes and improvements introduced in the v7.5.0-preview.4 release. - `CHANGELOG/preview.md`: Added entries for engine updates, general cmdlet updates, code cleanup, tools, tests, build and packaging improvements, and documentation updates. --- CHANGELOG/preview.md | 119 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 119 insertions(+) diff --git a/CHANGELOG/preview.md b/CHANGELOG/preview.md index 444b58e5b9e..73d39ba122a 100644 --- a/CHANGELOG/preview.md +++ b/CHANGELOG/preview.md @@ -1,5 +1,124 @@ # Preview Changelog +## [7.5.0-preview.4] - 2024-08-28 + +### Engine Updates and Fixes + +- RecommendedAction: Explicitly start and stop ANSI Error Color (#24065) (Thanks @JustinGrote!) +- Improve .NET overload definition of generic methods (#21326) (Thanks @jborean93!) +- Optimize the `+=` operation for a collection when it's an object array (#23901) (Thanks @jborean93!) +- Allow redirecting to a variable as experimental feature `PSRedirectToVariable` (#20381) + +### General Cmdlet Updates and Fixes + +- Change type of `LineNumber` to `ulong` in `Select-String` (#24075) (Thanks @Snowman-25!) +- Fix `Invoke-RestMethod` to allow `-PassThru` and `-Outfile` work together (#24086) (Thanks @jshigetomi!) +- Fix Hyper-V Remoting when the module is imported via implicit remoting (#24032) (Thanks @jborean93!) +- Add `ConvertTo-CliXml` and `ConvertFrom-CliXml` cmdlets (#21063) (Thanks @ArmaanMcleod!) +- Add `OutFile` property in `WebResponseObject` (#24047) (Thanks @jshigetomi!) +- Show filename in `Invoke-WebRequest -OutFile -Verbose` (#24041) (Thanks @jshigetomi!) +- `Set-Acl`: Do not fail on untranslatable SID (#21096) (Thanks @jborean93!) +- Fix the extent of the parser error when a number constant is invalid (#24024) +- Fix `Move-Item` to throw error when moving into itself (#24004) +- Fix up .NET method invocation with `Optional` argument (#21387) (Thanks @jborean93!) +- Fix progress calculation on `Remove-Item` (#23869) (Thanks @jborean93!) +- Fix WebCmdlets when `-Body` is specified but `ContentType` is not (#23952) (Thanks @CarloToso!) +- Enable `-NoRestart` to work with `Register-PSSessionConfiguration` (#23891) +- Add `IgnoreComments` and `AllowTrailingCommas` options to `Test-Json` cmdlet (#23817) (Thanks @ArmaanMcleod!) +- Get-Help may report parameters with `ValueFromRemainingArguments` attribute as pipeline-able (#23871) + +### Code Cleanup + +
+ + + +

We thank the following contributors!

+

@xtqqczze, @eltociear

+ +
+ +
    +
  • Minor cleanup on local variable names within a method (#24105)
  • +
  • Remove explicit IDE1005 suppressions (#21217) (Thanks @xtqqczze!)
  • +
  • Fix a typo in WebRequestSession.cs (#23963) (Thanks @eltociear!)
  • +
+ +
+ +### Tools + +- devcontainers: mount workspace in /PowerShell (#23857) (Thanks @rzippo!) + +### Tests + +- Add debugging to the MTU size test (#21463) + +### Build and Packaging Improvements + +
+ + + +

We thank the following contributors!

+

@bosesubham2011

+ +
+ +
    +
  • Update third party notices (Internal 32128)
  • +
  • Update cgmanifest (#24163)
  • +
  • Fixes to Azure Public feed usage (#24149)
  • +
  • Add support for back porting PRs from GitHub or the Private Azure Repos (#20670)
  • +
  • Move to 9.0.0-preview.6.24327.7 (#24133)
  • +
  • update path (#24134)
  • +
  • Update to the latest NOTICES file (#24131)
  • +
  • Fix semver issue with updating cgmanifest (#24132)
  • +
  • Add ability to capture MSBuild Binary logs when restore fails (#24128)
  • +
  • add ability to skip windows stage (#24116)
  • +
  • chore: Refactor Nuget package source creation to use New-NugetPackageSource function (#24104)
  • +
  • Make Microsoft feeds the default (#24098)
  • +
  • Cleanup unused csproj (#23951)
  • +
  • Add script to update SDK version during release (#24034)
  • +
  • Enumerate over all signed zip packages (#24063)
  • +
  • Update metadata.json for PowerShell July releases (#24082)
  • +
  • Add macos signing for package files (#24015)
  • +
  • Update install-powershell.sh to support azure-linux (#23955) (Thanks @bosesubham2011!)
  • +
  • Skip build steps that do not have exe packages (#23945)
  • +
  • Update metadata.json for PowerShell June releases (#23973)
  • +
  • Create powershell.config.json for PowerShell.Windows.x64 global tool (#23941)
  • +
  • Fix error in the vPack release, debug script that blocked release (#23904)
  • +
  • Add vPack release (#23898)
  • +
  • Fix exe signing with third party signing for WiX engine (#23878)
  • +
  • Update wix installation in CI (#23870)
  • +
  • Add checkout to fix TSA config paths (#23865)
  • +
  • Merge the v7.5.0-preview.3 release branch to GitHub master branch
  • +
  • Update metadata.json for the v7.5.0-preview.3 release (#23862)
  • +
  • Bump PSResourceGet to 1.1.0-preview1 (#24129)
  • +
  • Bump github/codeql-action from 3.25.8 to 3.26.0 (#23953) (#23999) (#24053) (#24069) (#24095) (#24118)
  • +
  • Bump actions/upload-artifact from 4.3.3 to 4.3.6 (#24019) (#24113) (#24119)
  • +
  • Bump agrc/create-reminder-action from 1.1.13 to 1.1.15 (#24029) (#24043)
  • +
  • Bump agrc/reminder-action from 1.0.12 to 1.0.14 (#24028) (#24042)
  • +
  • Bump super-linter/super-linter from 5.7.2 to 6.8.0 (#23809) (#23856) (#23894) (#24030) (#24103)
  • +
  • Bump ossf/scorecard-action from 2.3.1 to 2.4.0 (#23802) (#24096)
  • +
  • Bump actions/dependency-review-action from 4.3.2 to 4.3.4 (#23897) (#24046)
  • +
  • Bump actions/checkout from 4.1.5 to 4.1.7 (#23813) (#23947)
  • +
  • Bump github/codeql-action from 3.25.4 to 3.25.8 (#23801) (#23893)
  • +
+ +
+ +### Documentation and Help Content + +- Update docs sample nuget.config (#24109) +- Update Code of Conduct and Security Policy (#23811) +- Update working-group-definitions.md for the Security WG (#23884) +- Fix up broken links in Markdown files (#23863) +- Update Engine Working Group Members (#23803) (Thanks @kilasuit!) +- Remove outdated and contradictory information from `README` (#23812) + +[7.5.0-preview.4]: https://github.com/PowerShell/PowerShell/compare/v7.5.0-preview.3...v7.5.0-preview.4 + ## [7.5.0-preview.3] - 2024-05-16 ### Breaking Changes From 792945e63781ae6103d58367d483fd7d9efeef8b Mon Sep 17 00:00:00 2001 From: Aditya Patwardhan Date: Fri, 20 Sep 2024 12:36:08 -0700 Subject: [PATCH 005/173] Check `Create and Submit` in vPack build by default (#24181) (#24305) --- .pipelines/PowerShell-vPack-Official.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pipelines/PowerShell-vPack-Official.yml b/.pipelines/PowerShell-vPack-Official.yml index b9444497614..bb780a6f203 100644 --- a/.pipelines/PowerShell-vPack-Official.yml +++ b/.pipelines/PowerShell-vPack-Official.yml @@ -6,7 +6,7 @@ parameters: # parameters are shown up in ADO UI in a build queue time - name: 'createVPack' displayName: 'Create and Submit VPack' type: boolean - default: false + default: true - name: 'debug' displayName: 'Enable debug output' type: boolean From f0461bc00f673ac20c2531d3006813ba692e7ba1 Mon Sep 17 00:00:00 2001 From: Aditya Patwardhan Date: Fri, 20 Sep 2024 12:36:49 -0700 Subject: [PATCH 006/173] Add windows signing for pwsh.exe (#24219) (#24306) --- .pipelines/templates/obp-file-signing.yml | 25 +++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/.pipelines/templates/obp-file-signing.yml b/.pipelines/templates/obp-file-signing.yml index ba761633b29..7ed973ddf5a 100644 --- a/.pipelines/templates/obp-file-signing.yml +++ b/.pipelines/templates/obp-file-signing.yml @@ -84,6 +84,31 @@ steps: files_to_sign: '**\*.psd1;**\*.psm1;**\*.ps1xml;**\*.ps1;**\*.dll;**\*.exe;**\pwsh' search_root: $(Pipeline.Workspace)/toBeSigned +- task: onebranch.pipeline.signing@1 + displayName: Sign pwsh.exe with Windows cert + inputs: + command: 'sign' + cp_code: '203' + files_to_sign: '**\pwsh.exe' + search_root: $(Pipeline.Workspace)/toBeSigned + +- pwsh: | + if (Test-Path $(Pipeline.Workspace)/toBeSigned/pwsh.exe) { + Write-Verbose -Verbose "pwsh.exe is found, verifying signature" + $signature = Get-AuthenticodeSignature -FilePath $(Pipeline.Workspace)/toBeSigned/pwsh.exe + if ($signature.SignerCertificate.Issuer -notmatch '^CN=Microsoft Windows Production.*') { + Write-Error -ErrorAction Stop "pwsh.exe is not signed by Microsoft" + } + else { + Write-Verbose -Verbose "pwsh.exe is signed by Microsoft" + } + } + else { + Write-Verbose -Verbose "pwsh.exe is not found, skipping" + } + + displayName: 'Verify windows signature' + - pwsh : | Get-ChildItem -Path env: displayName: Capture environment From a095a054b097f703a90a7d70c0d175701d7978d8 Mon Sep 17 00:00:00 2001 From: Aditya Patwardhan Date: Fri, 20 Sep 2024 12:37:16 -0700 Subject: [PATCH 007/173] Handle global tool specially when prepending `PSHome` to `PATH` (#24228) (#24307) --- .../host/msh/ConsoleHost.cs | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleHost.cs b/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleHost.cs index 3a9ab8e7f45..8cc7ee00f57 100644 --- a/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleHost.cs +++ b/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleHost.cs @@ -123,11 +123,23 @@ internal static int Start( throw new ConsoleHostStartupException(ConsoleHostStrings.ShellCannotBeStartedWithConfigConflict); } - // put PSHOME in front of PATH so that calling `powershell` within `powershell` always starts the same running version + // Put PSHOME in front of PATH so that calling `pwsh` within `pwsh` always starts the same running version. string path = Environment.GetEnvironmentVariable("PATH"); - string pshome = Utils.DefaultPowerShellAppBase + Path.PathSeparator; + string pshome = Utils.DefaultPowerShellAppBase; + string dotnetToolsPathSegment = $"{Path.DirectorySeparatorChar}.store{Path.DirectorySeparatorChar}powershell{Path.DirectorySeparatorChar}"; - // to not impact startup perf, we don't remove duplicates, but we avoid adding a duplicate to the front + int index = pshome.IndexOf(dotnetToolsPathSegment, StringComparison.Ordinal); + if (index > 0) + { + // We're running PowerShell global tool. In this case the real entry executable should be the 'pwsh' + // or 'pwsh.exe' within the tool folder which should be the path right before the '\.store', not what + // PSHome is pointing to. + pshome = pshome[0..index]; + } + + pshome += Path.PathSeparator; + + // To not impact startup perf, we don't remove duplicates, but we avoid adding a duplicate to the front // we also don't handle the edge case where PATH only contains $PSHOME if (string.IsNullOrEmpty(path)) { From 068f524bfccd53d00b837bf00b4311e6593d8a3f Mon Sep 17 00:00:00 2001 From: Aditya Patwardhan Date: Fri, 20 Sep 2024 12:37:35 -0700 Subject: [PATCH 008/173] Use Managed Identity for APIScan authentication (#24243) (#24308) --- tools/releaseBuild/azureDevOps/templates/compliance/apiscan.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/releaseBuild/azureDevOps/templates/compliance/apiscan.yml b/tools/releaseBuild/azureDevOps/templates/compliance/apiscan.yml index 585b640d48f..1b4f9067266 100644 --- a/tools/releaseBuild/azureDevOps/templates/compliance/apiscan.yml +++ b/tools/releaseBuild/azureDevOps/templates/compliance/apiscan.yml @@ -148,7 +148,7 @@ jobs: # write a status update every 5 minutes. Default is 1 minute statusUpdateInterval: '00:05:00' env: - AzureServicesAuthConnectionString: RunAs=App;AppId=$(APIScanClient);TenantId=$(APIScanTenant);AppKey=$(APIScanSecret) + AzureServicesAuthConnectionString: RunAs=App - task: securedevelopmentteam.vss-secure-development-tools.build-task-report.SdtReport@2 continueOnError: true From fa6f09f59a5e244cc08b8f6e67910e012b497f91 Mon Sep 17 00:00:00 2001 From: Aditya Patwardhan Date: Fri, 20 Sep 2024 12:37:57 -0700 Subject: [PATCH 009/173] Add specific path for issues in tsaconfig (#24244) (#24309) Co-authored-by: Travis Plunk --- .config/tsaoptions.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.config/tsaoptions.json b/.config/tsaoptions.json index bd2a6a00984..7552bd7226c 100644 --- a/.config/tsaoptions.json +++ b/.config/tsaoptions.json @@ -1,7 +1,7 @@ { "instanceUrl": "https://msazure.visualstudio.com", "projectName": "One", - "areaPath": "One\\MGMT\\Compute\\Powershell\\Powershell\\PowerShell Core", + "areaPath": "One\\MGMT\\Compute\\Powershell\\Powershell\\PowerShell Core\\pwsh", "notificationAliases": [ "adityap@microsoft.com", "dongbow@microsoft.com", From 099ed06fbf6311cf4dd3ae68e5643960a11b3f38 Mon Sep 17 00:00:00 2001 From: Aditya Patwardhan Date: Fri, 20 Sep 2024 12:38:25 -0700 Subject: [PATCH 010/173] Make features `PSCommandNotFoundSuggestion`, `PSCommandWithArgs`, and `PSModuleAutoLoadSkipOfflineFiles` stable (#24246) (#24310) Co-authored-by: Steve Lee --- .../ExperimentalFeature.cs | 11 ------ .../engine/Modules/ModuleUtils.cs | 17 ++++----- .../FeedbackSubsystem/IFeedbackProvider.cs | 35 +++++++++---------- .../engine/hostifaces/HostUtilities.cs | 21 +++++------ 4 files changed, 31 insertions(+), 53 deletions(-) diff --git a/src/System.Management.Automation/engine/ExperimentalFeature/ExperimentalFeature.cs b/src/System.Management.Automation/engine/ExperimentalFeature/ExperimentalFeature.cs index 176089d29cf..7e358e94e94 100644 --- a/src/System.Management.Automation/engine/ExperimentalFeature/ExperimentalFeature.cs +++ b/src/System.Management.Automation/engine/ExperimentalFeature/ExperimentalFeature.cs @@ -21,9 +21,7 @@ public class ExperimentalFeature #region Const Members internal const string EngineSource = "PSEngine"; - internal const string PSModuleAutoLoadSkipOfflineFilesFeatureName = "PSModuleAutoLoadSkipOfflineFiles"; internal const string PSFeedbackProvider = "PSFeedbackProvider"; - internal const string PSCommandWithArgs = "PSCommandWithArgs"; internal const string PSNativeWindowsTildeExpansion = nameof(PSNativeWindowsTildeExpansion); internal const string PSRedirectToVariable = "PSRedirectToVariable"; @@ -108,24 +106,15 @@ static ExperimentalFeature() name: "PSFileSystemProviderV2", description: "Replace the old FileSystemProvider with cleaner design and faster code"), */ - new ExperimentalFeature( - name: "PSCommandNotFoundSuggestion", - description: "Recommend potential commands based on fuzzy search on a CommandNotFoundException"), new ExperimentalFeature( name: "PSSubsystemPluginModel", description: "A plugin model for registering and un-registering PowerShell subsystems"), new ExperimentalFeature( name: "PSLoadAssemblyFromNativeCode", description: "Expose an API to allow assembly loading from native code"), - new ExperimentalFeature( - name: PSModuleAutoLoadSkipOfflineFilesFeatureName, - description: "Module discovery will skip over files that are marked by cloud providers as not fully on disk."), new ExperimentalFeature( name: PSFeedbackProvider, description: "Replace the hard-coded suggestion framework with the extensible feedback provider"), - new ExperimentalFeature( - name: PSCommandWithArgs, - description: "Enable `-CommandWithArgs` parameter for pwsh"), new ExperimentalFeature( name: PSNativeWindowsTildeExpansion, description: "On windows, expand unquoted tilde (`~`) with the user's current home folder."), diff --git a/src/System.Management.Automation/engine/Modules/ModuleUtils.cs b/src/System.Management.Automation/engine/Modules/ModuleUtils.cs index d8e2b24e016..f58f51dfd37 100644 --- a/src/System.Management.Automation/engine/Modules/ModuleUtils.cs +++ b/src/System.Management.Automation/engine/Modules/ModuleUtils.cs @@ -39,18 +39,13 @@ internal static class ModuleUtils static ModuleUtils() { - if (ExperimentalFeature.IsEnabled(ExperimentalFeature.PSModuleAutoLoadSkipOfflineFilesFeatureName)) - { - FileAttributesToSkip = FileAttributes.Hidden - // Skip OneDrive files/directories that are not fully on disk. - | FileAttributes.Offline - | (FileAttributes)FILE_ATTRIBUTE_RECALL_ON_DATA_ACCESS - | (FileAttributes)FILE_ATTRIBUTE_RECALL_ON_OPEN; - - return; - } + FileAttributesToSkip = FileAttributes.Hidden + // Skip OneDrive files/directories that are not fully on disk. + | FileAttributes.Offline + | (FileAttributes)FILE_ATTRIBUTE_RECALL_ON_DATA_ACCESS + | (FileAttributes)FILE_ATTRIBUTE_RECALL_ON_OPEN; - FileAttributesToSkip = FileAttributes.Hidden; + return; } /// diff --git a/src/System.Management.Automation/engine/Subsystem/FeedbackSubsystem/IFeedbackProvider.cs b/src/System.Management.Automation/engine/Subsystem/FeedbackSubsystem/IFeedbackProvider.cs index 1446983f791..aba105c8faa 100644 --- a/src/System.Management.Automation/engine/Subsystem/FeedbackSubsystem/IFeedbackProvider.cs +++ b/src/System.Management.Automation/engine/Subsystem/FeedbackSubsystem/IFeedbackProvider.cs @@ -276,26 +276,23 @@ internal GeneralCommandErrorFeedback() } // Check fuzzy matching command names. - if (ExperimentalFeature.IsEnabled("PSCommandNotFoundSuggestion")) + var pwsh = PowerShell.Create(RunspaceMode.CurrentRunspace); + var results = pwsh.AddCommand("Get-Command") + .AddParameter("UseFuzzyMatching") + .AddParameter("FuzzyMinimumDistance", 1) + .AddParameter("Name", target) + .AddCommand("Select-Object") + .AddParameter("First", 5) + .AddParameter("Unique") + .AddParameter("ExpandProperty", "Name") + .Invoke(); + + if (results.Count > 0) { - var pwsh = PowerShell.Create(RunspaceMode.CurrentRunspace); - var results = pwsh.AddCommand("Get-Command") - .AddParameter("UseFuzzyMatching") - .AddParameter("FuzzyMinimumDistance", 1) - .AddParameter("Name", target) - .AddCommand("Select-Object") - .AddParameter("First", 5) - .AddParameter("Unique") - .AddParameter("ExpandProperty", "Name") - .Invoke(); - - if (results.Count > 0) - { - return new FeedbackItem( - SuggestionStrings.Suggestion_CommandNotFound, - new List(results), - FeedbackDisplayLayout.Landscape); - } + return new FeedbackItem( + SuggestionStrings.Suggestion_CommandNotFound, + new List(results), + FeedbackDisplayLayout.Landscape); } return null; diff --git a/src/System.Management.Automation/engine/hostifaces/HostUtilities.cs b/src/System.Management.Automation/engine/hostifaces/HostUtilities.cs index 4398269842b..9e5612189fa 100644 --- a/src/System.Management.Automation/engine/hostifaces/HostUtilities.cs +++ b/src/System.Management.Automation/engine/hostifaces/HostUtilities.cs @@ -110,18 +110,15 @@ private static List InitializeSuggestions() enabled: true) }); - if (ExperimentalFeature.IsEnabled("PSCommandNotFoundSuggestion")) - { - suggestions.Add( - NewSuggestion( - id: 4, - category: "General", - matchType: SuggestionMatchType.ErrorId, - rule: "CommandNotFoundException", - suggestion: ScriptBlock.CreateDelayParsedScriptBlock(s_getFuzzyMatchedCommands, isProductCode: true), - suggestionArgs: new object[] { CodeGeneration.EscapeSingleQuotedStringContent(SuggestionStrings.Suggestion_CommandNotFound) }, - enabled: true)); - } + suggestions.Add( + NewSuggestion( + id: 4, + category: "General", + matchType: SuggestionMatchType.ErrorId, + rule: "CommandNotFoundException", + suggestion: ScriptBlock.CreateDelayParsedScriptBlock(s_getFuzzyMatchedCommands, isProductCode: true), + suggestionArgs: new object[] { CodeGeneration.EscapeSingleQuotedStringContent(SuggestionStrings.Suggestion_CommandNotFound) }, + enabled: true)); return suggestions; } From a82b7972f2177020a6c9de524515fa71d6ce124e Mon Sep 17 00:00:00 2001 From: Aditya Patwardhan Date: Fri, 20 Sep 2024 12:40:04 -0700 Subject: [PATCH 011/173] Create new pipeline for compliance (#24252) (#24312) --- .pipelines/apiscan-gen-notice.yml | 79 ++++++++ .pipelines/templates/compliance/apiscan.yml | 181 ++++++++++++++++++ .../templates/compliance/generateNotice.yml | 154 +++++++++++++++ 3 files changed, 414 insertions(+) create mode 100644 .pipelines/apiscan-gen-notice.yml create mode 100644 .pipelines/templates/compliance/apiscan.yml create mode 100644 .pipelines/templates/compliance/generateNotice.yml diff --git a/.pipelines/apiscan-gen-notice.yml b/.pipelines/apiscan-gen-notice.yml new file mode 100644 index 00000000000..02ab4ba3796 --- /dev/null +++ b/.pipelines/apiscan-gen-notice.yml @@ -0,0 +1,79 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + +trigger: none + +variables: + - name: ob_outputDirectory + value: '$(Build.ArtifactStagingDirectory)/ONEBRANCH_ARTIFACT' + - name: CDP_DEFINITION_BUILD_COUNT + value: $[counter('', 0)] + # Defines the variables AzureFileCopySubscription, StorageAccount, StorageAccountKey, StorageResourceGroup, StorageSubscriptionName + - group: 'Azure Blob variable group' + # Defines the variables CgPat, CgOrganization, and CgProject + - group: 'ComponentGovernance' + - group: 'PoolNames' + - name: LinuxContainerImage + value: onebranch.azurecr.io/linux/ubuntu-2004:latest + - name: WindowsContainerImage + value: onebranch.azurecr.io/windows/ltsc2022/vse2022:latest + +resources: + repositories: + - repository: templates + type: git + name: OneBranch.Pipelines/GovernedTemplates + ref: refs/heads/main + +extends: + template: v2/OneBranch.NonOfficial.CrossPlat.yml@templates + parameters: + featureFlags: + WindowsHostVersion: + Version: 2022 + globalSdl: + compiled: + enabled: true + armory: + enabled: false + sbom: + enabled: false + cg: + enabled: true + ignoreDirectories: '.devcontainer,demos,docker,docs,src,test,tools/packaging' + tsa: + enabled: true # onebranch publish all SDL results to TSA. If TSA is disabled all SDL tools will forced into 'break' build mode. + credscan: + enabled: true + scanFolder: $(Build.SourcesDirectory) + suppressionsFile: $(Build.SourcesDirectory)\.config\suppress.json + binskim: + break: true # always break the build on binskim issues in addition to TSA upload + policheck: + break: true # always break the build on policheck issues. You can disable it by setting to 'false' + # APIScan requires a non-Ready-To-Run build + apiscan: + enabled: true + softwareName: "PowerShell" # Default is repo name + versionNumber: "7.5" # Default is build number + isLargeApp: false # Default: false. +#softwareFolder - relative path to a folder to be scanned. Default value is root of artifacts folder. +#symbolsFolder - relative path to a folder that contains symbols. Default value is root of artifacts folder. + + tsaOptionsFile: .config\tsaoptions.json + + stages: + - stage: APIScan + displayName: 'ApiScan' + dependsOn: [] + jobs: + - template: /.pipelines/templates/compliance/apiscan.yml@self + parameters: + parentJobs: [] + - stage: notice + displayName: Generate Notice File + dependsOn: [] + jobs: + - template: /.pipelines/templates/compliance/generateNotice.yml@self + parameters: + parentJobs: [] diff --git a/.pipelines/templates/compliance/apiscan.yml b/.pipelines/templates/compliance/apiscan.yml new file mode 100644 index 00000000000..a96471aecd9 --- /dev/null +++ b/.pipelines/templates/compliance/apiscan.yml @@ -0,0 +1,181 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + +jobs: + - job: APIScan + variables: + - name: runCodesignValidationInjection + value : false + - name: NugetSecurityAnalysisWarningLevel + value: none + - name: ReleaseTagVar + value: fromBranch + # Defines the variables APIScanClient, APIScanTenant and APIScanSecret + - group: PS-PS-APIScan + # PAT permissions NOTE: Declare a SymbolServerPAT variable in this group with a 'microsoft' organizanization scoped PAT with 'Symbols' Read permission. + # A PAT in the wrong org will give a single Error 203. No PAT will give a single Error 401, and individual pdbs may be missing even if permissions are correct. + - group: symbols + - name: branchCounterKey + value: $[format('{0:yyyyMMdd}-{1}', pipeline.startTime,variables['Build.SourceBranch'])] + - name: branchCounter + value: $[counter(variables['branchCounterKey'], 1)] + - group: DotNetPrivateBuildAccess + - group: Azure Blob variable group + - group: ReleasePipelineSecrets + - group: mscodehub-feed-read-general + - group: mscodehub-feed-read-akv + - name: ob_outputDirectory + value: '$(Build.ArtifactStagingDirectory)/ONEBRANCH_ARTIFACT' + - name: repoRoot + value: '$(Build.SourcesDirectory)\PowerShell' + - name: ob_sdl_tsa_configFile + value: $(Build.SourcesDirectory)\PowerShell\.config\tsaoptions.json + - name: ob_sdl_credscan_suppressionsFile + value: $(Build.SourcesDirectory)\PowerShell\.config\suppress.json + + pool: + type: windows + + # APIScan can take a long time + timeoutInMinutes: 180 + + steps: + - checkout: self + clean: true + fetchTags: true + fetchDepth: 1000 + displayName: Checkout PowerShell + retryCountOnTaskFailure: 1 + env: + ob_restore_phase: true # This ensures checkout is done at the beginning of the restore phase + + - template: ../SetVersionVariables.yml + parameters: + ReleaseTagVar: $(ReleaseTagVar) + CreateJson: yes + UseJson: no + + - template: ../insert-nuget-config-azfeed.yml + parameters: + repoRoot: '$(repoRoot)' + + - pwsh: | + Import-Module .\build.psm1 -force + Start-PSBootstrap + workingDirectory: '$(repoRoot)' + retryCountOnTaskFailure: 2 + displayName: 'Bootstrap' + env: + __DOTNET_RUNTIME_FEED_KEY: $(RUNTIME_SOURCEFEED_KEY) + + - pwsh: | + Import-Module .\build.psm1 -force + Find-DotNet + dotnet tool install dotnet-symbol --tool-path $(Agent.ToolsDirectory)\tools\dotnet-symbol + $symbolToolPath = Get-ChildItem -Path $(Agent.ToolsDirectory)\tools\dotnet-symbol\dotnet-symbol.exe | Select-Object -First 1 -ExpandProperty FullName + Write-Host "##vso[task.setvariable variable=symbolToolPath]$symbolToolPath" + displayName: Install dotnet-symbol + workingDirectory: '$(repoRoot)' + retryCountOnTaskFailure: 2 + + - pwsh: | + $modules = 'Az.Accounts', 'Az.Storage' + foreach($module in $modules) { + if(!(get-module $module -listavailable)) { + Write-Verbose "installing $module..." -verbose + Install-Module $module -force -AllowClobber + } else { + Write-Verbose "$module already installed." -verbose + } + } + displayName: Install PowerShell modules + workingDirectory: '$(repoRoot)' + + - task: AzurePowerShell@5 + displayName: Download winverify-private Artifacts + inputs: + azureSubscription: az-blob-cicd-infra + scriptType: inlineScript + azurePowerShellVersion: LatestVersion + workingDirectory: '$(repoRoot)' + pwsh: true + inline: | + # download smybols for getfilesiginforedist.dll + $downloadsDirectory = '$(Build.ArtifactStagingDirectory)/downloads' + $uploadedDirectory = '$(Build.ArtifactStagingDirectory)/uploaded' + $storageAccountName = "pscoretestdata" + $containerName = 'winverify-private' + $winverifySymbolsPath = New-Item -ItemType Directory -Path '$(System.ArtifactsDirectory)/winverify-symbols' -Force + $dllName = 'getfilesiginforedist.dll' + $winverifySymbolsDllPath = Join-Path $winverifySymbolsPath $dllName + + $context = New-AzStorageContext -StorageAccountName $storageAccountName -UseConnectedAccount + + Get-AzStorageBlobContent -Container $containerName -Blob $dllName -Destination $winverifySymbolsDllPath -Context $context + + - pwsh: | + Get-ChildItem -Path '$(System.ArtifactsDirectory)/winverify-symbols' + displayName: Capture winverify-private Artifacts + workingDirectory: '$(repoRoot)' + condition: succeededOrFailed() + + - pwsh: | + Import-Module .\build.psm1 -force + Find-DotNet + Start-PSBuild -Configuration StaticAnalysis -PSModuleRestore -Clean -Runtime fxdependent-win-desktop + + $OutputFolder = Split-Path (Get-PSOutput) + + Write-Verbose -Verbose -Message "Deleting ref folder from output folder" + if (Test-Path $OutputFolder/ref) { + Remove-Item -Recurse -Force $OutputFolder/ref + } + + Copy-Item -Path "$OutputFolder\*" -Destination '$(ob_outputDirectory)' -Recurse -Verbose + + workingDirectory: '$(repoRoot)' + displayName: 'Build PowerShell Source' + + - pwsh: | + Get-ChildItem -Path env: | Out-String -width 9999 -Stream | write-Verbose -Verbose + workingDirectory: '$(repoRoot)' + displayName: Capture Environment + condition: succeededOrFailed() + + # Explicitly download symbols for the drop since the SDL image doesn't have http://SymWeb access and APIScan cannot handle https yet. + - pwsh: | + Import-Module .\build.psm1 -force + Find-DotNet + $pat = '$(SymbolServerPAT)' + if ($pat -like '*PAT*' -or $pat -eq '') + { + throw 'No PAT defined' + } + $url = 'https://microsoft.artifacts.visualstudio.com/defaultcollection/_apis/symbol/symsrv' + $(symbolToolPath) --authenticated-server-path $(SymbolServerPAT) $url --symbols -d "$env:ob_outputDirectory\*" --recurse-subdirectories + displayName: 'Download Symbols for binaries' + retryCountOnTaskFailure: 2 + workingDirectory: '$(repoRoot)' + + - pwsh: | + Get-ChildItem '$(ob_outputDirectory)' -File -Recurse | + Foreach-Object { + [pscustomobject]@{ + Path = $_.FullName + Version = $_.VersionInfo.FileVersion + Md5Hash = (Get-FileHash -Algorithm MD5 -Path $_.FullName).Hash + Sha512Hash = (Get-FileHash -Algorithm SHA512 -Path $_.FullName).Hash + } + } | Export-Csv -Path '$(Build.SourcesDirectory)/ReleaseFileHash.csv' + workingDirectory: '$(repoRoot)' + displayName: 'Create release file hash artifact' + + - pwsh: | + Copy-Item -Path '$(Build.SourcesDirectory)/ReleaseFileHash.csv' -Destination '$(ob_outputDirectory)' -Verbose + displayName: 'Publish Build File Hash artifact' + + - pwsh: | + Get-ChildItem -Path env: | Out-String -width 9999 -Stream | write-Verbose -Verbose + displayName: Capture Environment + condition: succeededOrFailed() + workingDirectory: '$(repoRoot)' diff --git a/.pipelines/templates/compliance/generateNotice.yml b/.pipelines/templates/compliance/generateNotice.yml new file mode 100644 index 00000000000..0c1282ea8ce --- /dev/null +++ b/.pipelines/templates/compliance/generateNotice.yml @@ -0,0 +1,154 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + +parameters: + - name: parentJobs + type: jobList + +jobs: +- job: generateNotice + variables: + - name: runCodesignValidationInjection + value : false + - name: NugetSecurityAnalysisWarningLevel + value: none + - name: ob_outputDirectory + value: '$(Build.ArtifactStagingDirectory)/ONEBRANCH_ARTIFACT/notice' + - name: ob_sdl_apiscan_enabled + value: false + - name: repoRoot + value: '$(Build.SourcesDirectory)\PowerShell' + - name: ob_sdl_tsa_configFile + value: $(Build.SourcesDirectory)\PowerShell\.config\tsaoptions.json + - name: ob_sdl_credscan_suppressionsFile + value: $(Build.SourcesDirectory)\PowerShell\.config\suppress.json + + displayName: Generate Notice + dependsOn: + ${{ parameters.parentJobs }} + pool: + type: windows + + timeoutInMinutes: 15 + + steps: + - checkout: self + clean: true + + - pwsh: | + [string]$Branch=$env:BUILD_SOURCEBRANCH + $branchOnly = $Branch -replace '^refs/heads/'; + $branchOnly = $branchOnly -replace '[_\-]' + + if ($branchOnly -eq 'master') { + $container = 'tpn' + } else { + $branchOnly = $branchOnly -replace '[\./]', '-' + $container = "tpn-$branchOnly" + } + + $vstsCommandString = "vso[task.setvariable variable=tpnContainer]$container" + Write-Verbose -Message $vstsCommandString -Verbose + Write-Host -Object "##$vstsCommandString" + displayName: Set ContainerName + + - task: ms.vss-governance-buildtask.governance-build-task-component-detection.ComponentGovernanceComponentDetection@0 + displayName: 'Component Detection' + inputs: + sourceScanPath: '$(repoRoot)\tools' + + - pwsh: | + $(repoRoot)/tools/clearlyDefined/ClearlyDefined.ps1 -TestAndHarvest + displayName: Verify that packages have license data + + + - task: msospo.ospo-extension.8d7f9abb-6896-461d-9e25-4f74ed65ddb2.notice@0 + displayName: 'NOTICE File Generator' + inputs: + outputfile: '$(ob_outputDirectory)\ThirdPartyNotices.txt' + # output format can be html or text + outputformat: text + # this isn't working + # additionaldata: $(Build.SourcesDirectory)\assets\additionalAttributions.txt + + + - pwsh: | + Get-Content -Raw -Path $(repoRoot)\assets\additionalAttributions.txt | Out-File '$(ob_outputDirectory)\ThirdPartyNotices.txt' -Encoding utf8NoBOM -Force -Append + Get-Content -Raw -Path $(repoRoot)\assets\additionalAttributions.txt + displayName: Append Additional Attributions + continueOnError: true + + - pwsh: | + Get-Content -Raw -Path '$(ob_outputDirectory)\ThirdPartyNotices.txt' + displayName: Capture Notice + continueOnError: true + + - powershell: | + [System.Net.ServicePointManager]::SecurityProtocol = + [System.Net.ServicePointManager]::SecurityProtocol -bor + [System.Security.Authentication.SslProtocols]::Tls12 -bor + [System.Security.Authentication.SslProtocols]::Tls11 + + Set-ItemProperty -Path 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\.NetFramework\v4.0.30319' -Name 'SchUseStrongCrypto' -Value '1' -Type DWord + Set-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\.NetFramework\v4.0.30319' -Name 'SchUseStrongCrypto' -Value '1' -Type DWord + Get-PackageProvider -Name NuGet -ForceBootstrap + displayName: Initalize PowerShellGet + + - powershell: | + $modules = 'Az.Accounts', 'Az.Storage' + foreach($module in $modules) { + if(!(get-module $module -listavailable)) { + Write-Verbose "installing $module..." -verbose + Install-Module $module -force -AllowClobber + } else { + Write-Verbose "$module already installed." -verbose + #Update-Module $module -verbose + } + } + displayName: Install PowerShell modules + + - powershell: | + if(Get-Command -Name Uninstall-AzureRm -ErrorAction Ignore){ + Write-Verbose "running Uninstall-AzureRm" -verbose + Uninstall-AzureRm + } else { + Write-Verbose "Uninstall-AzureRm not present" -verbose + } + displayName: Uninstall Uninstall-AzureRm + continueOnError: true + + - task: AzurePowerShell@5 + displayName: Upload Notice + inputs: + azureSubscription: az-blob-cicd-infra + scriptType: inlineScript + azurePowerShellVersion: LatestVersion + workingDirectory: '$(repoRoot)' + pwsh: true + inline: | + try { + $downloadsDirectory = '$(Build.ArtifactStagingDirectory)/downloads' + $uploadedDirectory = '$(Build.ArtifactStagingDirectory)/uploaded' + $storageAccountName = "pscoretestdata" + $containerName = '$(tpnContainer)' + $blobName = 'ThirdPartyNotices.txt' + $noticePath = "$(ob_outputDirectory)\$blobName" + + Write-Verbose -Verbose "creating context ($storageAccountName) ..." + $context = New-AzStorageContext -StorageAccountName $storageAccountName -UseConnectedAccount + + Write-Verbose -Verbose "checking if container ($containerName) exists ..." + $containerExists = Get-AzStorageContainer -Name $containerName -Context $context -ErrorAction SilentlyContinue + if (-not $containerExists) { + Write-Verbose -Verbose "Creating container ..." + $null = New-AzStorageContainer -Name $containerName -Context $context + Write-Verbose -Verbose "Blob container $containerName created successfully." + } + + Write-Verbose -Verbose "Setting blob ($blobName) content ($noticePath) ..." + $null = Set-AzStorageBlobContent -File $noticePath -Container $containerName -Blob $blobName -Context $context -confirm:$false -force + Write-Verbose -Verbose "Done" + } catch { + Get-Error + throw + } From 1b895ef858149dfa60a3d6fc346dd2c902d99a45 Mon Sep 17 00:00:00 2001 From: Aditya Patwardhan Date: Fri, 20 Sep 2024 12:40:19 -0700 Subject: [PATCH 012/173] Delete assets/AppImageThirdPartyNotices.txt (#24256) (#24313) --- assets/AppImageThirdPartyNotices.txt | 506 --------------------------- 1 file changed, 506 deletions(-) delete mode 100644 assets/AppImageThirdPartyNotices.txt diff --git a/assets/AppImageThirdPartyNotices.txt b/assets/AppImageThirdPartyNotices.txt deleted file mode 100644 index d492e7c3b53..00000000000 --- a/assets/AppImageThirdPartyNotices.txt +++ /dev/null @@ -1,506 +0,0 @@ -------------------------------------------- START OF THIRD PARTY NOTICE ----------------------------------------- - - This file is based on or incorporates material from the projects listed below (Third Party IP). The original copyright notice and the license under which Microsoft received such Third Party IP, are set forth below. Such licenses and notices are provided for informational purposes only. Microsoft licenses the Third Party IP to you under the licensing terms for the Microsoft product. Microsoft reserves all other rights not expressly granted under this agreement, whether by implication, estoppel or otherwise. - - - - -Copyright (c) 1991-2016 Unicode, Inc. All rights reserved. -Distributed under the Terms of Use in http://www.unicode.org/copyright.html - -Permission is hereby granted, free of charge, to any person obtaining -a copy of the Unicode data files and any associated documentation -(the "Data Files") or Unicode software and any associated documentation -(the "Software") to deal in the Data Files or Software -without restriction, including without limitation the rights to use, -copy, modify, merge, publish, distribute, and/or sell copies of -the Data Files or Software, and to permit persons to whom the Data Files -or Software are furnished to do so, provided that either -(a) this copyright and permission notice appear with all copies -of the Data Files or Software, or -(b) this copyright and permission notice appear in associated -Documentation. - -THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF -ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE -WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT OF THIRD PARTY RIGHTS. -IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS -NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL -DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, -DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER -TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR -PERFORMANCE OF THE DATA FILES OR SOFTWARE. - -Except as contained in this notice, the name of a copyright holder -shall not be used in advertising or otherwise to promote the sale, -use or other dealings in these Data Files or Software without prior -written authorization of the copyright holder. - ---------------------- - -Third-Party Software Licenses - -This section contains third-party software notices and/or additional -terms for licensed third-party software components included within ICU -libraries. - -1. ICU License - ICU 1.8.1 to ICU 57.1 - -COPYRIGHT AND PERMISSION NOTICE - -Copyright (c) 1995-2016 International Business Machines Corporation and others -All rights reserved. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, and/or sell copies of the Software, and to permit persons -to whom the Software is furnished to do so, provided that the above -copyright notice(s) and this permission notice appear in all copies of -the Software and that both the above copyright notice(s) and this -permission notice appear in supporting documentation. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT -OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR -HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY -SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER -RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF -CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN -CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -Except as contained in this notice, the name of a copyright holder -shall not be used in advertising or otherwise to promote the sale, use -or other dealings in this Software without prior written authorization -of the copyright holder. - -All trademarks and registered trademarks mentioned herein are the -property of their respective owners. - -2. Chinese/Japanese Word Break Dictionary Data (cjdict.txt) - - # The Google Chrome software developed by Google is licensed under - # the BSD license. Other software included in this distribution is - # provided under other licenses, as set forth below. - # - # The BSD License - # https://opensource.org/licenses/bsd-license.php - # Copyright (C) 2006-2008, Google Inc. - # - # All rights reserved. - # - # Redistribution and use in source and binary forms, with or without - # modification, are permitted provided that the following conditions are met: - # - # Redistributions of source code must retain the above copyright notice, - # this list of conditions and the following disclaimer. - # Redistributions in binary form must reproduce the above - # copyright notice, this list of conditions and the following - # disclaimer in the documentation and/or other materials provided with - # the distribution. - # Neither the name of Google Inc. nor the names of its - # contributors may be used to endorse or promote products derived from - # this software without specific prior written permission. - # - # - # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND - # CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, - # INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - # MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - # BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - # - # - # The word list in cjdict.txt are generated by combining three word lists - # listed below with further processing for compound word breaking. The - # frequency is generated with an iterative training against Google web - # corpora. - # - # * Libtabe (Chinese) - # - https://sourceforge.net/project/?group_id=1519 - # - Its license terms and conditions are shown below. - # - # * IPADIC (Japanese) - # - http://chasen.aist-nara.ac.jp/chasen/distribution.html - # - Its license terms and conditions are shown below. - # - # ---------COPYING.libtabe ---- BEGIN-------------------- - # - # /* - # * Copyrighy (c) 1999 TaBE Project. - # * Copyright (c) 1999 Pai-Hsiang Hsiao. - # * All rights reserved. - # * - # * Redistribution and use in source and binary forms, with or without - # * modification, are permitted provided that the following conditions - # * are met: - # * - # * . Redistributions of source code must retain the above copyright - # * notice, this list of conditions and the following disclaimer. - # * . Redistributions in binary form must reproduce the above copyright - # * notice, this list of conditions and the following disclaimer in - # * the documentation and/or other materials provided with the - # * distribution. - # * . Neither the name of the TaBE Project nor the names of its - # * contributors may be used to endorse or promote products derived - # * from this software without specific prior written permission. - # * - # * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - # * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - # * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - # * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - # * REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - # * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - # * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - # * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - # * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - # * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - # * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - # * OF THE POSSIBILITY OF SUCH DAMAGE. - # */ - # - # /* - # * Copyright (c) 1999 Computer Systems and Communication Lab, - # * Institute of Information Science, Academia - # * Sinica. All rights reserved. - # * - # * Redistribution and use in source and binary forms, with or without - # * modification, are permitted provided that the following conditions - # * are met: - # * - # * . Redistributions of source code must retain the above copyright - # * notice, this list of conditions and the following disclaimer. - # * . Redistributions in binary form must reproduce the above copyright - # * notice, this list of conditions and the following disclaimer in - # * the documentation and/or other materials provided with the - # * distribution. - # * . Neither the name of the Computer Systems and Communication Lab - # * nor the names of its contributors may be used to endorse or - # * promote products derived from this software without specific - # * prior written permission. - # * - # * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - # * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - # * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - # * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - # * REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - # * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - # * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - # * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - # * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - # * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - # * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - # * OF THE POSSIBILITY OF SUCH DAMAGE. - # */ - # - # Copyright 1996 Chih-Hao Tsai @ Beckman Institute, - # University of Illinois - # c-tsai4@uiuc.edu http://casper.beckman.uiuc.edu/~c-tsai4 - # - # ---------------COPYING.libtabe-----END-------------------------------- - # - # - # ---------------COPYING.ipadic-----BEGIN------------------------------- - # - # Copyright 2000, 2001, 2002, 2003 Nara Institute of Science - # and Technology. All Rights Reserved. - # - # Use, reproduction, and distribution of this software is permitted. - # Any copy of this software, whether in its original form or modified, - # must include both the above copyright notice and the following - # paragraphs. - # - # Nara Institute of Science and Technology (NAIST), - # the copyright holders, disclaims all warranties with regard to this - # software, including all implied warranties of merchantability and - # fitness, in no event shall NAIST be liable for - # any special, indirect or consequential damages or any damages - # whatsoever resulting from loss of use, data or profits, whether in an - # action of contract, negligence or other tortuous action, arising out - # of or in connection with the use or performance of this software. - # - # A large portion of the dictionary entries - # originate from ICOT Free Software. The following conditions for ICOT - # Free Software applies to the current dictionary as well. - # - # Each User may also freely distribute the Program, whether in its - # original form or modified, to any third party or parties, PROVIDED - # that the provisions of Section 3 ("NO WARRANTY") will ALWAYS appear - # on, or be attached to, the Program, which is distributed substantially - # in the same form as set out herein and that such intended - # distribution, if actually made, will neither violate or otherwise - # contravene any of the laws and regulations of the countries having - # jurisdiction over the User or the intended distribution itself. - # - # NO WARRANTY - # - # The program was produced on an experimental basis in the course of the - # research and development conducted during the project and is provided - # to users as so produced on an experimental basis. Accordingly, the - # program is provided without any warranty whatsoever, whether express, - # implied, statutory or otherwise. The term "warranty" used herein - # includes, but is not limited to, any warranty of the quality, - # performance, merchantability and fitness for a particular purpose of - # the program and the nonexistence of any infringement or violation of - # any right of any third party. - # - # Each user of the program will agree and understand, and be deemed to - # have agreed and understood, that there is no warranty whatsoever for - # the program and, accordingly, the entire risk arising from or - # otherwise connected with the program is assumed by the user. - # - # Therefore, neither ICOT, the copyright holder, or any other - # organization that participated in or was otherwise related to the - # development of the program and their respective officials, directors, - # officers and other employees shall be held liable for any and all - # damages, including, without limitation, general, special, incidental - # and consequential damages, arising out of or otherwise in connection - # with the use or inability to use the program or any product, material - # or result produced or otherwise obtained by using the program, - # regardless of whether they have been advised of, or otherwise had - # knowledge of, the possibility of such damages at any time during the - # project or thereafter. Each user will be deemed to have agreed to the - # foregoing by his or her commencement of use of the program. The term - # "use" as used herein includes, but is not limited to, the use, - # modification, copying and distribution of the program and the - # production of secondary products from the program. - # - # In the case where the program, whether in its original form or - # modified, was distributed or delivered to or received by a user from - # any person, organization or entity other than ICOT, unless it makes or - # grants independently of ICOT any specific warranty to the user in - # writing, such person, organization or entity, will also be exempted - # from and not be held liable to the user for any such damages as noted - # above as far as the program is concerned. - # - # ---------------COPYING.ipadic-----END---------------------------------- - -3. Lao Word Break Dictionary Data (laodict.txt) - - # Copyright (c) 2013 International Business Machines Corporation - # and others. All Rights Reserved. - # - # Project: https://code.google.com/p/lao-dictionary/ - # Dictionary: http://lao-dictionary.googlecode.com/git/Lao-Dictionary.txt - # License: http://lao-dictionary.googlecode.com/git/Lao-Dictionary-LICENSE.txt - # (copied below) - # - # This file is derived from the above dictionary, with slight - # modifications. - # ---------------------------------------------------------------------- - # Copyright (C) 2013 Brian Eugene Wilson, Robert Martin Campbell. - # All rights reserved. - # - # Redistribution and use in source and binary forms, with or without - # modification, - # are permitted provided that the following conditions are met: - # - # - # Redistributions of source code must retain the above copyright notice, this - # list of conditions and the following disclaimer. Redistributions in - # binary form must reproduce the above copyright notice, this list of - # conditions and the following disclaimer in the documentation and/or - # other materials provided with the distribution. - # - # - # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - # FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - # COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - # STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - # OF THE POSSIBILITY OF SUCH DAMAGE. - # -------------------------------------------------------------------------- - -4. Burmese Word Break Dictionary Data (burmesedict.txt) - - # Copyright (c) 2014 International Business Machines Corporation - # and others. All Rights Reserved. - # - # This list is part of a project hosted at: - # github.com/kanyawtech/myanmar-karen-word-lists - # - # -------------------------------------------------------------------------- - # Copyright (c) 2013, LeRoy Benjamin Sharon - # All rights reserved. - # - # Redistribution and use in source and binary forms, with or without - # modification, are permitted provided that the following conditions - # are met: Redistributions of source code must retain the above - # copyright notice, this list of conditions and the following - # disclaimer. Redistributions in binary form must reproduce the - # above copyright notice, this list of conditions and the following - # disclaimer in the documentation and/or other materials provided - # with the distribution. - # - # Neither the name Myanmar Karen Word Lists, nor the names of its - # contributors may be used to endorse or promote products derived - # from this software without specific prior written permission. - # - # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND - # CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, - # INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - # MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS - # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - # TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - # ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR - # TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF - # THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - # SUCH DAMAGE. - # -------------------------------------------------------------------------- - -5. Time Zone Database - - ICU uses the public domain data and code derived from Time Zone -Database for its time zone support. The ownership of the TZ database -is explained in BCP 175: Procedure for Maintaining the Time Zone -Database section 7. - - # 7. Database Ownership - # - # The TZ database itself is not an IETF Contribution or an IETF - # document. Rather it is a pre-existing and regularly updated work - # that is in the public domain, and is intended to remain in the - # public domain. Therefore, BCPs 78 [RFC5378] and 79 [RFC3979] do - # not apply to the TZ Database or contributions that individuals make - # to it. Should any claims be made and substantiated against the TZ - # Database, the organization that is providing the IANA - # Considerations defined in this RFC, under the memorandum of - # understanding with the IETF, currently ICANN, may act in accordance - # with all competent court orders. No ownership claims will be made - # by ICANN or the IETF Trust on the database or the code. Any person - # making a contribution to the database or code waives all rights to - # future claims in that contribution or in the TZ Database. - - -8. liblzma - -XZ Utils Licensing -================== - - Different licenses apply to different files in this package. Here - is a rough summary of which licenses apply to which parts of this - package (but check the individual files to be sure!): - - - liblzma is in the public domain. - - - xz, xzdec, and lzmadec command line tools are in the public - domain unless GNU getopt_long had to be compiled and linked - in from the lib directory. The getopt_long code is under - GNU LGPLv2.1+. - - - The scripts to grep, diff, and view compressed files have been - adapted from gzip. These scripts and their documentation are - under GNU GPLv2+. - - - All the documentation in the doc directory and most of the - XZ Utils specific documentation files in other directories - are in the public domain. - - - Translated messages are in the public domain. - - - The build system contains public domain files, and files that - are under GNU GPLv2+ or GNU GPLv3+. None of these files end up - in the binaries being built. - - - Test files and test code in the tests directory, and debugging - utilities in the debug directory are in the public domain. - - - The extra directory may contain public domain files, and files - that are under various free software licenses. - - You can do whatever you want with the files that have been put into - the public domain. If you find public domain legally problematic, - take the previous sentence as a license grant. If you still find - the lack of copyright legally problematic, you have too many - lawyers. - - As usual, this software is provided "as is", without any warranty. - - If you copy significant amounts of public domain code from XZ Utils - into your project, acknowledging this somewhere in your software is - polite (especially if it is proprietary, non-free software), but - naturally it is not legally required. Here is an example of a good - notice to put into "about box" or into documentation: - - This software includes code from XZ Utils . - - The following license texts are included in the following files: - - COPYING.LGPLv2.1: GNU Lesser General Public License version 2.1 - - COPYING.GPLv2: GNU General Public License version 2 - - COPYING.GPLv3: GNU General Public License version 3 - - Note that the toolchain (compiler, linker etc.) may add some code - pieces that are copyrighted. Thus, it is possible that e.g. liblzma - binary wouldn't actually be in the public domain in its entirety - even though it contains no copyrighted code from the XZ Utils source - package. - - If you have questions, don't hesitate to ask the author(s) for more - information. - - -BSD License - -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - -Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - -Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ""AS IS"" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -9. libunwind - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -Provided for Informational Purposes Only - -MIT License - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the Software), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - - - ------------------------------------------------ END OF THIRD PARTY NOTICE ------------------------------------------ From ec222e62b1ac00bd505525c4d1827ccdf8b731c2 Mon Sep 17 00:00:00 2001 From: Aditya Patwardhan Date: Fri, 20 Sep 2024 12:40:38 -0700 Subject: [PATCH 013/173] Delete demos directory (#24258) (#24314) --- demos/Apache/Apache/Apache.psm1 | 236 ---------------- demos/Apache/apache-demo.ps1 | 33 --- demos/Apache/readme.md | 18 -- demos/Azure/Azure-Demo.ps1 | 70 ----- demos/Azure/Compute-Linux.json | 200 ------------- demos/Azure/README.md | 11 - demos/DSC/dsc-demo.ps1 | 124 -------- demos/DSC/readme.md | 15 - demos/Docker-PowerShell/Docker-PowerShell.ps1 | 32 --- demos/README.md | 4 - demos/SystemD/SystemD/SystemD.psm1 | 21 -- demos/SystemD/journalctl-demo.ps1 | 12 - demos/SystemD/readme.md | 10 - demos/WindowsPowerShellModules/README.md | 54 ---- demos/crontab/CronTab/CronTab.ps1xml | 69 ----- demos/crontab/CronTab/CronTab.psd1 | 61 ---- demos/crontab/CronTab/CronTab.psm1 | 264 ------------------ demos/crontab/README.md | 15 - demos/crontab/crontab.ps1 | 32 --- demos/dsc.ps1 | 14 - demos/powershellget/PowerShellGet.ps1 | 80 ------ demos/powershellget/README.md | 5 - demos/python/README.md | 8 - demos/python/class1.ps1 | 14 - demos/python/class1.py | 19 -- demos/python/demo_script.ps1 | 63 ----- demos/python/inline_python.ps1 | 19 -- demos/rest/README.md | 7 - demos/rest/rest.ps1 | 45 --- 29 files changed, 1555 deletions(-) delete mode 100644 demos/Apache/Apache/Apache.psm1 delete mode 100644 demos/Apache/apache-demo.ps1 delete mode 100644 demos/Apache/readme.md delete mode 100644 demos/Azure/Azure-Demo.ps1 delete mode 100644 demos/Azure/Compute-Linux.json delete mode 100644 demos/Azure/README.md delete mode 100644 demos/DSC/dsc-demo.ps1 delete mode 100644 demos/DSC/readme.md delete mode 100644 demos/Docker-PowerShell/Docker-PowerShell.ps1 delete mode 100644 demos/README.md delete mode 100644 demos/SystemD/SystemD/SystemD.psm1 delete mode 100644 demos/SystemD/journalctl-demo.ps1 delete mode 100644 demos/SystemD/readme.md delete mode 100644 demos/WindowsPowerShellModules/README.md delete mode 100644 demos/crontab/CronTab/CronTab.ps1xml delete mode 100755 demos/crontab/CronTab/CronTab.psd1 delete mode 100644 demos/crontab/CronTab/CronTab.psm1 delete mode 100644 demos/crontab/README.md delete mode 100644 demos/crontab/crontab.ps1 delete mode 100644 demos/dsc.ps1 delete mode 100644 demos/powershellget/PowerShellGet.ps1 delete mode 100644 demos/powershellget/README.md delete mode 100644 demos/python/README.md delete mode 100644 demos/python/class1.ps1 delete mode 100755 demos/python/class1.py delete mode 100644 demos/python/demo_script.ps1 delete mode 100644 demos/python/inline_python.ps1 delete mode 100644 demos/rest/README.md delete mode 100644 demos/rest/rest.ps1 diff --git a/demos/Apache/Apache/Apache.psm1 b/demos/Apache/Apache/Apache.psm1 deleted file mode 100644 index 5f980f26bae..00000000000 --- a/demos/Apache/Apache/Apache.psm1 +++ /dev/null @@ -1,236 +0,0 @@ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. - -#Region utility functions - -$global:sudocmd = "sudo" - -Function GetApacheCmd{ - if (Test-Path "/usr/sbin/apache2ctl"){ - $cmd = "/usr/sbin/apache2ctl" - }elseif(Test-Path "/usr/sbin/httpd"){ - $cmd = "/usr/sbin/httpd" - }else{ - Write-Error "Unable to find httpd or apache2ctl program. Unable to continue" - exit -1 - } - $cmd -} - -Function GetApacheVHostDir{ - if (Test-Path "/etc/httpd/conf.d"){ - Return "/etc/httpd/conf.d/" - } - if (Test-Path "/etc/apache2/sites-enabled"){ - Return "/etc/apache2/sites-enabled" - } -} - -Function CleanInputString([string]$inputStr){ - $outputStr = $inputStr.Trim().Replace('`n','').Replace('\n','') - $outputStr -} - -#EndRegion utility functions - -#Region Class specifications - -Class ApacheModule{ - [string]$ModuleName - - ApacheModule([string]$aModule){ - $this.ModuleName = $aModule - } -} - -Class ApacheVirtualHost{ - [string]$ServerName - [string]$DocumentRoot - [string]$VirtualHostIPAddress = "*" - [string[]]$ServerAliases - [int]$VirtualHostPort = "80" - [string]$ServerAdmin - [string]$CustomLogPath - [string]$ErrorLogPath - [string]$ConfigurationFile - - #region class constructors - ApacheVirtualHost([string]$ServerName, [string]$ConfFile, [string]$VirtualHostIPAddress,[int]$VirtualHostPort){ - $this.ServerName = $ServerName - $this.ConfigurationFile = $ConfFile - $this.VirtualHostIPAddress = $VirtualHostIPAddress - $this.VirtualHostPort = $VirtualHostPort - } - - #Full specification - ApacheVirtualHost([string]$ServerName, [string]$DocumentRoot, [string[]]$ServerAliases, [string]$ServerAdmin, [string]$CustomLogPath, [string]$ErrorLogPath, [string]$VirtualHostIPAddress, [int]$VirtualHostPort, [string]$ConfigurationFile){ - $this.ServerName = $ServerName - $this.DocumentRoot = $DocumentRoot - $this.ServerAliases = $ServerAliases - $this.ServerAdmin = $ServerAdmin - $this.CustomLogPath = $CustomLogPath - $this.ErrorLogPath = $ErrorLogPath - $this.VirtualHostIPAddress = $VirtualHostIPAddress - $this.VirtualHostPort = $VirtualHostPort - $this.ConfigurationFile = $ConfigurationFile - } - - #Default Port and IP - #endregion - - #region class methods - Save($ConfigurationFile){ - if (!(Test-Path $this.DocumentRoot)){ New-Item -Type Directory $this.DocumentRoot } - - $VHostsDirectory = GetApacheVHostDir - if (!(Test-Path $VHostsDirectory)){ - Write-Error "Specified virtual hosts directory does not exist: $VHostsDirectory" - exit 1 - } - $VHostIPAddress = $this.VirtualHostIPAddress - [string]$VhostPort = $this.VirtualHostPort - $VHostDef = "`n" - $vHostDef += "DocumentRoot " + $this.DocumentRoot + "`n" - ForEach ($Alias in $this.ServerAliases){ - if ($Alias.trim() -ne ""){ - $vHostDef += "ServerAlias " + $Alias + "`n" - } - } - $vHostDef += "ServerName " + $this.ServerName +"`n" - if ($this.ServerAdmin.Length -gt 1){$vHostDef += "ServerAdmin " + $this.ServerAdmin +"`n"} - if ($this.CustomLogPath -like "*/*"){$vHostDef += "CustomLog " + $this.CustomLogPath +"`n"} - if ($this.ErrorLogPath -like "*/*"){$vHostDef += "ErrorLog " + $this.ErrorLogpath +"`n"} - $vHostDef += "" - $filName = $ConfigurationFile - $VhostDef | Out-File "/tmp/${filName}" -Force -Encoding:ascii - & $global:sudocmd "mv" "/tmp/${filName}" "${VhostsDirectory}/${filName}" - Write-Information "Restarting Apache HTTP Server" - Restart-ApacheHTTPServer - } - - #endregion -} - -#EndRegion Class Specifications - -Function New-ApacheVHost { - [CmdletBinding()] - param( - [parameter (Mandatory = $true)][string]$ServerName, - [parameter (Mandatory = $true)][string]$DocumentRoot, - [string]$VirtualHostIPAddress, - [string[]]$ServerAliases, - [int]$VirtualHostPort, - [string]$ServerAdmin, - [string]$CustomLogPath, - [string]$ErrorLogPath - ) - - $NewConfFile = $VHostsDirectory + "/" + $ServerName + ".conf" - if(!($VirtualHostIPAddress)){$VirtualHostIPAddress = "*"} - if(!($VirtualHostPort)){$VirtualHostPort = "80"} - $newVHost = [ApacheVirtualHost]::new("$ServerName","$DocumentRoot","$ServerAliases","$ServerAdmin","$CustomLogPath","$ErrorLogPath","$VirtualHostIPAddress",$VirtualHostPort,"$NewConfFile") - $newVHost.Save("$ServerName.conf") -} - -Function GetVHostProps([string]$ConfFile,[string]$ServerName,[string]$Listener){ - $confContents = Get-Content $ConfFile - [boolean]$Match = $false - $DocumentRoot = "" - $CustomLogPath = "" - $ErrorLogPath = "" - $ServerAdmin = "" - ForEach ($confline in $confContents){ - if ($confLine -like "*"){ - $Match = $false - } - } - } - @{"DocumentRoot" = "$DocumentRoot"; "CustomLogPath" = "$CustomLogPath"; "ErrorLogPath" = "$ErrorLogPath"; "ServerAdmin" = $ServerAdmin} - -} - -Function Get-ApacheVHost{ - $cmd = GetApacheCmd - - $Vhosts = @() - $res = & $global:sudocmd $cmd -t -D DUMP_VHOSTS - - ForEach ($line in $res){ - $ServerName = $null - if ($line -like "*:*.conf*"){ - $RMatch = $line -match "(?.*:[0-9]*)(?.*)\((?.*)\)" - $ListenAddress = $Matches.Listen.trim() - $ServerName = $Matches.ServerName.trim() - $ConfFile = $Matches.ConfFile.trim().split(":")[0].Replace('(','') - }else{ - if ($line.trim().split()[0] -like "*:*"){ - $ListenAddress = $line.trim().split()[0] - }elseif($line -like "*.conf*"){ - if ($line -like "*default*"){ - $ServerName = "_Default" - $ConfFile = $line.trim().split()[3].split(":")[0].Replace('(','') - }elseif($line -like "*namevhost*"){ - $ServerName = $line.trim().split()[3] - $ConfFile = $line.trim().split()[4].split(":")[0].Replace('(','') - } - } - } - - if ($null -ne $ServerName){ - $vHost = [ApacheVirtualHost]::New($ServerName, $ConfFile, $ListenAddress.Split(":")[0],$ListenAddress.Split(":")[1]) - $ExtProps = GetVHostProps $ConfFile $ServerName $ListenAddress - $vHost.DocumentRoot = $ExtProps.DocumentRoot - #Custom log requires additional handling. NYI - #$vHost.CustomLogPath = $ExtProps.CustomLogPath - $vHost.ErrorLogPath = $ExtProps.ErrorLogPath - $vHost.ServerAdmin = $ExtProps.ServerAdmin - $Vhosts += $vHost - } - } - - Return $Vhosts - } - -Function Restart-ApacheHTTPServer{ - [CmdletBinding()] - Param( - [switch]$Graceful - ) - - if ($null -eq $Graceful){$Graceful = $false} - $cmd = GetApacheCmd - if ($Graceful){ - & $global:sudocmd $cmd -k graceful - }else{ - & $global:sudocmd $cmd -k restart - } - -} - -Function Get-ApacheModule{ - $cmd = GetApacheCmd - - $ApacheModules = @() - - $Results = & $global:sudocmd $cmd -M |grep -v Loaded - - Foreach ($mod in $Results){ - $modInst = [ApacheModule]::new($mod.trim()) - $ApacheModules += ($modInst) - } - - $ApacheModules - -} diff --git a/demos/Apache/apache-demo.ps1 b/demos/Apache/apache-demo.ps1 deleted file mode 100644 index 299ce0cc0de..00000000000 --- a/demos/Apache/apache-demo.ps1 +++ /dev/null @@ -1,33 +0,0 @@ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. - -Import-Module $PSScriptRoot/Apache/Apache.psm1 - -#list Apache Modules -Write-Host -Foreground Blue "Get installed Apache Modules like *proxy* and Sort by name" -Get-ApacheModule | Where-Object {$_.ModuleName -like "*proxy*"} | Sort-Object ModuleName | Out-Host - -#Graceful restart of Apache -Write-Host -Foreground Blue "Restart Apache Server gracefully" -Restart-ApacheHTTPServer -Graceful | Out-Host - -#Enumerate current virtual hosts (web sites) -Write-Host -Foreground Blue "Enumerate configured Apache Virtual Hosts" -Get-ApacheVHost |Out-Host - -#Add a new virtual host -Write-Host -Foreground Yellow "Create a new Apache Virtual Host" -New-ApacheVHost -ServerName "mytestserver" -DocumentRoot /var/www/html/mytestserver -VirtualHostIPAddress * -VirtualHostPort 8090 | Out-Host - -#Enumerate new set of virtual hosts -Write-Host -Foreground Blue "Enumerate Apache Virtual Hosts Again" -Get-ApacheVHost |Out-Host - -#Cleanup -Write-Host -Foreground Blue "Remove demo virtual host" -if (Test-Path "/etc/httpd/conf.d"){ - & sudo rm "/etc/httpd/conf.d/mytestserver.conf" -} -if (Test-Path "/etc/apache2/sites-enabled"){ - & sudo rm "/etc/apache2/sites-enabled/mytestserver.conf" -} diff --git a/demos/Apache/readme.md b/demos/Apache/readme.md deleted file mode 100644 index 30e36b3811a..00000000000 --- a/demos/Apache/readme.md +++ /dev/null @@ -1,18 +0,0 @@ -## Apache Management Demo - -This demo shows management of Apache HTTP Server with PowerShell cmdlets implemented in a script module. - -- **Get-ApacheVHost**: Enumerate configured Apache Virtual Host (website) instances as objects. -- **Get-ApacheModule**: Enumerate loaded Apache modules -- **Restart-ApacheHTTPserver**: Restart the Apache web server -- **New-ApacheVHost**: Create a new Apache Virtual Host (website) based on supplied parameters - - -## Prerequisites ## -- Install PowerShell -- Install Apache packages - - `sudo apt-get install apache2` - - `sudo yum install httpd` - - -Note: Management of Apache requires privileges. The user must have authorization to elevate with sudo. You will be prompted for a sudo password when running the demo. \ No newline at end of file diff --git a/demos/Azure/Azure-Demo.ps1 b/demos/Azure/Azure-Demo.ps1 deleted file mode 100644 index 22b316686a7..00000000000 --- a/demos/Azure/Azure-Demo.ps1 +++ /dev/null @@ -1,70 +0,0 @@ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. - -### The techniques used in this demo are documented at -### https://azure.microsoft.com/documentation/articles/powershell-azure-resource-manager/ - -### Import AzureRM.Profile.NetCore.Preview and AzureRM.Resources.NetCore.Preview modules. -### AzureRM.NetCore.Preview is a wrapper module that pulls in these modules -### -### Because of issue https://github.com/PowerShell/PowerShell/issues/1618, -### currently you will not be able to use "Install-Module AzureRM.NetCore.Preview" from -### PowerShellGallery. You can use the following workaround until the issue is fixed: -### -### Install-Package -Name AzureRM.NetCore.Preview -Source https://www.powershellgallery.com/api/v2 -ProviderName NuGet -ExcludeVersion -Destination -### -### Ensure $env:PSModulePath is updated with the location you used to install. -Import-Module AzureRM.NetCore.Preview - -### Supply your Azure Credentials -Login-AzureRmAccount - -### Specify a name for Azure Resource Group -$resourceGroupName = "PSAzDemo" + (New-Guid | ForEach-Object guid) -replace "-","" -$resourceGroupName - -### Create a new Azure Resource Group -New-AzureRmResourceGroup -Name $resourceGroupName -Location "West US" - -### Deploy an Ubuntu 14.04 VM using Resource Manager cmdlets -### Template is available at -### http://armviz.io/#/?load=https:%2F%2Fraw.githubusercontent.com%2FAzure%2Fazure-quickstart-templates%2Fmaster%2F101-vm-simple-linux%2Fazuredeploy.json -$dnsLabelPrefix = $resourceGroupName | ForEach-Object tolower -$dnsLabelPrefix - -#[SuppressMessage("Microsoft.Security", "CS002:SecretInNextLine", Justification="Demo/doc secret.")] -$password = ConvertTo-SecureString -String "PowerShellRocks!" -AsPlainText -Force -New-AzureRmResourceGroupDeployment -ResourceGroupName $resourceGroupName -TemplateFile ./Compute-Linux.json -adminUserName psuser -adminPassword $password -dnsLabelPrefix $dnsLabelPrefix - -### Monitor the status of the deployment -Get-AzureRmResourceGroupDeployment -ResourceGroupName $resourceGroupName - -### Discover the resources we created by the previous deployment -Find-AzureRmResource -ResourceGroupName $resourceGroupName | Select-Object Name,ResourceType,Location - -### Get the state of the VM we created -### Notice: The VM is in running state -Get-AzureRmResource -ResourceName MyUbuntuVM -ResourceType Microsoft.Compute/virtualMachines -ResourceGroupName $resourceGroupName -ODataQuery '$expand=instanceView' | ForEach-Object properties | ForEach-Object instanceview | ForEach-Object statuses - -### Discover the operations we can perform on the compute resource -### Notice: Operations like "Power Off Virtual Machine", "Start Virtual Machine", "Create Snapshot", "Delete Snapshot", "Delete Virtual Machine" -Get-AzureRmProviderOperation -OperationSearchString Microsoft.Compute/* | Select-Object OperationName,Operation - -### Power Off the Virtual Machine we created -Invoke-AzureRmResourceAction -ResourceGroupName $resourceGroupName -ResourceType Microsoft.Compute/virtualMachines -ResourceName MyUbuntuVM -Action poweroff - -### Check the VM state again. It should be stopped now. -Get-AzureRmResource -ResourceName MyUbuntuVM -ResourceType Microsoft.Compute/virtualMachines -ResourceGroupName $resourceGroupName -ODataQuery '$expand=instanceView' | ForEach-Object properties | ForEach-Object instanceview | ForEach-Object statuses - -### As you know, you may still be incurring charges even if the VM is in stopped state -### Deallocate the resource to avoid this charge -Invoke-AzureRmResourceAction -ResourceGroupName $resourceGroupName -ResourceType Microsoft.Compute/virtualMachines -ResourceName MyUbuntuVM -Action deallocate - -### The following command removes the Virtual Machine -Remove-AzureRmResource -ResourceName MyUbuntuVM -ResourceType Microsoft.Compute/virtualMachines -ResourceGroupName $resourceGroupName - -### Look at the resources that still exists -Find-AzureRmResource -ResourceGroupName $resourceGroupName | Select-Object Name,ResourceType,Location - -### Remove the resource group and its resources -Remove-AzureRmResourceGroup -Name $resourceGroupName diff --git a/demos/Azure/Compute-Linux.json b/demos/Azure/Compute-Linux.json deleted file mode 100644 index a0e9e27b85e..00000000000 --- a/demos/Azure/Compute-Linux.json +++ /dev/null @@ -1,200 +0,0 @@ -{ - "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "parameters": { - "adminUsername": { - "type": "string", - "metadata": { - "description": "User name for the Virtual Machine." - } - }, - "adminPassword": { - "type": "securestring", - "metadata": { - "description": "Password for the Virtual Machine." - } - }, - "dnsLabelPrefix": { - "type": "string", - "metadata": { - "description": "Unique DNS Name for the Public IP used to access the Virtual Machine." - } - }, - "ubuntuOSVersion": { - "type": "string", - "defaultValue": "14.04.2-LTS", - "allowedValues": [ - "12.04.5-LTS", - "14.04.2-LTS", - "15.10", - "16.04.0-LTS" - ], - "metadata": { - "description": "The Ubuntu version for the VM. This will pick a fully patched image of this given Ubuntu version. Allowed values: 12.04.5-LTS, 14.04.2-LTS, 15.10, 16.04.0-LTS." - } - } - }, - "variables": { - "storageAccountName": "[concat(uniquestring(resourceGroup().id), 'salinuxvm')]", - "dataDisk1VhdName": "datadisk1", - "imagePublisher": "Canonical", - "imageOffer": "UbuntuServer", - "OSDiskName": "osdiskforlinuxsimple", - "nicName": "myVMNic", - "addressPrefix": "10.0.0.0/16", - "subnetName": "Subnet", - "subnetPrefix": "10.0.0.0/24", - "storageAccountType": "Standard_LRS", - "publicIPAddressName": "myPublicIP", - "publicIPAddressType": "Dynamic", - "vmStorageAccountContainerName": "vhds", - "vmName": "MyUbuntuVM", - "vmSize": "Standard_D1", - "virtualNetworkName": "MyVNET", - "vnetID": "[resourceId('Microsoft.Network/virtualNetworks',variables('virtualNetworkName'))]", - "subnetRef": "[concat(variables('vnetID'),'/subnets/',variables('subnetName'))]", - "apiVersion": "2015-06-15" - }, - "resources": [ - { - "type": "Microsoft.Storage/storageAccounts", - "name": "[variables('storageAccountName')]", - "apiVersion": "2016-01-01", - "location": "[resourceGroup().location]", - "sku": { - "name": "[variables('storageAccountType')]" - }, - "kind": "Storage", - "properties": {} - }, - { - "apiVersion": "[variables('apiVersion')]", - "type": "Microsoft.Network/publicIPAddresses", - "name": "[variables('publicIPAddressName')]", - "location": "[resourceGroup().location]", - "properties": { - "publicIPAllocationMethod": "[variables('publicIPAddressType')]", - "dnsSettings": { - "domainNameLabel": "[parameters('dnsLabelPrefix')]" - } - } - }, - { - "apiVersion": "[variables('apiVersion')]", - "type": "Microsoft.Network/virtualNetworks", - "name": "[variables('virtualNetworkName')]", - "location": "[resourceGroup().location]", - "properties": { - "addressSpace": { - "addressPrefixes": [ - "[variables('addressPrefix')]" - ] - }, - "subnets": [ - { - "name": "[variables('subnetName')]", - "properties": { - "addressPrefix": "[variables('subnetPrefix')]" - } - } - ] - } - }, - { - "apiVersion": "[variables('apiVersion')]", - "type": "Microsoft.Network/networkInterfaces", - "name": "[variables('nicName')]", - "location": "[resourceGroup().location]", - "dependsOn": [ - "[concat('Microsoft.Network/publicIPAddresses/', variables('publicIPAddressName'))]", - "[concat('Microsoft.Network/virtualNetworks/', variables('virtualNetworkName'))]" - ], - "properties": { - "ipConfigurations": [ - { - "name": "ipconfig1", - "properties": { - "privateIPAllocationMethod": "Dynamic", - "publicIPAddress": { - "id": "[resourceId('Microsoft.Network/publicIPAddresses',variables('publicIPAddressName'))]" - }, - "subnet": { - "id": "[variables('subnetRef')]" - } - } - } - ] - } - }, - { - "apiVersion": "[variables('apiVersion')]", - "type": "Microsoft.Compute/virtualMachines", - "name": "[variables('vmName')]", - "location": "[resourceGroup().location]", - "dependsOn": [ - "[concat('Microsoft.Storage/storageAccounts/', variables('storageAccountName'))]", - "[concat('Microsoft.Network/networkInterfaces/', variables('nicName'))]" - ], - "properties": { - "hardwareProfile": { - "vmSize": "[variables('vmSize')]" - }, - "osProfile": { - "computerName": "[variables('vmName')]", - "adminUsername": "[parameters('adminUsername')]", - "adminPassword": "[parameters('adminPassword')]" - }, - "storageProfile": { - "imageReference": { - "publisher": "[variables('imagePublisher')]", - "offer": "[variables('imageOffer')]", - "sku": "[parameters('ubuntuOSVersion')]", - "version": "latest" - }, - "osDisk": { - "name": "osdisk", - "vhd": { - "uri": "[concat(reference(concat('Microsoft.Storage/storageAccounts/', variables('storageAccountName')), variables('apiVersion')).primaryEndpoints.blob, variables('vmStorageAccountContainerName'),'/',variables('OSDiskName'),'.vhd')]" - }, - "caching": "ReadWrite", - "createOption": "FromImage" - }, - "dataDisks": [ - { - "name": "datadisk1", - "diskSizeGB": "100", - "lun": 0, - "vhd": { - "uri": "[concat(reference(concat('Microsoft.Storage/storageAccounts/', variables('storageAccountName')), variables('apiVersion')).primaryEndpoints.blob, variables('vmStorageAccountContainerName'),'/',variables('dataDisk1VhdName'),'.vhd')]" - }, - "createOption": "Empty" - } - ] - }, - "networkProfile": { - "networkInterfaces": [ - { - "id": "[resourceId('Microsoft.Network/networkInterfaces',variables('nicName'))]" - } - ] - }, - "diagnosticsProfile": { - "bootDiagnostics": { - "enabled": "true", - "storageUri": "[concat(reference(concat('Microsoft.Storage/storageAccounts/', variables('storageAccountName')), variables('apiVersion')).primaryEndpoints.blob)]" - } - } - } - } - ], - "outputs": { - "hostname": { - "type": "string", - "value": "[concat(parameters('dnsLabelPrefix'), '.', resourceGroup().location, '.cloudapp.azure.com')]" - }, - "sshCommand": { - "type": "string", - "value": "[concat('ssh ', parameters('adminUsername'), '@', parameters('dnsLabelPrefix'), '.', resourceGroup().location, '.cloudapp.azure.com')]" - } - } -} diff --git a/demos/Azure/README.md b/demos/Azure/README.md deleted file mode 100644 index d2c8155f6f4..00000000000 --- a/demos/Azure/README.md +++ /dev/null @@ -1,11 +0,0 @@ -## Demo: Managing Azure using PowerShell - -This demo (Azure-Demo.ps1) shows management of Azure Compute resource using Azure Resource Management (ARM) cmdlets. - -## Prerequisites ## -- Install the latest PowerShell Core. -- Install AzureRM.NetCore.Preview, AzureRM.Profile.NetCore.Preview and AzureRM.Resources.NetCore.Preview modules to a local directory. - - The instructions for downloading these modules are in Azure-Demo.ps1 file. - - You have to use the command "Install-Package -Name AzureRM.NetCore.Preview -Source https://www.powershellgallery.com/api/v2 -ProviderName NuGet -ExcludeVersion -Destination " - - diff --git a/demos/DSC/dsc-demo.ps1 b/demos/DSC/dsc-demo.ps1 deleted file mode 100644 index 3abd642a3b4..00000000000 --- a/demos/DSC/dsc-demo.ps1 +++ /dev/null @@ -1,124 +0,0 @@ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. - -#Get Distro type and set distro-specific variables -$OSname = Get-Content "/etc/os-release" |Select-String -Pattern "^Name=" -$OSName = $OSName.tostring().split("=")[1].Replace('"','') -if ($OSName -like "Ubuntu*"){ - $distro = "Ubuntu" - $ApachePackages = @("apache2","php5","libapache2-mod-php5") - $ServiceName = "apache2" - $VHostDir = "/etc/apache2/sites-enabled" - $PackageManager = "apt" -}elseif (($OSName -like "CentOS*") -or ($OSName -like "Red Hat*") -or ($OSname -like "Oracle*")){ - $distro = "Fedora" - $ApachePackages = @("httpd","mod_ssl","php","php-mysql") - $ServiceName = "httpd" - $VHostDir = "/etc/httpd/conf.d" - $PackageManager = "yum" -}else{ - Write-Error "Unknown Linux operating system. Cannot continue." -} - -#Get Service Controller -if ((Test-Path "/bin/systemctl") -or (Test-Path "/usr/bin/systemctl")){ - $ServiceCtl = "SystemD" -}else{ - $ServiceCtl = "init" -} - -#Get FQDN -$hostname = & hostname --fqdn - -Write-Host -ForegroundColor Blue "Compile a DSC MOF for the Apache Server configuration" -Configuration ApacheServer{ - Node localhost{ - - ForEach ($Package in $ApachePackages){ - nxPackage $Package{ - Ensure = "Present" - Name = $Package - PackageManager = $PackageManager - } - } - - nxFile vHostDirectory{ - DestinationPath = $VhostDir - Type = "Directory" - Ensure = "Present" - Owner = "root" - Mode = "744" - } - - #Ensure default content does not exist - nxFile DefVHost{ - DestinationPath = "${VhostDir}/000-default.conf" - Ensure = "Absent" - } - - nxFile Welcome.conf{ - DestinationPath = "${VhostDir}/welcome.conf" - Ensure = "Absent" - } - - nxFile UserDir.conf{ - DestinationPath = "${VhostDir}/userdir.conf" - Ensure = "Absent" - } - - #Ensure website is defined - nxFile DefaultSiteDir{ - DestinationPath = "/var/www/html/defaultsite" - Type = "Directory" - Owner = "root" - Mode = "744" - Ensure = "Present" - } - - nxFile DefaultSite.conf{ - Destinationpath = "${VhostDir}/defaultsite.conf" - Owner = "root" - Mode = "744" - Ensure = "Present" - Contents = @" - -DocumentRoot /var/www/html/defaultsite -ServerName $hostname - - -"@ - DependsOn = "[nxFile]DefaultSiteDir" - } - - nxFile TestPhp{ - DestinationPath = "/var/www/html/defaultsite/test.php" - Ensure = "Present" - Owner = "root" - Mode = "744" - Contents = @' - - -'@ - } - - #Configure Apache Service - nxService ApacheService{ - Name = "$ServiceName" - Enabled = $true - State = "running" - Controller = $ServiceCtl - DependsOn = "[nxFile]DefaultSite.conf" - } - - } -} - -ApacheServer -OutputPath "/tmp" - -Pause -Write-Host -ForegroundColor Blue "Apply the configuration locally" -& sudo /opt/microsoft/dsc/Scripts/StartDscConfiguration.py -configurationmof /tmp/localhost.mof | Out-Host - -Pause -Write-Host -ForegroundColor Blue "Get the current configuration" -& sudo /opt/microsoft/dsc/Scripts/GetDscConfiguration.py | Out-Host diff --git a/demos/DSC/readme.md b/demos/DSC/readme.md deleted file mode 100644 index 3a13cc6f2fe..00000000000 --- a/demos/DSC/readme.md +++ /dev/null @@ -1,15 +0,0 @@ -# DSC MOF Compilation Demo - -[PowerShell Desired State Configuration](https://learn.microsoft.com/powershell/dsc/overview) is a declarative configuration platform for Windows and Linux. -DSC configurations can be authored in PowerShell and compiled into the resultant MOF document. - -This demo shows use of PowerShell to author a DSC configuration to set the configuration of an Apache web server. PowerShell scripting is used to assess distribution and version-specific properties, -such as the service controller and repo manager tools, for use in the configuration. - -## Prerequisites - -- PowerShell >= 6.0.0-alpha.8 [https://github.com/PowerShell/PowerShell/releases](https://github.com/PowerShell/PowerShell/releases) -- OMI: >= 1.1.0 [https://www.github.com/microsoft/omi/releases](https://www.github.com/microsoft/omi/releases) -- Desired State Configuration for Linux >= 1.1.1-278 [https://github.com/Microsoft/PowerShell-DSC-for-Linux/releases](https://github.com/Microsoft/PowerShell-DSC-for-Linux/releases) - -> Note: applying the DSC configuration requires privileges. The user must have sudo authorization capabilities. You will be prompted for a sudo password when running the demo. diff --git a/demos/Docker-PowerShell/Docker-PowerShell.ps1 b/demos/Docker-PowerShell/Docker-PowerShell.ps1 deleted file mode 100644 index 18eb844fd32..00000000000 --- a/demos/Docker-PowerShell/Docker-PowerShell.ps1 +++ /dev/null @@ -1,32 +0,0 @@ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. - -# This is a short example of the Docker-PowerShell module. The same cmdlets may be used to manage both local & remote machines, including both Windows & Linux hosts -# The only difference between them is the example container image is pulled & run. - -# Import the Docker module -# It's available at https://github.com/Microsoft/Docker-PowerShell -Import-Module Docker - -# Pull the 'hello-world' image from Docker Hub -Pull-ContainerImage hello-world # Linux -# Pull-ContainerImage patricklang/hello-world # Windows - -# Now run it -Run-ContainerImage hello-world # Linux -# Run-ContainerImage patricklang/hello-world # Windows - -# Make some room on the screen -cls - -# List all containers that have exited -Get-Container | Where-Object State -EQ "exited" - -# That found the right one, so go ahead and remove it -Get-Container | Where-Object State -EQ "exited" | Remove-Container - -# Now remove the container image -Remove-ContainerImage hello-world - -# And list the container images left on the container host -Get-ContainerImage diff --git a/demos/README.md b/demos/README.md deleted file mode 100644 index 53882c047c6..00000000000 --- a/demos/README.md +++ /dev/null @@ -1,4 +0,0 @@ -This folder contains demos primarily targeted for Linux systems. -Each demo showcases how to use PowerShell to be more productive by -leveraging objects and how it can integrate with existing Linux -scripts and/or commands. diff --git a/demos/SystemD/SystemD/SystemD.psm1 b/demos/SystemD/SystemD/SystemD.psm1 deleted file mode 100644 index d1bf0d8e890..00000000000 --- a/demos/SystemD/SystemD/SystemD.psm1 +++ /dev/null @@ -1,21 +0,0 @@ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. - -Function Get-SystemDJournal { - [CmdletBinding()] - param ( - [Alias("args")][string]$journalctlParameters - ) - $sudocmd = "sudo" - $cmd = "journalctl" - $Result = & $sudocmd $cmd $journalctlParameters -o json --no-pager - Try - { - $JSONResult = $Result|ConvertFrom-Json - $JSONResult - } - Catch - { - $Result - } -} diff --git a/demos/SystemD/journalctl-demo.ps1 b/demos/SystemD/journalctl-demo.ps1 deleted file mode 100644 index 2597bdc3b66..00000000000 --- a/demos/SystemD/journalctl-demo.ps1 +++ /dev/null @@ -1,12 +0,0 @@ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. - -Import-Module $PSScriptRoot/SystemD/SystemD.psm1 - -#list recent journal events -Write-Host -Foreground Blue "Get recent SystemD journal messages" -Get-SystemDJournal -args "-xe" |Out-Host - -#Drill into SystemD unit messages -Write-Host -Foreground Blue "Get recent SystemD journal messages for services and return Unit, Message" -Get-SystemDJournal -args "-xe" | Where-Object {$_._SYSTEMD_UNIT -like "*.service"} | Format-Table _SYSTEMD_UNIT, MESSAGE | Select-Object -First 10 | Out-Host diff --git a/demos/SystemD/readme.md b/demos/SystemD/readme.md deleted file mode 100644 index 87580efbae3..00000000000 --- a/demos/SystemD/readme.md +++ /dev/null @@ -1,10 +0,0 @@ -## SystemD: journalctl demo - -This demo shows use of a PowerShell script module to wrap a native tool (journalctl) so that the output is structured for filtering and presentation control. `journalctl` is expressed as a cmdlet: Get-SystemDJournal, and the JSON output of journalctl is converted to a PowerShell object. - -## Prerequisites ## -- Requires a SystemD-based operating system (Red Hat or CentOS 7, Ubuntu 16.04) -- Install PowerShell - - -Note: Accessing the SystemD journal requires privileges. The user must have authorization to elevate with sudo. You will be prompted for a sudo password when running the demo. \ No newline at end of file diff --git a/demos/WindowsPowerShellModules/README.md b/demos/WindowsPowerShellModules/README.md deleted file mode 100644 index 3cf63bd947e..00000000000 --- a/demos/WindowsPowerShellModules/README.md +++ /dev/null @@ -1,54 +0,0 @@ -# Using Windows PowerShell modules with PowerShell Core - -## Windows PowerShell vs PowerShell Core - -Existing Windows PowerShell users are familiar with the large number of modules available, however, they are not necessarily compatible with PowerShell Core. -More information regarding compatibility is in a [blog post](https://devblogs.microsoft.com/powershell/powershell-6-0-roadmap-coreclr-backwards-compatibility-and-more/). - -Windows PowerShell 5.1 is based on .Net Framework 4.6.1, while PowerShell Core is based on .Net Core 2.x. -Although both adhere to .Net Standard 2.0 and can be compatible, some modules may be using APIs or cmdlets not supported on CoreCLR or using APIs from Windows PowerShell that have been deprecated and removed from PowerShell Core (for example, PSSnapins). - -## Importing a Windows PowerShell module - -Since compatibility cannot be ensured, PowerShell Core, by default, does not look in the Windows PowerShell module path to find those modules. -However, advanced users can explicitly enable PowerShell Core to include the Windows PowerShell module path and attempt to import those modules. - -First, install the [WindowsPSModulePath](https://www.powershellgallery.com/packages/WindowsPSModulePath) module from the PowerShellGallery: - -```powershell -Install-Module WindowsPSModulePath -Scope CurrentUser -``` - -Then run `Add-WindowsPSModulePath` cmdlet to add the Windows PowerShell module path to your PowerShell Core module path: - -```powershell -Add-WindowsPSModulePath -``` - -Note that this is only effective in the current PowerShell session. -If you want to persist this, you can add `Add-WindowsPSModulePath` to your profile: - -```powershell -"Add-WindowsPSModulePath" >> $profile -``` - -Once the module path has been updated, you can list available modules: - -```powershell -Get-Module -ListAvailable -``` - -Note that PowerShell Core is not aware which Windows PowerShell modules will work and which will not so all are listed. -We plan to improve this experience in the future. -You can now import a Windows PowerShell module or just execute a known cmdlet and allow auto-module loading to take care of importing the module: - -```powershell -Get-VM -# this will automatically load the Hyper-V module -``` - -Most of the cmdlets based on CDXML will work just fine, as well as some C# based cmdlets that happen to be .NET Standard 2.0 compatible (for example, Hyper-V module) but the Active Directory module, for example, won't work. - -## How you can help - -Provide comments on Windows PowerShell modules that work or don't work in our [tracking issue](https://github.com/PowerShell/PowerShell/issues/4062). diff --git a/demos/crontab/CronTab/CronTab.ps1xml b/demos/crontab/CronTab/CronTab.ps1xml deleted file mode 100644 index 4246b1f62af..00000000000 --- a/demos/crontab/CronTab/CronTab.ps1xml +++ /dev/null @@ -1,69 +0,0 @@ - - - - - - Default - - CronJob - - - - - - 10 - Left - - - - 10 - Left - - - - 10 - Left - - - - 10 - Left - - - - 10 - Left - - - - Left - - - - - - - Minute - - - Hour - - - DayOfMonth - - - Month - - - DayOfWeek - - - Command - - - - - - - - \ No newline at end of file diff --git a/demos/crontab/CronTab/CronTab.psd1 b/demos/crontab/CronTab/CronTab.psd1 deleted file mode 100755 index aabc48e572e..00000000000 --- a/demos/crontab/CronTab/CronTab.psd1 +++ /dev/null @@ -1,61 +0,0 @@ -@{ - -# Script module or binary module file associated with this manifest. -RootModule = 'CronTab.psm1' - -# Version number of this module. -ModuleVersion = '0.1.0.0' - -# Supported PSEditions -CompatiblePSEditions = @('Core') - -# ID used to uniquely identify this module -GUID = '508bb97f-de2e-482e-aae2-01caec0be8c7' - -# Author of this module -Author = 'PowerShell' - -# Company or vendor of this module -CompanyName = 'Microsoft Corporation' - -# Copyright statement for this module -Copyright = 'Copyright (c) Microsoft Corporation.' - -# Description of the functionality provided by this module -Description = 'Sample module for managing CronTab' - -# Format files (.ps1xml) to be loaded when importing this module -FormatsToProcess = 'CronTab.ps1xml' - -# Functions to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no functions to export. -FunctionsToExport = 'New-CronJob','Remove-CronJob','Get-CronJob','Get-CronTabUser' - -# Private data to pass to the module specified in RootModule/ModuleToProcess. This may also contain a PSData hashtable with additional module metadata used by PowerShell. -PrivateData = @{ - - PSData = @{ - - # Tags applied to this module. These help with module discovery in online galleries. - # Tags = @() - - # A URL to the license for this module. - # LicenseUri = '' - - # A URL to the main website for this project. - # ProjectUri = '' - - # A URL to an icon representing this module. - # IconUri = '' - - # ReleaseNotes of this module - # ReleaseNotes = '' - - } # End of PSData hashtable - -} # End of PrivateData hashtable - -# HelpInfo URI of this module -# HelpInfoURI = '' - -} - diff --git a/demos/crontab/CronTab/CronTab.psm1 b/demos/crontab/CronTab/CronTab.psm1 deleted file mode 100644 index 4cb88e586b9..00000000000 --- a/demos/crontab/CronTab/CronTab.psm1 +++ /dev/null @@ -1,264 +0,0 @@ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. - -using namespace System.Collections.Generic -using namespace System.Management.Automation - -$crontabcmd = "/usr/bin/crontab" - -class CronJob { - [string] $Minute - [string] $Hour - [string] $DayOfMonth - [string] $Month - [string] $DayOfWeek - [string] $Command - - [string] ToString() - { - return "{0} {1} {2} {3} {4} {5}" -f - $this.Minute, $this.Hour, $this.DayOfMonth, $this.Month, $this.DayOfWeek, $this.Command - } -} - -# Internal helper functions - -function Get-CronTab ([String] $user) { - $crontab = Invoke-CronTab -user $user -arguments "-l" -noThrow - if ($crontab -is [ErrorRecord]) { - if ($crontab.Exception.Message.StartsWith("no crontab for ")) { - $crontab = @() - } - else { - throw $crontab.Exception - } - } - [string[]] $crontab -} - -function ConvertTo-CronJob ([String] $crontab) { - $split = $crontab -split " ", 6 - $cronjob = [CronJob]@{ - Minute = $split[0]; - Hour = $split[1]; - DayOfMonth= $split[2]; - Month =$split[3]; - DayOfWeek = $split[4]; - Command = $split[5] - } - $cronjob -} - -function Invoke-CronTab ([String] $user, [String[]] $arguments, [Switch] $noThrow) { - If ($user -ne [String]::Empty) { - $arguments = Write-Output "-u" $UserName $arguments - } - - Write-Verbose "Running: $crontabcmd $arguments" - $output = & $crontabcmd @arguments 2>&1 - if ($LASTEXITCODE -ne 0 -and -not $noThrow) { - $e = New-Object System.InvalidOperationException -ArgumentList $output.Exception.Message - throw $e - } else { - $output - } -} - -function Import-CronTab ([String] $user, [String[]] $crontab) { - $temp = New-TemporaryFile - [String]::Join([Environment]::NewLine,$crontab) | Set-Content $temp.FullName - Invoke-CronTab -user $user $temp.FullName - Remove-Item $temp -} - -# Public functions - -function Remove-CronJob { -<# -.SYNOPSIS - Removes the exactly matching cron job from the cron table - -.DESCRIPTION - Removes the exactly matching cron job from the cron table - -.EXAMPLE - Get-CronJob | Where-Object {%_.Command -like 'foo *'} | Remove-CronJob - -.RETURNVALUE - None - -.PARAMETER UserName - Optional parameter to specify a specific user's cron table - -.PARAMETER Job - Cron job object returned from Get-CronJob - -.PARAMETER Force - Don't prompt when removing the cron job -#> - [CmdletBinding(SupportsShouldProcess=$true,ConfirmImpact="High")] - param ( - [ArgumentCompleter( { $wordToComplete = $args[2]; Get-CronTabUser | Where-Object { $_ -like "$wordToComplete*" } | Sort-Object } )] - [Alias("u")] - [Parameter(Mandatory=$false)] - [String] - $UserName, - - [Alias("j")] - [Parameter(Mandatory=$true,ValueFromPipeline=$true)] - [CronJob] - $Job, - - [Switch] - $Force - ) - process { - - [string[]] $crontab = Get-CronTab -user $UserName - $newcrontab = [List[string]]::new() - $found = $false - - $JobAsString = $Job.ToString() - foreach ($line in $crontab) { - if ($JobAsString -ceq $line) { - $found = $true - } else { - $newcrontab.Add($line) - } - } - - if (-not $found) { - $e = New-Object System.Exception -ArgumentList "Job not found" - throw $e - } - if ($Force -or $PSCmdlet.ShouldProcess($Job.Command,"Remove")) { - Import-CronTab -user $UserName -crontab $newcrontab - } - } -} - -function New-CronJob { -<# -.SYNOPSIS - Create a new cron job -.DESCRIPTION - Create a new job in the cron table. Date and time parameters can be specified - as ranges such as 10-30, as a list: 5,6,7, or combined 1-5,10-15. An asterisk - means 'first through last' (the entire allowed range). Step values can be used - with ranges or with an asterisk. Every 2 hours can be specified as either - 0-23/2 or */2. -.EXAMPLE - New-CronJob -Minute 10-30 -Hour 10-20/2 -DayOfMonth */2 -Command "/bin/bash -c 'echo hello' > ~/hello" - -.RETURNVALUE - If successful, an object representing the cron job is returned - -.PARAMETER UserName - Optional parameter to specify a specific user's cron table - -.PARAMETER Minute - Valid values are 0 to 59. If not specified, defaults to *. - -.PARAMETER Hour - Valid values are 0-23. If not specified, defaults to *. - -.PARAMETER DayOfMonth - Valid values are 1-31. If not specified, defaults to *. - -.PARAMETER Month - Valid values are 1-12. If not specified, defaults to *. - -.PARAMETER DayOfWeek - Valid values are 0-7. 0 and 7 are both Sunday. If not specified, defaults to *. - -.PARAMETER Command - Command to execute at the scheduled time and day. -#> - [CmdletBinding()] - param ( - [ArgumentCompleter( { $wordToComplete = $args[2]; Get-CronTabUser | Where-Object { $_ -like "$wordToComplete*" } | Sort-Object } )] - [Alias("u")] - [Parameter(Mandatory=$false)] - [String] - $UserName, - - [Alias("mi")][Parameter(Position=1)][String[]] $Minute = "*", - [Alias("h")][Parameter(Position=2)][String[]] $Hour = "*", - [Alias("dm")][Parameter(Position=3)][String[]] $DayOfMonth = "*", - [Alias("mo")][Parameter(Position=4)][String[]] $Month = "*", - [Alias("dw")][Parameter(Position=5)][String[]] $DayOfWeek = "*", - [Alias("c")][Parameter(Mandatory=$true,Position=6)][String] $Command - ) - process { - # TODO: validate parameters, note that different versions of crontab support different capabilities - $line = "{0} {1} {2} {3} {4} {5}" -f [String]::Join(",",$Minute), [String]::Join(",",$Hour), - [String]::Join(",",$DayOfMonth), [String]::Join(",",$Month), [String]::Join(",",$DayOfWeek), $Command - [string[]] $crontab = Get-CronTab -user $UserName - $crontab += $line - Import-CronTab -User $UserName -crontab $crontab - ConvertTo-CronJob -crontab $line - } -} - -function Get-CronJob { -<# -.SYNOPSIS - Returns the current cron jobs from the cron table - -.DESCRIPTION - Returns the current cron jobs from the cron table - -.EXAMPLE - Get-CronJob -UserName Steve - -.RETURNVALUE - CronJob objects - -.PARAMETER UserName - Optional parameter to specify a specific user's cron table -#> - [CmdletBinding()] - [OutputType([CronJob])] - param ( - [Alias("u")][Parameter(Mandatory=$false)][String] $UserName - ) - process { - $crontab = Get-CronTab -user $UserName - ForEach ($line in $crontab) { - if ($line.Trim().Length -gt 0) - { - ConvertTo-CronJob -crontab $line - } - } - } -} - -function Get-CronTabUser { -<# -.SYNOPSIS - Returns the users allowed to use crontab -#> - [CmdletBinding()] - [OutputType([String])] - param() - - $allow = '/etc/cron.allow' - if (Test-Path $allow) - { - Get-Content $allow - } - else - { - $users = Get-Content /etc/passwd | ForEach-Object { ($_ -split ':')[0] } - $deny = '/etc/cron.deny' - if (Test-Path $deny) - { - $denyUsers = Get-Content $deny - $users | Where-Object { $denyUsers -notcontains $_ } - } - else - { - $users - } - } -} diff --git a/demos/crontab/README.md b/demos/crontab/README.md deleted file mode 100644 index bdfb16dbb06..00000000000 --- a/demos/crontab/README.md +++ /dev/null @@ -1,15 +0,0 @@ -## CronTab demo - -This demo shows examining, creating, and removing cron jobs via crontab. - -Output of Get-CronJob is a strongly typed object with properties like DayOfWeek or Command. -Remove-CronJob prompts before removing the job unless you specify -Force. - -Tab completion of -UserName is supported, e.g. - -Get-CronJob -u - -NYI: no way to run crontab with sudo if necessary -NYI: ignoring shell variables or comments -NYI: New-CronJob -Description "..." (save in comments" -NYI: @reboot,@daily,@hourly,etc diff --git a/demos/crontab/crontab.ps1 b/demos/crontab/crontab.ps1 deleted file mode 100644 index 3d0ee0741ea..00000000000 --- a/demos/crontab/crontab.ps1 +++ /dev/null @@ -1,32 +0,0 @@ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. - -Import-Module $PSScriptRoot/CronTab/CronTab.psd1 - -Write-Host -Foreground Yellow "Get the existing cron jobs" -Get-CronJob | Out-Host - -Write-Host -Foreground Yellow "New cron job to clean out tmp every day at 1am" -New-CronJob -Command 'rm -rf /tmp/*; #demo' -Hour 1 | Out-Host - -Write-Host -Foreground Yellow "Add some more jobs" -New-CronJob -Command 'python -c ~/scripts/backup_users; #demo' -Hour 2 -DayOfWeek 1-5 | Out-Host -New-CronJob -Command 'powershell -c "cd ~/src/PowerShell; ipmo ./build.psm1; Start-PSBuild"; #demo' -Hour 2 -DayOfWeek * | Out-Host - -Write-Host -Foreground Yellow "Show in bash that the new cron job exists" -crontab -l - -Write-Host -Foreground Yellow "Get jobs that run every day" -Get-CronJob | Where-Object { $_.DayOfWeek -eq '*' -or $_.DayOfWeek -eq '1-7' } | Out-Host - -Write-Host -Foreground Yellow "Remove one cron job, with prompting to confirm" -Get-CronJob | Where-Object { $_.Command -match '^powershell.*' } | Remove-CronJob | Out-Host - -Write-Host -Foreground Yellow "And the other job remains" -Get-CronJob | Out-Host - -Write-Host -Foreground Yellow "Remove remaining demo jobs without prompting" -Get-CronJob | Where-Object { $_.Command -match '#demo'} | Remove-CronJob -Force - -Write-Host -Foreground Yellow "Show in bash that cron should be clean" -crontab -l diff --git a/demos/dsc.ps1 b/demos/dsc.ps1 deleted file mode 100644 index c59be643edc..00000000000 --- a/demos/dsc.ps1 +++ /dev/null @@ -1,14 +0,0 @@ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. - -# DSC MOF Compilation -# DSC Configuration() script that: -# Defines base configuration users, groups, settings -# Uses PS function to set package configuration (ensure=Present) for an array of packages -# Probes for the existence of a package (Apache or MySQL) and conditionally configures the workload. I.e., if Apache is installed, configure Apache settings - -# Demo execution: -# Show the .ps1 -# Run the .ps1 to generate a MOF -# Apply the MOF locally with Start-DSCConfiguration -# Show the newly configured state diff --git a/demos/powershellget/PowerShellGet.ps1 b/demos/powershellget/PowerShellGet.ps1 deleted file mode 100644 index e93216851da..00000000000 --- a/demos/powershellget/PowerShellGet.ps1 +++ /dev/null @@ -1,80 +0,0 @@ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. - -#region find, install, update, uninstall the PowerShell scripts from an online repository. -# Value: equivalent of pypi - -# List of PowerShellGet commands -Get-Command -Module PowerShellGet - -# Discover PowerShell Scripts -Find-Script -Find-Script -Name Start-Demo - -# Save scripts to a specified location -Save-Script Start-Demo -Repository PSGallery -Path /tmp -Get-ChildItem -Path /tmp/Start-Demo.ps1 - -# Install a script to the common scripts location -Find-Script -Name Start-Demo -Repository PSGallery | Install-Script -Get-InstalledScript - -# Install another script to show the update functionality -Install-Script Fabrikam-Script -RequiredVersion 1.0 -Get-InstalledScript -Get-InstalledScript Fabrikam-Script | Format-List * - -# Update the installed scripts -Update-Script -WhatIf -Update-Script -Get-InstalledScript - -# Uninstall a script file -Uninstall-Script Fabrikam-Script -Verbose - -#endregion - -#region Using PowerShellGet find and install modules - -# Value: equivalent of pypi -# Look for all the modules we'll be demoing today -Find-Module -Tag 'PowerShellCore_Demo' - -# Save module to specified location -Save-Module -Tag 'PowerShellCore_Demo' -Path /tmp - -# Pipe this to Install-Module to install them -Find-Module -Tag 'PowerShellCore_Demo' | Install-Module -Verbose -Get-InstalledModule - -# Update all installed modules -Update-Module - -#endregion - -#region Using PowerShellGet with tags - -# Look for all the scripts we'll be demoing today -Find-Script -Tag 'PowerShellCore_Demo' - -# Pipe this to Install-Script to install them -Find-Script -Tag 'PowerShellCore_Demo' | Install-Script -Verbose -Get-InstalledScript - -#endregion - -#region Working with PowerShellGet repositories - -# List available PS repositories -Get-PSRepository - -# Register a new private feed -Register-PSRepository -Name "myPrivateGallery" –SourceLocation "https://www.myget.org/F/powershellgetdemo/api/v2" -InstallationPolicy Trusted - -# Change the trust level for a repositories -Set-PSRepository -Name "myPrivateGallery" -InstallationPolicy "Untrusted" - -# Remove a private feed -Unregister-PSRepository -Name "myPrivateGallery" - -#endregion diff --git a/demos/powershellget/README.md b/demos/powershellget/README.md deleted file mode 100644 index f225610169b..00000000000 --- a/demos/powershellget/README.md +++ /dev/null @@ -1,5 +0,0 @@ -## PowerShellGet demo - -PowerShellGet is a PowerShell module with the commands for discovering, installing, updating and publishing the PowerShell artifacts like Modules, DSC Resources, Role Capabilities and Scripts. - -This demo shows discovering, installing, updating, uninstalling the PowerShell scripts from an online repository. diff --git a/demos/python/README.md b/demos/python/README.md deleted file mode 100644 index d2d1486e2fe..00000000000 --- a/demos/python/README.md +++ /dev/null @@ -1,8 +0,0 @@ -# PowerShell/Python Interoperation Demo - -The `demo_script.ps1` file in this directory walks through a -demonstration of basic interoperation between PowerShell and Python -including how to use JSON to exchange structured objects between -Python and PowerShell. - -The other files in this directory are referenced by `demo_script.ps1`. diff --git a/demos/python/class1.ps1 b/demos/python/class1.ps1 deleted file mode 100644 index b74c0c8d5d6..00000000000 --- a/demos/python/class1.ps1 +++ /dev/null @@ -1,14 +0,0 @@ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. - -# -# Wrap Python script in such a way to make it easy to -# consume from PowerShell -# -# The variable $PSScriptRoot points to the directory -# from which the script was executed. This allows -# picking up the Python script from the same directory -# - -& $PSScriptRoot/class1.py | ConvertFrom-Json - diff --git a/demos/python/class1.py b/demos/python/class1.py deleted file mode 100755 index ad923449455..00000000000 --- a/demos/python/class1.py +++ /dev/null @@ -1,19 +0,0 @@ -#!/usr/bin/python3 - -import json - -# Define a class with a method that returns JSON -class returnsjson: - def __init__(self): - the_object = self - def method1(self): - return json.dumps(['foo', - { - 'bar': ('baz', None, 1.0, 2), - 'buz': ('foo1', 'foo2', 'foo3') - }, - 'alpha', - 1,2,3]) - -c = returnsjson() -print(c.method1()) diff --git a/demos/python/demo_script.ps1 b/demos/python/demo_script.ps1 deleted file mode 100644 index af2067642a1..00000000000 --- a/demos/python/demo_script.ps1 +++ /dev/null @@ -1,63 +0,0 @@ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. - -# -# Demo simple interoperation between PowerShell and Python - -# Basic execution of a Python script fragment -python -c "print('Hi!')" - -# Capture output in a variable -$data = python -c "print('Hi!')" - -# And show the data -$data - -# Use in expressions -5 + (python -c "print(2 + 3)") + 7 - -# Create a Python script using a PowerShell here-string, no extension -@" -#!/usr/bin/python3 -print('Hi!') -"@ | Out-File -Encoding ascii hi - -# Make it executable -chmod +x hi - -# Run it - shows that PowerShell really is a shell -./hi - -# A more complex script that outputs JSON -cat class1.py - -# Run the script -./class1.py - -# Capture the data as structured objects (arrays and hashtables) -$data = ./class1.py | ConvertFrom-Json - -# look at the first element of the returned array -$data[0] - -# Look at the second -$data[1] - -# Get a specific element from the data -$data[1].buz[1] - -# Finally wrap it all up so it looks like a simple PowerShell command -cat class1.ps1 - -# And run it, treating the output as structured data. -(./class1)[1].buz[1] - -# Finally a PowerShell script with in-line Python -cat inline_python.ps1 - -# and run it -./inline_python - -#################################### -# cleanup -rm hi diff --git a/demos/python/inline_python.ps1 b/demos/python/inline_python.ps1 deleted file mode 100644 index 71b65215f74..00000000000 --- a/demos/python/inline_python.ps1 +++ /dev/null @@ -1,19 +0,0 @@ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. - -# -# An example showing inline Python code in a PowerShell script -# - -"Hello from PowerShell!" - -# Inline Python code in a "here string" which allows for a multi-line script -python3 -c @" -print(' Hello from Python!') -print(' Python and PowerShell get along great!') -"@ - -# Back to PowerShell... -"Back to PowerShell." -"Bye now!" - diff --git a/demos/rest/README.md b/demos/rest/README.md deleted file mode 100644 index 03bb103889e..00000000000 --- a/demos/rest/README.md +++ /dev/null @@ -1,7 +0,0 @@ -## REST demo - -This demo shows how to interact with the GitHub API using the Invoke-WebRequest cmdlet. - -rest.ps1: -Invoke-WebRequest and ConvertFrom-Json cmdlets are used to get the issues of a repo. -The issues are processed as objects to find the most commented on issues. diff --git a/demos/rest/rest.ps1 b/demos/rest/rest.ps1 deleted file mode 100644 index f40b49b6538..00000000000 --- a/demos/rest/rest.ps1 +++ /dev/null @@ -1,45 +0,0 @@ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. - -#----------------- - -function Get-Issue -{ - param([string]$UserName, - [string]$Repo, - [ValidateRange(1,100)][int]$PerPage = 100) - - $body = @{ - per_page = $PerPage - } - - $uri = "https://api.github.com/repos/$UserName/$Repo/issues" - while ($uri) - { - $response = Invoke-WebRequest -Uri $uri -Body $body - $response.Content | ConvertFrom-Json | Write-Output - - $uri = $null - foreach ($link in $response.Headers.Link -split ',') - { - if ($link -match '\s*<(.*)>;\s+rel="next"') - { - $uri = $Matches[1] - } - } - } -} - -$issues = Get-Issue -UserName lzybkr -Repo PSReadline - -$issues.Count - -$issues | Sort-Object -Descending comments | Select-Object -First 15 | ft number,comments,title - -foreach ($issue in $issues) -{ - if ($issue.labels.name -contains 'bug' -and $issue.labels.name -contains 'vi mode') - { - "{0} is a vi mode bug" -f $issue.url - } -} From ea39b567a5d8aeb190fdb87f97bc7c998023fed9 Mon Sep 17 00:00:00 2001 From: Aditya Patwardhan Date: Fri, 20 Sep 2024 12:40:59 -0700 Subject: [PATCH 014/173] Do not build the exe for Global tool shim project (#24263) (#24315) --- build.psm1 | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/build.psm1 b/build.psm1 index 36f958bab84..dd815da872a 100644 --- a/build.psm1 +++ b/build.psm1 @@ -587,6 +587,13 @@ Fix steps: try { Push-Location $globalToolSrcFolder + + if ($Options.Runtime -like 'fxdependent*') { + if ($Arguments -contains '/property:UseAppHost=true') { + $Arguments = @($Arguments | Where-Object { $_ -notlike '/property:UseAppHost=true' }) + } + } + if ($Arguments -notcontains '--output') { $Arguments += "--output", $publishPath } From 95850df6e9cbe1690990f9763545823256a2a39a Mon Sep 17 00:00:00 2001 From: Aditya Patwardhan Date: Fri, 20 Sep 2024 12:42:16 -0700 Subject: [PATCH 015/173] Fix how processor architecture is validated in `Import-Module` (#24265) (#24317) --- .../engine/Modules/ModuleCmdletBase.cs | 10 ++++++---- .../Import-Module.Tests.ps1 | 12 ++++++++++++ 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/src/System.Management.Automation/engine/Modules/ModuleCmdletBase.cs b/src/System.Management.Automation/engine/Modules/ModuleCmdletBase.cs index 3bbb9126fac..00b02368270 100644 --- a/src/System.Management.Automation/engine/Modules/ModuleCmdletBase.cs +++ b/src/System.Management.Automation/engine/Modules/ModuleCmdletBase.cs @@ -16,6 +16,7 @@ using System.Management.Automation.Runspaces; using System.Management.Automation.Security; using System.Reflection; +using System.Runtime.InteropServices; using System.Text; using System.Xml; using System.Diagnostics; @@ -1920,11 +1921,12 @@ internal PSModuleInfo LoadModuleManifest( else if ((requiredProcessorArchitecture != ProcessorArchitecture.None) && (requiredProcessorArchitecture != ProcessorArchitecture.MSIL)) { - #pragma warning disable SYSLIB0037 - ProcessorArchitecture currentArchitecture = typeof(object).Assembly.GetName().ProcessorArchitecture; - #pragma warning restore SYSLIB0037 + Architecture currentArchitecture = RuntimeInformation.ProcessArchitecture; - if (currentArchitecture != requiredProcessorArchitecture) + if ((requiredProcessorArchitecture == ProcessorArchitecture.X86 && currentArchitecture != Architecture.X86) || + (requiredProcessorArchitecture == ProcessorArchitecture.Amd64 && currentArchitecture != Architecture.X64) || + (requiredProcessorArchitecture == ProcessorArchitecture.Arm && (currentArchitecture != Architecture.Arm && currentArchitecture != Architecture.Arm64)) || + requiredProcessorArchitecture == ProcessorArchitecture.IA64) { containedErrors = true; if (writingErrors) diff --git a/test/powershell/Modules/Microsoft.PowerShell.Core/Import-Module.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Core/Import-Module.Tests.ps1 index d7216720dd7..6885abe847d 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Core/Import-Module.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Core/Import-Module.Tests.ps1 @@ -56,6 +56,18 @@ Describe "Import-Module" -Tags "CI" { Import-Module TestModule -RequiredVersion 1.1 (Get-Module TestModule).Version | Should -BeIn "1.1" } + + It 'ProcessorArchitecture should work' { + $currentProcessorArchitecture = switch ([System.Runtime.InteropServices.RuntimeInformation]::ProcessArchitecture) { + 'X86' { 'x86' } + 'X64' { 'amd64' } + 'Arm64' { 'arm' } + default { throw "Unknown processor architecture" } + } + New-ModuleManifest -Path "$TestDrive\TestModule.psd1" -ProcessorArchitecture $currentProcessorArchitecture + $module = Import-Module -Name "$TestDrive\TestModule.psd1" -PassThru + $module.ProcessorArchitecture | Should -Be $currentProcessorArchitecture + } } Describe "Import-Module with ScriptsToProcess" -Tags "CI" { From ca88d3c4a722e5c16804ff8ce22650ecf65ae650 Mon Sep 17 00:00:00 2001 From: Aditya Patwardhan Date: Fri, 20 Sep 2024 12:42:42 -0700 Subject: [PATCH 016/173] Make some release tests run in a hosted pools (#24270) (#24318) Co-authored-by: Travis Plunk --- .pipelines/PowerShell-Release-Official.yml | 10 ++-- .pipelines/templates/release-validate-sdk.yml | 46 +++++++++++-------- 2 files changed, 33 insertions(+), 23 deletions(-) diff --git a/.pipelines/PowerShell-Release-Official.yml b/.pipelines/PowerShell-Release-Official.yml index 223517f2e96..eb21b407ba7 100644 --- a/.pipelines/PowerShell-Release-Official.yml +++ b/.pipelines/PowerShell-Release-Official.yml @@ -51,6 +51,7 @@ variables: value: mcr.microsoft.com/onebranch/cbl-mariner/build:2.0 - name: ReleaseTagVar value: ${{ parameters.ReleaseTagVar }} + - group: PoolNames resources: repositories: @@ -111,19 +112,22 @@ extends: parameters: jobName: "windowsSDK" displayName: "Windows SDK Validation" - jobtype: windows + imageName: PSMMS2019-Secure + poolName: $(windowsPool) - template: /.pipelines/templates/release-validate-sdk.yml@self parameters: jobName: "MacOSSDK" displayName: "MacOS SDK Validation" - jobtype: macos + imageName: macOS-latest + poolName: Azure Pipelines - template: /.pipelines/templates/release-validate-sdk.yml@self parameters: jobName: "LinuxSDK" displayName: "Linux SDK Validation" - jobtype: linux + imageName: PSMMSUbuntu20.04-Secure + poolName: $(ubuntuPool) - stage: gbltool displayName: 'Validate Global tools' diff --git a/.pipelines/templates/release-validate-sdk.yml b/.pipelines/templates/release-validate-sdk.yml index 3cd5425478e..f626051b543 100644 --- a/.pipelines/templates/release-validate-sdk.yml +++ b/.pipelines/templates/release-validate-sdk.yml @@ -1,34 +1,36 @@ parameters: jobName: "" displayName: "" - jobtype: "windows" + poolName: "windows" + imageName: 'none' jobs: - job: ${{ parameters.jobName }} displayName: ${{ parameters.displayName }} pool: - ${{ if eq(parameters.jobtype, 'macos') }}: - type: linux - isCustom: true - name: Azure Pipelines - vmImage: 'macOS-latest' + type: linux + isCustom: true + ${{ if eq( parameters.poolName, 'Azure Pipelines') }}: + name: ${{ parameters.poolName }} + vmImage: ${{ parameters.imageName }} ${{ else }}: - type: ${{ parameters.jobtype }} + name: ${{ parameters.poolName }} + demands: + - ImageOverride -equals ${{ parameters.imageName }} variables: - group: mscodehub-feed-read-general - group: mscodehub-feed-read-akv - group: DotNetPrivateBuildAccess - - name: ob_outputDirectory - value: '$(Build.ArtifactStagingDirectory)/ONEBRANCH_ARTIFACT' - - name: ob_sdl_credscan_suppressionsFile - value: $(Build.SourcesDirectory)\PowerShell\.config\suppress.json - - name: ob_sdl_tsa_configFile - value: $(Build.SourcesDirectory)\PowerShell\.config\tsaoptions.json steps: - checkout: self clean: true + lfs: false + + - template: /.pipelines/templates/insert-nuget-config-azfeed.yml@self + parameters: + repoRoot: "$(Build.SourcesDirectory)" - template: release-SetReleaseTagandContainerName.yml@self @@ -45,7 +47,7 @@ jobs: displayName: 'Capture Downloaded Artifacts' - pwsh: | - $repoRoot = $isMacOS ? "$(Build.SourcesDirectory)" : "$(Build.SourcesDirectory)/PowerShell" + $repoRoot = "$(Build.SourcesDirectory)" $dotnetMetadataPath = "$repoRoot/DotnetRuntimeMetadata.json" $dotnetMetadataJson = Get-Content $dotnetMetadataPath -Raw | ConvertFrom-Json @@ -80,7 +82,7 @@ jobs: __DOTNET_RUNTIME_FEED_KEY: $(RUNTIME_SOURCEFEED_KEY) - pwsh: | - $repoRoot = $isMacOS ? "$(Build.SourcesDirectory)" : "$(Build.SourcesDirectory)/PowerShell" + $repoRoot = "$(Build.SourcesDirectory)" $env:DOTNET_SKIP_FIRST_TIME_EXPERIENCE=1 Import-Module "$repoRoot/build.psm1" -Force @@ -102,12 +104,17 @@ jobs: Get-ChildItem ## register the packages download directory in the nuget file - # $nugetConfigContent = Get-Content ./NuGet.Config -Raw - # $updateNugetContent = $nugetConfigContent.Replace("", $xmlElement) + $nugetPath = './NuGet.Config' + if(!(test-path $nugetPath)) { + $nugetPath = "$repoRoot/nuget.config" + } + Write-Verbose -Verbose "nugetPath: $nugetPath" + $nugetConfigContent = Get-Content $nugetPath -Raw + $updateNugetContent = $nugetConfigContent.Replace("", $xmlElement) - # $updateNugetContent | Out-File ./NuGet.Config -Encoding ascii + $updateNugetContent | Out-File $nugetPath -Encoding ascii - # Get-Content ./NuGet.Config + Get-Content $nugetPath # Add workaround to unblock xUnit testing see issue: https://github.com/dotnet/sdk/issues/26462 $dotnetPath = if ($IsWindows) { "$env:LocalAppData\Microsoft\dotnet" } else { "$env:HOME/.dotnet" } @@ -116,7 +123,6 @@ jobs: dotnet --info dotnet restore dotnet test /property:RELEASE_VERSION=$releaseVersion --test-adapter-path:. "--logger:xunit;LogFilePath=$(System.DefaultWorkingDirectory)/test-hosting.xml" - displayName: Restore and execute tests env: __DOTNET_RUNTIME_FEED_KEY: $(RUNTIME_SOURCEFEED_KEY) From 77422389593a3363805a36af807d5a958ab9c3b5 Mon Sep 17 00:00:00 2001 From: Aditya Patwardhan Date: Fri, 20 Sep 2024 12:43:08 -0700 Subject: [PATCH 017/173] Update experimental-feature json files (#24271) (#24319) --- experimental-feature-linux.json | 7 ++----- experimental-feature-windows.json | 7 ++----- 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/experimental-feature-linux.json b/experimental-feature-linux.json index b5af1955d29..f97b56b6013 100644 --- a/experimental-feature-linux.json +++ b/experimental-feature-linux.json @@ -1,10 +1,7 @@ [ - "PSCommandNotFoundSuggestion", - "PSCommandWithArgs", "PSFeedbackProvider", "PSLoadAssemblyFromNativeCode", - "PSModuleAutoLoadSkipOfflineFiles", "PSNativeWindowsTildeExpansion", - "PSSubsystemPluginModel", - "PSRedirectToVariable" + "PSRedirectToVariable", + "PSSubsystemPluginModel" ] diff --git a/experimental-feature-windows.json b/experimental-feature-windows.json index b5af1955d29..f97b56b6013 100644 --- a/experimental-feature-windows.json +++ b/experimental-feature-windows.json @@ -1,10 +1,7 @@ [ - "PSCommandNotFoundSuggestion", - "PSCommandWithArgs", "PSFeedbackProvider", "PSLoadAssemblyFromNativeCode", - "PSModuleAutoLoadSkipOfflineFiles", "PSNativeWindowsTildeExpansion", - "PSSubsystemPluginModel", - "PSRedirectToVariable" + "PSRedirectToVariable", + "PSSubsystemPluginModel" ] From f484c607d277bfecc11552f03029eca96799709f Mon Sep 17 00:00:00 2001 From: Aditya Patwardhan Date: Fri, 20 Sep 2024 12:43:27 -0700 Subject: [PATCH 018/173] Bump .NET 9 to `9.0.100-rc.1.24452.12` (#24273) (#24320) --- global.json | 2 +- ...rosoft.PowerShell.Commands.Diagnostics.csproj | 2 +- ...crosoft.PowerShell.Commands.Management.csproj | 2 +- .../cimSupport/cmdletization/cim/cimConverter.cs | 2 ++ .../Microsoft.PowerShell.Commands.Utility.csproj | 4 ++-- .../Microsoft.PowerShell.CoreCLR.Eventing.csproj | 2 +- .../Microsoft.PowerShell.SDK.csproj | 8 ++++---- .../security/CertificateCommands.cs | 3 +++ .../Microsoft.WSMan.Management.csproj | 2 +- .../System.Management.Automation.csproj | 16 ++++++++-------- .../engine/serialization.cs | 2 ++ .../security/SecuritySupport.cs | 9 +++++++-- test/powershell/Host/Startup.Tests.ps1 | 1 + test/tools/TestService/TestService.csproj | 4 ++-- test/tools/WebListener/Program.cs | 12 ++++++++++++ test/tools/WebListener/WebListener.csproj | 4 ++-- 16 files changed, 50 insertions(+), 25 deletions(-) diff --git a/global.json b/global.json index de9b44d3e3b..0519736ab95 100644 --- a/global.json +++ b/global.json @@ -1,5 +1,5 @@ { "sdk": { - "version": "9.0.100-preview.6.24328.19" + "version": "9.0.100-rc.1.24452.12" } } diff --git a/src/Microsoft.PowerShell.Commands.Diagnostics/Microsoft.PowerShell.Commands.Diagnostics.csproj b/src/Microsoft.PowerShell.Commands.Diagnostics/Microsoft.PowerShell.Commands.Diagnostics.csproj index a438fa73e0d..9f36b8134d1 100644 --- a/src/Microsoft.PowerShell.Commands.Diagnostics/Microsoft.PowerShell.Commands.Diagnostics.csproj +++ b/src/Microsoft.PowerShell.Commands.Diagnostics/Microsoft.PowerShell.Commands.Diagnostics.csproj @@ -8,7 +8,7 @@ - + diff --git a/src/Microsoft.PowerShell.Commands.Management/Microsoft.PowerShell.Commands.Management.csproj b/src/Microsoft.PowerShell.Commands.Management/Microsoft.PowerShell.Commands.Management.csproj index cfa5ea247dc..695ed6f21e4 100644 --- a/src/Microsoft.PowerShell.Commands.Management/Microsoft.PowerShell.Commands.Management.csproj +++ b/src/Microsoft.PowerShell.Commands.Management/Microsoft.PowerShell.Commands.Management.csproj @@ -47,7 +47,7 @@ - + diff --git a/src/Microsoft.PowerShell.Commands.Management/cimSupport/cmdletization/cim/cimConverter.cs b/src/Microsoft.PowerShell.Commands.Management/cimSupport/cmdletization/cim/cimConverter.cs index 5522049a48f..17a085b7ce5 100644 --- a/src/Microsoft.PowerShell.Commands.Management/cimSupport/cmdletization/cim/cimConverter.cs +++ b/src/Microsoft.PowerShell.Commands.Management/cimSupport/cmdletization/cim/cimConverter.cs @@ -425,7 +425,9 @@ internal static object ConvertFromCimToDotNet(object cimObject, Type expectedDot var cimIntrinsicValue = (byte[])LanguagePrimitives.ConvertTo(cimObject, typeof(byte[]), CultureInfo.InvariantCulture); return exceptionSafeReturn(delegate { + #pragma warning disable SYSLIB0057 return new X509Certificate2(cimIntrinsicValue); + #pragma warning restore SYSLIB0057 }); } diff --git a/src/Microsoft.PowerShell.Commands.Utility/Microsoft.PowerShell.Commands.Utility.csproj b/src/Microsoft.PowerShell.Commands.Utility/Microsoft.PowerShell.Commands.Utility.csproj index 9dd33935fc2..113d62231f0 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/Microsoft.PowerShell.Commands.Utility.csproj +++ b/src/Microsoft.PowerShell.Commands.Utility/Microsoft.PowerShell.Commands.Utility.csproj @@ -33,8 +33,8 @@ - - + + diff --git a/src/Microsoft.PowerShell.CoreCLR.Eventing/Microsoft.PowerShell.CoreCLR.Eventing.csproj b/src/Microsoft.PowerShell.CoreCLR.Eventing/Microsoft.PowerShell.CoreCLR.Eventing.csproj index 4271ef37843..1296b1e28ba 100644 --- a/src/Microsoft.PowerShell.CoreCLR.Eventing/Microsoft.PowerShell.CoreCLR.Eventing.csproj +++ b/src/Microsoft.PowerShell.CoreCLR.Eventing/Microsoft.PowerShell.CoreCLR.Eventing.csproj @@ -8,7 +8,7 @@ - + diff --git a/src/Microsoft.PowerShell.SDK/Microsoft.PowerShell.SDK.csproj b/src/Microsoft.PowerShell.SDK/Microsoft.PowerShell.SDK.csproj index 4bc37fa3d11..34c462edbd4 100644 --- a/src/Microsoft.PowerShell.SDK/Microsoft.PowerShell.SDK.csproj +++ b/src/Microsoft.PowerShell.SDK/Microsoft.PowerShell.SDK.csproj @@ -21,9 +21,9 @@ - - - + + + - + diff --git a/src/Microsoft.PowerShell.Security/security/CertificateCommands.cs b/src/Microsoft.PowerShell.Security/security/CertificateCommands.cs index 4d65d628ad3..e3a386ee507 100644 --- a/src/Microsoft.PowerShell.Security/security/CertificateCommands.cs +++ b/src/Microsoft.PowerShell.Security/security/CertificateCommands.cs @@ -208,8 +208,11 @@ protected override void ProcessRecord() private static X509Certificate2 GetCertFromPfxFile(string path, SecureString password) { + // No overload found in X509CertificateLoader that takes SecureString + #pragma warning disable SYSLIB0057 var cert = new X509Certificate2(path, password, X509KeyStorageFlags.DefaultKeySet); return cert; + #pragma warning restore SYSLIB0057 } } } diff --git a/src/Microsoft.WSMan.Management/Microsoft.WSMan.Management.csproj b/src/Microsoft.WSMan.Management/Microsoft.WSMan.Management.csproj index 382b7c63913..9a8f4973d1a 100644 --- a/src/Microsoft.WSMan.Management/Microsoft.WSMan.Management.csproj +++ b/src/Microsoft.WSMan.Management/Microsoft.WSMan.Management.csproj @@ -10,7 +10,7 @@ - + diff --git a/src/System.Management.Automation/System.Management.Automation.csproj b/src/System.Management.Automation/System.Management.Automation.csproj index 3319c928fa2..e4b0c5d7e48 100644 --- a/src/System.Management.Automation/System.Management.Automation.csproj +++ b/src/System.Management.Automation/System.Management.Automation.csproj @@ -34,16 +34,16 @@ - - - - + + + + - + - - - + + + diff --git a/src/System.Management.Automation/engine/serialization.cs b/src/System.Management.Automation/engine/serialization.cs index 244e83d6af9..9e2fe5db58a 100644 --- a/src/System.Management.Automation/engine/serialization.cs +++ b/src/System.Management.Automation/engine/serialization.cs @@ -7292,7 +7292,9 @@ internal static PSSenderInfo RehydratePSSenderInfo(PSObject pso) private static System.Security.Cryptography.X509Certificates.X509Certificate2 RehydrateX509Certificate2(PSObject pso) { byte[] rawData = GetPropertyValue(pso, "RawData"); + #pragma warning disable SYSLIB0057 return new System.Security.Cryptography.X509Certificates.X509Certificate2(rawData); + #pragma warning restore SYSLIB0057 } private static System.Security.Cryptography.X509Certificates.X500DistinguishedName RehydrateX500DistinguishedName(PSObject pso) diff --git a/src/System.Management.Automation/security/SecuritySupport.cs b/src/System.Management.Automation/security/SecuritySupport.cs index 2089c2217ed..0c563eb46b3 100644 --- a/src/System.Management.Automation/security/SecuritySupport.cs +++ b/src/System.Management.Automation/security/SecuritySupport.cs @@ -1104,7 +1104,10 @@ private void ResolveFromBase64Encoding(ResolutionPurpose purpose, out ErrorRecor var certificatesToProcess = new X509Certificate2Collection(); try { + #pragma warning disable SYSLIB0057 X509Certificate2 newCertificate = new X509Certificate2(messageBytes); + #pragma warning restore SYSLIB0057 + certificatesToProcess.Add(newCertificate); } catch (Exception) @@ -1182,7 +1185,9 @@ private void ResolveFromPath(SessionState sessionState, ResolutionPurpose purpos try { + #pragma warning disable SYSLIB0057 certificate = new X509Certificate2(path); + #pragma warning restore SYSLIB0057 } catch (Exception) { @@ -1337,7 +1342,7 @@ internal static class AmsiUtils static AmsiUtils() { #if !UNIX - try + try { s_amsiInitFailed = !CheckAmsiInit(); } @@ -1347,7 +1352,7 @@ static AmsiUtils() s_amsiInitFailed = true; return; } - + PSEtwLog.LogAmsiUtilStateEvent($"init-{s_amsiInitFailed}", $"{s_amsiContext}-{s_amsiSession}"); #endif } diff --git a/test/powershell/Host/Startup.Tests.ps1 b/test/powershell/Host/Startup.Tests.ps1 index 2845e79cccd..35c22fefe58 100644 --- a/test/powershell/Host/Startup.Tests.ps1 +++ b/test/powershell/Host/Startup.Tests.ps1 @@ -71,6 +71,7 @@ Describe "Validate start of console host" -Tag CI { } else { $allowedAssemblies += @( + 'System.Diagnostics.DiagnosticSource.dll' 'System.Net.Sockets.dll' ) } diff --git a/test/tools/TestService/TestService.csproj b/test/tools/TestService/TestService.csproj index 38deb50c615..f6ca75e1dae 100644 --- a/test/tools/TestService/TestService.csproj +++ b/test/tools/TestService/TestService.csproj @@ -15,8 +15,8 @@ - - + + diff --git a/test/tools/WebListener/Program.cs b/test/tools/WebListener/Program.cs index a2d49a45fc5..500e1c7062c 100644 --- a/test/tools/WebListener/Program.cs +++ b/test/tools/WebListener/Program.cs @@ -44,7 +44,10 @@ public static IWebHost BuildWebHost(string[] args) => int.Parse(args[3]), listenOptions => { + #pragma warning disable SYSLIB0057 var certificate = new X509Certificate2(args[0], args[1]); + #pragma warning restore SYSLIB0057 + HttpsConnectionAdapterOptions httpsOption = new HttpsConnectionAdapterOptions(); httpsOption.SslProtocols = SslProtocols.Tls12; httpsOption.ClientCertificateMode = ClientCertificateMode.AllowCertificate; @@ -60,7 +63,10 @@ public static IWebHost BuildWebHost(string[] args) => int.Parse(args[4]), listenOptions => { + #pragma warning disable SYSLIB0057 var certificate = new X509Certificate2(args[0], args[1]); + #pragma warning restore SYSLIB0057 + HttpsConnectionAdapterOptions httpsOption = new HttpsConnectionAdapterOptions(); // TLS 1.1 is obsolete. Using this value now defaults to TLS 1.2. @@ -79,7 +85,10 @@ public static IWebHost BuildWebHost(string[] args) => int.Parse(args[5]), listenOptions => { + #pragma warning disable SYSLIB0057 var certificate = new X509Certificate2(args[0], args[1]); + #pragma warning restore SYSLIB0057 + HttpsConnectionAdapterOptions httpsOption = new HttpsConnectionAdapterOptions(); // TLS is obsolete. Using this value now defaults to TLS 1.2. @@ -98,7 +107,10 @@ public static IWebHost BuildWebHost(string[] args) => int.Parse(args[6]), listenOptions => { + #pragma warning disable SYSLIB0057 var certificate = new X509Certificate2(args[0], args[1]); + #pragma warning restore SYSLIB0057 + HttpsConnectionAdapterOptions httpsOption = new HttpsConnectionAdapterOptions(); httpsOption.SslProtocols = SslProtocols.Tls13; httpsOption.ClientCertificateMode = ClientCertificateMode.AllowCertificate; diff --git a/test/tools/WebListener/WebListener.csproj b/test/tools/WebListener/WebListener.csproj index c6cd9d4c6eb..791be2fd228 100644 --- a/test/tools/WebListener/WebListener.csproj +++ b/test/tools/WebListener/WebListener.csproj @@ -7,7 +7,7 @@ - - + + From fd4e71b1fac68d667bc40967ecfaa05d4cf33eeb Mon Sep 17 00:00:00 2001 From: Aditya Patwardhan Date: Fri, 20 Sep 2024 14:48:06 -0700 Subject: [PATCH 019/173] Update and add new NuGet package sources for different environments. (#24264) (#24316) --- build.psm1 | 2 ++ test/tools/Modules/nuget.config | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/build.psm1 b/build.psm1 index dd815da872a..2d038367713 100644 --- a/build.psm1 +++ b/build.psm1 @@ -767,11 +767,13 @@ function Switch-PSNugetConfig { New-NugetConfigFile -NugetPackageSource $nugetorg, $dotnetSdk -Destination "$PSScriptRoot/" @extraParams New-NugetConfigFile -NugetPackageSource $gallery -Destination "$PSScriptRoot/src/Modules/" @extraParams + New-NugetConfigFile -NugetPackageSource $gallery -Destination "$PSScriptRoot/test/tools/Modules/" @extraParams } elseif ( $Source -eq 'Private') { $powerShellPackages = [NugetPackageSource] @{Url = 'https://pkgs.dev.azure.com/powershell/PowerShell/_packaging/PowerShell-7-5-preview-test-2/nuget/v3/index.json'; Name = 'powershell' } New-NugetConfigFile -NugetPackageSource $powerShellPackages -Destination "$PSScriptRoot/" @extraParams New-NugetConfigFile -NugetPackageSource $powerShellPackages -Destination "$PSScriptRoot/src/Modules/" @extraParams + New-NugetConfigFile -NugetPackageSource $powerShellPackages -Destination "$PSScriptRoot/test/tools/Modules/" @extraParams } else { throw "Unknown source: $Source" } diff --git a/test/tools/Modules/nuget.config b/test/tools/Modules/nuget.config index b0fc73009da..3ca2bee3c18 100644 --- a/test/tools/Modules/nuget.config +++ b/test/tools/Modules/nuget.config @@ -2,7 +2,7 @@ - + From 7d1ab31ce256ca5598845b4b50753b3cc1d4ec96 Mon Sep 17 00:00:00 2001 From: Aditya Patwardhan Date: Fri, 20 Sep 2024 14:54:42 -0700 Subject: [PATCH 020/173] Add mapping to `AzureLinux` repo (#24290) (#24322) Co-authored-by: Anam Navied --- tools/packages.microsoft.com/mapping.json | 32 +++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/tools/packages.microsoft.com/mapping.json b/tools/packages.microsoft.com/mapping.json index d0be6c8e93f..b904aa9d63b 100644 --- a/tools/packages.microsoft.com/mapping.json +++ b/tools/packages.microsoft.com/mapping.json @@ -53,6 +53,38 @@ "PackageFormat": "PACKAGE_NAME-POWERSHELL_RELEASE-1.cm.x86_64.rpm", "channel": "preview" }, + { + "url": "azurelinux-3.0-prod-ms-oss-aarch64", + "distribution": [ + "bionic" + ], + "PackageFormat": "PACKAGE_NAME-POWERSHELL_RELEASE-1.cm.aarch64.rpm", + "channel": "stable" + }, + { + "url": "azurelinux-3.0-prod-ms-oss-x86_64", + "distribution": [ + "bionic" + ], + "PackageFormat": "PACKAGE_NAME-POWERSHELL_RELEASE-1.cm.x86_64.rpm", + "channel": "stable" + }, + { + "url": "azurelinux-3.0-preview-ms-oss-aarch64", + "distribution": [ + "bionic" + ], + "PackageFormat": "PACKAGE_NAME-POWERSHELL_RELEASE-1.cm.aarch64.rpm", + "channel": "preview" + }, + { + "url": "azurelinux-3.0-preview-ms-oss-x86_64", + "distribution": [ + "bionic" + ], + "PackageFormat": "PACKAGE_NAME-POWERSHELL_RELEASE-1.cm.x86_64.rpm", + "channel": "preview" + }, { "url": "microsoft-debian-stretch-prod", "distribution": [ From 4ac60c954831bd7fb8809f94f9036e5b4c2df24c Mon Sep 17 00:00:00 2001 From: Aditya Patwardhan Date: Fri, 20 Sep 2024 14:55:20 -0700 Subject: [PATCH 021/173] Add updated `libicu` dependency for Debian packages (#24301) (#24324) --- tools/packages.microsoft.com/mapping.json | 7 +++++++ tools/packaging/packaging.psm1 | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/tools/packages.microsoft.com/mapping.json b/tools/packages.microsoft.com/mapping.json index b904aa9d63b..b3753722a59 100644 --- a/tools/packages.microsoft.com/mapping.json +++ b/tools/packages.microsoft.com/mapping.json @@ -120,6 +120,13 @@ ], "PackageFormat": "PACKAGE_NAME_POWERSHELL_RELEASE-1.deb_amd64.deb" }, + { + "url": "microsoft-ubuntu-noble-prod", + "distribution": [ + "noble" + ], + "PackageFormat": "PACKAGE_NAME_POWERSHELL_RELEASE-1.deb_amd64.deb" + }, { "url": "microsoft-ubuntu-xenial-prod", "distribution": [ diff --git a/tools/packaging/packaging.psm1 b/tools/packaging/packaging.psm1 index c12974a6880..1c3686591f0 100644 --- a/tools/packaging/packaging.psm1 +++ b/tools/packaging/packaging.psm1 @@ -1598,7 +1598,7 @@ function Get-PackageDependencies "libgssapi-krb5-2", "libstdc++6", "zlib1g", - "libicu72|libicu71|libicu70|libicu69|libicu68|libicu67|libicu66|libicu65|libicu63|libicu60|libicu57|libicu55|libicu52", + "libicu74|libicu72|libicu71|libicu70|libicu69|libicu68|libicu67|libicu66|libicu65|libicu63|libicu60|libicu57|libicu55|libicu52", "libssl3|libssl1.1|libssl1.0.2|libssl1.0.0" ) From 8ff65501a4eefef3972e8da64b090c8877f6eee2 Mon Sep 17 00:00:00 2001 From: Aditya Patwardhan Date: Fri, 20 Sep 2024 14:55:44 -0700 Subject: [PATCH 022/173] Treat large Enum values as numbers in `ConvertTo-Json` (#20999) (#24304) --- experimental-feature-linux.json | 1 + experimental-feature-windows.json | 1 + .../commands/utility/WebCmdlet/JsonObject.cs | 2 +- .../ExperimentalFeature.cs | 5 +++ ....PSSerializeJSONLongEnumAsNumber.Tests.ps1 | 34 +++++++++++++++++ .../Json.Tests.ps1 | 38 ++++++++++--------- test/tools/TestMetadata.json | 3 +- 7 files changed, 64 insertions(+), 20 deletions(-) create mode 100644 test/powershell/Modules/Microsoft.PowerShell.Utility/ConvertTo-Json.PSSerializeJSONLongEnumAsNumber.Tests.ps1 diff --git a/experimental-feature-linux.json b/experimental-feature-linux.json index f97b56b6013..232109de447 100644 --- a/experimental-feature-linux.json +++ b/experimental-feature-linux.json @@ -3,5 +3,6 @@ "PSLoadAssemblyFromNativeCode", "PSNativeWindowsTildeExpansion", "PSRedirectToVariable", + "PSSerializeJSONLongEnumAsNumber", "PSSubsystemPluginModel" ] diff --git a/experimental-feature-windows.json b/experimental-feature-windows.json index f97b56b6013..232109de447 100644 --- a/experimental-feature-windows.json +++ b/experimental-feature-windows.json @@ -3,5 +3,6 @@ "PSLoadAssemblyFromNativeCode", "PSNativeWindowsTildeExpansion", "PSRedirectToVariable", + "PSSerializeJSONLongEnumAsNumber", "PSSubsystemPluginModel" ] diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/JsonObject.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/JsonObject.cs index 8e0e7e7776d..33465683153 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/JsonObject.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/JsonObject.cs @@ -577,7 +577,7 @@ private static object ProcessValue(object obj, int currentDepth, in ConvertToJso { Type t = obj.GetType(); - if (t.IsPrimitive) + if (t.IsPrimitive || (t.IsEnum && ExperimentalFeature.IsEnabled(ExperimentalFeature.PSSerializeJSONLongEnumAsNumber))) { rv = obj; } diff --git a/src/System.Management.Automation/engine/ExperimentalFeature/ExperimentalFeature.cs b/src/System.Management.Automation/engine/ExperimentalFeature/ExperimentalFeature.cs index 7e358e94e94..dd26e609641 100644 --- a/src/System.Management.Automation/engine/ExperimentalFeature/ExperimentalFeature.cs +++ b/src/System.Management.Automation/engine/ExperimentalFeature/ExperimentalFeature.cs @@ -24,6 +24,7 @@ public class ExperimentalFeature internal const string PSFeedbackProvider = "PSFeedbackProvider"; internal const string PSNativeWindowsTildeExpansion = nameof(PSNativeWindowsTildeExpansion); internal const string PSRedirectToVariable = "PSRedirectToVariable"; + internal const string PSSerializeJSONLongEnumAsNumber = nameof(PSSerializeJSONLongEnumAsNumber); #endregion @@ -121,6 +122,10 @@ static ExperimentalFeature() new ExperimentalFeature( name: PSRedirectToVariable, description: "Add support for redirecting to the variable drive"), + new ExperimentalFeature( + name: PSSerializeJSONLongEnumAsNumber, + description: "Serialize enums based on long or ulong as an numeric value rather than the string representation when using ConvertTo-Json." + ) }; EngineExperimentalFeatures = new ReadOnlyCollection(engineFeatures); diff --git a/test/powershell/Modules/Microsoft.PowerShell.Utility/ConvertTo-Json.PSSerializeJSONLongEnumAsNumber.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Utility/ConvertTo-Json.PSSerializeJSONLongEnumAsNumber.Tests.ps1 new file mode 100644 index 00000000000..d21b87ce221 --- /dev/null +++ b/test/powershell/Modules/Microsoft.PowerShell.Utility/ConvertTo-Json.PSSerializeJSONLongEnumAsNumber.Tests.ps1 @@ -0,0 +1,34 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. +Describe 'ConvertTo-Json with PSSerializeJSONLongEnumAsNumber' -tags "CI" { + + BeforeAll { + $originalDefaultParameterValues = $PSDefaultParameterValues.Clone() + $PSDefaultParameterValues['It:Skip'] = -not [ExperimentalFeature]::IsEnabled('PSSerializeJSONLongEnumAsNumber') + } + + AfterAll { + $global:PSDefaultParameterValues = $originalDefaultParameterValues + } + + It 'Should treat enums as integers' { + enum LongEnum : long { + LongValue = -1 + } + + enum ULongEnum : ulong { + ULongValue = 18446744073709551615 + } + + $obj = [Ordered]@{ + Long = [LongEnum]::LongValue + ULong = [ULongEnum]::ULongValue + } + + $actual = ConvertTo-Json -InputObject $obj -Compress + $actual | Should -Be '{"Long":-1,"ULong":18446744073709551615}' + + $actual = ConvertTo-Json -InputObject $obj -EnumsAsStrings -Compress + $actual | Should -Be '{"Long":"LongValue","ULong":"ULongValue"}' + } +} diff --git a/test/powershell/Modules/Microsoft.PowerShell.Utility/Json.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Utility/Json.Tests.ps1 index 5f33e1b6b75..46ce42c223c 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Utility/Json.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Utility/Json.Tests.ps1 @@ -58,7 +58,9 @@ Describe "Json Tests" -Tags "Feature" { $valueFromNotCompressedResult.FirstName | Should -Match $valueFromCompressedResult.FirstName } - It "Convertto-Json should handle Enum based on Int64" { + It "Convertto-Json should handle Enum based on Int64" -Skip:( + [ExperimentalFeature]::IsEnabled("PSSerializeJSONLongEnumAsNumber") + ) { # Test follow-up for bug Win8: 378368 Convertto-Json problems with Enum based on Int64. if ( $null -eq ("JsonEnumTest" -as "Type")) { @@ -355,7 +357,7 @@ Describe "Json Tests" -Tags "Feature" { { "date-s-should-parse-as-datetime": "2008-09-22T14:01:54", "date-upperO-should-parse-as-datetime": "2008-09-22T14:01:54.9571247Z", - + "date-o-should-parse-as-string": "2019-12-17T06:14:06 +06:00", "date-upperD-should-parse-as-string": "Monday, September 22, 2008", "date-f-should-parse-as-string": "Monday, September 22, 2008 2:01 PM", @@ -399,7 +401,7 @@ Describe "Json Tests" -Tags "Feature" { $result."date-s-should-parse-as-datetime".ToString("Y") | Should -Be "September 2008" $result."date-s-should-parse-as-datetime".ToString("y") | Should -Be "September 2008" $result."date-s-should-parse-as-datetime" | Should -BeOfType [DateTime] - + $result."date-upperO-should-parse-as-datetime" = [datetime]::SpecifyKind($result."date-upperO-should-parse-as-datetime", [System.DateTimeKind]::Utc) $result."date-upperO-should-parse-as-datetime".ToString("d") | Should -Be "9/22/2008" $result."date-upperO-should-parse-as-datetime".ToString("D") | Should -Be "Monday, September 22, 2008" @@ -420,7 +422,7 @@ Describe "Json Tests" -Tags "Feature" { $result."date-upperO-should-parse-as-datetime".ToString("Y") | Should -Be "September 2008" $result."date-upperO-should-parse-as-datetime".ToString("y") | Should -Be "September 2008" $result."date-upperO-should-parse-as-datetime" | Should -BeOfType [DateTime] - + $result."date-o-should-parse-as-string" | Should -Be "2019-12-17T06:14:06 +06:00" $result."date-o-should-parse-as-string" | Should -BeOfType [String] $result."date-f-should-parse-as-string" | Should -Be "Monday, September 22, 2008 2:01 PM" @@ -453,7 +455,7 @@ Describe "Json Tests" -Tags "Feature" { $result."date-y-should-parse-as-string" | Should -BeOfType [String] } } - + It "ConvertFrom-Json properly parses complex objects" { $json = @" { @@ -541,13 +543,13 @@ Describe "Json Tests" -Tags "Feature" { $result."registered" | Should -BeOfType [String] $result."_id"| Should -BeExactly "60dd3ea9253016932039a0a2" $result."_id" | Should -BeOfType [String] - + $result.Tags | Should -BeOfType [string] - - $result.Tags.count | Should -Be 7 + + $result.Tags.count | Should -Be 7 $result.Tags[0] | Should -BeExactly "laboris" $result.Tags | Should -Be @("laboris", "voluptate", "amet", "ad", "velit", "ipsum", "do") - + $result.Friends | Should -BeOfType [pscustomobject] $result.Friends[0].id | Should -Be 0 $result.Friends[0].name | Should -BeExactly "Renee Holden" @@ -556,7 +558,7 @@ Describe "Json Tests" -Tags "Feature" { $result.Friends[2].id | Should -Be 2 $result.Friends[2].name | Should -BeExactly "Emilia Holder" } - + It "ConvertFrom-Json chooses the appropriate number type" { ConvertFrom-Json -InputObject "5" | should -Be 5 ConvertFrom-Json -InputObject 5 | should -Be 5 @@ -570,33 +572,33 @@ Describe "Json Tests" -Tags "Feature" { ConvertFrom-Json -InputObject 5.0 | should -Be 5.0 ConvertFrom-Json -InputObject "5.0" | should -BeOfType [double] ConvertFrom-Json -InputObject 5.0 | should -BeOfType [double] - + # The decimal is lost but only when this is quoted ConvertFrom-Json -InputObject "500000000000.0000000000000001" | should -Be "500000000000" - + # Counter intuitively all four of these tests pass because precision is lost on both sides of the test, likely due to powershell number handling ConvertFrom-Json -InputObject 500000000000.0000000000000001 | should -Be 500000000000 ConvertFrom-Json -InputObject 500000000000.0000000000000001 | should -Be 500000000000.0000000000000001 ConvertFrom-Json -InputObject 500000000000 | should -Be 500000000000.0000000000000001 ConvertFrom-Json -InputObject 500000000000 | should -Be 500000000000 - + ConvertFrom-Json -InputObject "500000000000.0000000000000001" | should -BeOfType [double] ConvertFrom-Json -InputObject 500000000000.0000000000000001 | should -BeOfType [double] - + # these tests also pass because precision is lost during conversion/powershell handling ConvertFrom-Json -InputObject "50000000000000000000000000000000000.0000000000000001" | should -Be "5E+34" ConvertFrom-Json -InputObject 50000000000000000000000000000000000.0000000000000001 | should -Be "5E+34" - + ConvertFrom-Json -InputObject "50000000000000000000000000000000000.0000000000000001" | should -BeOfType [double] ConvertFrom-Json -InputObject 50000000000000000000000000000000000.0000000000000001 | should -BeOfType [double] - - + + ConvertFrom-Json -InputObject "50000000000000000000000000000000000" | should -Be 50000000000000000000000000000000000 ConvertFrom-Json -InputObject 50000000000000000000000000000000000 | should -Be 50000000000000000000000000000000000 ConvertFrom-Json -InputObject "50000000000000000000000000000000000" | should -BeOfType [BigInt] ConvertFrom-Json -InputObject 50000000000000000000000000000000000 | should -BeOfType [BigInt] } - + It "ConvertFrom-Json with special characters" { $json = '{"SampleValue":"\"\\\b\f\n\r\t\u4321\uD7FF"}' diff --git a/test/tools/TestMetadata.json b/test/tools/TestMetadata.json index cd94ce83a79..bd716ccec7b 100644 --- a/test/tools/TestMetadata.json +++ b/test/tools/TestMetadata.json @@ -3,6 +3,7 @@ "ExpTest.FeatureOne": [ "test/powershell/engine/ExperimentalFeature/ExperimentalFeature.Basic.Tests.ps1" ], "PSCultureInvariantReplaceOperator": [ "test/powershell/Language/Operators/ReplaceOperator.Tests.ps1" ], "Microsoft.PowerShell.Utility.PSManageBreakpointsInRunspace": [ "test/powershell/Modules/Microsoft.PowerShell.Utility/RunspaceBreakpointManagement.Tests.ps1" ], - "PSNativeWindowsTildeExpansion": [ "test/powershell/Language/Scripting/NativeExecution/NativeWindowsTildeExpansion.Tests.ps1" ] + "PSNativeWindowsTildeExpansion": [ "test/powershell/Language/Scripting/NativeExecution/NativeWindowsTildeExpansion.Tests.ps1" ], + "PSSerializeJSONLongEnumAsNumber": [ "test/powershell/Modules/Microsoft.PowerShell.Utility/ConvertTo-Json.PSSerializeJSONLongEnumAsNumber.Tests.ps1" ] } } From 652c6b3b6d6021a37c193c4807b8b960c5fe036a Mon Sep 17 00:00:00 2001 From: Aditya Patwardhan Date: Fri, 20 Sep 2024 14:56:38 -0700 Subject: [PATCH 023/173] Remove the MD5 branch in the strong name signing token calculation (#24288) (#24321) --- src/TypeCatalogGen/TypeCatalogGen.cs | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/TypeCatalogGen/TypeCatalogGen.cs b/src/TypeCatalogGen/TypeCatalogGen.cs index 05a47814568..3d4c0f21ed9 100644 --- a/src/TypeCatalogGen/TypeCatalogGen.cs +++ b/src/TypeCatalogGen/TypeCatalogGen.cs @@ -235,9 +235,6 @@ private static string GetAssemblyStrongName(MetadataReader metadataReader) case AssemblyHashAlgorithm.Sha1: hashImpl = SHA1.Create(); break; - case AssemblyHashAlgorithm.MD5: - hashImpl = MD5.Create(); - break; case AssemblyHashAlgorithm.Sha256: hashImpl = SHA256.Create(); break; From 91c96f3186525e455faffbc1327a1958545cd424 Mon Sep 17 00:00:00 2001 From: Aditya Patwardhan Date: Mon, 23 Sep 2024 10:55:16 -0700 Subject: [PATCH 024/173] Add telemetry to track the use of features (#24247) (#24331) --- .../CoreCLR/CorePsAssemblyLoadContext.cs | 8 ++- .../engine/Modules/ModuleUtils.cs | 2 - .../FeedbackSubsystem/IFeedbackProvider.cs | 16 +++-- .../engine/Subsystem/SubsystemInfo.cs | 2 + .../utils/Telemetry.cs | 71 +++++++++++++++++-- 5 files changed, 83 insertions(+), 16 deletions(-) diff --git a/src/System.Management.Automation/CoreCLR/CorePsAssemblyLoadContext.cs b/src/System.Management.Automation/CoreCLR/CorePsAssemblyLoadContext.cs index 6be8d3c595e..5a15df53ca8 100644 --- a/src/System.Management.Automation/CoreCLR/CorePsAssemblyLoadContext.cs +++ b/src/System.Management.Automation/CoreCLR/CorePsAssemblyLoadContext.cs @@ -9,6 +9,7 @@ using System.Runtime.InteropServices; using System.Reflection; using System.Runtime.Loader; +using Microsoft.PowerShell.Telemetry; namespace System.Management.Automation { @@ -607,16 +608,19 @@ public static unsafe class PowerShellUnsafeAssemblyLoad [UnmanagedCallersOnly] public static int LoadAssemblyFromNativeMemory(IntPtr data, int size) { + int result = 0; try { using var stream = new UnmanagedMemoryStream((byte*)data, size); AssemblyLoadContext.Default.LoadFromStream(stream); - return 0; } catch { - return -1; + result = -1; } + + ApplicationInsightsTelemetry.SendUseTelemetry("PowerShellUnsafeAssemblyLoad", result == 0 ? "1" : "0"); + return result; } } } diff --git a/src/System.Management.Automation/engine/Modules/ModuleUtils.cs b/src/System.Management.Automation/engine/Modules/ModuleUtils.cs index f58f51dfd37..41bf4ac3521 100644 --- a/src/System.Management.Automation/engine/Modules/ModuleUtils.cs +++ b/src/System.Management.Automation/engine/Modules/ModuleUtils.cs @@ -44,8 +44,6 @@ static ModuleUtils() | FileAttributes.Offline | (FileAttributes)FILE_ATTRIBUTE_RECALL_ON_DATA_ACCESS | (FileAttributes)FILE_ATTRIBUTE_RECALL_ON_OPEN; - - return; } /// diff --git a/src/System.Management.Automation/engine/Subsystem/FeedbackSubsystem/IFeedbackProvider.cs b/src/System.Management.Automation/engine/Subsystem/FeedbackSubsystem/IFeedbackProvider.cs index aba105c8faa..328eb4eee87 100644 --- a/src/System.Management.Automation/engine/Subsystem/FeedbackSubsystem/IFeedbackProvider.cs +++ b/src/System.Management.Automation/engine/Subsystem/FeedbackSubsystem/IFeedbackProvider.cs @@ -9,6 +9,7 @@ using System.Management.Automation.Language; using System.Management.Automation.Runspaces; using System.Threading; +using Microsoft.PowerShell.Telemetry; namespace System.Management.Automation.Subsystem.Feedback { @@ -287,13 +288,14 @@ internal GeneralCommandErrorFeedback() .AddParameter("ExpandProperty", "Name") .Invoke(); - if (results.Count > 0) - { - return new FeedbackItem( - SuggestionStrings.Suggestion_CommandNotFound, - new List(results), - FeedbackDisplayLayout.Landscape); - } + if (results.Count > 0) + { + ApplicationInsightsTelemetry.SendUseTelemetry("FuzzyMatching", "CommandNotFound"); + return new FeedbackItem( + SuggestionStrings.Suggestion_CommandNotFound, + new List(results), + FeedbackDisplayLayout.Landscape); + } return null; } diff --git a/src/System.Management.Automation/engine/Subsystem/SubsystemInfo.cs b/src/System.Management.Automation/engine/Subsystem/SubsystemInfo.cs index c290e807ce4..8756fd69c9b 100644 --- a/src/System.Management.Automation/engine/Subsystem/SubsystemInfo.cs +++ b/src/System.Management.Automation/engine/Subsystem/SubsystemInfo.cs @@ -7,6 +7,7 @@ using System.Collections.Generic; using System.Collections.ObjectModel; using System.Management.Automation.Internal; +using Microsoft.PowerShell.Telemetry; namespace System.Management.Automation.Subsystem { @@ -96,6 +97,7 @@ private protected SubsystemInfo(SubsystemKind kind, Type subsystemType) internal void RegisterImplementation(ISubsystem impl) { AddImplementation(impl); + ApplicationInsightsTelemetry.SendUseTelemetry(ApplicationInsightsTelemetry.s_subsystemRegistration, impl.Name); } internal ISubsystem UnregisterImplementation(Guid id) diff --git a/src/System.Management.Automation/utils/Telemetry.cs b/src/System.Management.Automation/utils/Telemetry.cs index ff655bbe60e..9e40e60a4d6 100644 --- a/src/System.Management.Automation/utils/Telemetry.cs +++ b/src/System.Management.Automation/utils/Telemetry.cs @@ -83,6 +83,13 @@ internal enum TelemetryType /// Remote session creation. /// RemoteSessionOpen, + + /// + /// Send telemetry for a stable feature when used. + /// By making a distinction between this and experimental feature use, it will make + /// queries much easier. + /// + FeatureUse, } /// @@ -110,6 +117,9 @@ public void Initialize(ITelemetry telemetry) /// public static class ApplicationInsightsTelemetry { + // The string for SubsystermRegistration + internal const string s_subsystemRegistration = "Subsystem.Registration"; + // If this env var is true, yes, or 1, telemetry will NOT be sent. private const string _telemetryOptoutEnvVar = "POWERSHELL_TELEMETRY_OPTOUT"; @@ -152,6 +162,8 @@ public static class ApplicationInsightsTelemetry private static readonly HashSet s_knownModules; private static readonly HashSet s_knownModuleTags; + private static readonly HashSet s_knownSubsystemNames; + /// Gets a value indicating whether telemetry can be sent. public static bool CanSendTelemetry { get; private set; } = false; @@ -620,6 +632,13 @@ static ApplicationInsightsTelemetry() }; s_uniqueUserIdentifier = GetUniqueIdentifier().ToString(); + s_knownSubsystemNames = new HashSet(StringComparer.OrdinalIgnoreCase) + { + "Completion", + "general", + "Windows Package Manager - WinGet", + "Az Predictor" + }; } } @@ -715,7 +734,7 @@ internal static void SendModuleTelemetryMetric(TelemetryType telemetryType, PSMo s_telemetryClient. GetMetric(new MetricIdentifier(string.Empty, telemetryType.ToString(), "uuid", "SessionId", "ModuleName", "Version", "Tag")). - TrackValue(metricValue: 1.0, s_uniqueUserIdentifier, s_sessionId, allowedModuleName, allowedModuleVersion, allowedModuleTagString); + TrackValue(metricValue: 1.0, s_uniqueUserIdentifier, s_sessionId, allowedModuleName, allowedModuleVersion, allowedModuleTagString); } catch { @@ -754,7 +773,8 @@ internal static void SendModuleTelemetryMetric(TelemetryType telemetryType, stri /// /// The type of telemetry that we'll be sending. /// The specific details about the telemetry. - internal static void SendTelemetryMetric(TelemetryType metricId, string data) + /// The count of instances for the telemetry payload. + internal static void SendTelemetryMetric(TelemetryType metricId, string data, double value = 1.0) { if (!CanSendTelemetry) { @@ -776,12 +796,13 @@ internal static void SendTelemetryMetric(TelemetryType metricId, string data) case TelemetryType.ExperimentalEngineFeatureActivation: case TelemetryType.ExperimentalEngineFeatureDeactivation: case TelemetryType.ExperimentalFeatureUse: - s_telemetryClient.GetMetric(metricName, "uuid", "SessionId", "Detail").TrackValue(metricValue: 1.0, s_uniqueUserIdentifier, s_sessionId, data); + case TelemetryType.FeatureUse: + s_telemetryClient.GetMetric(metricName, "uuid", "SessionId", "Detail").TrackValue(metricValue: value, s_uniqueUserIdentifier, s_sessionId, data); break; case TelemetryType.ExperimentalModuleFeatureActivation: case TelemetryType.ExperimentalModuleFeatureDeactivation: string experimentalFeatureName = GetExperimentalFeatureName(data); - s_telemetryClient.GetMetric(metricName, "uuid", "SessionId", "Detail").TrackValue(metricValue: 1.0, s_uniqueUserIdentifier, s_sessionId, experimentalFeatureName); + s_telemetryClient.GetMetric(metricName, "uuid", "SessionId", "Detail").TrackValue(metricValue: value, s_uniqueUserIdentifier, s_sessionId, experimentalFeatureName); break; } } @@ -792,6 +813,35 @@ internal static void SendTelemetryMetric(TelemetryType metricId, string data) } } + /// + /// Send additional information about an feature as it is used. + /// + /// The name of the feature. + /// The details about the feature use. + /// The value to report when sending the payload. + internal static void SendUseTelemetry(string featureName, string detail, double value = 1.0) + { + if (!CanSendTelemetry) + { + return; + } + + // keep payload small + if (featureName is null || detail is null || featureName.Length > 33 || detail.Length > 33) + { + return; + } + + if (string.Compare(featureName, s_subsystemRegistration, true) == 0) + { + ApplicationInsightsTelemetry.SendTelemetryMetric(TelemetryType.FeatureUse, string.Join(":", featureName, GetSubsystemName(detail)), value); + } + else + { + ApplicationInsightsTelemetry.SendTelemetryMetric(TelemetryType.FeatureUse, string.Join(":", featureName, detail), value); + } + } + /// /// Send additional information about an experimental feature as it is used. /// @@ -822,7 +872,18 @@ private static string GetExperimentalFeatureName(string featureNameToValidate) return Anonymous; } - // Get the module name. If we can report it, we'll return the name, otherwise, we'll return "anonymous" + // Get the module name. If we can report it, we'll return the name, otherwise, we'll return the string "anonymous" + private static string GetSubsystemName(string subsystemNameToValidate) + { + if (s_knownSubsystemNames.Contains(subsystemNameToValidate)) + { + return subsystemNameToValidate; + } + + return Anonymous; + } + + // Get the module name. If we can report it, we'll return the name, otherwise, we'll return anonymous. private static string GetModuleName(string moduleNameToValidate) { if (s_knownModules.Contains(moduleNameToValidate)) From 5733a9c10444c911d89aa3201a4f92e9e04d438b Mon Sep 17 00:00:00 2001 From: Aditya Patwardhan Date: Tue, 24 Sep 2024 09:19:11 -0700 Subject: [PATCH 025/173] Update `Microsoft.PowerShell.PSResourceGet` to `1.1.0-preview2` (#24300) (#24337) --- src/Modules/PSGalleryModules.csproj | 2 +- ...crosoft.PowerShell.PSResourceGet.Tests.ps1 | 109 ++++++++++++++++++ 2 files changed, 110 insertions(+), 1 deletion(-) diff --git a/src/Modules/PSGalleryModules.csproj b/src/Modules/PSGalleryModules.csproj index e677b124710..1c8e5e64356 100644 --- a/src/Modules/PSGalleryModules.csproj +++ b/src/Modules/PSGalleryModules.csproj @@ -13,7 +13,7 @@ - + diff --git a/test/powershell/Modules/Microsoft.PowerShell.PSResourceGet/Microsoft.PowerShell.PSResourceGet.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.PSResourceGet/Microsoft.PowerShell.PSResourceGet.Tests.ps1 index d58a8535903..b06f0aa427a 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.PSResourceGet/Microsoft.PowerShell.PSResourceGet.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.PSResourceGet/Microsoft.PowerShell.PSResourceGet.Tests.ps1 @@ -7,10 +7,20 @@ $ProgressPreference = "SilentlyContinue" $RepositoryName = 'PSGallery' $ACRRepositoryName = "ACRRepo" $ACRRepoUri = "https://psresourcegettest.azurecr.io/" +$LocalRepoName = 'LocalRepo' +$TempDir = 'TempDir' +$LocalRepoUri = Microsoft.PowerShell.Management\Join-Path -Path $TempDir -ChildPath 'TempLocalRepoUri' $TestModule = 'newTestModule' $TestScript = 'TestTestScript' $ACRTestModule = 'newTestMod' +$PublishedNupkgs = Microsoft.PowerShell.Management\Join-Path -Path $TempDir -ChildPath 'PublishedNupkgs' +$TestModuleNupkgName = "$TestModule.0.0.1.nupkg" +$TestModuleNupkgPath = Microsoft.PowerShell.Management\Join-Path -Path $PublishedNupkgs -ChildPath $TestModuleNupkgName +$TestScriptPath = "$TestScript.ps1" +$TestScriptNupkgName = "$TestScript.0.0.1.nupkg" +$TestScriptNupkgPath = Microsoft.PowerShell.Management\Join-Path -Path $PublishedNupkgs -ChildPath $TestScriptNupkgName + $Initialized = $false #region Install locations for modules and scripts @@ -72,6 +82,11 @@ if (!(Test-Path $script:MyDocumentsScriptsPath)) { function Initialize { + if(!(Test-Path $TempDir)) + { + New-Item -Path $TempDir -ItemType Directory + } + $repo = Get-PSResourceRepository $RepositoryName -ErrorAction SilentlyContinue if($repo) { @@ -97,6 +112,15 @@ function Initialize } } +function Register-LocalRepo +{ + if (!(Test-Path $LocalRepoUri)) { + New-Item -Path $LocalRepoUri -ItemType Directory + } + + Register-PSResourceRepository -Name $LocalRepoName -Uri $LocalRepoUri -Trusted -Force +} + #endregion function Remove-InstalledModules @@ -104,6 +128,28 @@ function Remove-InstalledModules Get-InstalledPSResource -Name $TestModule -Version '*' -ErrorAction SilentlyContinue | Microsoft.PowerShell.PSResourceGet\Uninstall-PSResource } +function New-TestPackages +{ + if (!(Test-Path $PublishedNupkgs)) { + New-Item $PublishedNupkgs -ItemType Directory + } + + if (!(Test-Path $TestModule)) { + New-Item $TestModule -ItemType Directory + } + + $moduleManifestPath = Join-Path $TestModule -ChildPath "$TestModule.psd1" + if (!(Test-Path $moduleManifestPath)) + { + New-ModuleManifest $moduleManifestPath -Description "Test module for PowerShell CI" -Author "PSGetAuthor" + } + + if (!(Test-Path $TestScriptPath)) + { + New-ScriptFileInfo -Path $TestScriptPath -Description "Test script for PowerShell CI" -Author "PSGetAuthor" + } +} + Describe "PSResourceGet - Module tests" -tags "Feature" { BeforeAll { @@ -111,6 +157,9 @@ Describe "PSResourceGet - Module tests" -tags "Feature" { Initialize $script:Initialized = $true } + + Register-LocalRepo + New-TestPackages } BeforeEach { @@ -138,6 +187,39 @@ Describe "PSResourceGet - Module tests" -tags "Feature" { } } + It "Should publish a module" { + Publish-PSResource -Path $TestModule -Repository $LocalRepoName + + $foundModuleInfo = Find-PSResource $TestModule -Repository $LocalRepoName + $foundModuleInfo | Should -Not -BeNullOrEmpty + $foundModuleInfo.Count | Should -Be 1 + $foundModuleInfo.Name | Should -Be $TestModule + } + + It "Should compress a module into a .nupkg" { + Compress-PSResource -Path $TestModule -DestinationPath $PublishedNupkgs + + $modulePublished = Get-ChildItem $TestModuleNupkgPath + $modulePublished | Should -Not -BeNullOrEmpty + $modulePublished.Name | Should -Be $TestModuleNupkgName + } + + It "Should publish compressed .nupkg" { + Compress-PSResource -Path $TestModule -DestinationPath $PublishedNupkgs + + Publish-PSResource -NupkgPath $TestModuleNupkgPath -Repository $LocalRepoName + + $foundModuleInfo = Find-PSResource $TestModule -Repository $LocalRepoName + $foundModuleInfo | Should -Not -BeNullOrEmpty + $foundModuleInfo.Count | Should -Be 1 + $foundModuleInfo.Name | Should -Be $TestModule + } + + AfterEach { + Get-ChildItem $PublishedNupkgs | Remove-Item -Recurse -Force + Get-ChildItem $LocalRepoUri | Remove-Item -Recurse -Force + } + AfterAll { Remove-InstalledModules } @@ -181,6 +263,9 @@ Describe "PSResourceGet - Script tests" -tags "Feature" { Initialize $script:Initialized = $true } + + Register-LocalRepo + New-TestPackages } BeforeEach { @@ -205,6 +290,20 @@ Describe "PSResourceGet - Script tests" -tags "Feature" { } } + It "Should publish a script" { + Publish-PSResource -Path $TestScriptPath -Repository $LocalRepoName + + $foundScriptInfo = Find-PSResource $TestScript -Repository $LocalRepoName + $foundScriptInfo | Should -Not -BeNullOrEmpty + $foundScriptInfo.Count | Should -Be 1 + $foundScriptInfo.Name | Should -Be $TestScript + } + + AfterEach { + Get-ChildItem $PublishedNupkgs | Remove-Item -Recurse -Force + Get-ChildItem $LocalRepoUri | Remove-Item -Recurse -Force + } + AfterAll { Remove-InstalledScripts } @@ -294,5 +393,15 @@ Describe "PSResourceGet - ACR tests" -tags "Feature" { } Remove-InstalledModules + FinalCleanUp + } +} + + +function FinalCleanUp +{ + if(Test-Path $TempDir) + { + Remove-Item -Path $TempDir -Recurse -Force } } From 20ad8f3fd7e10b161f2f8878d9d7d3d0e824e8f9 Mon Sep 17 00:00:00 2001 From: Aditya Patwardhan Date: Wed, 25 Sep 2024 11:02:35 -0700 Subject: [PATCH 026/173] Add `-Force` parameter to `Resolve-Path` and `Convert-Path` cmdlets to support wildcard hidden files (#20981) (#24344) --- .../commands/management/ConvertPathCommand.cs | 10 +++ .../commands/management/ResolvePathCommand.cs | 10 +++ .../Convert-Path.Tests.ps1 | 69 +++++++++++++++++++ .../Resolve-Path.Tests.ps1 | 63 ++++++++++++++++- 4 files changed, 151 insertions(+), 1 deletion(-) diff --git a/src/Microsoft.PowerShell.Commands.Management/commands/management/ConvertPathCommand.cs b/src/Microsoft.PowerShell.Commands.Management/commands/management/ConvertPathCommand.cs index c32d0f2aa67..33796b23378 100644 --- a/src/Microsoft.PowerShell.Commands.Management/commands/management/ConvertPathCommand.cs +++ b/src/Microsoft.PowerShell.Commands.Management/commands/management/ConvertPathCommand.cs @@ -55,6 +55,16 @@ public string[] LiteralPath } } + /// + /// Gets or sets the force property. + /// + [Parameter] + public override SwitchParameter Force + { + get => base.Force; + set => base.Force = value; + } + #endregion Parameters #region parameter data diff --git a/src/Microsoft.PowerShell.Commands.Management/commands/management/ResolvePathCommand.cs b/src/Microsoft.PowerShell.Commands.Management/commands/management/ResolvePathCommand.cs index b624c6e08cf..3d1b66933d2 100644 --- a/src/Microsoft.PowerShell.Commands.Management/commands/management/ResolvePathCommand.cs +++ b/src/Microsoft.PowerShell.Commands.Management/commands/management/ResolvePathCommand.cs @@ -93,6 +93,16 @@ public string RelativeBasePath } } + /// + /// Gets or sets the force property. + /// + [Parameter] + public override SwitchParameter Force + { + get => base.Force; + set => base.Force = value; + } + #endregion Parameters #region parameter data diff --git a/test/powershell/Modules/Microsoft.PowerShell.Management/Convert-Path.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Management/Convert-Path.Tests.ps1 index 1cc88b36bb7..7de1d97dd20 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Management/Convert-Path.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Management/Convert-Path.Tests.ps1 @@ -1,6 +1,27 @@ # Copyright (c) Microsoft Corporation. # Licensed under the MIT License. Describe "Convert-Path tests" -Tag CI { + BeforeAll { + $hiddenFilePrefix = ($IsLinux -or $IsMacOS) ? '.' : '' + + $hiddenFilePath1 = Join-Path -Path $TestDrive -ChildPath "$($hiddenFilePrefix)test1.txt" + $hiddenFilePath2 = Join-Path -Path $TestDrive -ChildPath "$($hiddenFilePrefix)test2.txt" + + $hiddenFile1 = New-Item -Path $hiddenFilePath1 -ItemType File + $hiddenFile2 = New-Item -Path $hiddenFilePath2 -ItemType File + + $relativeHiddenFilePath1 = ".$([System.IO.Path]::DirectorySeparatorChar)$($hiddenFilePrefix)test1.txt" + $relativeHiddenFilePath2 = ".$([System.IO.Path]::DirectorySeparatorChar)$($hiddenFilePrefix)test2.txt" + + if ($IsWindows) { + $hiddenFile1.Attributes = "Hidden" + $hiddenFile2.Attributes = "Hidden" + } + + $hiddenFileWildcardPath = Join-Path -Path $TestDrive -ChildPath "$($hiddenFilePrefix)test*.txt" + $relativeHiddenFileWildcardPath = ".$([System.IO.Path]::DirectorySeparatorChar)$($hiddenFilePrefix)test*.txt" + } + It "Convert-Path should handle provider qualified paths" { Convert-Path -Path "FileSystem::${TestDrive}" | Should -BeExactly "${TestDrive}" } @@ -41,4 +62,52 @@ Describe "Convert-Path tests" -Tag CI { It "Convert-Path should return something which exists" { Convert-Path -Path $TestDrive | Should -Exist } + + It "Convert-Path -Path '' -Force: should return ''" -TestCases @( + @{ + Path = $relativeHiddenFilePath1 + BasePath = $TestDrive + Force = $false + ExpectedResult = $hiddenFilePath1 + } + @{ + Path = $relativeHiddenFilePath2 + BasePath = $TestDrive + Force = $false + ExpectedResult = $hiddenFilePath2 + } + @{ + Path = $relativeHiddenFileWildcardPath + BasePath = $TestDrive + Force = $false + ExpectedResult = $null + } + @{ + Path = $relativeHiddenFilePath1 + BasePath = $TestDrive + Force = $true + ExpectedResult = $hiddenFilePath1 + } + @{ + Path = $relativeHiddenFilePath2 + BasePath = $TestDrive + Force = $true + ExpectedResult = $hiddenFilePath2 + } + @{ + Path = $relativeHiddenFileWildcardPath + BasePath = $TestDrive + Force = $true + ExpectedResult = @($hiddenFilePath1, $hiddenFilePath2) + } + ) { + param($Path, $BasePath, $Force, $ExpectedResult) + try { + Push-Location -Path $BasePath + Convert-Path -Path $Path -Force:$Force | Should -BeExactly $ExpectedResult + } + finally { + Pop-Location + } + } } diff --git a/test/powershell/Modules/Microsoft.PowerShell.Management/Resolve-Path.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Management/Resolve-Path.Tests.ps1 index efd2441e0a7..9e38d1f8c20 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Management/Resolve-Path.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Management/Resolve-Path.Tests.ps1 @@ -16,6 +16,25 @@ Describe "Resolve-Path returns proper path" -Tag "CI" { @{ wd = $fakeRoot; target = $testRoot; expected = $testRoot } @{ wd = $testRoot; target = Join-Path $fakeRoot "file.txt"; expected = Join-Path "." "fakeroot" "file.txt" } ) + + $hiddenFilePrefix = ($IsLinux -or $IsMacOS) ? '.' : '' + + $hiddenFilePath1 = Join-Path -Path $TestDrive -ChildPath "$($hiddenFilePrefix)test1.txt" + $hiddenFilePath2 = Join-Path -Path $TestDrive -ChildPath "$($hiddenFilePrefix)test2.txt" + + $hiddenFile1 = New-Item -Path $hiddenFilePath1 -ItemType File + $hiddenFile2 = New-Item -Path $hiddenFilePath2 -ItemType File + + $relativeHiddenFilePath1 = ".$([System.IO.Path]::DirectorySeparatorChar)$($hiddenFilePrefix)test1.txt" + $relativeHiddenFilePath2 = ".$([System.IO.Path]::DirectorySeparatorChar)$($hiddenFilePrefix)test2.txt" + + if ($IsWindows) { + $hiddenFile1.Attributes = "Hidden" + $hiddenFile2.Attributes = "Hidden" + } + + $hiddenFileWildcardPath = Join-Path -Path $TestDrive -ChildPath "$($hiddenFilePrefix)test*.txt" + $relativeHiddenFileWildcardPath = ".$([System.IO.Path]::DirectorySeparatorChar)$($hiddenFilePrefix)test*.txt" } AfterAll { Remove-PSDrive -Name $driveName -Force @@ -86,7 +105,7 @@ Describe "Resolve-Path returns proper path" -Tag "CI" { } ) -Test { param($Path, $BasePath, $Expected, $CD) - + if ($null -eq $Expected) { {Resolve-Path -Path $Path -RelativeBasePath $BasePath -ErrorAction Stop} | Should -Throw -ErrorId "PathNotFound,Microsoft.PowerShell.Commands.ResolvePathCommand" @@ -114,4 +133,46 @@ Describe "Resolve-Path returns proper path" -Tag "CI" { } } } + + It "Resolve-Path -Path '' -RelativeBasePath '' -Force: should return ''" -TestCases @( + @{ + Path = $relativeHiddenFilePath1 + BasePath = $TestDrive + Force = $false + ExpectedResult = $hiddenFilePath1 + } + @{ + Path = $relativeHiddenFilePath2 + BasePath = $TestDrive + Force = $false + ExpectedResult = $hiddenFilePath2 + } + @{ + Path = $relativeHiddenFileWildcardPath + BasePath = $TestDrive + Force = $false + ExpectedResult = $null + } + @{ + Path = $relativeHiddenFilePath1 + BasePath = $TestDrive + Force = $true + ExpectedResult = $hiddenFilePath1 + } + @{ + Path = $relativeHiddenFilePath2 + BasePath = $TestDrive + Force = $true + ExpectedResult = $hiddenFilePath2 + } + @{ + Path = $relativeHiddenFileWildcardPath + BasePath = $TestDrive + Force = $true + ExpectedResult = @($hiddenFilePath1, $hiddenFilePath2) + } + ) { + param($Path, $BasePath, $Force, $ExpectedResult) + (Resolve-Path -Path $Path -RelativeBasePath $BasePath -Force:$Force).Path | Should -BeExactly $ExpectedResult + } } From ecf40d6f5f3f1180f42e2d6a64fdae13f97dd32a Mon Sep 17 00:00:00 2001 From: Aditya Patwardhan Date: Wed, 25 Sep 2024 11:12:11 -0700 Subject: [PATCH 027/173] Copy to static site instead of making blob public (#24269) (#24343) --- .../templates/release-MakeBlobPublic.yml | 119 +++++++++++------- .../templates/release-upload-buildinfo.yml | 21 ++-- tools/install-powershell.ps1 | 4 +- 3 files changed, 84 insertions(+), 60 deletions(-) diff --git a/.pipelines/templates/release-MakeBlobPublic.yml b/.pipelines/templates/release-MakeBlobPublic.yml index 1e3789b207a..ba4fb14ec8a 100644 --- a/.pipelines/templates/release-MakeBlobPublic.yml +++ b/.pipelines/templates/release-MakeBlobPublic.yml @@ -1,31 +1,22 @@ jobs: - template: /.pipelines/templates/approvalJob.yml@self parameters: - displayName: Approve Blob Public - jobName: ApproveBlobPublic + displayName: Approve Copy release packages to PSInfra storage + jobName: CopyReleaseBlobApproval instructions: | - Are you sure you want to make the blob public? + Approval for Copy release packages to PSInfra storage -- job: blobPublic - displayName: Make Azure Blob Public - dependsOn: ApproveBlobPublic - condition: succeeded() +- job: PSInfraReleaseBlobPublic + displayName: Copy release to PSInfra storage + dependsOn: CopyReleaseBlobApproval pool: type: windows + variables: - - name: runCodesignValidationInjection - value: false - - name: NugetSecurityAnalysisWarningLevel - value: none - - name: DOTNET_SKIP_FIRST_TIME_EXPERIENCE - value: 1 + - group: 'PSInfraStorage' - group: 'Azure Blob variable group' - name: ob_outputDirectory value: '$(Build.ArtifactStagingDirectory)/ONEBRANCH_ARTIFACT' - - name: ob_sdl_codeSignValidation_enabled - value: false - - name: ob_sdl_binskim_enabled - value: false - name: ob_sdl_tsa_configFile value: $(Build.SourcesDirectory)\PowerShell\.config\tsaoptions.json - name: ob_sdl_credscan_suppressionsFile @@ -34,47 +25,81 @@ jobs: value: false steps: - - checkout: self - clean: true - env: - ob_restore_phase: true # This ensures checkout is done at the beginning of the restore phase + - checkout: self + clean: true + env: + ob_restore_phase: true # This ensures checkout is done at the beginning of the restore phase - - template: /.pipelines/templates/SetVersionVariables.yml@self - parameters: - ReleaseTagVar: $(ReleaseTagVar) - CreateJson: yes - UseJson: no + - template: /.pipelines/templates/SetVersionVariables.yml@self + parameters: + ReleaseTagVar: $(ReleaseTagVar) + CreateJson: yes + UseJson: no - pwsh: | Get-ChildItem Env: displayName: 'Capture Environment Variables' - - pwsh: | - $azureRmModule = Get-InstalledModule AzureRM -ErrorAction SilentlyContinue -Verbose - if ($azureRmModule) { - Write-Host 'AzureRM module exists. Removing it' - Uninstall-AzureRm - Write-Host 'AzureRM module removed' - } - - Install-Module -Name Az.Storage -Force -AllowClobber -Scope CurrentUser -Verbose - displayName: Remove AzRM modules - - - task: AzureCLI@2 - displayName: 'Set blob permissions' - inputs: - azureSubscription: az-blob-cicd-infra - scriptType: 'pscore' - scriptLocation: 'inlineScript' - inlineScript: | - az storage container set-permission --account-name $(StorageAccount) --name $(azureVersion) --public-access blob - az storage container set-permission --account-name $(StorageAccount) --name $(azureVersion)-gc --public-access blob + - pwsh: | + $azureRmModule = Get-InstalledModule AzureRM -ErrorAction SilentlyContinue -Verbose + if ($azureRmModule) { + Write-Host 'AzureRM module exists. Removing it' + Uninstall-AzureRm + Write-Host 'AzureRM module removed' + } + + Install-Module -Name Az.Storage -Force -AllowClobber -Scope CurrentUser -Verbose + displayName: Remove AzRM modules + + - task: AzurePowerShell@5 + displayName: Copy blobs to PSInfra storage + inputs: + azureSubscription: az-blob-cicd-infra + scriptType: inlineScript + azurePowerShellVersion: LatestVersion + pwsh: true + inline: | + $sourceStorageAccountName = '$(StorageAccount)' + $destinationStorageAccountName = '$(PSInfraStorageAccount)' + $destinationContainerName = '$web' + $destinationPrefix = 'install/$(ReleaseTagVar)' + + $sourceContext = New-AzStorageContext -StorageAccountName $sourceStorageAccountName + Write-Verbose -Verbose "Source context: $($sourceContext.BlobEndPoint)" + + $destinationContext = New-AzStorageContext -StorageAccountName $destinationStorageAccountName + Write-Verbose -Verbose "Destination context: $($destinationContext.BlobEndPoint)" + + foreach ($sourceContainerName in '$(AzureVersion)', '$(AzureVersion)-gc') { + $blobs = Get-AzStorageBlob -Context $sourceContext -Container $sourceContainerName + + Write-Verbose -Verbose "Blobs found in $sourceContainerName" + $blobs.Name | Write-Verbose -Verbose + + Write-Verbose -Verbose "Copying blobs from $sourceContainerName to $destinationContainerName/$destinationPrefix" + + foreach ($blob in $blobs) { + $sourceBlobName = $blob.Name + Write-Verbose -Verbose "sourceBlobName = $sourceBlobName" + + $destinationBlobName = "$destinationPrefix/$sourceBlobName" + Write-Verbose -Verbose "destinationBlobName = $destinationBlobName" + $existingBlob = Get-AzStorageBlob -Blob $destinationBlobName -Container $destinationContainerName -Context $destinationContext -ErrorAction Ignore + if ($existingBlob) { + Write-Verbose -Verbose "Blob $destinationBlobName already exists in '$destinationStorageAccountName/$destinationContainerName', removing before copy." + $existingBlob | Remove-AzStorageBlob -ErrorAction Stop -Verbose + } + + Copy-AzStorageBlob -SourceContext $sourceContext -DestinationContext $destinationContext -SrcContainer $sourceContainerName -SrcBlob $sourceBlobName -DestContainer $destinationContainerName -DestBlob $destinationBlobName -Force -Verbose -Confirm:$false + } + } + - template: /.pipelines/templates/approvalJob.yml@self parameters: displayName: Approve Copy Global tool packages to PSInfra storage jobName: CopyBlobApproval - dependsOnJob: blobPublic + dependsOnJob: PSInfraReleaseBlobPublic instructions: | Approval for Copy global tool packages to PSInfra storage diff --git a/.pipelines/templates/release-upload-buildinfo.yml b/.pipelines/templates/release-upload-buildinfo.yml index 3738328004b..f2b06cd2010 100644 --- a/.pipelines/templates/release-upload-buildinfo.yml +++ b/.pipelines/templates/release-upload-buildinfo.yml @@ -45,14 +45,14 @@ jobs: displayName: Download build info artifact - pwsh: | - Import-Module '$(Build.SourcesDirectory)/tools/ci.psm1' + Import-Module '$(Build.SourcesDirectory)/PowerShell/tools/ci.psm1' $jsonFile = Get-Item "$ENV:PIPELINE_WORKSPACE/PSPackagesOfficial/BuildInfoJson/*.json" $fileName = Split-Path $jsonFile -Leaf $dateTime = [datetime]::UtcNow $dateTime = [datetime]::new($dateTime.Ticks - ($dateTime.Ticks % [timespan]::TicksPerSecond), $dateTime.Kind) - $metadata = Get-Content ./tools/metadata.json | ConvertFrom-Json + $metadata = Get-Content -LiteralPath '$(Build.SourcesDirectory)/PowerShell/tools/metadata.json' -ErrorAction Stop | ConvertFrom-Json $stableRelease = $metadata.StableRelease.Latest $ltsRelease = $metadata.LTSRelease.Latest @@ -118,29 +118,30 @@ jobs: azurePowerShellVersion: LatestVersion pwsh: true inline: | - $containerName = "buildinfo" - $storageAccount = '$(StorageAccount)' + $containerName = '$web' + $storageAccount = '$(PSInfraStorageAccount)' + $prefix = "buildinfo" $storageContext = New-AzStorageContext -StorageAccountName $storageAccount -UseConnectedAccount if ($env:CopyMainBuildInfo -eq 'YES') { $jsonFile = "$env:BuildInfoJsonFile" $blobName = Get-Item $jsonFile | Split-Path -Leaf - Write-Verbose -Verbose "Uploading $jsonFile to $containerName/$blobName" - Set-AzStorageBlobContent -File $jsonFile -Container $containerName -Blob $blobName -Context $storageContext -Force + Write-Verbose -Verbose "Uploading $jsonFile to $containerName/$prefix/$blobName" + Set-AzStorageBlobContent -File $jsonFile -Container $containerName -Blob "$prefix/$blobName" -Context $storageContext -Force } if ($env:CopyLTSBuildInfo -eq 'YES') { $jsonFile = "$env:LtsBuildInfoJsonFile" $blobName = Get-Item $jsonFile | Split-Path -Leaf - Write-Verbose -Verbose "Uploading $jsonFile to $containerName/$blobName" - Set-AzStorageBlobContent -File $jsonFile -Container $containerName -Blob $blobName -Context $storageContext -Force + Write-Verbose -Verbose "Uploading $jsonFile to $containerName/$prefix/$blobName" + Set-AzStorageBlobContent -File $jsonFile -Container $containerName -Blob "$prefix/$blobName" -Context $storageContext -Force } if ($env:CopyVersionBuildInfo -eq 'YES') { $jsonFile = "$env:VersionBuildInfoJsonFile" $blobName = Get-Item $jsonFile | Split-Path -Leaf - Write-Verbose -Verbose "Uploading $jsonFile to $containerName/$blobName" - Set-AzStorageBlobContent -File $jsonFile -Container $containerName -Blob $blobName -Context $storageContext -Force + Write-Verbose -Verbose "Uploading $jsonFile to $containerName/$prefix/$blobName" + Set-AzStorageBlobContent -File $jsonFile -Container $containerName -Blob "$prefix/$blobName" -Context $storageContext -Force } condition: and(succeeded(), eq(variables['CopyMainBuildInfo'], 'YES')) diff --git a/tools/install-powershell.ps1 b/tools/install-powershell.ps1 index b6c8f595ccb..2f40e9223c1 100644 --- a/tools/install-powershell.ps1 +++ b/tools/install-powershell.ps1 @@ -268,7 +268,6 @@ try { if ($Daily) { $metadata = Invoke-RestMethod 'https://aka.ms/pwsh-buildinfo-daily' $release = $metadata.ReleaseTag -replace '^v' - $blobName = $metadata.BlobName # Get version from currently installed PowerShell Daily if available. $pwshPath = if ($IsWinEnv) {Join-Path $Destination "pwsh.exe"} else {Join-Path $Destination "pwsh"} @@ -297,8 +296,7 @@ try { throw "The OS architecture is '$architecture'. However, we currently only support daily package for x64." } - - $downloadURL = "https://pscoretestdata.blob.core.windows.net/${blobName}/${packageName}" + $downloadURL = "https://powershellinfraartifacts-gkhedzdeaghdezhr.z01.azurefd.net/install/$($metadata.ReleaseTag)/$packageName" Write-Verbose "About to download package from '$downloadURL'" -Verbose $packagePath = Join-Path -Path $tempDir -ChildPath $packageName From 508825bb407083e8e256569ecf756ea303d4294c Mon Sep 17 00:00:00 2001 From: Aditya Patwardhan Date: Wed, 25 Sep 2024 11:43:17 -0700 Subject: [PATCH 028/173] Fix cleanup in PSResourceGet test (#24339) (#24345) --- ...Microsoft.PowerShell.PSResourceGet.Tests.ps1 | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/test/powershell/Modules/Microsoft.PowerShell.PSResourceGet/Microsoft.PowerShell.PSResourceGet.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.PSResourceGet/Microsoft.PowerShell.PSResourceGet.Tests.ps1 index b06f0aa427a..01f9a90127a 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.PSResourceGet/Microsoft.PowerShell.PSResourceGet.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.PSResourceGet/Microsoft.PowerShell.PSResourceGet.Tests.ps1 @@ -331,6 +331,14 @@ Describe "PSResourceGet - Script tests (Admin)" -Tags @('Feature', 'RequireAdmin } } +function FinalCleanUp +{ + if(Test-Path $TempDir) + { + Remove-Item -Path $TempDir -Recurse -Force + } +} + Describe "PSResourceGet - ACR tests" -tags "Feature" { BeforeAll { @@ -396,12 +404,3 @@ Describe "PSResourceGet - ACR tests" -tags "Feature" { FinalCleanUp } } - - -function FinalCleanUp -{ - if(Test-Path $TempDir) - { - Remove-Item -Path $TempDir -Recurse -Force - } -} From 113e15ef345f93c0ab8bbe3f46ac76892d8b2332 Mon Sep 17 00:00:00 2001 From: Justin Chung <124807742+jshigetomi@users.noreply.github.com> Date: Wed, 2 Oct 2024 12:59:44 -0500 Subject: [PATCH 029/173] Fix found during 7.5-preview.5 release (#24368) * Merged PR 32689: Fix typo in release-MakeBlobPublic.yml Fix typo in release-MakeBlobPublic.yml * Merged PR 32693: Add back local NuGet source for test packages Add back local NuGet source for test packages * Merged PR 32696: Fixed Test Scenario for Compress-PSResource The test was failing because a relative path was provided to parameter -DestinationPath. Should update Compress-PSResource to accept relative paths for -DestinationPath. ---- #### AI description (iteration 1) #### PR Classification Bug fix for a failing test scenario. #### PR Summary This pull request fixes the test scenario for the `Compress-PSResource` function. - `Microsoft.PowerShell.PSResourceGet.Tests.ps1`: Updated the path resolution for `$PublishedNupkgs` using `Resolve-Path` and added a missing line break in the test for compressing a module. * Merged PR 32709: Changelog for v7.5.0-preview.5 Added 7.5.0-preview.5 change log ---- #### AI description (iteration 1) #### PR Classification Changelog update for the new preview release. #### PR Summary This pull request updates the changelog for the v7.5.0-preview.5 release, documenting breaking changes, engine updates, new features, and other improvements. - `ConvertTo-Json`: Treat large Enum values as numbers. - `Import-Module`: Fix processor architecture validation. - `Resolve-Path` and `Convert-Path`: Add `-Force` parameter to support wildcard hidden files. - `PSResourceGet` test: Fix cleanup. - Various build and packaging improvements, including updates to dependencies and test scenarios. * fixed readme lint error --------- Co-authored-by: Aditya Patwardhan Co-authored-by: Justin Chung Co-authored-by: Justin Chung --- .../templates/release-MakeBlobPublic.yml | 6 +- .pipelines/templates/release-validate-sdk.yml | 10 +-- CHANGELOG/preview.md | 68 ++++++++++++++++++- ...crosoft.PowerShell.PSResourceGet.Tests.ps1 | 6 +- 4 files changed, 77 insertions(+), 13 deletions(-) diff --git a/.pipelines/templates/release-MakeBlobPublic.yml b/.pipelines/templates/release-MakeBlobPublic.yml index ba4fb14ec8a..52b3476d1e3 100644 --- a/.pipelines/templates/release-MakeBlobPublic.yml +++ b/.pipelines/templates/release-MakeBlobPublic.yml @@ -36,9 +36,9 @@ jobs: CreateJson: yes UseJson: no - - pwsh: | - Get-ChildItem Env: - displayName: 'Capture Environment Variables' + - pwsh: | + Get-ChildItem Env: + displayName: 'Capture Environment Variables' - pwsh: | $azureRmModule = Get-InstalledModule AzureRM -ErrorAction SilentlyContinue -Verbose diff --git a/.pipelines/templates/release-validate-sdk.yml b/.pipelines/templates/release-validate-sdk.yml index f626051b543..db3f550b965 100644 --- a/.pipelines/templates/release-validate-sdk.yml +++ b/.pipelines/templates/release-validate-sdk.yml @@ -89,11 +89,11 @@ jobs: Start-PSBootstrap $localLocation = "$(Pipeline.Workspace)/PSPackagesOfficial/drop_nupkg_build_nupkg" - # $xmlElement = @" - # - # - # - # "@ + $xmlElement = @" + + + + "@ $releaseVersion = '$(Version)' diff --git a/CHANGELOG/preview.md b/CHANGELOG/preview.md index 73d39ba122a..847ca7a2919 100644 --- a/CHANGELOG/preview.md +++ b/CHANGELOG/preview.md @@ -1,5 +1,69 @@ # Preview Changelog +## [7.5.0-preview.5] - 2024-10-01 + +### Breaking Changes + +- Treat large `Enum` values as numbers in `ConvertTo-Json` (#20999) (#24304) + +### Engine Updates and Fixes + +- Fix how processor architecture is validated in `Import-Module` (#24265) (#24317) + +### Experimental Features + +### General Cmdlet Updates and Fixes + +- Add `-Force` parameter to `Resolve-Path` and `Convert-Path` cmdlets to support wildcard hidden files (#20981) (#24344) +- Add telemetry to track the use of features (#24247) (#24331) +- Treat large `Enum` values as numbers in `ConvertTo-Json` (#20999) (#24304) +- Make features `PSCommandNotFoundSuggestion`, `PSCommandWithArgs`, and `PSModuleAutoLoadSkipOfflineFiles` stable (#24246) (#24310) +- Handle global tool when prepending `$PSHome` to `PATH` (#24228) (#24307) + +### Tests + +- Fix cleanup in `PSResourceGet` test (#24339) (#24345) + +### Build and Packaging Improvements + +
+ + + +

Bump .NET SDK to 9.0.100-rc.1.24452.12

+ +
+ +
    +
  • Fixed Test Scenario for Compress-PSResource (Internal 32696)
  • +
  • Add back local NuGet source for test packages (Internal 32693)
  • +
  • Fix typo in release-MakeBlobPublic.yml (Internal 32689)
  • +
  • Copy to static site instead of making blob public (#24269) (#24343)
  • +
  • Update Microsoft.PowerShell.PSResourceGet to 1.1.0-preview2 (#24300) (#24337)
  • +
  • Remove the MD5 branch in the strong name signing token calculation (#24288) (#24321)
  • +
  • Update experimental-feature json files (#24271) (#24319)
  • +
  • Add updated libicu dependency for Debian packages (#24301) (#24324)
  • +
  • Add mapping to AzureLinux repo (#24290) (#24322)
  • +
  • Update and add new NuGet package sources for different environments. (#24264) (#24316)
  • +
  • Bump .NET 9 to 9.0.100-rc.1.24452.12 (#24273) (#24320)
  • +
  • Make some release tests run in a hosted pools (#24270) (#24318)
  • +
  • Do not build the exe for Global tool shim project (#24263) (#24315)
  • +
  • Delete assets/AppImageThirdPartyNotices.txt (#24256) (#24313)
  • +
  • Create new pipeline for compliance (#24252) (#24312)
  • +
  • Add specific path for issues in tsaconfig (#24244) (#24309)
  • +
  • Use Managed Identity for APIScan authentication (#24243) (#24308)
  • +
  • Add Windows signing for pwsh.exe (#24219) (#24306)
  • +
  • Check Create and Submit in vPack build by default (#24181) (#24305)
  • +
+ +
+ +### Documentation and Help Content + +- Delete demos directory (#24258) (#24314) + +[7.5.0-preview.5]: https://github.com/PowerShell/PowerShell/compare/v7.5.0-preview.4...v7.5.0-preview.5 + ## [7.5.0-preview.4] - 2024-08-28 ### Engine Updates and Fixes @@ -474,7 +538,7 @@ ### Documentation and Help Content -- Include information about upgrading in README (#20993) +- Include information about upgrading in readme (#20993) - Expand "iff" to "if-and-only-if" in XML doc content (#20852) - Update LTS links in README.md to point to the v7.4 packages (#20839) (Thanks @kilasuit!) - Update `README.md` to improve readability (#20553) (Thanks @AnkitaSikdar005!) @@ -482,7 +546,7 @@ - Update `ADOPTERS.md` (#20555) (Thanks @AnkitaSikdar005!) - Fix a typo in `ADOPTERS.md` (#20504, #20520) (Thanks @shruti-sen2004!) - Correct grammatical errors in `README.md` (#20509) (Thanks @alienishi!) -- Add 7.3 changelog URL to Readme (#20473) (Thanks @Saibamen!) +- Add 7.3 changelog URL to readme (#20473) (Thanks @Saibamen!) - Clarify some comments and documentation (#20462) (Thanks @darkstar!) [7.5.0-preview.1]: https://github.com/PowerShell/PowerShell/compare/v7.4.1...v7.5.0-preview.1 diff --git a/test/powershell/Modules/Microsoft.PowerShell.PSResourceGet/Microsoft.PowerShell.PSResourceGet.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.PSResourceGet/Microsoft.PowerShell.PSResourceGet.Tests.ps1 index 01f9a90127a..46e4f60cbc2 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.PSResourceGet/Microsoft.PowerShell.PSResourceGet.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.PSResourceGet/Microsoft.PowerShell.PSResourceGet.Tests.ps1 @@ -197,15 +197,15 @@ Describe "PSResourceGet - Module tests" -tags "Feature" { } It "Should compress a module into a .nupkg" { - Compress-PSResource -Path $TestModule -DestinationPath $PublishedNupkgs - + Compress-PSResource -Path $TestModule -DestinationPath (Resolve-Path -Path $PublishedNupkgs) + $modulePublished = Get-ChildItem $TestModuleNupkgPath $modulePublished | Should -Not -BeNullOrEmpty $modulePublished.Name | Should -Be $TestModuleNupkgName } It "Should publish compressed .nupkg" { - Compress-PSResource -Path $TestModule -DestinationPath $PublishedNupkgs + Compress-PSResource -Path $TestModule -DestinationPath (Resolve-Path -Path $PublishedNupkgs) Publish-PSResource -NupkgPath $TestModuleNupkgPath -Repository $LocalRepoName From 34c679ec05b18f39f212a4d8852875d929e1aea3 Mon Sep 17 00:00:00 2001 From: Travis Plunk Date: Thu, 3 Oct 2024 13:09:57 -0700 Subject: [PATCH 030/173] Add `BaseUrl` to `buildinfo` json file (#24376) (#24377) Co-authored-by: Patrick Meinecke --- tools/releaseBuild/setReleaseTag.ps1 | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/releaseBuild/setReleaseTag.ps1 b/tools/releaseBuild/setReleaseTag.ps1 index 3f501051c19..c5f2f016554 100644 --- a/tools/releaseBuild/setReleaseTag.ps1 +++ b/tools/releaseBuild/setReleaseTag.ps1 @@ -41,6 +41,7 @@ function New-BuildInfoJson { ReleaseTag = $ReleaseTag ReleaseDate = $dateTime BlobName = $blobName + BaseUrl = 'https://powershellinfraartifacts-gkhedzdeaghdezhr.z01.azurefd.net/install' } | ConvertTo-Json | Out-File -Encoding ascii -Force -FilePath $filename $resolvedPath = (Resolve-Path -Path $filename).ProviderPath From 04efcdc3f09f439794d00ba7feaf121d54239619 Mon Sep 17 00:00:00 2001 From: Justin Chung <124807742+jshigetomi@users.noreply.github.com> Date: Thu, 3 Oct 2024 17:21:14 -0500 Subject: [PATCH 031/173] Bring preview.5 release fixes to release/v7.5 (#24379) * added ks2 to release pipeline * Merged PR 32752: Copy global tools to static site Rather than an intermediate folder that must be manually copied into the static site. ---- #### AI description (iteration 1) #### PR Classification Code modification to enhance functionality. #### PR Summary This pull request updates the release pipeline to copy global tools to a static site. - Changes in `/.pipelines/templates/release-MakeBlobPublic.yml` to set `prefix` and `destinationPrefix` for blob copying. - Adjusted destination container name to use `$web` and updated blob naming conventions. * Merged PR 32759: Switch to single quotes for container name in global tool copy #### AI description (iteration 1) #### PR Classification Code cleanup #### PR Summary This pull request updates the container name string to use single quotes for consistency. - Changes in `/.pipelines/templates/release-MakeBlobPublic.yml` to switch `$destinationContainerName` from double quotes to single quotes. * Added condition for make blob public * moved conditional from global tools to copy * conditional as a paramter instead of var * removed dependency * blob folder name to release Tag --------- Co-authored-by: Justin Chung Co-authored-by: Patrick Meinecke --- .pipelines/PowerShell-Release-Official.yml | 12 +++++++ .../templates/release-MakeBlobPublic.yml | 33 +++++++++++-------- .pipelines/templates/release-publish-pmc.yml | 2 +- 3 files changed, 33 insertions(+), 14 deletions(-) diff --git a/.pipelines/PowerShell-Release-Official.yml b/.pipelines/PowerShell-Release-Official.yml index eb21b407ba7..2538d1b5370 100644 --- a/.pipelines/PowerShell-Release-Official.yml +++ b/.pipelines/PowerShell-Release-Official.yml @@ -21,6 +21,10 @@ parameters: # parameters are shown up in ADO UI in a build queue time displayName: Skip PMC Publish type: boolean default: false + - name: SkipPSInfraInstallers + displayName: Skip Copying Archives and Installers to PSInfrastructure Public Location + type: boolean + default: false variables: - name: CDP_DEFINITION_BUILD_COUNT @@ -75,6 +79,12 @@ resources: extends: template: v2/OneBranch.Official.CrossPlat.yml@templates parameters: + # still using KS2 because we are not yet using a Box Product Deployment + featureFlags: + LinuxHostVersion: + Network: KS2 + WindowsHostVersion: + Network: KS2 cloudvault: enabled: false globalSdl: @@ -257,6 +267,8 @@ extends: dependsOn: UpdateChangeLog jobs: - template: /.pipelines/templates/release-MakeBlobPublic.yml@self + parameters: + SkipPSInfraInstallers: ${{ parameters.SkipPSInfraInstallers }} - stage: PublishGitHubRelease displayName: Publish GitHub Release diff --git a/.pipelines/templates/release-MakeBlobPublic.yml b/.pipelines/templates/release-MakeBlobPublic.yml index 52b3476d1e3..f9afbebb909 100644 --- a/.pipelines/templates/release-MakeBlobPublic.yml +++ b/.pipelines/templates/release-MakeBlobPublic.yml @@ -1,3 +1,9 @@ +parameters: + - name: SkipPSInfraInstallers + displayName: Skip Copying Archives and Installers to PSInfrastructure Public Location + type: boolean + default: false + jobs: - template: /.pipelines/templates/approvalJob.yml@self parameters: @@ -9,6 +15,7 @@ jobs: - job: PSInfraReleaseBlobPublic displayName: Copy release to PSInfra storage dependsOn: CopyReleaseBlobApproval + condition: and(succeeded(), ne('${{ parameters.SkipPSInfraInstallers }}', true)) pool: type: windows @@ -99,7 +106,6 @@ jobs: parameters: displayName: Approve Copy Global tool packages to PSInfra storage jobName: CopyBlobApproval - dependsOnJob: PSInfraReleaseBlobPublic instructions: | Approval for Copy global tool packages to PSInfra storage @@ -110,14 +116,14 @@ jobs: type: windows variables: - - group: 'PSInfraStorage' - - group: 'Azure Blob variable group' - - name: ob_outputDirectory - value: '$(Build.ArtifactStagingDirectory)/ONEBRANCH_ARTIFACT' - - name: ob_sdl_tsa_configFile - value: $(Build.SourcesDirectory)\PowerShell\.config\tsaoptions.json - - name: ob_sdl_credscan_suppressionsFile - value: $(Build.SourcesDirectory)\PowerShell\.config\suppress.json + - group: 'PSInfraStorage' + - group: 'Azure Blob variable group' + - name: ob_outputDirectory + value: '$(Build.ArtifactStagingDirectory)/ONEBRANCH_ARTIFACT' + - name: ob_sdl_tsa_configFile + value: $(Build.SourcesDirectory)\PowerShell\.config\tsaoptions.json + - name: ob_sdl_credscan_suppressionsFile + value: $(Build.SourcesDirectory)\PowerShell\.config\suppress.json steps: - checkout: self @@ -156,9 +162,11 @@ jobs: inline: | $sourceStorageAccountName = '$(StorageAccount)' $sourceContainerName = '$(AzureVersion)-nuget' + $prefix = 'globaltool' $destinationStorageAccountName = '$(PSInfraStorageAccount)' - $destinationContainerName = "tool" + $destinationContainerName = '$web' + $destinationPrefix = 'tool/$(Version)' $sourceContext = New-AzStorageContext -StorageAccountName $sourceStorageAccountName Write-Verbose -Verbose "Source context: $($sourceContext.BlobEndPoint)" @@ -166,19 +174,18 @@ jobs: $destinationContext = New-AzStorageContext -StorageAccountName $destinationStorageAccountName Write-Verbose -Verbose "Destination context: $($destinationContext.BlobEndPoint)" - $prefix = 'globaltool' $blobs = Get-AzStorageBlob -Context $sourceContext -Container $sourceContainerName -Prefix $prefix Write-Verbose -Verbose "Blobs found in $sourceContainerName" $blobs.Name | Write-Verbose -Verbose - Write-Verbose -Verbose "Copying blobs from $sourceContainerName to $destinationContainerName" + Write-Verbose -Verbose "Copying blobs from $sourceContainerName to $destinationContainerName/$destinationPrefix" foreach ($blob in $blobs) { $sourceBlobName = $blob.Name Write-Verbose -Verbose "sourceBlobName = $sourceBlobName" - $destinationBlobName = $sourceBlobName -replace "$prefix", '$(Version)' + $destinationBlobName = $sourceBlobName -replace "$prefix", $destinationPrefix Write-Verbose -Verbose "destinationBlobName = $destinationBlobName" Copy-AzStorageBlob -SourceContext $sourceContext -DestinationContext $destinationContext -SrcContainer $sourceContainerName -SrcBlob $sourceBlobName -DestContainer $destinationContainerName -DestBlob $destinationBlobName -Force -Verbose -Confirm:$false diff --git a/.pipelines/templates/release-publish-pmc.yml b/.pipelines/templates/release-publish-pmc.yml index 93032f35b3b..27311611e61 100644 --- a/.pipelines/templates/release-publish-pmc.yml +++ b/.pipelines/templates/release-publish-pmc.yml @@ -77,7 +77,7 @@ jobs: $params = @{ ReleaseTag = "$(ReleaseTag)" AadClientId = "$(PmcCliClientID)" - BlobFolderName = "$(AzureVersion)" + BlobFolderName = "$(ReleaseTag)" LTS = $metadata.LTSRelease.Latest ForProduction = $true SkipPublish = $${{ parameters.skipPublish }} From 30b9b9ddbfaada7dbc94e28bd508c6a129c630ba Mon Sep 17 00:00:00 2001 From: Travis Plunk Date: Thu, 10 Oct 2024 12:28:43 -0700 Subject: [PATCH 032/173] Revert "Add windows signing for pwsh.exe (#24219) (#24306)" (#24408) This reverts commit f0461bc00f673ac20c2531d3006813ba692e7ba1. --- .pipelines/templates/obp-file-signing.yml | 25 ----------------------- 1 file changed, 25 deletions(-) diff --git a/.pipelines/templates/obp-file-signing.yml b/.pipelines/templates/obp-file-signing.yml index 7ed973ddf5a..ba761633b29 100644 --- a/.pipelines/templates/obp-file-signing.yml +++ b/.pipelines/templates/obp-file-signing.yml @@ -84,31 +84,6 @@ steps: files_to_sign: '**\*.psd1;**\*.psm1;**\*.ps1xml;**\*.ps1;**\*.dll;**\*.exe;**\pwsh' search_root: $(Pipeline.Workspace)/toBeSigned -- task: onebranch.pipeline.signing@1 - displayName: Sign pwsh.exe with Windows cert - inputs: - command: 'sign' - cp_code: '203' - files_to_sign: '**\pwsh.exe' - search_root: $(Pipeline.Workspace)/toBeSigned - -- pwsh: | - if (Test-Path $(Pipeline.Workspace)/toBeSigned/pwsh.exe) { - Write-Verbose -Verbose "pwsh.exe is found, verifying signature" - $signature = Get-AuthenticodeSignature -FilePath $(Pipeline.Workspace)/toBeSigned/pwsh.exe - if ($signature.SignerCertificate.Issuer -notmatch '^CN=Microsoft Windows Production.*') { - Write-Error -ErrorAction Stop "pwsh.exe is not signed by Microsoft" - } - else { - Write-Verbose -Verbose "pwsh.exe is signed by Microsoft" - } - } - else { - Write-Verbose -Verbose "pwsh.exe is not found, skipping" - } - - displayName: 'Verify windows signature' - - pwsh : | Get-ChildItem -Path env: displayName: Capture environment From d50eeea479811b752be87ebacae0dd7c9e3dcd0d Mon Sep 17 00:00:00 2001 From: Aditya Patwardhan Date: Wed, 30 Oct 2024 20:57:41 -0700 Subject: [PATCH 033/173] Fix seed max value for Container Linux CI (#24510) (#24511) --- tools/ci.psm1 | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tools/ci.psm1 b/tools/ci.psm1 index 73c6cb41e83..6628d54e043 100644 --- a/tools/ci.psm1 +++ b/tools/ci.psm1 @@ -863,11 +863,17 @@ function Invoke-InitializeContainerStage { # For PRs set the seed to the PR number so that the image is always the same $seed = $env:SYSTEM_PULLREQUEST_PULLREQUESTID + if(!$seed) { # for non-PRs use the integer identifier of the build as the seed. $seed = $fallbackSeed } + # cut down to 32 bits and keep the most varying parts, which are lower bits + if ($seed -ge [Int32]::MaxValue) { + $seed = [int]($seed -band [int]::MaxValue) + } + Write-Verbose "Seed: $seed" -Verbose # Get the latest image matrix JSON for preview From ff03706831da454567f4077fbb1a2c80eee21cac Mon Sep 17 00:00:00 2001 From: Aditya Patwardhan Date: Wed, 30 Oct 2024 23:10:21 -0700 Subject: [PATCH 034/173] Update package references (#24414) (#24513) --- ...oft.PowerShell.Commands.Diagnostics.csproj | 2 +- ...soft.PowerShell.Commands.Management.csproj | 2 +- ...crosoft.PowerShell.Commands.Utility.csproj | 4 ++-- ...crosoft.PowerShell.CoreCLR.Eventing.csproj | 2 +- .../Microsoft.PowerShell.SDK.csproj | 10 +++++----- .../Microsoft.WSMan.Management.csproj | 2 +- .../PSVersionInfoGenerator.csproj | 2 +- .../System.Management.Automation.csproj | 20 +++++++++---------- test/tools/TestService/TestService.csproj | 4 ++-- 9 files changed, 23 insertions(+), 25 deletions(-) diff --git a/src/Microsoft.PowerShell.Commands.Diagnostics/Microsoft.PowerShell.Commands.Diagnostics.csproj b/src/Microsoft.PowerShell.Commands.Diagnostics/Microsoft.PowerShell.Commands.Diagnostics.csproj index 9f36b8134d1..34502ced25d 100644 --- a/src/Microsoft.PowerShell.Commands.Diagnostics/Microsoft.PowerShell.Commands.Diagnostics.csproj +++ b/src/Microsoft.PowerShell.Commands.Diagnostics/Microsoft.PowerShell.Commands.Diagnostics.csproj @@ -8,7 +8,7 @@ - + diff --git a/src/Microsoft.PowerShell.Commands.Management/Microsoft.PowerShell.Commands.Management.csproj b/src/Microsoft.PowerShell.Commands.Management/Microsoft.PowerShell.Commands.Management.csproj index 695ed6f21e4..4f20755c6e6 100644 --- a/src/Microsoft.PowerShell.Commands.Management/Microsoft.PowerShell.Commands.Management.csproj +++ b/src/Microsoft.PowerShell.Commands.Management/Microsoft.PowerShell.Commands.Management.csproj @@ -47,7 +47,7 @@ - + diff --git a/src/Microsoft.PowerShell.Commands.Utility/Microsoft.PowerShell.Commands.Utility.csproj b/src/Microsoft.PowerShell.Commands.Utility/Microsoft.PowerShell.Commands.Utility.csproj index 113d62231f0..dd2bf636955 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/Microsoft.PowerShell.Commands.Utility.csproj +++ b/src/Microsoft.PowerShell.Commands.Utility/Microsoft.PowerShell.Commands.Utility.csproj @@ -33,8 +33,8 @@ - - + + diff --git a/src/Microsoft.PowerShell.CoreCLR.Eventing/Microsoft.PowerShell.CoreCLR.Eventing.csproj b/src/Microsoft.PowerShell.CoreCLR.Eventing/Microsoft.PowerShell.CoreCLR.Eventing.csproj index 1296b1e28ba..003999e97b3 100644 --- a/src/Microsoft.PowerShell.CoreCLR.Eventing/Microsoft.PowerShell.CoreCLR.Eventing.csproj +++ b/src/Microsoft.PowerShell.CoreCLR.Eventing/Microsoft.PowerShell.CoreCLR.Eventing.csproj @@ -8,7 +8,7 @@ - + diff --git a/src/Microsoft.PowerShell.SDK/Microsoft.PowerShell.SDK.csproj b/src/Microsoft.PowerShell.SDK/Microsoft.PowerShell.SDK.csproj index 34c462edbd4..5a1001ddc2c 100644 --- a/src/Microsoft.PowerShell.SDK/Microsoft.PowerShell.SDK.csproj +++ b/src/Microsoft.PowerShell.SDK/Microsoft.PowerShell.SDK.csproj @@ -17,13 +17,13 @@ - + - - - + + + - + diff --git a/src/Microsoft.WSMan.Management/Microsoft.WSMan.Management.csproj b/src/Microsoft.WSMan.Management/Microsoft.WSMan.Management.csproj index 9a8f4973d1a..77aa3cef77c 100644 --- a/src/Microsoft.WSMan.Management/Microsoft.WSMan.Management.csproj +++ b/src/Microsoft.WSMan.Management/Microsoft.WSMan.Management.csproj @@ -10,7 +10,7 @@ - +
diff --git a/src/System.Management.Automation/SourceGenerators/PSVersionInfoGenerator/PSVersionInfoGenerator.csproj b/src/System.Management.Automation/SourceGenerators/PSVersionInfoGenerator/PSVersionInfoGenerator.csproj index fe82962adca..228126c3267 100644 --- a/src/System.Management.Automation/SourceGenerators/PSVersionInfoGenerator/PSVersionInfoGenerator.csproj +++ b/src/System.Management.Automation/SourceGenerators/PSVersionInfoGenerator/PSVersionInfoGenerator.csproj @@ -15,6 +15,6 @@ - + diff --git a/src/System.Management.Automation/System.Management.Automation.csproj b/src/System.Management.Automation/System.Management.Automation.csproj index e4b0c5d7e48..cefbbfa31f0 100644 --- a/src/System.Management.Automation/System.Management.Automation.csproj +++ b/src/System.Management.Automation/System.Management.Automation.csproj @@ -19,9 +19,7 @@ - + @@ -34,16 +32,16 @@ - - - - + + + + - + - - - + + + diff --git a/test/tools/TestService/TestService.csproj b/test/tools/TestService/TestService.csproj index f6ca75e1dae..56b17f3d7bc 100644 --- a/test/tools/TestService/TestService.csproj +++ b/test/tools/TestService/TestService.csproj @@ -15,8 +15,8 @@ - - + + From 81e916c1c0894dd6d7351829e8a13e7da83dfa6c Mon Sep 17 00:00:00 2001 From: Aditya Patwardhan Date: Wed, 30 Oct 2024 23:17:18 -0700 Subject: [PATCH 035/173] Update vpack pipeline (#24281) (#24514) --- .pipelines/PowerShell-vPack-Official.yml | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/.pipelines/PowerShell-vPack-Official.yml b/.pipelines/PowerShell-vPack-Official.yml index bb780a6f203..91735669d99 100644 --- a/.pipelines/PowerShell-vPack-Official.yml +++ b/.pipelines/PowerShell-vPack-Official.yml @@ -82,19 +82,14 @@ extends: enabled: true scanFolder: $(Build.SourcesDirectory) suppressionsFile: $(Build.SourcesDirectory)\.config\suppress.json - asyncSdl: - enabled: true - forStages: ['main'] - credscan: - enabled: true - scanFolder: $(Build.SourcesDirectory) - suppressionsFile: $(Build.SourcesDirectory)\PowerShell\.config\suppress.json - binskim: - enabled: false - # APIScan requires a non-Ready-To-Run build - apiscan: - enabled: false - tsaOptionsFile: .config/tsaoptions.json + binskim: + enabled: false + # APIScan requires a non-Ready-To-Run build + apiscan: + enabled: false + asyncSDL: + enabled: false + tsaOptionsFile: .config/tsaoptions.json stages: - stage: main jobs: From c22f576a49f7dc1771f131cfb8d9973852371a62 Mon Sep 17 00:00:00 2001 From: Aditya Patwardhan Date: Wed, 30 Oct 2024 23:17:44 -0700 Subject: [PATCH 036/173] Add CodeQL scanning to APIScan build (#24303) (#24515) --- .pipelines/apiscan-gen-notice.yml | 32 +++++++++- .pipelines/templates/compliance/apiscan.yml | 68 ++++++++++++--------- 2 files changed, 69 insertions(+), 31 deletions(-) diff --git a/.pipelines/apiscan-gen-notice.yml b/.pipelines/apiscan-gen-notice.yml index 02ab4ba3796..f469a49eef5 100644 --- a/.pipelines/apiscan-gen-notice.yml +++ b/.pipelines/apiscan-gen-notice.yml @@ -1,8 +1,14 @@ # Copyright (c) Microsoft Corporation. # Licensed under the MIT License. - +name: apiscan-genNotice-$(BUILD.SOURCEBRANCHNAME)-$(Build.BuildId) trigger: none +parameters: + - name: FORCE_CODEQL + displayName: Debugging - Enable CodeQL and set cadence to 1 hour + type: boolean + default: false + variables: - name: ob_outputDirectory value: '$(Build.ArtifactStagingDirectory)/ONEBRANCH_ARTIFACT' @@ -17,6 +23,24 @@ variables: value: onebranch.azurecr.io/linux/ubuntu-2004:latest - name: WindowsContainerImage value: onebranch.azurecr.io/windows/ltsc2022/vse2022:latest + - ${{ if eq(parameters['FORCE_CODEQL'],'true') }}: + # Cadence is hours before CodeQL will allow a re-upload of the database + - name: CodeQL.Cadence + value: 0 + - name: CODEQL_ENABLED + ${{ if or(eq(variables['Build.SourceBranch'], 'refs/heads/master'), eq(parameters['FORCE_CODEQL'],'true')) }}: + value: true + ${{ else }}: + value: false + - name: Codeql.TSAEnabled + value: $(CODEQL_ENABLED) + # AnalyzeInPipeline: false = upload results + # AnalyzeInPipeline: true = do not upload results + - name: Codeql.AnalyzeInPipeline + ${{ if or(eq(variables['Build.SourceBranch'], 'refs/heads/master'), eq(parameters['FORCE_CODEQL'],'true')) }}: + value: false + ${{ else }}: + value: true resources: repositories: @@ -32,8 +56,10 @@ extends: WindowsHostVersion: Version: 2022 globalSdl: - compiled: - enabled: true + codeql: + compiled: + enabled: $(CODEQL_ENABLED) + tsaEnabled: $(CODEQL_ENABLED) # This enables TSA bug filing only for CodeQL 3000 armory: enabled: false sbom: diff --git a/.pipelines/templates/compliance/apiscan.yml b/.pipelines/templates/compliance/apiscan.yml index a96471aecd9..b30d72f6a56 100644 --- a/.pipelines/templates/compliance/apiscan.yml +++ b/.pipelines/templates/compliance/apiscan.yml @@ -4,34 +4,36 @@ jobs: - job: APIScan variables: - - name: runCodesignValidationInjection - value : false - - name: NugetSecurityAnalysisWarningLevel - value: none - - name: ReleaseTagVar - value: fromBranch - # Defines the variables APIScanClient, APIScanTenant and APIScanSecret - - group: PS-PS-APIScan - # PAT permissions NOTE: Declare a SymbolServerPAT variable in this group with a 'microsoft' organizanization scoped PAT with 'Symbols' Read permission. - # A PAT in the wrong org will give a single Error 203. No PAT will give a single Error 401, and individual pdbs may be missing even if permissions are correct. - - group: symbols - - name: branchCounterKey - value: $[format('{0:yyyyMMdd}-{1}', pipeline.startTime,variables['Build.SourceBranch'])] - - name: branchCounter - value: $[counter(variables['branchCounterKey'], 1)] - - group: DotNetPrivateBuildAccess - - group: Azure Blob variable group - - group: ReleasePipelineSecrets - - group: mscodehub-feed-read-general - - group: mscodehub-feed-read-akv - - name: ob_outputDirectory - value: '$(Build.ArtifactStagingDirectory)/ONEBRANCH_ARTIFACT' - - name: repoRoot - value: '$(Build.SourcesDirectory)\PowerShell' - - name: ob_sdl_tsa_configFile - value: $(Build.SourcesDirectory)\PowerShell\.config\tsaoptions.json - - name: ob_sdl_credscan_suppressionsFile - value: $(Build.SourcesDirectory)\PowerShell\.config\suppress.json + - name: runCodesignValidationInjection + value : false + - name: NugetSecurityAnalysisWarningLevel + value: none + - name: ReleaseTagVar + value: fromBranch + # Defines the variables APIScanClient, APIScanTenant and APIScanSecret + - group: PS-PS-APIScan + # PAT permissions NOTE: Declare a SymbolServerPAT variable in this group with a 'microsoft' organizanization scoped PAT with 'Symbols' Read permission. + # A PAT in the wrong org will give a single Error 203. No PAT will give a single Error 401, and individual pdbs may be missing even if permissions are correct. + - group: symbols + - name: branchCounterKey + value: $[format('{0:yyyyMMdd}-{1}', pipeline.startTime,variables['Build.SourceBranch'])] + - name: branchCounter + value: $[counter(variables['branchCounterKey'], 1)] + - group: DotNetPrivateBuildAccess + - group: Azure Blob variable group + - group: ReleasePipelineSecrets + - group: mscodehub-feed-read-general + - group: mscodehub-feed-read-akv + - name: ob_outputDirectory + value: '$(Build.ArtifactStagingDirectory)/ONEBRANCH_ARTIFACT' + - name: repoRoot + value: '$(Build.SourcesDirectory)\PowerShell' + - name: ob_sdl_tsa_configFile + value: $(Build.SourcesDirectory)\PowerShell\.config\tsaoptions.json + - name: ob_sdl_credscan_suppressionsFile + value: $(Build.SourcesDirectory)\PowerShell\.config\suppress.json + - name: Codeql.SourceRoot + value: $(repoRoot) pool: type: windows @@ -119,6 +121,12 @@ jobs: workingDirectory: '$(repoRoot)' condition: succeededOrFailed() + - task: CodeQL3000Init@0 # Add CodeQL Init task right before your 'Build' step. + displayName: 🔏 CodeQL 3000 Init + condition: eq(variables['CODEQL_ENABLED'], 'true') + inputs: + Language: csharp + - pwsh: | Import-Module .\build.psm1 -force Find-DotNet @@ -136,6 +144,10 @@ jobs: workingDirectory: '$(repoRoot)' displayName: 'Build PowerShell Source' + - task: CodeQL3000Finalize@0 # Add CodeQL Finalize task right after your 'Build' step. + displayName: 🔏 CodeQL 3000 Finalize + condition: eq(variables['CODEQL_ENABLED'], 'true') + - pwsh: | Get-ChildItem -Path env: | Out-String -width 9999 -Stream | write-Verbose -Verbose workingDirectory: '$(repoRoot)' From 3c2d60eafd2d7bc34c26ad8754fc8b9e563e8a31 Mon Sep 17 00:00:00 2001 From: Aditya Patwardhan Date: Wed, 30 Oct 2024 23:18:01 -0700 Subject: [PATCH 037/173] Delete the msix blob if it's already there (#24353) (#24516) --- .pipelines/templates/release-create-msix.yml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/.pipelines/templates/release-create-msix.yml b/.pipelines/templates/release-create-msix.yml index 89f2e7b5a2c..448a46c1194 100644 --- a/.pipelines/templates/release-create-msix.yml +++ b/.pipelines/templates/release-create-msix.yml @@ -104,8 +104,14 @@ jobs: if ($env:BundleDir) { $bundleFile = Get-Item "$env:BundleDir\*.msixbundle" $blobName = $bundleFile | Split-Path -Leaf + $existing = Get-AzStorageBlob -Container $containerName -Blob $blobName -Context $storageContext -ErrorAction Ignore + if ($existing) { + Write-Verbose -Verbose "MSIX bundle already exists at '$storageAccount/$containerName/$blobName', removing first." + $existingBlob | Remove-AzStorageBlob -ErrorAction Stop -Verbose + } + Write-Verbose -Verbose "Uploading $bundleFile to $containerName/$blobName" - Set-AzStorageBlobContent -File $bundleFile -Container $containerName -Blob $blobName -Context $storageContext + Set-AzStorageBlobContent -File $bundleFile -Container $containerName -Blob $blobName -Context $storageContext -Force } else{ throw "BundleDir not found" From 8dfb52184663731ed3d1ab0f423231dbed3b7e41 Mon Sep 17 00:00:00 2001 From: Aditya Patwardhan Date: Wed, 30 Oct 2024 23:18:40 -0700 Subject: [PATCH 038/173] Download package from package build for generating vpack (#24481) (#24521) --- .pipelines/PowerShell-vPack-Official.yml | 31 +++++++++++++----------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/.pipelines/PowerShell-vPack-Official.yml b/.pipelines/PowerShell-vPack-Official.yml index 91735669d99..33eddc88d0e 100644 --- a/.pipelines/PowerShell-vPack-Official.yml +++ b/.pipelines/PowerShell-vPack-Official.yml @@ -59,6 +59,15 @@ resources: name: OneBranch.Pipelines/GovernedTemplates ref: refs/heads/main + pipelines: + - pipeline: PSPackagesOfficial + source: 'PowerShell-Packages-Official' + trigger: + branches: + include: + - master + - releases/* + extends: template: v2/Microsoft.Official.yml@templates parameters: @@ -129,21 +138,15 @@ extends: installationPath: $(Agent.ToolsDirectory)/dotnet - pwsh: | - Import-module '$(BUILD.SOURCESDIRECTORY)/build.psm1' - Install-AzCopy - displayName: Install AzCopy - retryCountOnTaskFailure: 2 + $packageArtifactName = 'drop_windows_package_package_${{ parameters.architecture }}' + $vstsCommandString = "vso[task.setvariable variable=PackageArtifactName]$packageArtifactName" + Write-Host "sending " + $vstsCommandString + Write-Host "##$vstsCommandString" + displayName: 'Set package artifact name' - - pwsh: | - Import-module '$(BUILD.SOURCESDIRECTORY)/build.psm1' - $azcopy = Find-AzCopy - Write-Verbose -Verbose "Found AzCopy: $azcopy" - Write-Host "running: $azcopy cp https://$(StorageAccount).blob.core.windows.net/$(AzureVersion)/PowerShell-$(Version)-win-${{ parameters.architecture }}.zip $(System.ArtifactsDirectory)" - & $azcopy cp https://$(StorageAccount).blob.core.windows.net/$(AzureVersion)/PowerShell-$(Version)-win-${{ parameters.architecture }}.zip $(System.ArtifactsDirectory) - displayName: 'Download Azure Artifacts' - retryCountOnTaskFailure: 2 - env: - AZCOPY_AUTO_LOGIN_TYPE: MSI + - download: PSPackagesOfficial + artifact: $(PackageArtifactName) + displayName: Download package - pwsh: 'Get-ChildItem $(System.ArtifactsDirectory)\* -recurse | Select-Object -ExpandProperty Name' displayName: 'Capture Artifact Listing' From 7649d338f7599dee20b4b466990167bf16ef8e44 Mon Sep 17 00:00:00 2001 From: Aditya Patwardhan Date: Thu, 31 Oct 2024 09:14:24 -0700 Subject: [PATCH 039/173] Update PSReadLine to 2.3.6 (#24380) (#24517) --- src/Modules/PSGalleryModules.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Modules/PSGalleryModules.csproj b/src/Modules/PSGalleryModules.csproj index 1c8e5e64356..e105facf8e4 100644 --- a/src/Modules/PSGalleryModules.csproj +++ b/src/Modules/PSGalleryModules.csproj @@ -15,7 +15,7 @@ - + From afd21a32c1d083b9beeb2c8a803bbd3fe794671d Mon Sep 17 00:00:00 2001 From: Aditya Patwardhan Date: Thu, 31 Oct 2024 09:15:11 -0700 Subject: [PATCH 040/173] Checkin generated manpage (#24423) (#24519) --- .vsts-ci/mac.yml | 17 +++++++++++++++++ assets/manpage/pwsh.1 | 10 ++++++++++ assets/{ => manpage}/pwsh.1.ronn | 0 build.psm1 | 3 +-- tools/packaging/packaging.psm1 | 27 ++++++++------------------- 5 files changed, 36 insertions(+), 21 deletions(-) create mode 100644 assets/manpage/pwsh.1 rename assets/{ => manpage}/pwsh.1.ronn (100%) diff --git a/.vsts-ci/mac.yml b/.vsts-ci/mac.yml index 9e297cf4ae6..bfb0b3afd21 100644 --- a/.vsts-ci/mac.yml +++ b/.vsts-ci/mac.yml @@ -96,3 +96,20 @@ stages: parameters: pool: macOS-latest +- stage: PackageMac + dependsOn: ['BuildMac'] + displayName: Package macOS (bootstrap only) + jobs: + - job: macos_packaging + pool: + vmImage: macOS-latest + + displayName: macOS packaging (bootstrap only) + steps: + - checkout: self + clean: true + - pwsh: | + import-module ./build.psm1 + start-psbootstrap -package + displayName: Bootstrap packaging + condition: succeededOrFailed() diff --git a/assets/manpage/pwsh.1 b/assets/manpage/pwsh.1 new file mode 100644 index 00000000000..14c191241a9 --- /dev/null +++ b/assets/manpage/pwsh.1 @@ -0,0 +1,10 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "PWSH" "1" "October 2023" "" "" +. +.SH "NAME" +\fBpwsh\fR \- PowerShell command\-line shell and \.NET REPL +. +.SH "SYNOPSIS" +\fBpwsh\fR [\fB\-Login\fR] [ [\fB\-File\fR] \fIfilePath\fR [args] ] [\fB\-Command\fR { \- | \fIscript\-block\fR [\fB\-args\fR \fIarg\-array\fR] | \fIstring\fR [\fICommandParameters\fR] } ] [\fB\-ConfigurationFile\fR \fIfilePath\fR] [\fB\-ConfigurationName\fR \fIstring\fR] [\fB\-CustomPipeName\fR \fIstring\fR] [\fB\-EncodedArguments\fR \fIBase64EncodedArguments\fR] [\fB\-EncodedCommand\fR \fIBase64EncodedCommand\fR] [\fB\-ExecutionPolicy\fR \fIExecutionPolicy\fR] [\fB\-Help\fR] [\fB\-InputFormat\fR {Text | XML}] [\fB\-Interactive\fR] [\fB\-MTA\fR] [\fB\-NoExit\fR] [\fB\-NoLogo\fR] [\fB\-NonInteractive\fR] [\fB\-NoProfile\fR] [\fB\-NoProfileLoadTime\fR] [\fB\-OutputFormat\fR {Text | XML}] [\fB\-SettingsFile\fR \fIfilePath\fR] [\fB\-SSHServerMode\fR] [\fB\-STA\fR] [\fB\-Version\fR] [\fB\-WindowStyle\fR diff --git a/assets/pwsh.1.ronn b/assets/manpage/pwsh.1.ronn similarity index 100% rename from assets/pwsh.1.ronn rename to assets/manpage/pwsh.1.ronn diff --git a/build.psm1 b/build.psm1 index 2d038367713..7855e46ac1a 100644 --- a/build.psm1 +++ b/build.psm1 @@ -2333,12 +2333,11 @@ function Start-PSBootstrap { } } - # Install [fpm](https://github.com/jordansissel/fpm) and [ronn](https://github.com/rtomayko/ronn) + # Install [fpm](https://github.com/jordansissel/fpm) if ($Package) { Install-GlobalGem -Sudo $sudo -GemName "dotenv" -GemVersion "2.8.1" Install-GlobalGem -Sudo $sudo -GemName "ffi" -GemVersion "1.16.3" Install-GlobalGem -Sudo $sudo -GemName "fpm" -GemVersion "1.15.1" - Install-GlobalGem -Sudo $sudo -GemName "ronn" -GemVersion "0.7.3" Install-GlobalGem -Sudo $sudo -GemName "rexml" -GemVersion "3.2.5" } } diff --git a/tools/packaging/packaging.psm1 b/tools/packaging/packaging.psm1 index 1c3686591f0..95caafede8d 100644 --- a/tools/packaging/packaging.psm1 +++ b/tools/packaging/packaging.psm1 @@ -1636,7 +1636,7 @@ function Get-PackageDependencies function Test-Dependencies { - foreach ($Dependency in "fpm", "ronn") { + foreach ($Dependency in "fpm") { if (!(precheck $Dependency "Package dependency '$Dependency' not found. Run Start-PSBootstrap -Package")) { # These tools are not added to the path automatically on OpenSUSE 13.2 # try adding them to the path and re-tesing first @@ -1714,26 +1714,15 @@ function New-ManGzip ) Write-Log "Creating man gz..." - # run ronn to convert man page to roff - $RonnFile = "$RepoRoot/assets/pwsh.1.ronn" - if ($IsPreview.IsPresent -or $IsLTS.IsPresent) - { - $prodName = if ($IsLTS) { 'pwsh-lts' } else { 'pwsh-preview' } - $newRonnFile = $RonnFile -replace 'pwsh', $prodName - Copy-Item -Path $RonnFile -Destination $newRonnFile -Force - $RonnFile = $newRonnFile - } - - $RoffFile = $RonnFile -replace "\.ronn$" + # run roff to convert man page to roff + $RoffFile = "$RepoRoot/assets/manpage/pwsh.1" - # Run ronn on assets file - Write-Log "Creating man gz - running ronn..." - Start-NativeExecution { ronn --roff $RonnFile } - - if ($IsPreview.IsPresent) - { - Remove-Item $RonnFile + if ($IsPreview.IsPresent -or $IsLTS.IsPresent) { + $prodName = if ($IsLTS) { 'pwsh-lts' } else { 'pwsh-preview' } + $newRoffFile = $RoffFile -replace 'pwsh', $prodName + Copy-Item -Path $RoffFile -Destination $newRoffFile -Force -Verbose + $RoffFile = $newRoffFile } # gzip in assets directory From 82cefa6f198c4208e9c4c9f6caab1a8180af092b Mon Sep 17 00:00:00 2001 From: Aditya Patwardhan Date: Thu, 31 Oct 2024 09:15:40 -0700 Subject: [PATCH 041/173] Keep the roff file when gzipping it. (#24450) (#24520) --- .gitignore | 3 +++ tools/packaging/packaging.psm1 | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 13d3a89b888..cb12a297984 100644 --- a/.gitignore +++ b/.gitignore @@ -108,3 +108,6 @@ nuget.config # Ignore MSBuild Binary Logs msbuild.binlog + +# Ignore gzip files in the manpage folder +assets/manpage/*.gz diff --git a/tools/packaging/packaging.psm1 b/tools/packaging/packaging.psm1 index 95caafede8d..6e88df19dec 100644 --- a/tools/packaging/packaging.psm1 +++ b/tools/packaging/packaging.psm1 @@ -1728,7 +1728,7 @@ function New-ManGzip # gzip in assets directory $GzipFile = "$RoffFile.gz" Write-Log "Creating man gz - running gzip..." - Start-NativeExecution { gzip -f $RoffFile } -VerboseOutputOnError + Start-NativeExecution { gzip -kf $RoffFile } -VerboseOutputOnError $ManFile = Join-Path "/usr/local/share/man/man1" (Split-Path -Leaf $GzipFile) From 23a8da2748106d24550570b0ec62a97cb22231a9 Mon Sep 17 00:00:00 2001 From: Aditya Patwardhan Date: Thu, 31 Oct 2024 09:15:59 -0700 Subject: [PATCH 042/173] Bump .NET to 9.0.100-rc.2.24474.11 (#24509) (#24522) --- global.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/global.json b/global.json index 0519736ab95..2dd360f846e 100644 --- a/global.json +++ b/global.json @@ -1,5 +1,5 @@ { "sdk": { - "version": "9.0.100-rc.1.24452.12" + "version": "9.0.100-rc.2.24474.11" } } From f6c8dfc8f5b1ac452c7e6eaacde9b68e4683b49d Mon Sep 17 00:00:00 2001 From: Aditya Patwardhan Date: Thu, 31 Oct 2024 09:21:21 -0700 Subject: [PATCH 043/173] Add PMC mapping for debian 12 (bookworm) (#24413) (#24518) Co-authored-by: Anam Navied --- tools/packages.microsoft.com/mapping.json | 35 ++++++++++++++--------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/tools/packages.microsoft.com/mapping.json b/tools/packages.microsoft.com/mapping.json index b3753722a59..682c96d9110 100644 --- a/tools/packages.microsoft.com/mapping.json +++ b/tools/packages.microsoft.com/mapping.json @@ -127,19 +127,26 @@ ], "PackageFormat": "PACKAGE_NAME_POWERSHELL_RELEASE-1.deb_amd64.deb" }, - { - "url": "microsoft-ubuntu-xenial-prod", - "distribution": [ - "xenial" - ], - "PackageFormat": "PACKAGE_NAME_POWERSHELL_RELEASE-1.deb_amd64.deb" - }, - { - "url": "microsoft-debian-bullseye-prod", - "distribution": [ - "bullseye" - ], - "PackageFormat": "PACKAGE_NAME_POWERSHELL_RELEASE-1.deb_amd64.deb" - } + { + "url": "microsoft-ubuntu-xenial-prod", + "distribution": [ + "xenial" + ], + "PackageFormat": "PACKAGE_NAME_POWERSHELL_RELEASE-1.deb_amd64.deb" + }, + { + "url": "microsoft-debian-bullseye-prod", + "distribution": [ + "bullseye" + ], + "PackageFormat": "PACKAGE_NAME_POWERSHELL_RELEASE-1.deb_amd64.deb" + }, + { + "url": "microsoft-debian-bookworm-prod", + "distribution": [ + "bookworm" + ], + "PackageFormat": "PACKAGE_NAME_POWERSHELL_RELEASE-1.deb_amd64.deb" + } ] } From 9432b4500f5e0a9a2751d182ea8d33c3390adfaa Mon Sep 17 00:00:00 2001 From: Aditya Patwardhan Date: Thu, 31 Oct 2024 10:01:09 -0700 Subject: [PATCH 044/173] Update PSResourceGet to v1.1.0-RC2 (#24512) (#24525) --- src/Modules/PSGalleryModules.csproj | 2 +- tools/packaging/boms/windows.json | 18 +++++++++--------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/Modules/PSGalleryModules.csproj b/src/Modules/PSGalleryModules.csproj index e105facf8e4..9df1121f38b 100644 --- a/src/Modules/PSGalleryModules.csproj +++ b/src/Modules/PSGalleryModules.csproj @@ -13,7 +13,7 @@ - + diff --git a/tools/packaging/boms/windows.json b/tools/packaging/boms/windows.json index c467adbbfa9..c9fd280930f 100644 --- a/tools/packaging/boms/windows.json +++ b/tools/packaging/boms/windows.json @@ -787,14 +787,6 @@ "Pattern": "Microsoft.WSMan.Runtime.xml", "FileType": "NonProduct" }, - { - "Pattern": "Modules/*.json", - "FileType": "NonProduct" - }, - { - "Pattern": "Modules/*.sha256", - "FileType": "NonProduct" - }, { "Pattern": "Modules/Microsoft.PowerShell.Archive/*.cat", "FileType": "NonProduct" @@ -900,7 +892,11 @@ "FileType": "NonProduct" }, { - "Pattern": "Modules\\PSReadLine\\_manifest\\spdx_2.2\\manifest.cat", + "Pattern": "Modules\\Microsoft.PowerShell.PSResourceGet\\PSResourceRepository.adml", + "FileType": "NonProduct" + }, + { + "Pattern": "Modules\\Microsoft.PowerShell.PSResourceGet\\PSResourceRepository.admx", "FileType": "NonProduct" }, { @@ -3455,6 +3451,10 @@ "Pattern": "Modules/PSDiagnostics/PSDiagnostics.psm1", "FileType": "Product" }, + { + "Pattern": "Modules\\Microsoft.PowerShell.PSResourceGet\\InstallPSResourceGetPolicyDefinitions.ps1", + "FileType": "Product" + }, { "Pattern": "pwsh.dll", "FileType": "Product" From 4020aac7a69a7e3706c920eff2102f8c74e48f24 Mon Sep 17 00:00:00 2001 From: Aditya Patwardhan Date: Thu, 31 Oct 2024 13:38:26 -0700 Subject: [PATCH 045/173] Revert "Update package references (#24414)" (#24532) (#24533) This reverts commit 01ae63263661351c812c8ab5fee3a6cceaa559c0. --- ...oft.PowerShell.Commands.Diagnostics.csproj | 2 +- ...soft.PowerShell.Commands.Management.csproj | 2 +- ...crosoft.PowerShell.Commands.Utility.csproj | 4 ++-- ...crosoft.PowerShell.CoreCLR.Eventing.csproj | 2 +- .../Microsoft.PowerShell.SDK.csproj | 10 +++++----- .../Microsoft.WSMan.Management.csproj | 2 +- .../PSVersionInfoGenerator.csproj | 2 +- .../System.Management.Automation.csproj | 20 ++++++++++--------- test/tools/TestService/TestService.csproj | 4 ++-- 9 files changed, 25 insertions(+), 23 deletions(-) diff --git a/src/Microsoft.PowerShell.Commands.Diagnostics/Microsoft.PowerShell.Commands.Diagnostics.csproj b/src/Microsoft.PowerShell.Commands.Diagnostics/Microsoft.PowerShell.Commands.Diagnostics.csproj index 34502ced25d..9f36b8134d1 100644 --- a/src/Microsoft.PowerShell.Commands.Diagnostics/Microsoft.PowerShell.Commands.Diagnostics.csproj +++ b/src/Microsoft.PowerShell.Commands.Diagnostics/Microsoft.PowerShell.Commands.Diagnostics.csproj @@ -8,7 +8,7 @@ - + diff --git a/src/Microsoft.PowerShell.Commands.Management/Microsoft.PowerShell.Commands.Management.csproj b/src/Microsoft.PowerShell.Commands.Management/Microsoft.PowerShell.Commands.Management.csproj index 4f20755c6e6..695ed6f21e4 100644 --- a/src/Microsoft.PowerShell.Commands.Management/Microsoft.PowerShell.Commands.Management.csproj +++ b/src/Microsoft.PowerShell.Commands.Management/Microsoft.PowerShell.Commands.Management.csproj @@ -47,7 +47,7 @@ - + diff --git a/src/Microsoft.PowerShell.Commands.Utility/Microsoft.PowerShell.Commands.Utility.csproj b/src/Microsoft.PowerShell.Commands.Utility/Microsoft.PowerShell.Commands.Utility.csproj index dd2bf636955..113d62231f0 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/Microsoft.PowerShell.Commands.Utility.csproj +++ b/src/Microsoft.PowerShell.Commands.Utility/Microsoft.PowerShell.Commands.Utility.csproj @@ -33,8 +33,8 @@ - - + + diff --git a/src/Microsoft.PowerShell.CoreCLR.Eventing/Microsoft.PowerShell.CoreCLR.Eventing.csproj b/src/Microsoft.PowerShell.CoreCLR.Eventing/Microsoft.PowerShell.CoreCLR.Eventing.csproj index 003999e97b3..1296b1e28ba 100644 --- a/src/Microsoft.PowerShell.CoreCLR.Eventing/Microsoft.PowerShell.CoreCLR.Eventing.csproj +++ b/src/Microsoft.PowerShell.CoreCLR.Eventing/Microsoft.PowerShell.CoreCLR.Eventing.csproj @@ -8,7 +8,7 @@ - + diff --git a/src/Microsoft.PowerShell.SDK/Microsoft.PowerShell.SDK.csproj b/src/Microsoft.PowerShell.SDK/Microsoft.PowerShell.SDK.csproj index 5a1001ddc2c..34c462edbd4 100644 --- a/src/Microsoft.PowerShell.SDK/Microsoft.PowerShell.SDK.csproj +++ b/src/Microsoft.PowerShell.SDK/Microsoft.PowerShell.SDK.csproj @@ -17,13 +17,13 @@ - + - - - + + + - + diff --git a/src/Microsoft.WSMan.Management/Microsoft.WSMan.Management.csproj b/src/Microsoft.WSMan.Management/Microsoft.WSMan.Management.csproj index 77aa3cef77c..9a8f4973d1a 100644 --- a/src/Microsoft.WSMan.Management/Microsoft.WSMan.Management.csproj +++ b/src/Microsoft.WSMan.Management/Microsoft.WSMan.Management.csproj @@ -10,7 +10,7 @@ - + diff --git a/src/System.Management.Automation/SourceGenerators/PSVersionInfoGenerator/PSVersionInfoGenerator.csproj b/src/System.Management.Automation/SourceGenerators/PSVersionInfoGenerator/PSVersionInfoGenerator.csproj index 228126c3267..fe82962adca 100644 --- a/src/System.Management.Automation/SourceGenerators/PSVersionInfoGenerator/PSVersionInfoGenerator.csproj +++ b/src/System.Management.Automation/SourceGenerators/PSVersionInfoGenerator/PSVersionInfoGenerator.csproj @@ -15,6 +15,6 @@ - + diff --git a/src/System.Management.Automation/System.Management.Automation.csproj b/src/System.Management.Automation/System.Management.Automation.csproj index cefbbfa31f0..e4b0c5d7e48 100644 --- a/src/System.Management.Automation/System.Management.Automation.csproj +++ b/src/System.Management.Automation/System.Management.Automation.csproj @@ -19,7 +19,9 @@ - + @@ -32,16 +34,16 @@ - - - - + + + + - + - - - + + + diff --git a/test/tools/TestService/TestService.csproj b/test/tools/TestService/TestService.csproj index 56b17f3d7bc..f6ca75e1dae 100644 --- a/test/tools/TestService/TestService.csproj +++ b/test/tools/TestService/TestService.csproj @@ -15,8 +15,8 @@ - - + + From 8b94694726594b60cb015bdbed7eaad7dc70ee30 Mon Sep 17 00:00:00 2001 From: Aditya Patwardhan Date: Thu, 31 Oct 2024 14:05:37 -0700 Subject: [PATCH 046/173] Add a way to use only NuGet feed sources (#24528) (#24530) --- build.psm1 | 15 +++++++++------ nuget.config | 2 +- src/Modules/nuget.config | 2 +- test/tools/Modules/nuget.config | 2 +- tools/findMissingNotices.ps1 | 6 ++++-- 5 files changed, 16 insertions(+), 11 deletions(-) diff --git a/build.psm1 b/build.psm1 index 7855e46ac1a..e21194c9af9 100644 --- a/build.psm1 +++ b/build.psm1 @@ -740,7 +740,7 @@ function Switch-PSNugetConfig { param( [Parameter(Mandatory = $true, ParameterSetName = 'user')] [Parameter(Mandatory = $true, ParameterSetName = 'nouser')] - [ValidateSet('Public', 'Private')] + [ValidateSet('Public', 'Private', 'NuGetOnly')] [string] $Source, [Parameter(Mandatory = $true, ParameterSetName = 'user')] @@ -760,16 +760,19 @@ function Switch-PSNugetConfig { } } + $dotnetSdk = [NugetPackageSource] @{Url = 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet9/nuget/v2'; Name = 'dotnet' } + $gallery = [NugetPackageSource] @{Url = 'https://www.powershellgallery.com/api/v2/'; Name = 'psgallery' } + $nugetorg = [NugetPackageSource] @{Url = 'https://api.nuget.org/v3/index.json'; Name = 'nuget.org' } if ( $Source -eq 'Public') { - $dotnetSdk = [NugetPackageSource] @{Url = 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet9/nuget/v2'; Name = 'dotnet' } - $gallery = [NugetPackageSource] @{Url = 'https://www.powershellgallery.com/api/v2/'; Name = 'psgallery' } - $nugetorg = [NugetPackageSource] @{Url = 'https://api.nuget.org/v3/index.json'; Name = 'nuget.org' } - New-NugetConfigFile -NugetPackageSource $nugetorg, $dotnetSdk -Destination "$PSScriptRoot/" @extraParams New-NugetConfigFile -NugetPackageSource $gallery -Destination "$PSScriptRoot/src/Modules/" @extraParams New-NugetConfigFile -NugetPackageSource $gallery -Destination "$PSScriptRoot/test/tools/Modules/" @extraParams + } elseif ( $Source -eq 'NuGetOnly') { + New-NugetConfigFile -NugetPackageSource $nugetorg -Destination "$PSScriptRoot/" @extraParams + New-NugetConfigFile -NugetPackageSource $gallery -Destination "$PSScriptRoot/src/Modules/" @extraParams + New-NugetConfigFile -NugetPackageSource $gallery -Destination "$PSScriptRoot/test/tools/Modules/" @extraParams } elseif ( $Source -eq 'Private') { - $powerShellPackages = [NugetPackageSource] @{Url = 'https://pkgs.dev.azure.com/powershell/PowerShell/_packaging/PowerShell-7-5-preview-test-2/nuget/v3/index.json'; Name = 'powershell' } + $powerShellPackages = [NugetPackageSource] @{Url = 'https://pkgs.dev.azure.com/powershell/PowerShell/_packaging/PowerShell/nuget/v3/index.json'; Name = 'powershell' } New-NugetConfigFile -NugetPackageSource $powerShellPackages -Destination "$PSScriptRoot/" @extraParams New-NugetConfigFile -NugetPackageSource $powerShellPackages -Destination "$PSScriptRoot/src/Modules/" @extraParams diff --git a/nuget.config b/nuget.config index db65daa061e..388a65572dd 100644 --- a/nuget.config +++ b/nuget.config @@ -2,7 +2,7 @@ - + diff --git a/src/Modules/nuget.config b/src/Modules/nuget.config index db65daa061e..388a65572dd 100644 --- a/src/Modules/nuget.config +++ b/src/Modules/nuget.config @@ -2,7 +2,7 @@ - + diff --git a/test/tools/Modules/nuget.config b/test/tools/Modules/nuget.config index 3ca2bee3c18..388a65572dd 100644 --- a/test/tools/Modules/nuget.config +++ b/test/tools/Modules/nuget.config @@ -2,7 +2,7 @@ - + diff --git a/tools/findMissingNotices.ps1 b/tools/findMissingNotices.ps1 index 2915853ec38..490edebb81b 100644 --- a/tools/findMissingNotices.ps1 +++ b/tools/findMissingNotices.ps1 @@ -26,7 +26,9 @@ $existingRegistrationsJson.Registrations | ForEach-Object { $registration = [Registration]$_ if ($registration.Component) { $name = $registration.Component.Name() - $existingRegistrationTable.Add($name, $registration) + if (!$existingRegistrationTable.ContainsKey($name)) { + $existingRegistrationTable.Add($name, $registration) + } } } @@ -103,7 +105,7 @@ function ConvertTo-SemVer { So, I'm making the logic work for that scenario by thorwing away any part that doesn't match non-pre-release semver portion #> - $null = $Version -match '^(\d+\.\d+\.\d+)).*' + $null = $Version -match '^(\d+\.\d+\.\d+).*' $desiredVersion = $matches[1] } From 0fe4b9fffc75fbb924b02f37a41548f1d0e5ab0b Mon Sep 17 00:00:00 2001 From: PowerShell Team Bot <69177312+pwshBot@users.noreply.github.com> Date: Thu, 31 Oct 2024 15:09:49 -0700 Subject: [PATCH 047/173] Update branch for release (#24535) --- ...oft.PowerShell.Commands.Diagnostics.csproj | 2 +- ...soft.PowerShell.Commands.Management.csproj | 2 +- ...crosoft.PowerShell.Commands.Utility.csproj | 18 ++- ...crosoft.PowerShell.CoreCLR.Eventing.csproj | 2 +- .../Microsoft.PowerShell.SDK.csproj | 23 +++- .../Microsoft.WSMan.Management.csproj | 2 +- .../PSVersionInfoGenerator.csproj | 7 +- .../System.Management.Automation.csproj | 24 ++-- .../BenchmarkDotNet.Extensions.csproj | 11 +- .../dotnet-tools/Reporting/Reporting.csproj | 3 +- .../ResultsComparer/ResultsComparer.csproj | 10 +- .../engine/Module/IsolatedModule.Tests.ps1 | 3 + ...soft.PowerShell.NamedPipeConnection.csproj | 15 ++- .../TestAlc/init/Test.Isolated.Init.csproj | 4 +- .../nested/Test.Isolated.Nested.csproj | 11 +- .../TestAlc/root/Test.Isolated.Root.csproj | 4 +- test/tools/TestService/TestService.csproj | 35 +++++- test/tools/WebListener/WebListener.csproj | 5 +- test/xUnit/xUnit.tests.csproj | 20 +++- tools/cgmanifest.json | 108 ++++++------------ 20 files changed, 186 insertions(+), 123 deletions(-) diff --git a/src/Microsoft.PowerShell.Commands.Diagnostics/Microsoft.PowerShell.Commands.Diagnostics.csproj b/src/Microsoft.PowerShell.Commands.Diagnostics/Microsoft.PowerShell.Commands.Diagnostics.csproj index 9f36b8134d1..34502ced25d 100644 --- a/src/Microsoft.PowerShell.Commands.Diagnostics/Microsoft.PowerShell.Commands.Diagnostics.csproj +++ b/src/Microsoft.PowerShell.Commands.Diagnostics/Microsoft.PowerShell.Commands.Diagnostics.csproj @@ -8,7 +8,7 @@ - + diff --git a/src/Microsoft.PowerShell.Commands.Management/Microsoft.PowerShell.Commands.Management.csproj b/src/Microsoft.PowerShell.Commands.Management/Microsoft.PowerShell.Commands.Management.csproj index 695ed6f21e4..4f20755c6e6 100644 --- a/src/Microsoft.PowerShell.Commands.Management/Microsoft.PowerShell.Commands.Management.csproj +++ b/src/Microsoft.PowerShell.Commands.Management/Microsoft.PowerShell.Commands.Management.csproj @@ -47,7 +47,7 @@ - + diff --git a/src/Microsoft.PowerShell.Commands.Utility/Microsoft.PowerShell.Commands.Utility.csproj b/src/Microsoft.PowerShell.Commands.Utility/Microsoft.PowerShell.Commands.Utility.csproj index 113d62231f0..9b61bb2b53d 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/Microsoft.PowerShell.Commands.Utility.csproj +++ b/src/Microsoft.PowerShell.Commands.Utility/Microsoft.PowerShell.Commands.Utility.csproj @@ -7,8 +7,16 @@ + + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + - + @@ -32,10 +40,10 @@ - - - - + + + + diff --git a/src/Microsoft.PowerShell.CoreCLR.Eventing/Microsoft.PowerShell.CoreCLR.Eventing.csproj b/src/Microsoft.PowerShell.CoreCLR.Eventing/Microsoft.PowerShell.CoreCLR.Eventing.csproj index 1296b1e28ba..003999e97b3 100644 --- a/src/Microsoft.PowerShell.CoreCLR.Eventing/Microsoft.PowerShell.CoreCLR.Eventing.csproj +++ b/src/Microsoft.PowerShell.CoreCLR.Eventing/Microsoft.PowerShell.CoreCLR.Eventing.csproj @@ -8,7 +8,7 @@ - + diff --git a/src/Microsoft.PowerShell.SDK/Microsoft.PowerShell.SDK.csproj b/src/Microsoft.PowerShell.SDK/Microsoft.PowerShell.SDK.csproj index 34c462edbd4..03898ace0d3 100644 --- a/src/Microsoft.PowerShell.SDK/Microsoft.PowerShell.SDK.csproj +++ b/src/Microsoft.PowerShell.SDK/Microsoft.PowerShell.SDK.csproj @@ -17,13 +17,25 @@ - + + + + + + + + - - - + + + + + + + + - + + diff --git a/src/Microsoft.WSMan.Management/Microsoft.WSMan.Management.csproj b/src/Microsoft.WSMan.Management/Microsoft.WSMan.Management.csproj index 9a8f4973d1a..77aa3cef77c 100644 --- a/src/Microsoft.WSMan.Management/Microsoft.WSMan.Management.csproj +++ b/src/Microsoft.WSMan.Management/Microsoft.WSMan.Management.csproj @@ -10,7 +10,7 @@ - + diff --git a/src/System.Management.Automation/SourceGenerators/PSVersionInfoGenerator/PSVersionInfoGenerator.csproj b/src/System.Management.Automation/SourceGenerators/PSVersionInfoGenerator/PSVersionInfoGenerator.csproj index fe82962adca..9de256a3ba1 100644 --- a/src/System.Management.Automation/SourceGenerators/PSVersionInfoGenerator/PSVersionInfoGenerator.csproj +++ b/src/System.Management.Automation/SourceGenerators/PSVersionInfoGenerator/PSVersionInfoGenerator.csproj @@ -14,7 +14,10 @@ - - + + + + + diff --git a/src/System.Management.Automation/System.Management.Automation.csproj b/src/System.Management.Automation/System.Management.Automation.csproj index e4b0c5d7e48..6fce6d93111 100644 --- a/src/System.Management.Automation/System.Management.Automation.csproj +++ b/src/System.Management.Automation/System.Management.Automation.csproj @@ -19,9 +19,7 @@ - + @@ -34,21 +32,25 @@ - - - - + + + + + + - + - - - + + + + + diff --git a/test/perf/dotnet-tools/BenchmarkDotNet.Extensions/BenchmarkDotNet.Extensions.csproj b/test/perf/dotnet-tools/BenchmarkDotNet.Extensions/BenchmarkDotNet.Extensions.csproj index 2a398dad179..47dc5733932 100644 --- a/test/perf/dotnet-tools/BenchmarkDotNet.Extensions/BenchmarkDotNet.Extensions.csproj +++ b/test/perf/dotnet-tools/BenchmarkDotNet.Extensions/BenchmarkDotNet.Extensions.csproj @@ -6,8 +6,15 @@ - - + + + + + + + + + diff --git a/test/perf/dotnet-tools/Reporting/Reporting.csproj b/test/perf/dotnet-tools/Reporting/Reporting.csproj index 70447cf5d73..693cc1b6481 100644 --- a/test/perf/dotnet-tools/Reporting/Reporting.csproj +++ b/test/perf/dotnet-tools/Reporting/Reporting.csproj @@ -6,7 +6,8 @@ - + + diff --git a/test/perf/dotnet-tools/ResultsComparer/ResultsComparer.csproj b/test/perf/dotnet-tools/ResultsComparer/ResultsComparer.csproj index a8b48dde151..02f7255bcdb 100644 --- a/test/perf/dotnet-tools/ResultsComparer/ResultsComparer.csproj +++ b/test/perf/dotnet-tools/ResultsComparer/ResultsComparer.csproj @@ -6,10 +6,16 @@ 11.0 + + + + + - - + + + diff --git a/test/powershell/engine/Module/IsolatedModule.Tests.ps1 b/test/powershell/engine/Module/IsolatedModule.Tests.ps1 index 5d1289271de..00dae01838c 100644 --- a/test/powershell/engine/Module/IsolatedModule.Tests.ps1 +++ b/test/powershell/engine/Module/IsolatedModule.Tests.ps1 @@ -3,6 +3,9 @@ Describe "Isolated module scenario - load the whole module in custom ALC" -Tag 'CI' { It "Loading 'IsolatedModule' should work as expected" { + + Set-ItResult -Pending -Because "The test is failing as we cannot depend on Newtonsoft.Json v10.0.0 as it has security vulnerabilities." + ## The 'IsolatedModule' module can be found at '\test\tools\Modules'. ## The module assemblies are created and deployed by '\test\tools\TestAlc'. ## The module defines its own custom ALC and has its module structure organized in a special way that allows the module to be loaded in that custom ALC. diff --git a/test/tools/NamedPipeConnection/src/code/Microsoft.PowerShell.NamedPipeConnection.csproj b/test/tools/NamedPipeConnection/src/code/Microsoft.PowerShell.NamedPipeConnection.csproj index aa50d6ec179..d6cc1071790 100644 --- a/test/tools/NamedPipeConnection/src/code/Microsoft.PowerShell.NamedPipeConnection.csproj +++ b/test/tools/NamedPipeConnection/src/code/Microsoft.PowerShell.NamedPipeConnection.csproj @@ -14,7 +14,20 @@ + - + + + + + + + + + + + + + diff --git a/test/tools/TestAlc/init/Test.Isolated.Init.csproj b/test/tools/TestAlc/init/Test.Isolated.Init.csproj index c1a291fa550..c8d37ac959a 100644 --- a/test/tools/TestAlc/init/Test.Isolated.Init.csproj +++ b/test/tools/TestAlc/init/Test.Isolated.Init.csproj @@ -1,6 +1,6 @@ - + @@ -15,7 +15,7 @@ - + diff --git a/test/tools/TestAlc/nested/Test.Isolated.Nested.csproj b/test/tools/TestAlc/nested/Test.Isolated.Nested.csproj index 85ea03a9c4f..483ae9267fb 100644 --- a/test/tools/TestAlc/nested/Test.Isolated.Nested.csproj +++ b/test/tools/TestAlc/nested/Test.Isolated.Nested.csproj @@ -1,6 +1,6 @@ - + @@ -16,8 +16,13 @@ - - + + + + + + + diff --git a/test/tools/TestAlc/root/Test.Isolated.Root.csproj b/test/tools/TestAlc/root/Test.Isolated.Root.csproj index ab333e0668a..2a757064167 100644 --- a/test/tools/TestAlc/root/Test.Isolated.Root.csproj +++ b/test/tools/TestAlc/root/Test.Isolated.Root.csproj @@ -1,6 +1,6 @@ - + @@ -15,7 +15,7 @@ - + diff --git a/test/tools/TestService/TestService.csproj b/test/tools/TestService/TestService.csproj index f6ca75e1dae..10bf8593408 100644 --- a/test/tools/TestService/TestService.csproj +++ b/test/tools/TestService/TestService.csproj @@ -1,6 +1,6 @@ - + Very tiny windows service to do service testing @@ -15,9 +15,38 @@ - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/tools/WebListener/WebListener.csproj b/test/tools/WebListener/WebListener.csproj index 791be2fd228..d3e8a1f3244 100644 --- a/test/tools/WebListener/WebListener.csproj +++ b/test/tools/WebListener/WebListener.csproj @@ -7,7 +7,8 @@ - - + + + diff --git a/test/xUnit/xUnit.tests.csproj b/test/xUnit/xUnit.tests.csproj index b09abbf7483..2b04741dba8 100644 --- a/test/xUnit/xUnit.tests.csproj +++ b/test/xUnit/xUnit.tests.csproj @@ -23,11 +23,23 @@ - + + + + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + - - - + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + diff --git a/tools/cgmanifest.json b/tools/cgmanifest.json index a1b0338c41f..64926e8c0d2 100644 --- a/tools/cgmanifest.json +++ b/tools/cgmanifest.json @@ -35,7 +35,7 @@ "Type": "nuget", "Nuget": { "Name": "Json.More.Net", - "Version": "2.0.1.2" + "Version": "2.0.2" } }, "DevelopmentDependency": false @@ -45,7 +45,7 @@ "Type": "nuget", "Nuget": { "Name": "JsonPointer.Net", - "Version": "5.0.0" + "Version": "5.0.2" } }, "DevelopmentDependency": false @@ -55,7 +55,7 @@ "Type": "nuget", "Nuget": { "Name": "JsonSchema.Net", - "Version": "7.0.1" + "Version": "7.2.3" } }, "DevelopmentDependency": false @@ -65,7 +65,7 @@ "Type": "nuget", "Nuget": { "Name": "Markdig.Signed", - "Version": "0.37.0" + "Version": "0.38.0" } }, "DevelopmentDependency": false @@ -90,22 +90,12 @@ }, "DevelopmentDependency": false }, - { - "Component": { - "Type": "nuget", - "Nuget": { - "Name": "Microsoft.CodeAnalysis.Analyzers", - "Version": "3.3.4" - } - }, - "DevelopmentDependency": true - }, { "Component": { "Type": "nuget", "Nuget": { "Name": "Microsoft.CodeAnalysis.Common", - "Version": "4.9.2" + "Version": "4.11.0" } }, "DevelopmentDependency": false @@ -115,7 +105,7 @@ "Type": "nuget", "Nuget": { "Name": "Microsoft.CodeAnalysis.CSharp", - "Version": "4.9.2" + "Version": "4.11.0" } }, "DevelopmentDependency": false @@ -125,7 +115,7 @@ "Type": "nuget", "Nuget": { "Name": "Microsoft.Extensions.ObjectPool", - "Version": "8.0.4" + "Version": "8.0.10" } }, "DevelopmentDependency": false @@ -205,7 +195,7 @@ "Type": "nuget", "Nuget": { "Name": "Microsoft.Win32.Registry", - "Version": "4.7.0" + "Version": "5.0.0" } }, "DevelopmentDependency": false @@ -225,7 +215,7 @@ "Type": "nuget", "Nuget": { "Name": "Microsoft.Windows.Compatibility", - "Version": "8.0.8" + "Version": "8.0.10" } }, "DevelopmentDependency": false @@ -245,7 +235,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.android-arm.runtime.native.System.IO.Ports", - "Version": "9.0.0-preview.3.24172.9" + "Version": "9.0.0-rc.2.24473.5" } }, "DevelopmentDependency": false @@ -255,7 +245,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.android-arm64.runtime.native.System.IO.Ports", - "Version": "9.0.0-preview.3.24172.9" + "Version": "9.0.0-rc.2.24473.5" } }, "DevelopmentDependency": false @@ -265,7 +255,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.android-x64.runtime.native.System.IO.Ports", - "Version": "9.0.0-preview.3.24172.9" + "Version": "9.0.0-rc.2.24473.5" } }, "DevelopmentDependency": false @@ -275,7 +265,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.android-x86.runtime.native.System.IO.Ports", - "Version": "9.0.0-preview.3.24172.9" + "Version": "9.0.0-rc.2.24473.5" } }, "DevelopmentDependency": false @@ -305,7 +295,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.linux-bionic-arm64.runtime.native.System.IO.Ports", - "Version": "9.0.0-preview.3.24172.9" + "Version": "9.0.0-rc.2.24473.5" } }, "DevelopmentDependency": false @@ -315,7 +305,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.linux-bionic-x64.runtime.native.System.IO.Ports", - "Version": "9.0.0-preview.3.24172.9" + "Version": "9.0.0-rc.2.24473.5" } }, "DevelopmentDependency": false @@ -325,7 +315,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.linux-musl-arm.runtime.native.System.IO.Ports", - "Version": "9.0.0-preview.3.24172.9" + "Version": "9.0.0-rc.2.24473.5" } }, "DevelopmentDependency": false @@ -335,7 +325,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.linux-musl-arm64.runtime.native.System.IO.Ports", - "Version": "9.0.0-preview.3.24172.9" + "Version": "9.0.0-rc.2.24473.5" } }, "DevelopmentDependency": false @@ -345,7 +335,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.linux-musl-x64.runtime.native.System.IO.Ports", - "Version": "9.0.0-preview.3.24172.9" + "Version": "9.0.0-rc.2.24473.5" } }, "DevelopmentDependency": false @@ -365,7 +355,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.maccatalyst-arm64.runtime.native.System.IO.Ports", - "Version": "9.0.0-preview.3.24172.9" + "Version": "9.0.0-rc.2.24473.5" } }, "DevelopmentDependency": false @@ -375,7 +365,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.maccatalyst-x64.runtime.native.System.IO.Ports", - "Version": "9.0.0-preview.3.24172.9" + "Version": "9.0.0-rc.2.24473.5" } }, "DevelopmentDependency": false @@ -515,7 +505,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Configuration.ConfigurationManager", - "Version": "8.0.0" + "Version": "8.0.1" } }, "DevelopmentDependency": false @@ -525,7 +515,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Data.Odbc", - "Version": "8.0.0" + "Version": "8.0.1" } }, "DevelopmentDependency": false @@ -535,7 +525,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Data.OleDb", - "Version": "8.0.0" + "Version": "8.0.1" } }, "DevelopmentDependency": false @@ -565,17 +555,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Diagnostics.EventLog", - "Version": "8.0.0" - } - }, - "DevelopmentDependency": false - }, - { - "Component": { - "Type": "nuget", - "Nuget": { - "Name": "System.Diagnostics.PerformanceCounter", - "Version": "8.0.0" + "Version": "8.0.1" } }, "DevelopmentDependency": false @@ -585,7 +565,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Diagnostics.PerformanceCounter", - "Version": "8.0.0" + "Version": "8.0.1" } }, "DevelopmentDependency": false @@ -595,7 +575,7 @@ "Type": "nuget", "Nuget": { "Name": "System.DirectoryServices.AccountManagement", - "Version": "8.0.0" + "Version": "8.0.1" } }, "DevelopmentDependency": false @@ -625,17 +605,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Drawing.Common", - "Version": "8.0.8" - } - }, - "DevelopmentDependency": false - }, - { - "Component": { - "Type": "nuget", - "Nuget": { - "Name": "System.Formats.Asn1", - "Version": "8.0.1" + "Version": "8.0.10" } }, "DevelopmentDependency": false @@ -645,7 +615,7 @@ "Type": "nuget", "Nuget": { "Name": "System.IO.Packaging", - "Version": "8.0.0" + "Version": "8.0.1" } }, "DevelopmentDependency": false @@ -725,7 +695,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Reflection.Metadata", - "Version": "8.0.0" + "Version": "8.0.1" } }, "DevelopmentDependency": false @@ -735,17 +705,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Runtime.Caching", - "Version": "8.0.0" - } - }, - "DevelopmentDependency": false - }, - { - "Component": { - "Type": "nuget", - "Nuget": { - "Name": "System.Runtime.CompilerServices.Unsafe", - "Version": "6.0.0" + "Version": "8.0.1" } }, "DevelopmentDependency": false @@ -765,7 +725,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Security.Cryptography.Pkcs", - "Version": "8.0.0" + "Version": "8.0.1" } }, "DevelopmentDependency": false @@ -785,7 +745,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Security.Cryptography.Xml", - "Version": "8.0.1" + "Version": "8.0.2" } }, "DevelopmentDependency": false @@ -875,7 +835,7 @@ "Type": "nuget", "Nuget": { "Name": "System.ServiceProcess.ServiceController", - "Version": "8.0.0" + "Version": "8.0.1" } }, "DevelopmentDependency": false @@ -925,7 +885,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Web.Services.Description", - "Version": "4.10.0" + "Version": "8.0.0" } }, "DevelopmentDependency": false From 396e3089a99fb41745df6d2e24d568d55d09bc40 Mon Sep 17 00:00:00 2001 From: Aditya Patwardhan Date: Fri, 1 Nov 2024 13:05:52 -0700 Subject: [PATCH 048/173] Update ThirdPartyNotices for release (#24536) --- ThirdPartyNotices.txt | 306 +++++++++++++----------------------------- 1 file changed, 90 insertions(+), 216 deletions(-) diff --git a/ThirdPartyNotices.txt b/ThirdPartyNotices.txt index 27dd8ead268..24c332f7074 100644 --- a/ThirdPartyNotices.txt +++ b/ThirdPartyNotices.txt @@ -17,7 +17,7 @@ required to debug changes to any libraries licensed under the GNU Lesser General --------------------------------------------------------- -Markdig.Signed 0.37.0 - BSD-2-Clause +Markdig.Signed 0.38.0 - BSD-2-Clause @@ -55,14 +55,14 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI --------------------------------------------------------- -Json.More.Net 2.0.1.2 - MIT +Json.More.Net 2.0.2 - MIT -Copyright (c) 2024 Greg Dennis +Copyright (c) .NET Foundation and Contributors MIT License -Copyright (c) 2024 Greg Dennis +Copyright (c) .NET Foundation and Contributors Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -87,14 +87,14 @@ SOFTWARE. --------------------------------------------------------- -JsonPointer.Net 5.0.0 - MIT +JsonPointer.Net 5.0.2 - MIT -Copyright (c) 2024 Greg Dennis +Copyright (c) .NET Foundation and Contributors MIT License -Copyright (c) 2024 Greg Dennis +Copyright (c) .NET Foundation and Contributors Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -119,7 +119,7 @@ SOFTWARE. --------------------------------------------------------- -JsonSchema.Net 7.0.1 - MIT +JsonSchema.Net 7.2.3 - MIT @@ -242,7 +242,7 @@ SOFTWARE. --------------------------------------------------------- -Microsoft.CodeAnalysis.Common 4.9.2 - MIT +Microsoft.CodeAnalysis.Common 4.11.0 - MIT (c) Microsoft Corporation @@ -262,7 +262,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI --------------------------------------------------------- -Microsoft.CodeAnalysis.CSharp 4.9.2 - MIT +Microsoft.CodeAnalysis.CSharp 4.11.0 - MIT (c) Microsoft Corporation @@ -284,7 +284,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI --------------------------------------------------------- -Microsoft.Extensions.ObjectPool 8.0.4 - MIT +Microsoft.Extensions.ObjectPool 8.0.10 - MIT Copyright 2019 The gRPC @@ -374,29 +374,48 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI --------------------------------------------------------- -Microsoft.Win32.Registry 4.7.0 - MIT +Microsoft.Win32.Registry 5.0.0 - MIT -(c) Microsoft Corporation. -Copyright (c) .NET Foundation. +(c) Microsoft Corporation +Copyright (c) Andrew Arnott +Copyright 2018 Daniel Lemire +Copyright (c) .NET Foundation Copyright (c) 2011, Google Inc. -(c) 1997-2005 Sean Eron Anderson. +Copyright (c) 2020 Dan Shechter +(c) 1997-2005 Sean Eron Anderson +Copyright (c) 1998 Microsoft. To +Copyright (c) 2017 Yoshifumi Kawai +Copyright (c) Microsoft Corporation Copyright (c) 2007 James Newton-King -Copyright (c) 1991-2017 Unicode, Inc. +Copyright (c) 2012-2014, Yann Collet +Copyright (c) 1991-2020 Unicode, Inc. Copyright (c) 2013-2017, Alfred Klomp +Copyright 2012 the V8 project authors +Copyright (c) 2011-2020 Microsoft Corp Copyright (c) 2015-2017, Wojciech Mula Copyright (c) 2005-2007, Nick Galbreath +Copyright (c) 2015 The Chromium Authors +Copyright (c) 2018 Alexander Chermyanin +Copyright (c) The Internet Society 1997 Portions (c) International Organization -Copyright (c) 2015 The Chromium Authors. Copyright (c) 2004-2006 Intel Corporation +Copyright (c) 2013-2017, Milosz Krajewski Copyright (c) 2016-2017, Matthieu Darbois +Copyright (c) The Internet Society (2003) Copyright (c) .NET Foundation Contributors Copyright (c) .NET Foundation and Contributors Copyright (c) 2011 Novell, Inc (http://www.novell.com) Copyright (c) 1995-2017 Jean-loup Gailly and Mark Adler Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com) -Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors. -Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers THIS WORK IS PROVIDED AS +Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors +Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com +Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc. +Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers +Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip +Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California +Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass +Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass. To The MIT License (MIT) @@ -599,7 +618,7 @@ SOFTWARE. --------------------------------------------------------- -Microsoft.Windows.Compatibility 8.0.8 - MIT +Microsoft.Windows.Compatibility 8.0.10 - MIT (c) Microsoft Corporation @@ -652,7 +671,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. --------------------------------------------------------- -runtime.android-arm.runtime.native.System.IO.Ports 9.0.0-preview.3.24172.9 - MIT +runtime.android-arm.runtime.native.System.IO.Ports 9.0.0-rc.2.24473.5 - MIT Copyright (c) Six Labors @@ -676,6 +695,7 @@ Copyright (c) Microsoft Corporation Copyright (c) 2007 James Newton-King Copyright (c) 1991-2022 Unicode, Inc. Copyright (c) 2013-2017, Alfred Klomp +Copyright (c) 2018 Nemanja Mijailovic Copyright 2012 the V8 project authors Copyright (c) 1999 Lucent Technologies Copyright (c) 2008-2016, Wojciech Mula @@ -694,6 +714,7 @@ Copyright (c) 2013-2017, Milosz Krajewski Copyright (c) 2016-2017, Matthieu Darbois Copyright (c) The Internet Society (2003) Copyright (c) .NET Foundation Contributors +(c) 1995-2024 Jean-loup Gailly and Mark Adler Copyright (c) 2020 Mara Bos Copyright (c) .NET Foundation and Contributors Copyright (c) 2012 - present, Victor Zverovich @@ -701,7 +722,6 @@ Copyright (c) 2006 Jb Evain (jbevain@gmail.com) Copyright (c) 2008-2020 Advanced Micro Devices, Inc. Copyright (c) 2019 Microsoft Corporation, Daan Leijen Copyright (c) 2011 Novell, Inc (http://www.novell.com) -Copyright (c) 1995-2022 Jean-loup Gailly and Mark Adler Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com) Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com @@ -741,7 +761,7 @@ SOFTWARE. --------------------------------------------------------- -runtime.android-arm64.runtime.native.System.IO.Ports 9.0.0-preview.3.24172.9 - MIT +runtime.android-arm64.runtime.native.System.IO.Ports 9.0.0-rc.2.24473.5 - MIT Copyright (c) Six Labors @@ -765,6 +785,7 @@ Copyright (c) Microsoft Corporation Copyright (c) 2007 James Newton-King Copyright (c) 1991-2022 Unicode, Inc. Copyright (c) 2013-2017, Alfred Klomp +Copyright (c) 2018 Nemanja Mijailovic Copyright 2012 the V8 project authors Copyright (c) 1999 Lucent Technologies Copyright (c) 2008-2016, Wojciech Mula @@ -783,6 +804,7 @@ Copyright (c) 2013-2017, Milosz Krajewski Copyright (c) 2016-2017, Matthieu Darbois Copyright (c) The Internet Society (2003) Copyright (c) .NET Foundation Contributors +(c) 1995-2024 Jean-loup Gailly and Mark Adler Copyright (c) 2020 Mara Bos Copyright (c) .NET Foundation and Contributors Copyright (c) 2012 - present, Victor Zverovich @@ -790,7 +812,6 @@ Copyright (c) 2006 Jb Evain (jbevain@gmail.com) Copyright (c) 2008-2020 Advanced Micro Devices, Inc. Copyright (c) 2019 Microsoft Corporation, Daan Leijen Copyright (c) 2011 Novell, Inc (http://www.novell.com) -Copyright (c) 1995-2022 Jean-loup Gailly and Mark Adler Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com) Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com @@ -830,7 +851,7 @@ SOFTWARE. --------------------------------------------------------- -runtime.android-x64.runtime.native.System.IO.Ports 9.0.0-preview.3.24172.9 - MIT +runtime.android-x64.runtime.native.System.IO.Ports 9.0.0-rc.2.24473.5 - MIT Copyright (c) Six Labors @@ -854,6 +875,7 @@ Copyright (c) Microsoft Corporation Copyright (c) 2007 James Newton-King Copyright (c) 1991-2022 Unicode, Inc. Copyright (c) 2013-2017, Alfred Klomp +Copyright (c) 2018 Nemanja Mijailovic Copyright 2012 the V8 project authors Copyright (c) 1999 Lucent Technologies Copyright (c) 2008-2016, Wojciech Mula @@ -872,6 +894,7 @@ Copyright (c) 2013-2017, Milosz Krajewski Copyright (c) 2016-2017, Matthieu Darbois Copyright (c) The Internet Society (2003) Copyright (c) .NET Foundation Contributors +(c) 1995-2024 Jean-loup Gailly and Mark Adler Copyright (c) 2020 Mara Bos Copyright (c) .NET Foundation and Contributors Copyright (c) 2012 - present, Victor Zverovich @@ -879,7 +902,6 @@ Copyright (c) 2006 Jb Evain (jbevain@gmail.com) Copyright (c) 2008-2020 Advanced Micro Devices, Inc. Copyright (c) 2019 Microsoft Corporation, Daan Leijen Copyright (c) 2011 Novell, Inc (http://www.novell.com) -Copyright (c) 1995-2022 Jean-loup Gailly and Mark Adler Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com) Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com @@ -919,7 +941,7 @@ SOFTWARE. --------------------------------------------------------- -runtime.android-x86.runtime.native.System.IO.Ports 9.0.0-preview.3.24172.9 - MIT +runtime.android-x86.runtime.native.System.IO.Ports 9.0.0-rc.2.24473.5 - MIT Copyright (c) Six Labors @@ -943,6 +965,7 @@ Copyright (c) Microsoft Corporation Copyright (c) 2007 James Newton-King Copyright (c) 1991-2022 Unicode, Inc. Copyright (c) 2013-2017, Alfred Klomp +Copyright (c) 2018 Nemanja Mijailovic Copyright 2012 the V8 project authors Copyright (c) 1999 Lucent Technologies Copyright (c) 2008-2016, Wojciech Mula @@ -961,6 +984,7 @@ Copyright (c) 2013-2017, Milosz Krajewski Copyright (c) 2016-2017, Matthieu Darbois Copyright (c) The Internet Society (2003) Copyright (c) .NET Foundation Contributors +(c) 1995-2024 Jean-loup Gailly and Mark Adler Copyright (c) 2020 Mara Bos Copyright (c) .NET Foundation and Contributors Copyright (c) 2012 - present, Victor Zverovich @@ -968,7 +992,6 @@ Copyright (c) 2006 Jb Evain (jbevain@gmail.com) Copyright (c) 2008-2020 Advanced Micro Devices, Inc. Copyright (c) 2019 Microsoft Corporation, Daan Leijen Copyright (c) 2011 Novell, Inc (http://www.novell.com) -Copyright (c) 1995-2022 Jean-loup Gailly and Mark Adler Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com) Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com @@ -1180,7 +1203,7 @@ SOFTWARE. --------------------------------------------------------- -runtime.linux-bionic-arm64.runtime.native.System.IO.Ports 9.0.0-preview.3.24172.9 - MIT +runtime.linux-bionic-arm64.runtime.native.System.IO.Ports 9.0.0-rc.2.24473.5 - MIT Copyright (c) Six Labors @@ -1204,6 +1227,7 @@ Copyright (c) Microsoft Corporation Copyright (c) 2007 James Newton-King Copyright (c) 1991-2022 Unicode, Inc. Copyright (c) 2013-2017, Alfred Klomp +Copyright (c) 2018 Nemanja Mijailovic Copyright 2012 the V8 project authors Copyright (c) 1999 Lucent Technologies Copyright (c) 2008-2016, Wojciech Mula @@ -1222,6 +1246,7 @@ Copyright (c) 2013-2017, Milosz Krajewski Copyright (c) 2016-2017, Matthieu Darbois Copyright (c) The Internet Society (2003) Copyright (c) .NET Foundation Contributors +(c) 1995-2024 Jean-loup Gailly and Mark Adler Copyright (c) 2020 Mara Bos Copyright (c) .NET Foundation and Contributors Copyright (c) 2012 - present, Victor Zverovich @@ -1229,7 +1254,6 @@ Copyright (c) 2006 Jb Evain (jbevain@gmail.com) Copyright (c) 2008-2020 Advanced Micro Devices, Inc. Copyright (c) 2019 Microsoft Corporation, Daan Leijen Copyright (c) 2011 Novell, Inc (http://www.novell.com) -Copyright (c) 1995-2022 Jean-loup Gailly and Mark Adler Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com) Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com @@ -1269,7 +1293,7 @@ SOFTWARE. --------------------------------------------------------- -runtime.linux-bionic-x64.runtime.native.System.IO.Ports 9.0.0-preview.3.24172.9 - MIT +runtime.linux-bionic-x64.runtime.native.System.IO.Ports 9.0.0-rc.2.24473.5 - MIT Copyright (c) Six Labors @@ -1293,6 +1317,7 @@ Copyright (c) Microsoft Corporation Copyright (c) 2007 James Newton-King Copyright (c) 1991-2022 Unicode, Inc. Copyright (c) 2013-2017, Alfred Klomp +Copyright (c) 2018 Nemanja Mijailovic Copyright 2012 the V8 project authors Copyright (c) 1999 Lucent Technologies Copyright (c) 2008-2016, Wojciech Mula @@ -1311,6 +1336,7 @@ Copyright (c) 2013-2017, Milosz Krajewski Copyright (c) 2016-2017, Matthieu Darbois Copyright (c) The Internet Society (2003) Copyright (c) .NET Foundation Contributors +(c) 1995-2024 Jean-loup Gailly and Mark Adler Copyright (c) 2020 Mara Bos Copyright (c) .NET Foundation and Contributors Copyright (c) 2012 - present, Victor Zverovich @@ -1318,7 +1344,6 @@ Copyright (c) 2006 Jb Evain (jbevain@gmail.com) Copyright (c) 2008-2020 Advanced Micro Devices, Inc. Copyright (c) 2019 Microsoft Corporation, Daan Leijen Copyright (c) 2011 Novell, Inc (http://www.novell.com) -Copyright (c) 1995-2022 Jean-loup Gailly and Mark Adler Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com) Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com @@ -1358,7 +1383,7 @@ SOFTWARE. --------------------------------------------------------- -runtime.linux-musl-arm.runtime.native.System.IO.Ports 9.0.0-preview.3.24172.9 - MIT +runtime.linux-musl-arm.runtime.native.System.IO.Ports 9.0.0-rc.2.24473.5 - MIT Copyright (c) Six Labors @@ -1382,6 +1407,7 @@ Copyright (c) Microsoft Corporation Copyright (c) 2007 James Newton-King Copyright (c) 1991-2022 Unicode, Inc. Copyright (c) 2013-2017, Alfred Klomp +Copyright (c) 2018 Nemanja Mijailovic Copyright 2012 the V8 project authors Copyright (c) 1999 Lucent Technologies Copyright (c) 2008-2016, Wojciech Mula @@ -1400,6 +1426,7 @@ Copyright (c) 2013-2017, Milosz Krajewski Copyright (c) 2016-2017, Matthieu Darbois Copyright (c) The Internet Society (2003) Copyright (c) .NET Foundation Contributors +(c) 1995-2024 Jean-loup Gailly and Mark Adler Copyright (c) 2020 Mara Bos Copyright (c) .NET Foundation and Contributors Copyright (c) 2012 - present, Victor Zverovich @@ -1407,7 +1434,6 @@ Copyright (c) 2006 Jb Evain (jbevain@gmail.com) Copyright (c) 2008-2020 Advanced Micro Devices, Inc. Copyright (c) 2019 Microsoft Corporation, Daan Leijen Copyright (c) 2011 Novell, Inc (http://www.novell.com) -Copyright (c) 1995-2022 Jean-loup Gailly and Mark Adler Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com) Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com @@ -1447,7 +1473,7 @@ SOFTWARE. --------------------------------------------------------- -runtime.linux-musl-arm64.runtime.native.System.IO.Ports 9.0.0-preview.3.24172.9 - MIT +runtime.linux-musl-arm64.runtime.native.System.IO.Ports 9.0.0-rc.2.24473.5 - MIT Copyright (c) Six Labors @@ -1471,6 +1497,7 @@ Copyright (c) Microsoft Corporation Copyright (c) 2007 James Newton-King Copyright (c) 1991-2022 Unicode, Inc. Copyright (c) 2013-2017, Alfred Klomp +Copyright (c) 2018 Nemanja Mijailovic Copyright 2012 the V8 project authors Copyright (c) 1999 Lucent Technologies Copyright (c) 2008-2016, Wojciech Mula @@ -1489,6 +1516,7 @@ Copyright (c) 2013-2017, Milosz Krajewski Copyright (c) 2016-2017, Matthieu Darbois Copyright (c) The Internet Society (2003) Copyright (c) .NET Foundation Contributors +(c) 1995-2024 Jean-loup Gailly and Mark Adler Copyright (c) 2020 Mara Bos Copyright (c) .NET Foundation and Contributors Copyright (c) 2012 - present, Victor Zverovich @@ -1496,7 +1524,6 @@ Copyright (c) 2006 Jb Evain (jbevain@gmail.com) Copyright (c) 2008-2020 Advanced Micro Devices, Inc. Copyright (c) 2019 Microsoft Corporation, Daan Leijen Copyright (c) 2011 Novell, Inc (http://www.novell.com) -Copyright (c) 1995-2022 Jean-loup Gailly and Mark Adler Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com) Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com @@ -1536,7 +1563,7 @@ SOFTWARE. --------------------------------------------------------- -runtime.linux-musl-x64.runtime.native.System.IO.Ports 9.0.0-preview.3.24172.9 - MIT +runtime.linux-musl-x64.runtime.native.System.IO.Ports 9.0.0-rc.2.24473.5 - MIT Copyright (c) Six Labors @@ -1560,6 +1587,7 @@ Copyright (c) Microsoft Corporation Copyright (c) 2007 James Newton-King Copyright (c) 1991-2022 Unicode, Inc. Copyright (c) 2013-2017, Alfred Klomp +Copyright (c) 2018 Nemanja Mijailovic Copyright 2012 the V8 project authors Copyright (c) 1999 Lucent Technologies Copyright (c) 2008-2016, Wojciech Mula @@ -1578,6 +1606,7 @@ Copyright (c) 2013-2017, Milosz Krajewski Copyright (c) 2016-2017, Matthieu Darbois Copyright (c) The Internet Society (2003) Copyright (c) .NET Foundation Contributors +(c) 1995-2024 Jean-loup Gailly and Mark Adler Copyright (c) 2020 Mara Bos Copyright (c) .NET Foundation and Contributors Copyright (c) 2012 - present, Victor Zverovich @@ -1585,7 +1614,6 @@ Copyright (c) 2006 Jb Evain (jbevain@gmail.com) Copyright (c) 2008-2020 Advanced Micro Devices, Inc. Copyright (c) 2019 Microsoft Corporation, Daan Leijen Copyright (c) 2011 Novell, Inc (http://www.novell.com) -Copyright (c) 1995-2022 Jean-loup Gailly and Mark Adler Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com) Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com @@ -1711,7 +1739,7 @@ SOFTWARE. --------------------------------------------------------- -runtime.maccatalyst-arm64.runtime.native.System.IO.Ports 9.0.0-preview.3.24172.9 - MIT +runtime.maccatalyst-arm64.runtime.native.System.IO.Ports 9.0.0-rc.2.24473.5 - MIT Copyright (c) Six Labors @@ -1735,6 +1763,7 @@ Copyright (c) Microsoft Corporation Copyright (c) 2007 James Newton-King Copyright (c) 1991-2022 Unicode, Inc. Copyright (c) 2013-2017, Alfred Klomp +Copyright (c) 2018 Nemanja Mijailovic Copyright 2012 the V8 project authors Copyright (c) 1999 Lucent Technologies Copyright (c) 2008-2016, Wojciech Mula @@ -1753,6 +1782,7 @@ Copyright (c) 2013-2017, Milosz Krajewski Copyright (c) 2016-2017, Matthieu Darbois Copyright (c) The Internet Society (2003) Copyright (c) .NET Foundation Contributors +(c) 1995-2024 Jean-loup Gailly and Mark Adler Copyright (c) 2020 Mara Bos Copyright (c) .NET Foundation and Contributors Copyright (c) 2012 - present, Victor Zverovich @@ -1760,7 +1790,6 @@ Copyright (c) 2006 Jb Evain (jbevain@gmail.com) Copyright (c) 2008-2020 Advanced Micro Devices, Inc. Copyright (c) 2019 Microsoft Corporation, Daan Leijen Copyright (c) 2011 Novell, Inc (http://www.novell.com) -Copyright (c) 1995-2022 Jean-loup Gailly and Mark Adler Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com) Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com @@ -1800,7 +1829,7 @@ SOFTWARE. --------------------------------------------------------- -runtime.maccatalyst-x64.runtime.native.System.IO.Ports 9.0.0-preview.3.24172.9 - MIT +runtime.maccatalyst-x64.runtime.native.System.IO.Ports 9.0.0-rc.2.24473.5 - MIT Copyright (c) Six Labors @@ -1824,6 +1853,7 @@ Copyright (c) Microsoft Corporation Copyright (c) 2007 James Newton-King Copyright (c) 1991-2022 Unicode, Inc. Copyright (c) 2013-2017, Alfred Klomp +Copyright (c) 2018 Nemanja Mijailovic Copyright 2012 the V8 project authors Copyright (c) 1999 Lucent Technologies Copyright (c) 2008-2016, Wojciech Mula @@ -1842,6 +1872,7 @@ Copyright (c) 2013-2017, Milosz Krajewski Copyright (c) 2016-2017, Matthieu Darbois Copyright (c) The Internet Society (2003) Copyright (c) .NET Foundation Contributors +(c) 1995-2024 Jean-loup Gailly and Mark Adler Copyright (c) 2020 Mara Bos Copyright (c) .NET Foundation and Contributors Copyright (c) 2012 - present, Victor Zverovich @@ -1849,7 +1880,6 @@ Copyright (c) 2006 Jb Evain (jbevain@gmail.com) Copyright (c) 2008-2020 Advanced Micro Devices, Inc. Copyright (c) 2019 Microsoft Corporation, Daan Leijen Copyright (c) 2011 Novell, Inc (http://www.novell.com) -Copyright (c) 1995-2022 Jean-loup Gailly and Mark Adler Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com) Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com @@ -2544,7 +2574,7 @@ SOFTWARE. --------------------------------------------------------- -System.Configuration.ConfigurationManager 8.0.0 - MIT +System.Configuration.ConfigurationManager 8.0.1 - MIT Copyright (c) Six Labors @@ -2630,7 +2660,7 @@ SOFTWARE. --------------------------------------------------------- -System.Data.Odbc 8.0.0 - MIT +System.Data.Odbc 8.0.1 - MIT Copyright (c) Six Labors @@ -2716,7 +2746,7 @@ SOFTWARE. --------------------------------------------------------- -System.Data.OleDb 8.0.0 - MIT +System.Data.OleDb 8.0.1 - MIT Copyright (c) Six Labors @@ -2941,7 +2971,7 @@ SOFTWARE. --------------------------------------------------------- -System.Diagnostics.EventLog 8.0.0 - MIT +System.Diagnostics.EventLog 8.0.1 - MIT Copyright (c) Six Labors @@ -3027,7 +3057,7 @@ SOFTWARE. --------------------------------------------------------- -System.Diagnostics.PerformanceCounter 8.0.0 - MIT +System.Diagnostics.PerformanceCounter 8.0.1 - MIT Copyright (c) Six Labors @@ -3199,7 +3229,7 @@ SOFTWARE. --------------------------------------------------------- -System.DirectoryServices.AccountManagement 8.0.0 - MIT +System.DirectoryServices.AccountManagement 8.0.1 - MIT Copyright (c) Six Labors @@ -3371,7 +3401,7 @@ SOFTWARE. --------------------------------------------------------- -System.Drawing.Common 8.0.8 - MIT +System.Drawing.Common 8.0.10 - MIT (c) Microsoft Corporation @@ -3406,93 +3436,7 @@ SOFTWARE. --------------------------------------------------------- -System.Formats.Asn1 8.0.1 - MIT - - -Copyright (c) Six Labors -(c) Microsoft Corporation -Copyright (c) Andrew Arnott -Copyright 2019 LLVM Project -Copyright 2018 Daniel Lemire -Copyright (c) .NET Foundation -Copyright (c) 2011, Google Inc. -Copyright (c) 2020 Dan Shechter -(c) 1997-2005 Sean Eron Anderson -Copyright (c) 1998 Microsoft. To -Copyright (c) 2022, Wojciech Mula -Copyright (c) 2017 Yoshifumi Kawai -Copyright (c) 2022, Geoff Langdale -Copyright (c) 2005-2020 Rich Felker -Copyright (c) 2012-2021 Yann Collet -Copyright (c) Microsoft Corporation -Copyright (c) 2007 James Newton-King -Copyright (c) 1991-2022 Unicode, Inc. -Copyright (c) 2013-2017, Alfred Klomp -Copyright 2012 the V8 project authors -Copyright (c) 1999 Lucent Technologies -Copyright (c) 2008-2016, Wojciech Mula -Copyright (c) 2011-2020 Microsoft Corp -Copyright (c) 2015-2017, Wojciech Mula -Copyright (c) 2021 csFastFloat authors -Copyright (c) 2005-2007, Nick Galbreath -Copyright (c) 2015 The Chromium Authors -Copyright (c) 2018 Alexander Chermyanin -Copyright (c) The Internet Society 1997 -Portions (c) International Organization -Copyright (c) 2004-2006 Intel Corporation -Copyright (c) 2011-2015 Intel Corporation -Copyright (c) 2013-2017, Milosz Krajewski -Copyright (c) 2016-2017, Matthieu Darbois -Copyright (c) The Internet Society (2003) -Copyright (c) .NET Foundation Contributors -Copyright (c) 2020 Mara Bos -Copyright (c) .NET Foundation and Contributors -Copyright (c) 2012 - present, Victor Zverovich -Copyright (c) 2006 Jb Evain (jbevain@gmail.com) -Copyright (c) 2008-2020 Advanced Micro Devices, Inc. -Copyright (c) 2019 Microsoft Corporation, Daan Leijen -Copyright (c) 2011 Novell, Inc (http://www.novell.com) -Copyright (c) 1995-2022 Jean-loup Gailly and Mark Adler -Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com) -Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors -Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com -Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc. -Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers -Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip -Copyright (c) 1980, 1986, 1993 The Regents of the University of California -Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California -Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass - -The MIT License (MIT) - -Copyright (c) .NET Foundation and Contributors - -All rights reserved. - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - - ---------------------------------------------------------- - ---------------------------------------------------------- - -System.IO.Packaging 8.0.0 - MIT +System.IO.Packaging 8.0.1 - MIT Copyright (c) Six Labors @@ -4060,7 +4004,7 @@ SOFTWARE. --------------------------------------------------------- -System.Reflection.Metadata 8.0.0 - MIT +System.Reflection.Metadata 8.0.1 - MIT Copyright (c) Six Labors @@ -4147,7 +4091,7 @@ SOFTWARE. --------------------------------------------------------- -System.Runtime.Caching 8.0.0 - MIT +System.Runtime.Caching 8.0.1 - MIT Copyright (c) Six Labors @@ -4229,80 +4173,6 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------- - ---------------------------------------------------------- - -System.Runtime.CompilerServices.Unsafe 6.0.0 - MIT - - -(c) Microsoft Corporation -Copyright (c) Andrew Arnott -Copyright 2018 Daniel Lemire -Copyright (c) .NET Foundation -Copyright (c) 2011, Google Inc. -Copyright (c) 2020 Dan Shechter -(c) 1997-2005 Sean Eron Anderson -Copyright (c) 1998 Microsoft. To -Copyright (c) 2017 Yoshifumi Kawai -Copyright (c) 2005-2020 Rich Felker -Copyright (c) Microsoft Corporation -Copyright (c) 2007 James Newton-King -Copyright (c) 2012-2014, Yann Collet -Copyright (c) 1991-2020 Unicode, Inc. -Copyright (c) 2013-2017, Alfred Klomp -Copyright 2012 the V8 project authors -Copyright (c) 2011-2020 Microsoft Corp -Copyright (c) 2015-2017, Wojciech Mula -Copyright (c) 2005-2007, Nick Galbreath -Copyright (c) 2015 The Chromium Authors -Copyright (c) 2018 Alexander Chermyanin -Copyright (c) The Internet Society 1997 -Portions (c) International Organization -Copyright (c) 2004-2006 Intel Corporation -Copyright (c) 2013-2017, Milosz Krajewski -Copyright (c) 2016-2017, Matthieu Darbois -Copyright (c) The Internet Society (2003) -Copyright (c) .NET Foundation Contributors -Copyright (c) .NET Foundation and Contributors -Copyright (c) 2019 Microsoft Corporation, Daan Leijen -Copyright (c) 2011 Novell, Inc (http://www.novell.com) -Copyright (c) 1995-2017 Jean-loup Gailly and Mark Adler -Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com) -Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors -Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com -Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc. -Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers -Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip -Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California -Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass -Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass. To - -The MIT License (MIT) - -Copyright (c) .NET Foundation and Contributors - -All rights reserved. - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - - --------------------------------------------------------- --------------------------------------------------------- @@ -4382,7 +4252,7 @@ SOFTWARE. --------------------------------------------------------- -System.Security.Cryptography.Pkcs 8.0.0 - MIT +System.Security.Cryptography.Pkcs 8.0.1 - MIT Copyright (c) Six Labors @@ -4554,7 +4424,7 @@ SOFTWARE. --------------------------------------------------------- -System.Security.Cryptography.Xml 8.0.1 - MIT +System.Security.Cryptography.Xml 8.0.2 - MIT Copyright (c) Six Labors @@ -5061,7 +4931,7 @@ SOFTWARE. --------------------------------------------------------- -System.ServiceProcess.ServiceController 8.0.0 - MIT +System.ServiceProcess.ServiceController 8.0.1 - MIT Copyright (c) Six Labors @@ -5438,9 +5308,12 @@ SOFTWARE. --------------------------------------------------------- -System.Web.Services.Description 4.10.0 - MIT +System.Web.Services.Description 8.0.0 - MIT +(c) Microsoft Corporation +Copyright (c) .NET Foundation and Contributors +Copyright (c) 2000-2014 The Legion of the Bouncy Castle Inc. (http://www.bouncycastle.org) The MIT License (MIT) @@ -5747,3 +5620,4 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + From a84ab3a1cb76f32df0d118f48326d99724cbdc65 Mon Sep 17 00:00:00 2001 From: PowerShell Team Bot <69177312+pwshBot@users.noreply.github.com> Date: Tue, 12 Nov 2024 17:16:23 -0800 Subject: [PATCH 049/173] [release/v7.5] Update branch for release - Transitive - true - minor (#24576) --- DotnetRuntimeMetadata.json | 2 +- global.json | 2 +- ...oft.PowerShell.Commands.Diagnostics.csproj | 3 +- ...soft.PowerShell.Commands.Management.csproj | 3 +- ...crosoft.PowerShell.Commands.Utility.csproj | 6 +- ...crosoft.PowerShell.CoreCLR.Eventing.csproj | 2 +- .../Microsoft.PowerShell.SDK.csproj | 49 ++++++--- .../Microsoft.WSMan.Management.csproj | 3 +- .../System.Management.Automation.csproj | 24 ++--- .../BenchmarkDotNet.Extensions.csproj | 4 +- .../ResultsComparer/ResultsComparer.csproj | 4 +- ...soft.PowerShell.NamedPipeConnection.csproj | 20 ++-- .../nested/Test.Isolated.Nested.csproj | 2 + test/tools/TestService/TestService.csproj | 60 ++++++----- test/tools/WebListener/WebListener.csproj | 7 +- tools/cgmanifest.json | 102 +++++++++--------- 16 files changed, 162 insertions(+), 131 deletions(-) diff --git a/DotnetRuntimeMetadata.json b/DotnetRuntimeMetadata.json index 50884cd0a3c..472b5958a8c 100644 --- a/DotnetRuntimeMetadata.json +++ b/DotnetRuntimeMetadata.json @@ -4,7 +4,7 @@ "quality": "daily", "qualityFallback": "preview", "packageVersionPattern": "9.0.0-preview.6", - "sdkImageVersion": "9.0.0-preview.6.24327.7", + "sdkImageVersion": "9.0.100", "nextChannel": "9.0.0-preview.7", "azureFeed": "", "sdkImageOverride": "" diff --git a/global.json b/global.json index 2dd360f846e..65324522984 100644 --- a/global.json +++ b/global.json @@ -1,5 +1,5 @@ { "sdk": { - "version": "9.0.100-rc.2.24474.11" + "version": "9.0.100" } } diff --git a/src/Microsoft.PowerShell.Commands.Diagnostics/Microsoft.PowerShell.Commands.Diagnostics.csproj b/src/Microsoft.PowerShell.Commands.Diagnostics/Microsoft.PowerShell.Commands.Diagnostics.csproj index 34502ced25d..e575d8ef567 100644 --- a/src/Microsoft.PowerShell.Commands.Diagnostics/Microsoft.PowerShell.Commands.Diagnostics.csproj +++ b/src/Microsoft.PowerShell.Commands.Diagnostics/Microsoft.PowerShell.Commands.Diagnostics.csproj @@ -7,8 +7,9 @@ + - + diff --git a/src/Microsoft.PowerShell.Commands.Management/Microsoft.PowerShell.Commands.Management.csproj b/src/Microsoft.PowerShell.Commands.Management/Microsoft.PowerShell.Commands.Management.csproj index 4f20755c6e6..748df04b328 100644 --- a/src/Microsoft.PowerShell.Commands.Management/Microsoft.PowerShell.Commands.Management.csproj +++ b/src/Microsoft.PowerShell.Commands.Management/Microsoft.PowerShell.Commands.Management.csproj @@ -47,7 +47,8 @@ - + + diff --git a/src/Microsoft.PowerShell.Commands.Utility/Microsoft.PowerShell.Commands.Utility.csproj b/src/Microsoft.PowerShell.Commands.Utility/Microsoft.PowerShell.Commands.Utility.csproj index 9b61bb2b53d..e60c27d28a6 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/Microsoft.PowerShell.Commands.Utility.csproj +++ b/src/Microsoft.PowerShell.Commands.Utility/Microsoft.PowerShell.Commands.Utility.csproj @@ -13,7 +13,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive all - + @@ -41,8 +41,8 @@ - - + + diff --git a/src/Microsoft.PowerShell.CoreCLR.Eventing/Microsoft.PowerShell.CoreCLR.Eventing.csproj b/src/Microsoft.PowerShell.CoreCLR.Eventing/Microsoft.PowerShell.CoreCLR.Eventing.csproj index 003999e97b3..5c28e4fe256 100644 --- a/src/Microsoft.PowerShell.CoreCLR.Eventing/Microsoft.PowerShell.CoreCLR.Eventing.csproj +++ b/src/Microsoft.PowerShell.CoreCLR.Eventing/Microsoft.PowerShell.CoreCLR.Eventing.csproj @@ -8,7 +8,7 @@ - + diff --git a/src/Microsoft.PowerShell.SDK/Microsoft.PowerShell.SDK.csproj b/src/Microsoft.PowerShell.SDK/Microsoft.PowerShell.SDK.csproj index 03898ace0d3..bc5206ea9fa 100644 --- a/src/Microsoft.PowerShell.SDK/Microsoft.PowerShell.SDK.csproj +++ b/src/Microsoft.PowerShell.SDK/Microsoft.PowerShell.SDK.csproj @@ -17,25 +17,39 @@ - - - - - + + + + + + + + + + - - - + + + + + + - - - - - - - - + + + + + + + + + + + + + + - + + diff --git a/src/Microsoft.WSMan.Management/Microsoft.WSMan.Management.csproj b/src/Microsoft.WSMan.Management/Microsoft.WSMan.Management.csproj index 77aa3cef77c..5a379621c85 100644 --- a/src/Microsoft.WSMan.Management/Microsoft.WSMan.Management.csproj +++ b/src/Microsoft.WSMan.Management/Microsoft.WSMan.Management.csproj @@ -7,10 +7,11 @@ + - + diff --git a/src/System.Management.Automation/System.Management.Automation.csproj b/src/System.Management.Automation/System.Management.Automation.csproj index 6fce6d93111..12177ffd61c 100644 --- a/src/System.Management.Automation/System.Management.Automation.csproj +++ b/src/System.Management.Automation/System.Management.Automation.csproj @@ -32,25 +32,25 @@ - - - - - - + + + + + + - + - - - - + + + + - + diff --git a/test/perf/dotnet-tools/BenchmarkDotNet.Extensions/BenchmarkDotNet.Extensions.csproj b/test/perf/dotnet-tools/BenchmarkDotNet.Extensions/BenchmarkDotNet.Extensions.csproj index 47dc5733932..4c1975ac342 100644 --- a/test/perf/dotnet-tools/BenchmarkDotNet.Extensions/BenchmarkDotNet.Extensions.csproj +++ b/test/perf/dotnet-tools/BenchmarkDotNet.Extensions/BenchmarkDotNet.Extensions.csproj @@ -11,10 +11,12 @@ + - + + diff --git a/test/perf/dotnet-tools/ResultsComparer/ResultsComparer.csproj b/test/perf/dotnet-tools/ResultsComparer/ResultsComparer.csproj index 02f7255bcdb..61a9818dc23 100644 --- a/test/perf/dotnet-tools/ResultsComparer/ResultsComparer.csproj +++ b/test/perf/dotnet-tools/ResultsComparer/ResultsComparer.csproj @@ -11,11 +11,13 @@ + - + + diff --git a/test/tools/NamedPipeConnection/src/code/Microsoft.PowerShell.NamedPipeConnection.csproj b/test/tools/NamedPipeConnection/src/code/Microsoft.PowerShell.NamedPipeConnection.csproj index d6cc1071790..0acf5c81d43 100644 --- a/test/tools/NamedPipeConnection/src/code/Microsoft.PowerShell.NamedPipeConnection.csproj +++ b/test/tools/NamedPipeConnection/src/code/Microsoft.PowerShell.NamedPipeConnection.csproj @@ -20,14 +20,18 @@ - - - - - + + + + + + + - - - + + + + + diff --git a/test/tools/TestAlc/nested/Test.Isolated.Nested.csproj b/test/tools/TestAlc/nested/Test.Isolated.Nested.csproj index 483ae9267fb..200b284b31a 100644 --- a/test/tools/TestAlc/nested/Test.Isolated.Nested.csproj +++ b/test/tools/TestAlc/nested/Test.Isolated.Nested.csproj @@ -17,6 +17,8 @@ + + diff --git a/test/tools/TestService/TestService.csproj b/test/tools/TestService/TestService.csproj index 10bf8593408..e96e4defa48 100644 --- a/test/tools/TestService/TestService.csproj +++ b/test/tools/TestService/TestService.csproj @@ -15,38 +15,40 @@ - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + - - - - - + + + + + - - - - - - - - + + + + + + + + + diff --git a/test/tools/WebListener/WebListener.csproj b/test/tools/WebListener/WebListener.csproj index d3e8a1f3244..fc11e328e7e 100644 --- a/test/tools/WebListener/WebListener.csproj +++ b/test/tools/WebListener/WebListener.csproj @@ -7,8 +7,9 @@ - - - + + + + diff --git a/tools/cgmanifest.json b/tools/cgmanifest.json index 64926e8c0d2..4abc0cd4000 100644 --- a/tools/cgmanifest.json +++ b/tools/cgmanifest.json @@ -115,7 +115,7 @@ "Type": "nuget", "Nuget": { "Name": "Microsoft.Extensions.ObjectPool", - "Version": "8.0.10" + "Version": "8.0.11" } }, "DevelopmentDependency": false @@ -185,7 +185,7 @@ "Type": "nuget", "Nuget": { "Name": "Microsoft.Win32.Registry.AccessControl", - "Version": "8.0.0" + "Version": "9.0.0" } }, "DevelopmentDependency": false @@ -205,7 +205,7 @@ "Type": "nuget", "Nuget": { "Name": "Microsoft.Win32.SystemEvents", - "Version": "8.0.0" + "Version": "9.0.0" } }, "DevelopmentDependency": false @@ -215,7 +215,7 @@ "Type": "nuget", "Nuget": { "Name": "Microsoft.Windows.Compatibility", - "Version": "8.0.10" + "Version": "9.0.0" } }, "DevelopmentDependency": false @@ -235,7 +235,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.android-arm.runtime.native.System.IO.Ports", - "Version": "9.0.0-rc.2.24473.5" + "Version": "9.0.0" } }, "DevelopmentDependency": false @@ -245,7 +245,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.android-arm64.runtime.native.System.IO.Ports", - "Version": "9.0.0-rc.2.24473.5" + "Version": "9.0.0" } }, "DevelopmentDependency": false @@ -255,7 +255,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.android-x64.runtime.native.System.IO.Ports", - "Version": "9.0.0-rc.2.24473.5" + "Version": "9.0.0" } }, "DevelopmentDependency": false @@ -265,7 +265,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.android-x86.runtime.native.System.IO.Ports", - "Version": "9.0.0-rc.2.24473.5" + "Version": "9.0.0" } }, "DevelopmentDependency": false @@ -275,7 +275,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.linux-arm.runtime.native.System.IO.Ports", - "Version": "8.0.0" + "Version": "9.0.0" } }, "DevelopmentDependency": false @@ -285,7 +285,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.linux-arm64.runtime.native.System.IO.Ports", - "Version": "8.0.0" + "Version": "9.0.0" } }, "DevelopmentDependency": false @@ -295,7 +295,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.linux-bionic-arm64.runtime.native.System.IO.Ports", - "Version": "9.0.0-rc.2.24473.5" + "Version": "9.0.0" } }, "DevelopmentDependency": false @@ -305,7 +305,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.linux-bionic-x64.runtime.native.System.IO.Ports", - "Version": "9.0.0-rc.2.24473.5" + "Version": "9.0.0" } }, "DevelopmentDependency": false @@ -315,7 +315,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.linux-musl-arm.runtime.native.System.IO.Ports", - "Version": "9.0.0-rc.2.24473.5" + "Version": "9.0.0" } }, "DevelopmentDependency": false @@ -325,7 +325,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.linux-musl-arm64.runtime.native.System.IO.Ports", - "Version": "9.0.0-rc.2.24473.5" + "Version": "9.0.0" } }, "DevelopmentDependency": false @@ -335,7 +335,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.linux-musl-x64.runtime.native.System.IO.Ports", - "Version": "9.0.0-rc.2.24473.5" + "Version": "9.0.0" } }, "DevelopmentDependency": false @@ -345,7 +345,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.linux-x64.runtime.native.System.IO.Ports", - "Version": "8.0.0" + "Version": "9.0.0" } }, "DevelopmentDependency": false @@ -355,7 +355,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.maccatalyst-arm64.runtime.native.System.IO.Ports", - "Version": "9.0.0-rc.2.24473.5" + "Version": "9.0.0" } }, "DevelopmentDependency": false @@ -365,7 +365,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.maccatalyst-x64.runtime.native.System.IO.Ports", - "Version": "9.0.0-rc.2.24473.5" + "Version": "9.0.0" } }, "DevelopmentDependency": false @@ -385,7 +385,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.native.System.IO.Ports", - "Version": "8.0.0" + "Version": "9.0.0" } }, "DevelopmentDependency": false @@ -395,7 +395,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.osx-arm64.runtime.native.System.IO.Ports", - "Version": "8.0.0" + "Version": "9.0.0" } }, "DevelopmentDependency": false @@ -405,7 +405,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.osx-x64.runtime.native.System.IO.Ports", - "Version": "8.0.0" + "Version": "9.0.0" } }, "DevelopmentDependency": false @@ -465,7 +465,7 @@ "Type": "nuget", "Nuget": { "Name": "System.CodeDom", - "Version": "8.0.0" + "Version": "9.0.0" } }, "DevelopmentDependency": false @@ -485,7 +485,7 @@ "Type": "nuget", "Nuget": { "Name": "System.ComponentModel.Composition.Registration", - "Version": "8.0.0" + "Version": "9.0.0" } }, "DevelopmentDependency": false @@ -495,7 +495,7 @@ "Type": "nuget", "Nuget": { "Name": "System.ComponentModel.Composition", - "Version": "8.0.0" + "Version": "9.0.0" } }, "DevelopmentDependency": false @@ -505,7 +505,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Configuration.ConfigurationManager", - "Version": "8.0.1" + "Version": "9.0.0" } }, "DevelopmentDependency": false @@ -515,7 +515,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Data.Odbc", - "Version": "8.0.1" + "Version": "9.0.0" } }, "DevelopmentDependency": false @@ -525,7 +525,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Data.OleDb", - "Version": "8.0.1" + "Version": "9.0.0" } }, "DevelopmentDependency": false @@ -545,7 +545,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Diagnostics.DiagnosticSource", - "Version": "8.0.1" + "Version": "9.0.0" } }, "DevelopmentDependency": false @@ -555,7 +555,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Diagnostics.EventLog", - "Version": "8.0.1" + "Version": "9.0.0" } }, "DevelopmentDependency": false @@ -565,7 +565,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Diagnostics.PerformanceCounter", - "Version": "8.0.1" + "Version": "9.0.0" } }, "DevelopmentDependency": false @@ -575,7 +575,7 @@ "Type": "nuget", "Nuget": { "Name": "System.DirectoryServices.AccountManagement", - "Version": "8.0.1" + "Version": "9.0.0" } }, "DevelopmentDependency": false @@ -585,7 +585,7 @@ "Type": "nuget", "Nuget": { "Name": "System.DirectoryServices.Protocols", - "Version": "8.0.0" + "Version": "9.0.0" } }, "DevelopmentDependency": false @@ -595,7 +595,7 @@ "Type": "nuget", "Nuget": { "Name": "System.DirectoryServices", - "Version": "8.0.0" + "Version": "9.0.0" } }, "DevelopmentDependency": false @@ -605,7 +605,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Drawing.Common", - "Version": "8.0.10" + "Version": "9.0.0" } }, "DevelopmentDependency": false @@ -615,7 +615,7 @@ "Type": "nuget", "Nuget": { "Name": "System.IO.Packaging", - "Version": "8.0.1" + "Version": "9.0.0" } }, "DevelopmentDependency": false @@ -625,7 +625,7 @@ "Type": "nuget", "Nuget": { "Name": "System.IO.Ports", - "Version": "8.0.0" + "Version": "9.0.0" } }, "DevelopmentDependency": false @@ -635,7 +635,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Management", - "Version": "8.0.0" + "Version": "9.0.0" } }, "DevelopmentDependency": false @@ -645,7 +645,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Net.Http.WinHttpHandler", - "Version": "8.0.2" + "Version": "9.0.0" } }, "DevelopmentDependency": false @@ -675,7 +675,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Reflection.Context", - "Version": "8.0.0" + "Version": "9.0.0" } }, "DevelopmentDependency": false @@ -705,7 +705,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Runtime.Caching", - "Version": "8.0.1" + "Version": "9.0.0" } }, "DevelopmentDependency": false @@ -725,7 +725,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Security.Cryptography.Pkcs", - "Version": "8.0.1" + "Version": "9.0.0" } }, "DevelopmentDependency": false @@ -735,7 +735,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Security.Cryptography.ProtectedData", - "Version": "8.0.0" + "Version": "9.0.0" } }, "DevelopmentDependency": false @@ -745,7 +745,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Security.Cryptography.Xml", - "Version": "8.0.2" + "Version": "9.0.0" } }, "DevelopmentDependency": false @@ -755,7 +755,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Security.Permissions", - "Version": "8.0.0" + "Version": "9.0.0" } }, "DevelopmentDependency": false @@ -825,7 +825,7 @@ "Type": "nuget", "Nuget": { "Name": "System.ServiceModel.Syndication", - "Version": "8.0.0" + "Version": "9.0.0" } }, "DevelopmentDependency": false @@ -835,7 +835,7 @@ "Type": "nuget", "Nuget": { "Name": "System.ServiceProcess.ServiceController", - "Version": "8.0.1" + "Version": "9.0.0" } }, "DevelopmentDependency": false @@ -845,7 +845,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Speech", - "Version": "8.0.0" + "Version": "9.0.0" } }, "DevelopmentDependency": false @@ -855,7 +855,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Text.Encoding.CodePages", - "Version": "8.0.0" + "Version": "9.0.0" } }, "DevelopmentDependency": false @@ -865,7 +865,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Text.Encodings.Web", - "Version": "8.0.0" + "Version": "9.0.0" } }, "DevelopmentDependency": false @@ -875,7 +875,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Threading.AccessControl", - "Version": "8.0.0" + "Version": "9.0.0" } }, "DevelopmentDependency": false @@ -895,7 +895,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Windows.Extensions", - "Version": "8.0.0" + "Version": "9.0.0" } }, "DevelopmentDependency": false From c0142dde17137e436e302b3c4e93e2d6dc50c5c4 Mon Sep 17 00:00:00 2001 From: Aditya Patwardhan Date: Wed, 13 Nov 2024 11:23:21 -0800 Subject: [PATCH 050/173] Update ThirdPartyNotices file (#24582) --- ThirdPartyNotices.txt | 792 +++++++++++++++++++++++++----------------- 1 file changed, 468 insertions(+), 324 deletions(-) diff --git a/ThirdPartyNotices.txt b/ThirdPartyNotices.txt index 24c332f7074..a11a42b0aab 100644 --- a/ThirdPartyNotices.txt +++ b/ThirdPartyNotices.txt @@ -284,16 +284,16 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI --------------------------------------------------------- -Microsoft.Extensions.ObjectPool 8.0.10 - MIT +Microsoft.Extensions.ObjectPool 8.0.11 - MIT -Copyright 2019 The gRPC Copyright Jorn Zaefferer (c) Microsoft Corporation Copyright (c) Andrew Arnott Copyright (c) 2015, Google Inc. Copyright (c) 2019 David Fowler Copyright (c) HTML5 Boilerplate +Copyright 2019 The gRPC Authors Copyright (c) 2016 Richard Morris Copyright (c) 1998 John D. Polstra Copyright (c) 2017 Yoshifumi Kawai @@ -446,19 +446,22 @@ SOFTWARE. --------------------------------------------------------- -Microsoft.Win32.Registry.AccessControl 8.0.0 - MIT +Microsoft.Win32.Registry.AccessControl 9.0.0 - MIT +Copyright (c) 2021 Copyright (c) Six Labors (c) Microsoft Corporation +Copyright (c) 2022 FormatJS Copyright (c) Andrew Arnott Copyright 2019 LLVM Project +Copyright (c) 1998 Microsoft Copyright 2018 Daniel Lemire Copyright (c) .NET Foundation Copyright (c) 2011, Google Inc. Copyright (c) 2020 Dan Shechter (c) 1997-2005 Sean Eron Anderson -Copyright (c) 1998 Microsoft. To +Copyright (c) 2015 Andrew Gallant Copyright (c) 2022, Wojciech Mula Copyright (c) 2017 Yoshifumi Kawai Copyright (c) 2022, Geoff Langdale @@ -468,23 +471,24 @@ Copyright (c) Microsoft Corporation Copyright (c) 2007 James Newton-King Copyright (c) 1991-2022 Unicode, Inc. Copyright (c) 2013-2017, Alfred Klomp +Copyright (c) 2018 Nemanja Mijailovic Copyright 2012 the V8 project authors Copyright (c) 1999 Lucent Technologies Copyright (c) 2008-2016, Wojciech Mula Copyright (c) 2011-2020 Microsoft Corp Copyright (c) 2015-2017, Wojciech Mula -Copyright (c) 2021 csFastFloat authors +Copyright (c) 2015-2018, Wojciech Mula Copyright (c) 2005-2007, Nick Galbreath Copyright (c) 2015 The Chromium Authors Copyright (c) 2018 Alexander Chermyanin Copyright (c) The Internet Society 1997 -Portions (c) International Organization Copyright (c) 2004-2006 Intel Corporation Copyright (c) 2011-2015 Intel Corporation Copyright (c) 2013-2017, Milosz Krajewski Copyright (c) 2016-2017, Matthieu Darbois Copyright (c) The Internet Society (2003) Copyright (c) .NET Foundation Contributors +(c) 1995-2024 Jean-loup Gailly and Mark Adler Copyright (c) 2020 Mara Bos Copyright (c) .NET Foundation and Contributors Copyright (c) 2012 - present, Victor Zverovich @@ -492,12 +496,12 @@ Copyright (c) 2006 Jb Evain (jbevain@gmail.com) Copyright (c) 2008-2020 Advanced Micro Devices, Inc. Copyright (c) 2019 Microsoft Corporation, Daan Leijen Copyright (c) 2011 Novell, Inc (http://www.novell.com) -Copyright (c) 1995-2022 Jean-loup Gailly and Mark Adler Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com) Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc. -Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers +Portions (c) International Organization for Standardization 1986 +Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip Copyright (c) 1980, 1986, 1993 The Regents of the University of California Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California @@ -532,19 +536,22 @@ SOFTWARE. --------------------------------------------------------- -Microsoft.Win32.SystemEvents 8.0.0 - MIT +Microsoft.Win32.SystemEvents 9.0.0 - MIT +Copyright (c) 2021 Copyright (c) Six Labors (c) Microsoft Corporation +Copyright (c) 2022 FormatJS Copyright (c) Andrew Arnott Copyright 2019 LLVM Project +Copyright (c) 1998 Microsoft Copyright 2018 Daniel Lemire Copyright (c) .NET Foundation Copyright (c) 2011, Google Inc. Copyright (c) 2020 Dan Shechter (c) 1997-2005 Sean Eron Anderson -Copyright (c) 1998 Microsoft. To +Copyright (c) 2015 Andrew Gallant Copyright (c) 2022, Wojciech Mula Copyright (c) 2017 Yoshifumi Kawai Copyright (c) 2022, Geoff Langdale @@ -554,23 +561,24 @@ Copyright (c) Microsoft Corporation Copyright (c) 2007 James Newton-King Copyright (c) 1991-2022 Unicode, Inc. Copyright (c) 2013-2017, Alfred Klomp +Copyright (c) 2018 Nemanja Mijailovic Copyright 2012 the V8 project authors Copyright (c) 1999 Lucent Technologies Copyright (c) 2008-2016, Wojciech Mula Copyright (c) 2011-2020 Microsoft Corp Copyright (c) 2015-2017, Wojciech Mula -Copyright (c) 2021 csFastFloat authors +Copyright (c) 2015-2018, Wojciech Mula Copyright (c) 2005-2007, Nick Galbreath Copyright (c) 2015 The Chromium Authors Copyright (c) 2018 Alexander Chermyanin Copyright (c) The Internet Society 1997 -Portions (c) International Organization Copyright (c) 2004-2006 Intel Corporation Copyright (c) 2011-2015 Intel Corporation Copyright (c) 2013-2017, Milosz Krajewski Copyright (c) 2016-2017, Matthieu Darbois Copyright (c) The Internet Society (2003) Copyright (c) .NET Foundation Contributors +(c) 1995-2024 Jean-loup Gailly and Mark Adler Copyright (c) 2020 Mara Bos Copyright (c) .NET Foundation and Contributors Copyright (c) 2012 - present, Victor Zverovich @@ -578,12 +586,12 @@ Copyright (c) 2006 Jb Evain (jbevain@gmail.com) Copyright (c) 2008-2020 Advanced Micro Devices, Inc. Copyright (c) 2019 Microsoft Corporation, Daan Leijen Copyright (c) 2011 Novell, Inc (http://www.novell.com) -Copyright (c) 1995-2022 Jean-loup Gailly and Mark Adler Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com) Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc. -Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers +Portions (c) International Organization for Standardization 1986 +Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip Copyright (c) 1980, 1986, 1993 The Regents of the University of California Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California @@ -618,7 +626,7 @@ SOFTWARE. --------------------------------------------------------- -Microsoft.Windows.Compatibility 8.0.10 - MIT +Microsoft.Windows.Compatibility 9.0.0 - MIT (c) Microsoft Corporation @@ -671,20 +679,21 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. --------------------------------------------------------- -runtime.android-arm.runtime.native.System.IO.Ports 9.0.0-rc.2.24473.5 - MIT +runtime.android-arm.runtime.native.System.IO.Ports 9.0.0 - MIT +Copyright (c) 2021 Copyright (c) Six Labors (c) Microsoft Corporation Copyright (c) 2022 FormatJS Copyright (c) Andrew Arnott Copyright 2019 LLVM Project +Copyright (c) 1998 Microsoft Copyright 2018 Daniel Lemire Copyright (c) .NET Foundation Copyright (c) 2011, Google Inc. Copyright (c) 2020 Dan Shechter (c) 1997-2005 Sean Eron Anderson -Copyright (c) 1998 Microsoft. To Copyright (c) 2015 Andrew Gallant Copyright (c) 2022, Wojciech Mula Copyright (c) 2017 Yoshifumi Kawai @@ -702,12 +711,10 @@ Copyright (c) 2008-2016, Wojciech Mula Copyright (c) 2011-2020 Microsoft Corp Copyright (c) 2015-2017, Wojciech Mula Copyright (c) 2015-2018, Wojciech Mula -Copyright (c) 2021 csFastFloat authors Copyright (c) 2005-2007, Nick Galbreath Copyright (c) 2015 The Chromium Authors Copyright (c) 2018 Alexander Chermyanin Copyright (c) The Internet Society 1997 -Portions (c) International Organization Copyright (c) 2004-2006 Intel Corporation Copyright (c) 2011-2015 Intel Corporation Copyright (c) 2013-2017, Milosz Krajewski @@ -726,7 +733,8 @@ Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com) Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc. -Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers +Portions (c) International Organization for Standardization 1986 +Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip Copyright (c) 1980, 1986, 1993 The Regents of the University of California Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California @@ -761,20 +769,21 @@ SOFTWARE. --------------------------------------------------------- -runtime.android-arm64.runtime.native.System.IO.Ports 9.0.0-rc.2.24473.5 - MIT +runtime.android-arm64.runtime.native.System.IO.Ports 9.0.0 - MIT +Copyright (c) 2021 Copyright (c) Six Labors (c) Microsoft Corporation Copyright (c) 2022 FormatJS Copyright (c) Andrew Arnott Copyright 2019 LLVM Project +Copyright (c) 1998 Microsoft Copyright 2018 Daniel Lemire Copyright (c) .NET Foundation Copyright (c) 2011, Google Inc. Copyright (c) 2020 Dan Shechter (c) 1997-2005 Sean Eron Anderson -Copyright (c) 1998 Microsoft. To Copyright (c) 2015 Andrew Gallant Copyright (c) 2022, Wojciech Mula Copyright (c) 2017 Yoshifumi Kawai @@ -792,12 +801,10 @@ Copyright (c) 2008-2016, Wojciech Mula Copyright (c) 2011-2020 Microsoft Corp Copyright (c) 2015-2017, Wojciech Mula Copyright (c) 2015-2018, Wojciech Mula -Copyright (c) 2021 csFastFloat authors Copyright (c) 2005-2007, Nick Galbreath Copyright (c) 2015 The Chromium Authors Copyright (c) 2018 Alexander Chermyanin Copyright (c) The Internet Society 1997 -Portions (c) International Organization Copyright (c) 2004-2006 Intel Corporation Copyright (c) 2011-2015 Intel Corporation Copyright (c) 2013-2017, Milosz Krajewski @@ -816,7 +823,8 @@ Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com) Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc. -Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers +Portions (c) International Organization for Standardization 1986 +Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip Copyright (c) 1980, 1986, 1993 The Regents of the University of California Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California @@ -851,20 +859,21 @@ SOFTWARE. --------------------------------------------------------- -runtime.android-x64.runtime.native.System.IO.Ports 9.0.0-rc.2.24473.5 - MIT +runtime.android-x64.runtime.native.System.IO.Ports 9.0.0 - MIT +Copyright (c) 2021 Copyright (c) Six Labors (c) Microsoft Corporation Copyright (c) 2022 FormatJS Copyright (c) Andrew Arnott Copyright 2019 LLVM Project +Copyright (c) 1998 Microsoft Copyright 2018 Daniel Lemire Copyright (c) .NET Foundation Copyright (c) 2011, Google Inc. Copyright (c) 2020 Dan Shechter (c) 1997-2005 Sean Eron Anderson -Copyright (c) 1998 Microsoft. To Copyright (c) 2015 Andrew Gallant Copyright (c) 2022, Wojciech Mula Copyright (c) 2017 Yoshifumi Kawai @@ -882,12 +891,10 @@ Copyright (c) 2008-2016, Wojciech Mula Copyright (c) 2011-2020 Microsoft Corp Copyright (c) 2015-2017, Wojciech Mula Copyright (c) 2015-2018, Wojciech Mula -Copyright (c) 2021 csFastFloat authors Copyright (c) 2005-2007, Nick Galbreath Copyright (c) 2015 The Chromium Authors Copyright (c) 2018 Alexander Chermyanin Copyright (c) The Internet Society 1997 -Portions (c) International Organization Copyright (c) 2004-2006 Intel Corporation Copyright (c) 2011-2015 Intel Corporation Copyright (c) 2013-2017, Milosz Krajewski @@ -906,7 +913,8 @@ Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com) Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc. -Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers +Portions (c) International Organization for Standardization 1986 +Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip Copyright (c) 1980, 1986, 1993 The Regents of the University of California Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California @@ -941,20 +949,21 @@ SOFTWARE. --------------------------------------------------------- -runtime.android-x86.runtime.native.System.IO.Ports 9.0.0-rc.2.24473.5 - MIT +runtime.android-x86.runtime.native.System.IO.Ports 9.0.0 - MIT +Copyright (c) 2021 Copyright (c) Six Labors (c) Microsoft Corporation Copyright (c) 2022 FormatJS Copyright (c) Andrew Arnott Copyright 2019 LLVM Project +Copyright (c) 1998 Microsoft Copyright 2018 Daniel Lemire Copyright (c) .NET Foundation Copyright (c) 2011, Google Inc. Copyright (c) 2020 Dan Shechter (c) 1997-2005 Sean Eron Anderson -Copyright (c) 1998 Microsoft. To Copyright (c) 2015 Andrew Gallant Copyright (c) 2022, Wojciech Mula Copyright (c) 2017 Yoshifumi Kawai @@ -972,12 +981,10 @@ Copyright (c) 2008-2016, Wojciech Mula Copyright (c) 2011-2020 Microsoft Corp Copyright (c) 2015-2017, Wojciech Mula Copyright (c) 2015-2018, Wojciech Mula -Copyright (c) 2021 csFastFloat authors Copyright (c) 2005-2007, Nick Galbreath Copyright (c) 2015 The Chromium Authors Copyright (c) 2018 Alexander Chermyanin Copyright (c) The Internet Society 1997 -Portions (c) International Organization Copyright (c) 2004-2006 Intel Corporation Copyright (c) 2011-2015 Intel Corporation Copyright (c) 2013-2017, Milosz Krajewski @@ -996,7 +1003,8 @@ Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com) Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc. -Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers +Portions (c) International Organization for Standardization 1986 +Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip Copyright (c) 1980, 1986, 1993 The Regents of the University of California Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California @@ -1031,19 +1039,22 @@ SOFTWARE. --------------------------------------------------------- -runtime.linux-arm.runtime.native.System.IO.Ports 8.0.0 - MIT +runtime.linux-arm.runtime.native.System.IO.Ports 9.0.0 - MIT +Copyright (c) 2021 Copyright (c) Six Labors (c) Microsoft Corporation +Copyright (c) 2022 FormatJS Copyright (c) Andrew Arnott Copyright 2019 LLVM Project +Copyright (c) 1998 Microsoft Copyright 2018 Daniel Lemire Copyright (c) .NET Foundation Copyright (c) 2011, Google Inc. Copyright (c) 2020 Dan Shechter (c) 1997-2005 Sean Eron Anderson -Copyright (c) 1998 Microsoft. To +Copyright (c) 2015 Andrew Gallant Copyright (c) 2022, Wojciech Mula Copyright (c) 2017 Yoshifumi Kawai Copyright (c) 2022, Geoff Langdale @@ -1053,23 +1064,24 @@ Copyright (c) Microsoft Corporation Copyright (c) 2007 James Newton-King Copyright (c) 1991-2022 Unicode, Inc. Copyright (c) 2013-2017, Alfred Klomp +Copyright (c) 2018 Nemanja Mijailovic Copyright 2012 the V8 project authors Copyright (c) 1999 Lucent Technologies Copyright (c) 2008-2016, Wojciech Mula Copyright (c) 2011-2020 Microsoft Corp Copyright (c) 2015-2017, Wojciech Mula -Copyright (c) 2021 csFastFloat authors +Copyright (c) 2015-2018, Wojciech Mula Copyright (c) 2005-2007, Nick Galbreath Copyright (c) 2015 The Chromium Authors Copyright (c) 2018 Alexander Chermyanin Copyright (c) The Internet Society 1997 -Portions (c) International Organization Copyright (c) 2004-2006 Intel Corporation Copyright (c) 2011-2015 Intel Corporation Copyright (c) 2013-2017, Milosz Krajewski Copyright (c) 2016-2017, Matthieu Darbois Copyright (c) The Internet Society (2003) Copyright (c) .NET Foundation Contributors +(c) 1995-2024 Jean-loup Gailly and Mark Adler Copyright (c) 2020 Mara Bos Copyright (c) .NET Foundation and Contributors Copyright (c) 2012 - present, Victor Zverovich @@ -1077,12 +1089,12 @@ Copyright (c) 2006 Jb Evain (jbevain@gmail.com) Copyright (c) 2008-2020 Advanced Micro Devices, Inc. Copyright (c) 2019 Microsoft Corporation, Daan Leijen Copyright (c) 2011 Novell, Inc (http://www.novell.com) -Copyright (c) 1995-2022 Jean-loup Gailly and Mark Adler Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com) Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc. -Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers +Portions (c) International Organization for Standardization 1986 +Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip Copyright (c) 1980, 1986, 1993 The Regents of the University of California Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California @@ -1117,19 +1129,22 @@ SOFTWARE. --------------------------------------------------------- -runtime.linux-arm64.runtime.native.System.IO.Ports 8.0.0 - MIT +runtime.linux-arm64.runtime.native.System.IO.Ports 9.0.0 - MIT +Copyright (c) 2021 Copyright (c) Six Labors (c) Microsoft Corporation +Copyright (c) 2022 FormatJS Copyright (c) Andrew Arnott Copyright 2019 LLVM Project +Copyright (c) 1998 Microsoft Copyright 2018 Daniel Lemire Copyright (c) .NET Foundation Copyright (c) 2011, Google Inc. Copyright (c) 2020 Dan Shechter (c) 1997-2005 Sean Eron Anderson -Copyright (c) 1998 Microsoft. To +Copyright (c) 2015 Andrew Gallant Copyright (c) 2022, Wojciech Mula Copyright (c) 2017 Yoshifumi Kawai Copyright (c) 2022, Geoff Langdale @@ -1139,23 +1154,24 @@ Copyright (c) Microsoft Corporation Copyright (c) 2007 James Newton-King Copyright (c) 1991-2022 Unicode, Inc. Copyright (c) 2013-2017, Alfred Klomp +Copyright (c) 2018 Nemanja Mijailovic Copyright 2012 the V8 project authors Copyright (c) 1999 Lucent Technologies Copyright (c) 2008-2016, Wojciech Mula Copyright (c) 2011-2020 Microsoft Corp Copyright (c) 2015-2017, Wojciech Mula -Copyright (c) 2021 csFastFloat authors +Copyright (c) 2015-2018, Wojciech Mula Copyright (c) 2005-2007, Nick Galbreath Copyright (c) 2015 The Chromium Authors Copyright (c) 2018 Alexander Chermyanin Copyright (c) The Internet Society 1997 -Portions (c) International Organization Copyright (c) 2004-2006 Intel Corporation Copyright (c) 2011-2015 Intel Corporation Copyright (c) 2013-2017, Milosz Krajewski Copyright (c) 2016-2017, Matthieu Darbois Copyright (c) The Internet Society (2003) Copyright (c) .NET Foundation Contributors +(c) 1995-2024 Jean-loup Gailly and Mark Adler Copyright (c) 2020 Mara Bos Copyright (c) .NET Foundation and Contributors Copyright (c) 2012 - present, Victor Zverovich @@ -1163,12 +1179,12 @@ Copyright (c) 2006 Jb Evain (jbevain@gmail.com) Copyright (c) 2008-2020 Advanced Micro Devices, Inc. Copyright (c) 2019 Microsoft Corporation, Daan Leijen Copyright (c) 2011 Novell, Inc (http://www.novell.com) -Copyright (c) 1995-2022 Jean-loup Gailly and Mark Adler Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com) Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc. -Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers +Portions (c) International Organization for Standardization 1986 +Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip Copyright (c) 1980, 1986, 1993 The Regents of the University of California Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California @@ -1203,20 +1219,21 @@ SOFTWARE. --------------------------------------------------------- -runtime.linux-bionic-arm64.runtime.native.System.IO.Ports 9.0.0-rc.2.24473.5 - MIT +runtime.linux-bionic-arm64.runtime.native.System.IO.Ports 9.0.0 - MIT +Copyright (c) 2021 Copyright (c) Six Labors (c) Microsoft Corporation Copyright (c) 2022 FormatJS Copyright (c) Andrew Arnott Copyright 2019 LLVM Project +Copyright (c) 1998 Microsoft Copyright 2018 Daniel Lemire Copyright (c) .NET Foundation Copyright (c) 2011, Google Inc. Copyright (c) 2020 Dan Shechter (c) 1997-2005 Sean Eron Anderson -Copyright (c) 1998 Microsoft. To Copyright (c) 2015 Andrew Gallant Copyright (c) 2022, Wojciech Mula Copyright (c) 2017 Yoshifumi Kawai @@ -1234,12 +1251,10 @@ Copyright (c) 2008-2016, Wojciech Mula Copyright (c) 2011-2020 Microsoft Corp Copyright (c) 2015-2017, Wojciech Mula Copyright (c) 2015-2018, Wojciech Mula -Copyright (c) 2021 csFastFloat authors Copyright (c) 2005-2007, Nick Galbreath Copyright (c) 2015 The Chromium Authors Copyright (c) 2018 Alexander Chermyanin Copyright (c) The Internet Society 1997 -Portions (c) International Organization Copyright (c) 2004-2006 Intel Corporation Copyright (c) 2011-2015 Intel Corporation Copyright (c) 2013-2017, Milosz Krajewski @@ -1258,7 +1273,8 @@ Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com) Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc. -Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers +Portions (c) International Organization for Standardization 1986 +Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip Copyright (c) 1980, 1986, 1993 The Regents of the University of California Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California @@ -1293,20 +1309,21 @@ SOFTWARE. --------------------------------------------------------- -runtime.linux-bionic-x64.runtime.native.System.IO.Ports 9.0.0-rc.2.24473.5 - MIT +runtime.linux-bionic-x64.runtime.native.System.IO.Ports 9.0.0 - MIT +Copyright (c) 2021 Copyright (c) Six Labors (c) Microsoft Corporation Copyright (c) 2022 FormatJS Copyright (c) Andrew Arnott Copyright 2019 LLVM Project +Copyright (c) 1998 Microsoft Copyright 2018 Daniel Lemire Copyright (c) .NET Foundation Copyright (c) 2011, Google Inc. Copyright (c) 2020 Dan Shechter (c) 1997-2005 Sean Eron Anderson -Copyright (c) 1998 Microsoft. To Copyright (c) 2015 Andrew Gallant Copyright (c) 2022, Wojciech Mula Copyright (c) 2017 Yoshifumi Kawai @@ -1324,12 +1341,10 @@ Copyright (c) 2008-2016, Wojciech Mula Copyright (c) 2011-2020 Microsoft Corp Copyright (c) 2015-2017, Wojciech Mula Copyright (c) 2015-2018, Wojciech Mula -Copyright (c) 2021 csFastFloat authors Copyright (c) 2005-2007, Nick Galbreath Copyright (c) 2015 The Chromium Authors Copyright (c) 2018 Alexander Chermyanin Copyright (c) The Internet Society 1997 -Portions (c) International Organization Copyright (c) 2004-2006 Intel Corporation Copyright (c) 2011-2015 Intel Corporation Copyright (c) 2013-2017, Milosz Krajewski @@ -1348,7 +1363,8 @@ Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com) Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc. -Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers +Portions (c) International Organization for Standardization 1986 +Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip Copyright (c) 1980, 1986, 1993 The Regents of the University of California Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California @@ -1383,20 +1399,21 @@ SOFTWARE. --------------------------------------------------------- -runtime.linux-musl-arm.runtime.native.System.IO.Ports 9.0.0-rc.2.24473.5 - MIT +runtime.linux-musl-arm.runtime.native.System.IO.Ports 9.0.0 - MIT +Copyright (c) 2021 Copyright (c) Six Labors (c) Microsoft Corporation Copyright (c) 2022 FormatJS Copyright (c) Andrew Arnott Copyright 2019 LLVM Project +Copyright (c) 1998 Microsoft Copyright 2018 Daniel Lemire Copyright (c) .NET Foundation Copyright (c) 2011, Google Inc. Copyright (c) 2020 Dan Shechter (c) 1997-2005 Sean Eron Anderson -Copyright (c) 1998 Microsoft. To Copyright (c) 2015 Andrew Gallant Copyright (c) 2022, Wojciech Mula Copyright (c) 2017 Yoshifumi Kawai @@ -1414,12 +1431,10 @@ Copyright (c) 2008-2016, Wojciech Mula Copyright (c) 2011-2020 Microsoft Corp Copyright (c) 2015-2017, Wojciech Mula Copyright (c) 2015-2018, Wojciech Mula -Copyright (c) 2021 csFastFloat authors Copyright (c) 2005-2007, Nick Galbreath Copyright (c) 2015 The Chromium Authors Copyright (c) 2018 Alexander Chermyanin Copyright (c) The Internet Society 1997 -Portions (c) International Organization Copyright (c) 2004-2006 Intel Corporation Copyright (c) 2011-2015 Intel Corporation Copyright (c) 2013-2017, Milosz Krajewski @@ -1438,7 +1453,8 @@ Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com) Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc. -Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers +Portions (c) International Organization for Standardization 1986 +Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip Copyright (c) 1980, 1986, 1993 The Regents of the University of California Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California @@ -1473,20 +1489,21 @@ SOFTWARE. --------------------------------------------------------- -runtime.linux-musl-arm64.runtime.native.System.IO.Ports 9.0.0-rc.2.24473.5 - MIT +runtime.linux-musl-arm64.runtime.native.System.IO.Ports 9.0.0 - MIT +Copyright (c) 2021 Copyright (c) Six Labors (c) Microsoft Corporation Copyright (c) 2022 FormatJS Copyright (c) Andrew Arnott Copyright 2019 LLVM Project +Copyright (c) 1998 Microsoft Copyright 2018 Daniel Lemire Copyright (c) .NET Foundation Copyright (c) 2011, Google Inc. Copyright (c) 2020 Dan Shechter (c) 1997-2005 Sean Eron Anderson -Copyright (c) 1998 Microsoft. To Copyright (c) 2015 Andrew Gallant Copyright (c) 2022, Wojciech Mula Copyright (c) 2017 Yoshifumi Kawai @@ -1504,12 +1521,10 @@ Copyright (c) 2008-2016, Wojciech Mula Copyright (c) 2011-2020 Microsoft Corp Copyright (c) 2015-2017, Wojciech Mula Copyright (c) 2015-2018, Wojciech Mula -Copyright (c) 2021 csFastFloat authors Copyright (c) 2005-2007, Nick Galbreath Copyright (c) 2015 The Chromium Authors Copyright (c) 2018 Alexander Chermyanin Copyright (c) The Internet Society 1997 -Portions (c) International Organization Copyright (c) 2004-2006 Intel Corporation Copyright (c) 2011-2015 Intel Corporation Copyright (c) 2013-2017, Milosz Krajewski @@ -1528,7 +1543,8 @@ Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com) Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc. -Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers +Portions (c) International Organization for Standardization 1986 +Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip Copyright (c) 1980, 1986, 1993 The Regents of the University of California Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California @@ -1563,20 +1579,21 @@ SOFTWARE. --------------------------------------------------------- -runtime.linux-musl-x64.runtime.native.System.IO.Ports 9.0.0-rc.2.24473.5 - MIT +runtime.linux-musl-x64.runtime.native.System.IO.Ports 9.0.0 - MIT +Copyright (c) 2021 Copyright (c) Six Labors (c) Microsoft Corporation Copyright (c) 2022 FormatJS Copyright (c) Andrew Arnott Copyright 2019 LLVM Project +Copyright (c) 1998 Microsoft Copyright 2018 Daniel Lemire Copyright (c) .NET Foundation Copyright (c) 2011, Google Inc. Copyright (c) 2020 Dan Shechter (c) 1997-2005 Sean Eron Anderson -Copyright (c) 1998 Microsoft. To Copyright (c) 2015 Andrew Gallant Copyright (c) 2022, Wojciech Mula Copyright (c) 2017 Yoshifumi Kawai @@ -1594,12 +1611,10 @@ Copyright (c) 2008-2016, Wojciech Mula Copyright (c) 2011-2020 Microsoft Corp Copyright (c) 2015-2017, Wojciech Mula Copyright (c) 2015-2018, Wojciech Mula -Copyright (c) 2021 csFastFloat authors Copyright (c) 2005-2007, Nick Galbreath Copyright (c) 2015 The Chromium Authors Copyright (c) 2018 Alexander Chermyanin Copyright (c) The Internet Society 1997 -Portions (c) International Organization Copyright (c) 2004-2006 Intel Corporation Copyright (c) 2011-2015 Intel Corporation Copyright (c) 2013-2017, Milosz Krajewski @@ -1618,7 +1633,8 @@ Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com) Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc. -Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers +Portions (c) International Organization for Standardization 1986 +Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip Copyright (c) 1980, 1986, 1993 The Regents of the University of California Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California @@ -1653,19 +1669,22 @@ SOFTWARE. --------------------------------------------------------- -runtime.linux-x64.runtime.native.System.IO.Ports 8.0.0 - MIT +runtime.linux-x64.runtime.native.System.IO.Ports 9.0.0 - MIT +Copyright (c) 2021 Copyright (c) Six Labors (c) Microsoft Corporation +Copyright (c) 2022 FormatJS Copyright (c) Andrew Arnott Copyright 2019 LLVM Project +Copyright (c) 1998 Microsoft Copyright 2018 Daniel Lemire Copyright (c) .NET Foundation Copyright (c) 2011, Google Inc. Copyright (c) 2020 Dan Shechter (c) 1997-2005 Sean Eron Anderson -Copyright (c) 1998 Microsoft. To +Copyright (c) 2015 Andrew Gallant Copyright (c) 2022, Wojciech Mula Copyright (c) 2017 Yoshifumi Kawai Copyright (c) 2022, Geoff Langdale @@ -1675,23 +1694,24 @@ Copyright (c) Microsoft Corporation Copyright (c) 2007 James Newton-King Copyright (c) 1991-2022 Unicode, Inc. Copyright (c) 2013-2017, Alfred Klomp +Copyright (c) 2018 Nemanja Mijailovic Copyright 2012 the V8 project authors Copyright (c) 1999 Lucent Technologies Copyright (c) 2008-2016, Wojciech Mula Copyright (c) 2011-2020 Microsoft Corp Copyright (c) 2015-2017, Wojciech Mula -Copyright (c) 2021 csFastFloat authors +Copyright (c) 2015-2018, Wojciech Mula Copyright (c) 2005-2007, Nick Galbreath Copyright (c) 2015 The Chromium Authors Copyright (c) 2018 Alexander Chermyanin Copyright (c) The Internet Society 1997 -Portions (c) International Organization Copyright (c) 2004-2006 Intel Corporation Copyright (c) 2011-2015 Intel Corporation Copyright (c) 2013-2017, Milosz Krajewski Copyright (c) 2016-2017, Matthieu Darbois Copyright (c) The Internet Society (2003) Copyright (c) .NET Foundation Contributors +(c) 1995-2024 Jean-loup Gailly and Mark Adler Copyright (c) 2020 Mara Bos Copyright (c) .NET Foundation and Contributors Copyright (c) 2012 - present, Victor Zverovich @@ -1699,12 +1719,12 @@ Copyright (c) 2006 Jb Evain (jbevain@gmail.com) Copyright (c) 2008-2020 Advanced Micro Devices, Inc. Copyright (c) 2019 Microsoft Corporation, Daan Leijen Copyright (c) 2011 Novell, Inc (http://www.novell.com) -Copyright (c) 1995-2022 Jean-loup Gailly and Mark Adler Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com) Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc. -Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers +Portions (c) International Organization for Standardization 1986 +Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip Copyright (c) 1980, 1986, 1993 The Regents of the University of California Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California @@ -1739,20 +1759,21 @@ SOFTWARE. --------------------------------------------------------- -runtime.maccatalyst-arm64.runtime.native.System.IO.Ports 9.0.0-rc.2.24473.5 - MIT +runtime.maccatalyst-arm64.runtime.native.System.IO.Ports 9.0.0 - MIT +Copyright (c) 2021 Copyright (c) Six Labors (c) Microsoft Corporation Copyright (c) 2022 FormatJS Copyright (c) Andrew Arnott Copyright 2019 LLVM Project +Copyright (c) 1998 Microsoft Copyright 2018 Daniel Lemire Copyright (c) .NET Foundation Copyright (c) 2011, Google Inc. Copyright (c) 2020 Dan Shechter (c) 1997-2005 Sean Eron Anderson -Copyright (c) 1998 Microsoft. To Copyright (c) 2015 Andrew Gallant Copyright (c) 2022, Wojciech Mula Copyright (c) 2017 Yoshifumi Kawai @@ -1770,12 +1791,10 @@ Copyright (c) 2008-2016, Wojciech Mula Copyright (c) 2011-2020 Microsoft Corp Copyright (c) 2015-2017, Wojciech Mula Copyright (c) 2015-2018, Wojciech Mula -Copyright (c) 2021 csFastFloat authors Copyright (c) 2005-2007, Nick Galbreath Copyright (c) 2015 The Chromium Authors Copyright (c) 2018 Alexander Chermyanin Copyright (c) The Internet Society 1997 -Portions (c) International Organization Copyright (c) 2004-2006 Intel Corporation Copyright (c) 2011-2015 Intel Corporation Copyright (c) 2013-2017, Milosz Krajewski @@ -1794,7 +1813,8 @@ Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com) Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc. -Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers +Portions (c) International Organization for Standardization 1986 +Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip Copyright (c) 1980, 1986, 1993 The Regents of the University of California Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California @@ -1829,20 +1849,21 @@ SOFTWARE. --------------------------------------------------------- -runtime.maccatalyst-x64.runtime.native.System.IO.Ports 9.0.0-rc.2.24473.5 - MIT +runtime.maccatalyst-x64.runtime.native.System.IO.Ports 9.0.0 - MIT +Copyright (c) 2021 Copyright (c) Six Labors (c) Microsoft Corporation Copyright (c) 2022 FormatJS Copyright (c) Andrew Arnott Copyright 2019 LLVM Project +Copyright (c) 1998 Microsoft Copyright 2018 Daniel Lemire Copyright (c) .NET Foundation Copyright (c) 2011, Google Inc. Copyright (c) 2020 Dan Shechter (c) 1997-2005 Sean Eron Anderson -Copyright (c) 1998 Microsoft. To Copyright (c) 2015 Andrew Gallant Copyright (c) 2022, Wojciech Mula Copyright (c) 2017 Yoshifumi Kawai @@ -1860,12 +1881,10 @@ Copyright (c) 2008-2016, Wojciech Mula Copyright (c) 2011-2020 Microsoft Corp Copyright (c) 2015-2017, Wojciech Mula Copyright (c) 2015-2018, Wojciech Mula -Copyright (c) 2021 csFastFloat authors Copyright (c) 2005-2007, Nick Galbreath Copyright (c) 2015 The Chromium Authors Copyright (c) 2018 Alexander Chermyanin Copyright (c) The Internet Society 1997 -Portions (c) International Organization Copyright (c) 2004-2006 Intel Corporation Copyright (c) 2011-2015 Intel Corporation Copyright (c) 2013-2017, Milosz Krajewski @@ -1884,7 +1903,8 @@ Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com) Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc. -Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers +Portions (c) International Organization for Standardization 1986 +Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip Copyright (c) 1980, 1986, 1993 The Regents of the University of California Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California @@ -1972,19 +1992,22 @@ SOFTWARE. --------------------------------------------------------- -runtime.native.System.IO.Ports 8.0.0 - MIT +runtime.native.System.IO.Ports 9.0.0 - MIT +Copyright (c) 2021 Copyright (c) Six Labors (c) Microsoft Corporation +Copyright (c) 2022 FormatJS Copyright (c) Andrew Arnott Copyright 2019 LLVM Project +Copyright (c) 1998 Microsoft Copyright 2018 Daniel Lemire Copyright (c) .NET Foundation Copyright (c) 2011, Google Inc. Copyright (c) 2020 Dan Shechter (c) 1997-2005 Sean Eron Anderson -Copyright (c) 1998 Microsoft. To +Copyright (c) 2015 Andrew Gallant Copyright (c) 2022, Wojciech Mula Copyright (c) 2017 Yoshifumi Kawai Copyright (c) 2022, Geoff Langdale @@ -1994,23 +2017,24 @@ Copyright (c) Microsoft Corporation Copyright (c) 2007 James Newton-King Copyright (c) 1991-2022 Unicode, Inc. Copyright (c) 2013-2017, Alfred Klomp +Copyright (c) 2018 Nemanja Mijailovic Copyright 2012 the V8 project authors Copyright (c) 1999 Lucent Technologies Copyright (c) 2008-2016, Wojciech Mula Copyright (c) 2011-2020 Microsoft Corp Copyright (c) 2015-2017, Wojciech Mula -Copyright (c) 2021 csFastFloat authors +Copyright (c) 2015-2018, Wojciech Mula Copyright (c) 2005-2007, Nick Galbreath Copyright (c) 2015 The Chromium Authors Copyright (c) 2018 Alexander Chermyanin Copyright (c) The Internet Society 1997 -Portions (c) International Organization Copyright (c) 2004-2006 Intel Corporation Copyright (c) 2011-2015 Intel Corporation Copyright (c) 2013-2017, Milosz Krajewski Copyright (c) 2016-2017, Matthieu Darbois Copyright (c) The Internet Society (2003) Copyright (c) .NET Foundation Contributors +(c) 1995-2024 Jean-loup Gailly and Mark Adler Copyright (c) 2020 Mara Bos Copyright (c) .NET Foundation and Contributors Copyright (c) 2012 - present, Victor Zverovich @@ -2018,12 +2042,12 @@ Copyright (c) 2006 Jb Evain (jbevain@gmail.com) Copyright (c) 2008-2020 Advanced Micro Devices, Inc. Copyright (c) 2019 Microsoft Corporation, Daan Leijen Copyright (c) 2011 Novell, Inc (http://www.novell.com) -Copyright (c) 1995-2022 Jean-loup Gailly and Mark Adler Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com) Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc. -Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers +Portions (c) International Organization for Standardization 1986 +Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip Copyright (c) 1980, 1986, 1993 The Regents of the University of California Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California @@ -2058,19 +2082,22 @@ SOFTWARE. --------------------------------------------------------- -runtime.osx-arm64.runtime.native.System.IO.Ports 8.0.0 - MIT +runtime.osx-arm64.runtime.native.System.IO.Ports 9.0.0 - MIT +Copyright (c) 2021 Copyright (c) Six Labors (c) Microsoft Corporation +Copyright (c) 2022 FormatJS Copyright (c) Andrew Arnott Copyright 2019 LLVM Project +Copyright (c) 1998 Microsoft Copyright 2018 Daniel Lemire Copyright (c) .NET Foundation Copyright (c) 2011, Google Inc. Copyright (c) 2020 Dan Shechter (c) 1997-2005 Sean Eron Anderson -Copyright (c) 1998 Microsoft. To +Copyright (c) 2015 Andrew Gallant Copyright (c) 2022, Wojciech Mula Copyright (c) 2017 Yoshifumi Kawai Copyright (c) 2022, Geoff Langdale @@ -2080,23 +2107,24 @@ Copyright (c) Microsoft Corporation Copyright (c) 2007 James Newton-King Copyright (c) 1991-2022 Unicode, Inc. Copyright (c) 2013-2017, Alfred Klomp +Copyright (c) 2018 Nemanja Mijailovic Copyright 2012 the V8 project authors Copyright (c) 1999 Lucent Technologies Copyright (c) 2008-2016, Wojciech Mula Copyright (c) 2011-2020 Microsoft Corp Copyright (c) 2015-2017, Wojciech Mula -Copyright (c) 2021 csFastFloat authors +Copyright (c) 2015-2018, Wojciech Mula Copyright (c) 2005-2007, Nick Galbreath Copyright (c) 2015 The Chromium Authors Copyright (c) 2018 Alexander Chermyanin Copyright (c) The Internet Society 1997 -Portions (c) International Organization Copyright (c) 2004-2006 Intel Corporation Copyright (c) 2011-2015 Intel Corporation Copyright (c) 2013-2017, Milosz Krajewski Copyright (c) 2016-2017, Matthieu Darbois Copyright (c) The Internet Society (2003) Copyright (c) .NET Foundation Contributors +(c) 1995-2024 Jean-loup Gailly and Mark Adler Copyright (c) 2020 Mara Bos Copyright (c) .NET Foundation and Contributors Copyright (c) 2012 - present, Victor Zverovich @@ -2104,12 +2132,12 @@ Copyright (c) 2006 Jb Evain (jbevain@gmail.com) Copyright (c) 2008-2020 Advanced Micro Devices, Inc. Copyright (c) 2019 Microsoft Corporation, Daan Leijen Copyright (c) 2011 Novell, Inc (http://www.novell.com) -Copyright (c) 1995-2022 Jean-loup Gailly and Mark Adler Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com) Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc. -Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers +Portions (c) International Organization for Standardization 1986 +Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip Copyright (c) 1980, 1986, 1993 The Regents of the University of California Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California @@ -2144,19 +2172,22 @@ SOFTWARE. --------------------------------------------------------- -runtime.osx-x64.runtime.native.System.IO.Ports 8.0.0 - MIT +runtime.osx-x64.runtime.native.System.IO.Ports 9.0.0 - MIT +Copyright (c) 2021 Copyright (c) Six Labors (c) Microsoft Corporation +Copyright (c) 2022 FormatJS Copyright (c) Andrew Arnott Copyright 2019 LLVM Project +Copyright (c) 1998 Microsoft Copyright 2018 Daniel Lemire Copyright (c) .NET Foundation Copyright (c) 2011, Google Inc. Copyright (c) 2020 Dan Shechter (c) 1997-2005 Sean Eron Anderson -Copyright (c) 1998 Microsoft. To +Copyright (c) 2015 Andrew Gallant Copyright (c) 2022, Wojciech Mula Copyright (c) 2017 Yoshifumi Kawai Copyright (c) 2022, Geoff Langdale @@ -2166,23 +2197,24 @@ Copyright (c) Microsoft Corporation Copyright (c) 2007 James Newton-King Copyright (c) 1991-2022 Unicode, Inc. Copyright (c) 2013-2017, Alfred Klomp +Copyright (c) 2018 Nemanja Mijailovic Copyright 2012 the V8 project authors Copyright (c) 1999 Lucent Technologies Copyright (c) 2008-2016, Wojciech Mula Copyright (c) 2011-2020 Microsoft Corp Copyright (c) 2015-2017, Wojciech Mula -Copyright (c) 2021 csFastFloat authors +Copyright (c) 2015-2018, Wojciech Mula Copyright (c) 2005-2007, Nick Galbreath Copyright (c) 2015 The Chromium Authors Copyright (c) 2018 Alexander Chermyanin Copyright (c) The Internet Society 1997 -Portions (c) International Organization Copyright (c) 2004-2006 Intel Corporation Copyright (c) 2011-2015 Intel Corporation Copyright (c) 2013-2017, Milosz Krajewski Copyright (c) 2016-2017, Matthieu Darbois Copyright (c) The Internet Society (2003) Copyright (c) .NET Foundation Contributors +(c) 1995-2024 Jean-loup Gailly and Mark Adler Copyright (c) 2020 Mara Bos Copyright (c) .NET Foundation and Contributors Copyright (c) 2012 - present, Victor Zverovich @@ -2190,12 +2222,12 @@ Copyright (c) 2006 Jb Evain (jbevain@gmail.com) Copyright (c) 2008-2020 Advanced Micro Devices, Inc. Copyright (c) 2019 Microsoft Corporation, Daan Leijen Copyright (c) 2011 Novell, Inc (http://www.novell.com) -Copyright (c) 1995-2022 Jean-loup Gailly and Mark Adler Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com) Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc. -Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers +Portions (c) International Organization for Standardization 1986 +Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip Copyright (c) 1980, 1986, 1993 The Regents of the University of California Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California @@ -2230,19 +2262,22 @@ SOFTWARE. --------------------------------------------------------- -System.CodeDom 8.0.0 - MIT +System.CodeDom 9.0.0 - MIT +Copyright (c) 2021 Copyright (c) Six Labors (c) Microsoft Corporation +Copyright (c) 2022 FormatJS Copyright (c) Andrew Arnott Copyright 2019 LLVM Project +Copyright (c) 1998 Microsoft Copyright 2018 Daniel Lemire Copyright (c) .NET Foundation Copyright (c) 2011, Google Inc. Copyright (c) 2020 Dan Shechter (c) 1997-2005 Sean Eron Anderson -Copyright (c) 1998 Microsoft. To +Copyright (c) 2015 Andrew Gallant Copyright (c) 2022, Wojciech Mula Copyright (c) 2017 Yoshifumi Kawai Copyright (c) 2022, Geoff Langdale @@ -2252,23 +2287,24 @@ Copyright (c) Microsoft Corporation Copyright (c) 2007 James Newton-King Copyright (c) 1991-2022 Unicode, Inc. Copyright (c) 2013-2017, Alfred Klomp +Copyright (c) 2018 Nemanja Mijailovic Copyright 2012 the V8 project authors Copyright (c) 1999 Lucent Technologies Copyright (c) 2008-2016, Wojciech Mula Copyright (c) 2011-2020 Microsoft Corp Copyright (c) 2015-2017, Wojciech Mula -Copyright (c) 2021 csFastFloat authors +Copyright (c) 2015-2018, Wojciech Mula Copyright (c) 2005-2007, Nick Galbreath Copyright (c) 2015 The Chromium Authors Copyright (c) 2018 Alexander Chermyanin Copyright (c) The Internet Society 1997 -Portions (c) International Organization Copyright (c) 2004-2006 Intel Corporation Copyright (c) 2011-2015 Intel Corporation Copyright (c) 2013-2017, Milosz Krajewski Copyright (c) 2016-2017, Matthieu Darbois Copyright (c) The Internet Society (2003) Copyright (c) .NET Foundation Contributors +(c) 1995-2024 Jean-loup Gailly and Mark Adler Copyright (c) 2020 Mara Bos Copyright (c) .NET Foundation and Contributors Copyright (c) 2012 - present, Victor Zverovich @@ -2276,12 +2312,12 @@ Copyright (c) 2006 Jb Evain (jbevain@gmail.com) Copyright (c) 2008-2020 Advanced Micro Devices, Inc. Copyright (c) 2019 Microsoft Corporation, Daan Leijen Copyright (c) 2011 Novell, Inc (http://www.novell.com) -Copyright (c) 1995-2022 Jean-loup Gailly and Mark Adler Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com) Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc. -Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers +Portions (c) International Organization for Standardization 1986 +Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip Copyright (c) 1980, 1986, 1993 The Regents of the University of California Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California @@ -2402,19 +2438,22 @@ SOFTWARE. --------------------------------------------------------- -System.ComponentModel.Composition 8.0.0 - MIT +System.ComponentModel.Composition 9.0.0 - MIT +Copyright (c) 2021 Copyright (c) Six Labors (c) Microsoft Corporation +Copyright (c) 2022 FormatJS Copyright (c) Andrew Arnott Copyright 2019 LLVM Project +Copyright (c) 1998 Microsoft Copyright 2018 Daniel Lemire Copyright (c) .NET Foundation Copyright (c) 2011, Google Inc. Copyright (c) 2020 Dan Shechter (c) 1997-2005 Sean Eron Anderson -Copyright (c) 1998 Microsoft. To +Copyright (c) 2015 Andrew Gallant Copyright (c) 2022, Wojciech Mula Copyright (c) 2017 Yoshifumi Kawai Copyright (c) 2022, Geoff Langdale @@ -2424,23 +2463,24 @@ Copyright (c) Microsoft Corporation Copyright (c) 2007 James Newton-King Copyright (c) 1991-2022 Unicode, Inc. Copyright (c) 2013-2017, Alfred Klomp +Copyright (c) 2018 Nemanja Mijailovic Copyright 2012 the V8 project authors Copyright (c) 1999 Lucent Technologies Copyright (c) 2008-2016, Wojciech Mula Copyright (c) 2011-2020 Microsoft Corp Copyright (c) 2015-2017, Wojciech Mula -Copyright (c) 2021 csFastFloat authors +Copyright (c) 2015-2018, Wojciech Mula Copyright (c) 2005-2007, Nick Galbreath Copyright (c) 2015 The Chromium Authors Copyright (c) 2018 Alexander Chermyanin Copyright (c) The Internet Society 1997 -Portions (c) International Organization Copyright (c) 2004-2006 Intel Corporation Copyright (c) 2011-2015 Intel Corporation Copyright (c) 2013-2017, Milosz Krajewski Copyright (c) 2016-2017, Matthieu Darbois Copyright (c) The Internet Society (2003) Copyright (c) .NET Foundation Contributors +(c) 1995-2024 Jean-loup Gailly and Mark Adler Copyright (c) 2020 Mara Bos Copyright (c) .NET Foundation and Contributors Copyright (c) 2012 - present, Victor Zverovich @@ -2448,12 +2488,12 @@ Copyright (c) 2006 Jb Evain (jbevain@gmail.com) Copyright (c) 2008-2020 Advanced Micro Devices, Inc. Copyright (c) 2019 Microsoft Corporation, Daan Leijen Copyright (c) 2011 Novell, Inc (http://www.novell.com) -Copyright (c) 1995-2022 Jean-loup Gailly and Mark Adler Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com) Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc. -Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers +Portions (c) International Organization for Standardization 1986 +Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip Copyright (c) 1980, 1986, 1993 The Regents of the University of California Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California @@ -2488,19 +2528,22 @@ SOFTWARE. --------------------------------------------------------- -System.ComponentModel.Composition.Registration 8.0.0 - MIT +System.ComponentModel.Composition.Registration 9.0.0 - MIT +Copyright (c) 2021 Copyright (c) Six Labors (c) Microsoft Corporation +Copyright (c) 2022 FormatJS Copyright (c) Andrew Arnott Copyright 2019 LLVM Project +Copyright (c) 1998 Microsoft Copyright 2018 Daniel Lemire Copyright (c) .NET Foundation Copyright (c) 2011, Google Inc. Copyright (c) 2020 Dan Shechter (c) 1997-2005 Sean Eron Anderson -Copyright (c) 1998 Microsoft. To +Copyright (c) 2015 Andrew Gallant Copyright (c) 2022, Wojciech Mula Copyright (c) 2017 Yoshifumi Kawai Copyright (c) 2022, Geoff Langdale @@ -2510,23 +2553,24 @@ Copyright (c) Microsoft Corporation Copyright (c) 2007 James Newton-King Copyright (c) 1991-2022 Unicode, Inc. Copyright (c) 2013-2017, Alfred Klomp +Copyright (c) 2018 Nemanja Mijailovic Copyright 2012 the V8 project authors Copyright (c) 1999 Lucent Technologies Copyright (c) 2008-2016, Wojciech Mula Copyright (c) 2011-2020 Microsoft Corp Copyright (c) 2015-2017, Wojciech Mula -Copyright (c) 2021 csFastFloat authors +Copyright (c) 2015-2018, Wojciech Mula Copyright (c) 2005-2007, Nick Galbreath Copyright (c) 2015 The Chromium Authors Copyright (c) 2018 Alexander Chermyanin Copyright (c) The Internet Society 1997 -Portions (c) International Organization Copyright (c) 2004-2006 Intel Corporation Copyright (c) 2011-2015 Intel Corporation Copyright (c) 2013-2017, Milosz Krajewski Copyright (c) 2016-2017, Matthieu Darbois Copyright (c) The Internet Society (2003) Copyright (c) .NET Foundation Contributors +(c) 1995-2024 Jean-loup Gailly and Mark Adler Copyright (c) 2020 Mara Bos Copyright (c) .NET Foundation and Contributors Copyright (c) 2012 - present, Victor Zverovich @@ -2534,12 +2578,12 @@ Copyright (c) 2006 Jb Evain (jbevain@gmail.com) Copyright (c) 2008-2020 Advanced Micro Devices, Inc. Copyright (c) 2019 Microsoft Corporation, Daan Leijen Copyright (c) 2011 Novell, Inc (http://www.novell.com) -Copyright (c) 1995-2022 Jean-loup Gailly and Mark Adler Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com) Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc. -Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers +Portions (c) International Organization for Standardization 1986 +Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip Copyright (c) 1980, 1986, 1993 The Regents of the University of California Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California @@ -2574,19 +2618,22 @@ SOFTWARE. --------------------------------------------------------- -System.Configuration.ConfigurationManager 8.0.1 - MIT +System.Configuration.ConfigurationManager 9.0.0 - MIT +Copyright (c) 2021 Copyright (c) Six Labors (c) Microsoft Corporation +Copyright (c) 2022 FormatJS Copyright (c) Andrew Arnott Copyright 2019 LLVM Project +Copyright (c) 1998 Microsoft Copyright 2018 Daniel Lemire Copyright (c) .NET Foundation Copyright (c) 2011, Google Inc. Copyright (c) 2020 Dan Shechter (c) 1997-2005 Sean Eron Anderson -Copyright (c) 1998 Microsoft. To +Copyright (c) 2015 Andrew Gallant Copyright (c) 2022, Wojciech Mula Copyright (c) 2017 Yoshifumi Kawai Copyright (c) 2022, Geoff Langdale @@ -2596,23 +2643,24 @@ Copyright (c) Microsoft Corporation Copyright (c) 2007 James Newton-King Copyright (c) 1991-2022 Unicode, Inc. Copyright (c) 2013-2017, Alfred Klomp +Copyright (c) 2018 Nemanja Mijailovic Copyright 2012 the V8 project authors Copyright (c) 1999 Lucent Technologies Copyright (c) 2008-2016, Wojciech Mula Copyright (c) 2011-2020 Microsoft Corp Copyright (c) 2015-2017, Wojciech Mula -Copyright (c) 2021 csFastFloat authors +Copyright (c) 2015-2018, Wojciech Mula Copyright (c) 2005-2007, Nick Galbreath Copyright (c) 2015 The Chromium Authors Copyright (c) 2018 Alexander Chermyanin Copyright (c) The Internet Society 1997 -Portions (c) International Organization Copyright (c) 2004-2006 Intel Corporation Copyright (c) 2011-2015 Intel Corporation Copyright (c) 2013-2017, Milosz Krajewski Copyright (c) 2016-2017, Matthieu Darbois Copyright (c) The Internet Society (2003) Copyright (c) .NET Foundation Contributors +(c) 1995-2024 Jean-loup Gailly and Mark Adler Copyright (c) 2020 Mara Bos Copyright (c) .NET Foundation and Contributors Copyright (c) 2012 - present, Victor Zverovich @@ -2620,12 +2668,12 @@ Copyright (c) 2006 Jb Evain (jbevain@gmail.com) Copyright (c) 2008-2020 Advanced Micro Devices, Inc. Copyright (c) 2019 Microsoft Corporation, Daan Leijen Copyright (c) 2011 Novell, Inc (http://www.novell.com) -Copyright (c) 1995-2022 Jean-loup Gailly and Mark Adler Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com) Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc. -Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers +Portions (c) International Organization for Standardization 1986 +Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip Copyright (c) 1980, 1986, 1993 The Regents of the University of California Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California @@ -2660,19 +2708,22 @@ SOFTWARE. --------------------------------------------------------- -System.Data.Odbc 8.0.1 - MIT +System.Data.Odbc 9.0.0 - MIT +Copyright (c) 2021 Copyright (c) Six Labors (c) Microsoft Corporation +Copyright (c) 2022 FormatJS Copyright (c) Andrew Arnott Copyright 2019 LLVM Project +Copyright (c) 1998 Microsoft Copyright 2018 Daniel Lemire Copyright (c) .NET Foundation Copyright (c) 2011, Google Inc. Copyright (c) 2020 Dan Shechter (c) 1997-2005 Sean Eron Anderson -Copyright (c) 1998 Microsoft. To +Copyright (c) 2015 Andrew Gallant Copyright (c) 2022, Wojciech Mula Copyright (c) 2017 Yoshifumi Kawai Copyright (c) 2022, Geoff Langdale @@ -2682,23 +2733,24 @@ Copyright (c) Microsoft Corporation Copyright (c) 2007 James Newton-King Copyright (c) 1991-2022 Unicode, Inc. Copyright (c) 2013-2017, Alfred Klomp +Copyright (c) 2018 Nemanja Mijailovic Copyright 2012 the V8 project authors Copyright (c) 1999 Lucent Technologies Copyright (c) 2008-2016, Wojciech Mula Copyright (c) 2011-2020 Microsoft Corp Copyright (c) 2015-2017, Wojciech Mula -Copyright (c) 2021 csFastFloat authors +Copyright (c) 2015-2018, Wojciech Mula Copyright (c) 2005-2007, Nick Galbreath Copyright (c) 2015 The Chromium Authors Copyright (c) 2018 Alexander Chermyanin Copyright (c) The Internet Society 1997 -Portions (c) International Organization Copyright (c) 2004-2006 Intel Corporation Copyright (c) 2011-2015 Intel Corporation Copyright (c) 2013-2017, Milosz Krajewski Copyright (c) 2016-2017, Matthieu Darbois Copyright (c) The Internet Society (2003) Copyright (c) .NET Foundation Contributors +(c) 1995-2024 Jean-loup Gailly and Mark Adler Copyright (c) 2020 Mara Bos Copyright (c) .NET Foundation and Contributors Copyright (c) 2012 - present, Victor Zverovich @@ -2706,12 +2758,12 @@ Copyright (c) 2006 Jb Evain (jbevain@gmail.com) Copyright (c) 2008-2020 Advanced Micro Devices, Inc. Copyright (c) 2019 Microsoft Corporation, Daan Leijen Copyright (c) 2011 Novell, Inc (http://www.novell.com) -Copyright (c) 1995-2022 Jean-loup Gailly and Mark Adler Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com) Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc. -Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers +Portions (c) International Organization for Standardization 1986 +Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip Copyright (c) 1980, 1986, 1993 The Regents of the University of California Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California @@ -2746,19 +2798,22 @@ SOFTWARE. --------------------------------------------------------- -System.Data.OleDb 8.0.1 - MIT +System.Data.OleDb 9.0.0 - MIT +Copyright (c) 2021 Copyright (c) Six Labors (c) Microsoft Corporation +Copyright (c) 2022 FormatJS Copyright (c) Andrew Arnott Copyright 2019 LLVM Project +Copyright (c) 1998 Microsoft Copyright 2018 Daniel Lemire Copyright (c) .NET Foundation Copyright (c) 2011, Google Inc. Copyright (c) 2020 Dan Shechter (c) 1997-2005 Sean Eron Anderson -Copyright (c) 1998 Microsoft. To +Copyright (c) 2015 Andrew Gallant Copyright (c) 2022, Wojciech Mula Copyright (c) 2017 Yoshifumi Kawai Copyright (c) 2022, Geoff Langdale @@ -2768,23 +2823,24 @@ Copyright (c) Microsoft Corporation Copyright (c) 2007 James Newton-King Copyright (c) 1991-2022 Unicode, Inc. Copyright (c) 2013-2017, Alfred Klomp +Copyright (c) 2018 Nemanja Mijailovic Copyright 2012 the V8 project authors Copyright (c) 1999 Lucent Technologies Copyright (c) 2008-2016, Wojciech Mula Copyright (c) 2011-2020 Microsoft Corp Copyright (c) 2015-2017, Wojciech Mula -Copyright (c) 2021 csFastFloat authors +Copyright (c) 2015-2018, Wojciech Mula Copyright (c) 2005-2007, Nick Galbreath Copyright (c) 2015 The Chromium Authors Copyright (c) 2018 Alexander Chermyanin Copyright (c) The Internet Society 1997 -Portions (c) International Organization Copyright (c) 2004-2006 Intel Corporation Copyright (c) 2011-2015 Intel Corporation Copyright (c) 2013-2017, Milosz Krajewski Copyright (c) 2016-2017, Matthieu Darbois Copyright (c) The Internet Society (2003) Copyright (c) .NET Foundation Contributors +(c) 1995-2024 Jean-loup Gailly and Mark Adler Copyright (c) 2020 Mara Bos Copyright (c) .NET Foundation and Contributors Copyright (c) 2012 - present, Victor Zverovich @@ -2792,12 +2848,12 @@ Copyright (c) 2006 Jb Evain (jbevain@gmail.com) Copyright (c) 2008-2020 Advanced Micro Devices, Inc. Copyright (c) 2019 Microsoft Corporation, Daan Leijen Copyright (c) 2011 Novell, Inc (http://www.novell.com) -Copyright (c) 1995-2022 Jean-loup Gailly and Mark Adler Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com) Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc. -Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers +Portions (c) International Organization for Standardization 1986 +Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip Copyright (c) 1980, 1986, 1993 The Regents of the University of California Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California @@ -2885,62 +2941,9 @@ SOFTWARE. --------------------------------------------------------- -System.Diagnostics.DiagnosticSource 8.0.1 - MIT +System.Diagnostics.DiagnosticSource 9.0.0 - MIT -Copyright (c) Six Labors -(c) Microsoft Corporation -Copyright (c) Andrew Arnott -Copyright 2019 LLVM Project -Copyright 2018 Daniel Lemire -Copyright (c) .NET Foundation -Copyright (c) 2011, Google Inc. -Copyright (c) 2020 Dan Shechter -(c) 1997-2005 Sean Eron Anderson -Copyright (c) 1998 Microsoft. To -Copyright (c) 2022, Wojciech Mula -Copyright (c) 2017 Yoshifumi Kawai -Copyright (c) 2022, Geoff Langdale -Copyright (c) 2005-2020 Rich Felker -Copyright (c) 2012-2021 Yann Collet -Copyright (c) Microsoft Corporation -Copyright (c) 2007 James Newton-King -Copyright (c) 1991-2022 Unicode, Inc. -Copyright (c) 2013-2017, Alfred Klomp -Copyright 2012 the V8 project authors -Copyright (c) 1999 Lucent Technologies -Copyright (c) 2008-2016, Wojciech Mula -Copyright (c) 2011-2020 Microsoft Corp -Copyright (c) 2015-2017, Wojciech Mula -Copyright (c) 2021 csFastFloat authors -Copyright (c) 2005-2007, Nick Galbreath -Copyright (c) 2015 The Chromium Authors -Copyright (c) 2018 Alexander Chermyanin -Copyright (c) The Internet Society 1997 -Portions (c) International Organization -Copyright (c) 2004-2006 Intel Corporation -Copyright (c) 2011-2015 Intel Corporation -Copyright (c) 2013-2017, Milosz Krajewski -Copyright (c) 2016-2017, Matthieu Darbois -Copyright (c) The Internet Society (2003) -Copyright (c) .NET Foundation Contributors -Copyright (c) 2020 Mara Bos -Copyright (c) .NET Foundation and Contributors -Copyright (c) 2012 - present, Victor Zverovich -Copyright (c) 2006 Jb Evain (jbevain@gmail.com) -Copyright (c) 2008-2020 Advanced Micro Devices, Inc. -Copyright (c) 2019 Microsoft Corporation, Daan Leijen -Copyright (c) 2011 Novell, Inc (http://www.novell.com) -Copyright (c) 1995-2022 Jean-loup Gailly and Mark Adler -Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com) -Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors -Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com -Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc. -Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers -Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip -Copyright (c) 1980, 1986, 1993 The Regents of the University of California -Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California -Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass The MIT License (MIT) @@ -2971,19 +2974,22 @@ SOFTWARE. --------------------------------------------------------- -System.Diagnostics.EventLog 8.0.1 - MIT +System.Diagnostics.EventLog 9.0.0 - MIT +Copyright (c) 2021 Copyright (c) Six Labors (c) Microsoft Corporation +Copyright (c) 2022 FormatJS Copyright (c) Andrew Arnott Copyright 2019 LLVM Project +Copyright (c) 1998 Microsoft Copyright 2018 Daniel Lemire Copyright (c) .NET Foundation Copyright (c) 2011, Google Inc. Copyright (c) 2020 Dan Shechter (c) 1997-2005 Sean Eron Anderson -Copyright (c) 1998 Microsoft. To +Copyright (c) 2015 Andrew Gallant Copyright (c) 2022, Wojciech Mula Copyright (c) 2017 Yoshifumi Kawai Copyright (c) 2022, Geoff Langdale @@ -2993,23 +2999,24 @@ Copyright (c) Microsoft Corporation Copyright (c) 2007 James Newton-King Copyright (c) 1991-2022 Unicode, Inc. Copyright (c) 2013-2017, Alfred Klomp +Copyright (c) 2018 Nemanja Mijailovic Copyright 2012 the V8 project authors Copyright (c) 1999 Lucent Technologies Copyright (c) 2008-2016, Wojciech Mula Copyright (c) 2011-2020 Microsoft Corp Copyright (c) 2015-2017, Wojciech Mula -Copyright (c) 2021 csFastFloat authors +Copyright (c) 2015-2018, Wojciech Mula Copyright (c) 2005-2007, Nick Galbreath Copyright (c) 2015 The Chromium Authors Copyright (c) 2018 Alexander Chermyanin Copyright (c) The Internet Society 1997 -Portions (c) International Organization Copyright (c) 2004-2006 Intel Corporation Copyright (c) 2011-2015 Intel Corporation Copyright (c) 2013-2017, Milosz Krajewski Copyright (c) 2016-2017, Matthieu Darbois Copyright (c) The Internet Society (2003) Copyright (c) .NET Foundation Contributors +(c) 1995-2024 Jean-loup Gailly and Mark Adler Copyright (c) 2020 Mara Bos Copyright (c) .NET Foundation and Contributors Copyright (c) 2012 - present, Victor Zverovich @@ -3017,12 +3024,12 @@ Copyright (c) 2006 Jb Evain (jbevain@gmail.com) Copyright (c) 2008-2020 Advanced Micro Devices, Inc. Copyright (c) 2019 Microsoft Corporation, Daan Leijen Copyright (c) 2011 Novell, Inc (http://www.novell.com) -Copyright (c) 1995-2022 Jean-loup Gailly and Mark Adler Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com) Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc. -Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers +Portions (c) International Organization for Standardization 1986 +Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip Copyright (c) 1980, 1986, 1993 The Regents of the University of California Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California @@ -3057,19 +3064,22 @@ SOFTWARE. --------------------------------------------------------- -System.Diagnostics.PerformanceCounter 8.0.1 - MIT +System.Diagnostics.PerformanceCounter 9.0.0 - MIT +Copyright (c) 2021 Copyright (c) Six Labors (c) Microsoft Corporation +Copyright (c) 2022 FormatJS Copyright (c) Andrew Arnott Copyright 2019 LLVM Project +Copyright (c) 1998 Microsoft Copyright 2018 Daniel Lemire Copyright (c) .NET Foundation Copyright (c) 2011, Google Inc. Copyright (c) 2020 Dan Shechter (c) 1997-2005 Sean Eron Anderson -Copyright (c) 1998 Microsoft. To +Copyright (c) 2015 Andrew Gallant Copyright (c) 2022, Wojciech Mula Copyright (c) 2017 Yoshifumi Kawai Copyright (c) 2022, Geoff Langdale @@ -3079,23 +3089,24 @@ Copyright (c) Microsoft Corporation Copyright (c) 2007 James Newton-King Copyright (c) 1991-2022 Unicode, Inc. Copyright (c) 2013-2017, Alfred Klomp +Copyright (c) 2018 Nemanja Mijailovic Copyright 2012 the V8 project authors Copyright (c) 1999 Lucent Technologies Copyright (c) 2008-2016, Wojciech Mula Copyright (c) 2011-2020 Microsoft Corp Copyright (c) 2015-2017, Wojciech Mula -Copyright (c) 2021 csFastFloat authors +Copyright (c) 2015-2018, Wojciech Mula Copyright (c) 2005-2007, Nick Galbreath Copyright (c) 2015 The Chromium Authors Copyright (c) 2018 Alexander Chermyanin Copyright (c) The Internet Society 1997 -Portions (c) International Organization Copyright (c) 2004-2006 Intel Corporation Copyright (c) 2011-2015 Intel Corporation Copyright (c) 2013-2017, Milosz Krajewski Copyright (c) 2016-2017, Matthieu Darbois Copyright (c) The Internet Society (2003) Copyright (c) .NET Foundation Contributors +(c) 1995-2024 Jean-loup Gailly and Mark Adler Copyright (c) 2020 Mara Bos Copyright (c) .NET Foundation and Contributors Copyright (c) 2012 - present, Victor Zverovich @@ -3103,12 +3114,12 @@ Copyright (c) 2006 Jb Evain (jbevain@gmail.com) Copyright (c) 2008-2020 Advanced Micro Devices, Inc. Copyright (c) 2019 Microsoft Corporation, Daan Leijen Copyright (c) 2011 Novell, Inc (http://www.novell.com) -Copyright (c) 1995-2022 Jean-loup Gailly and Mark Adler Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com) Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc. -Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers +Portions (c) International Organization for Standardization 1986 +Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip Copyright (c) 1980, 1986, 1993 The Regents of the University of California Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California @@ -3143,19 +3154,22 @@ SOFTWARE. --------------------------------------------------------- -System.DirectoryServices 8.0.0 - MIT +System.DirectoryServices 9.0.0 - MIT +Copyright (c) 2021 Copyright (c) Six Labors (c) Microsoft Corporation +Copyright (c) 2022 FormatJS Copyright (c) Andrew Arnott Copyright 2019 LLVM Project +Copyright (c) 1998 Microsoft Copyright 2018 Daniel Lemire Copyright (c) .NET Foundation Copyright (c) 2011, Google Inc. Copyright (c) 2020 Dan Shechter (c) 1997-2005 Sean Eron Anderson -Copyright (c) 1998 Microsoft. To +Copyright (c) 2015 Andrew Gallant Copyright (c) 2022, Wojciech Mula Copyright (c) 2017 Yoshifumi Kawai Copyright (c) 2022, Geoff Langdale @@ -3165,23 +3179,24 @@ Copyright (c) Microsoft Corporation Copyright (c) 2007 James Newton-King Copyright (c) 1991-2022 Unicode, Inc. Copyright (c) 2013-2017, Alfred Klomp +Copyright (c) 2018 Nemanja Mijailovic Copyright 2012 the V8 project authors Copyright (c) 1999 Lucent Technologies Copyright (c) 2008-2016, Wojciech Mula Copyright (c) 2011-2020 Microsoft Corp Copyright (c) 2015-2017, Wojciech Mula -Copyright (c) 2021 csFastFloat authors +Copyright (c) 2015-2018, Wojciech Mula Copyright (c) 2005-2007, Nick Galbreath Copyright (c) 2015 The Chromium Authors Copyright (c) 2018 Alexander Chermyanin Copyright (c) The Internet Society 1997 -Portions (c) International Organization Copyright (c) 2004-2006 Intel Corporation Copyright (c) 2011-2015 Intel Corporation Copyright (c) 2013-2017, Milosz Krajewski Copyright (c) 2016-2017, Matthieu Darbois Copyright (c) The Internet Society (2003) Copyright (c) .NET Foundation Contributors +(c) 1995-2024 Jean-loup Gailly and Mark Adler Copyright (c) 2020 Mara Bos Copyright (c) .NET Foundation and Contributors Copyright (c) 2012 - present, Victor Zverovich @@ -3189,12 +3204,12 @@ Copyright (c) 2006 Jb Evain (jbevain@gmail.com) Copyright (c) 2008-2020 Advanced Micro Devices, Inc. Copyright (c) 2019 Microsoft Corporation, Daan Leijen Copyright (c) 2011 Novell, Inc (http://www.novell.com) -Copyright (c) 1995-2022 Jean-loup Gailly and Mark Adler Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com) Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc. -Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers +Portions (c) International Organization for Standardization 1986 +Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip Copyright (c) 1980, 1986, 1993 The Regents of the University of California Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California @@ -3229,19 +3244,22 @@ SOFTWARE. --------------------------------------------------------- -System.DirectoryServices.AccountManagement 8.0.1 - MIT +System.DirectoryServices.AccountManagement 9.0.0 - MIT +Copyright (c) 2021 Copyright (c) Six Labors (c) Microsoft Corporation +Copyright (c) 2022 FormatJS Copyright (c) Andrew Arnott Copyright 2019 LLVM Project +Copyright (c) 1998 Microsoft Copyright 2018 Daniel Lemire Copyright (c) .NET Foundation Copyright (c) 2011, Google Inc. Copyright (c) 2020 Dan Shechter (c) 1997-2005 Sean Eron Anderson -Copyright (c) 1998 Microsoft. To +Copyright (c) 2015 Andrew Gallant Copyright (c) 2022, Wojciech Mula Copyright (c) 2017 Yoshifumi Kawai Copyright (c) 2022, Geoff Langdale @@ -3251,23 +3269,24 @@ Copyright (c) Microsoft Corporation Copyright (c) 2007 James Newton-King Copyright (c) 1991-2022 Unicode, Inc. Copyright (c) 2013-2017, Alfred Klomp +Copyright (c) 2018 Nemanja Mijailovic Copyright 2012 the V8 project authors Copyright (c) 1999 Lucent Technologies Copyright (c) 2008-2016, Wojciech Mula Copyright (c) 2011-2020 Microsoft Corp Copyright (c) 2015-2017, Wojciech Mula -Copyright (c) 2021 csFastFloat authors +Copyright (c) 2015-2018, Wojciech Mula Copyright (c) 2005-2007, Nick Galbreath Copyright (c) 2015 The Chromium Authors Copyright (c) 2018 Alexander Chermyanin Copyright (c) The Internet Society 1997 -Portions (c) International Organization Copyright (c) 2004-2006 Intel Corporation Copyright (c) 2011-2015 Intel Corporation Copyright (c) 2013-2017, Milosz Krajewski Copyright (c) 2016-2017, Matthieu Darbois Copyright (c) The Internet Society (2003) Copyright (c) .NET Foundation Contributors +(c) 1995-2024 Jean-loup Gailly and Mark Adler Copyright (c) 2020 Mara Bos Copyright (c) .NET Foundation and Contributors Copyright (c) 2012 - present, Victor Zverovich @@ -3275,12 +3294,12 @@ Copyright (c) 2006 Jb Evain (jbevain@gmail.com) Copyright (c) 2008-2020 Advanced Micro Devices, Inc. Copyright (c) 2019 Microsoft Corporation, Daan Leijen Copyright (c) 2011 Novell, Inc (http://www.novell.com) -Copyright (c) 1995-2022 Jean-loup Gailly and Mark Adler Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com) Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc. -Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers +Portions (c) International Organization for Standardization 1986 +Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip Copyright (c) 1980, 1986, 1993 The Regents of the University of California Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California @@ -3315,19 +3334,22 @@ SOFTWARE. --------------------------------------------------------- -System.DirectoryServices.Protocols 8.0.0 - MIT +System.DirectoryServices.Protocols 9.0.0 - MIT +Copyright (c) 2021 Copyright (c) Six Labors (c) Microsoft Corporation +Copyright (c) 2022 FormatJS Copyright (c) Andrew Arnott Copyright 2019 LLVM Project +Copyright (c) 1998 Microsoft Copyright 2018 Daniel Lemire Copyright (c) .NET Foundation Copyright (c) 2011, Google Inc. Copyright (c) 2020 Dan Shechter (c) 1997-2005 Sean Eron Anderson -Copyright (c) 1998 Microsoft. To +Copyright (c) 2015 Andrew Gallant Copyright (c) 2022, Wojciech Mula Copyright (c) 2017 Yoshifumi Kawai Copyright (c) 2022, Geoff Langdale @@ -3337,23 +3359,24 @@ Copyright (c) Microsoft Corporation Copyright (c) 2007 James Newton-King Copyright (c) 1991-2022 Unicode, Inc. Copyright (c) 2013-2017, Alfred Klomp +Copyright (c) 2018 Nemanja Mijailovic Copyright 2012 the V8 project authors Copyright (c) 1999 Lucent Technologies Copyright (c) 2008-2016, Wojciech Mula Copyright (c) 2011-2020 Microsoft Corp Copyright (c) 2015-2017, Wojciech Mula -Copyright (c) 2021 csFastFloat authors +Copyright (c) 2015-2018, Wojciech Mula Copyright (c) 2005-2007, Nick Galbreath Copyright (c) 2015 The Chromium Authors Copyright (c) 2018 Alexander Chermyanin Copyright (c) The Internet Society 1997 -Portions (c) International Organization Copyright (c) 2004-2006 Intel Corporation Copyright (c) 2011-2015 Intel Corporation Copyright (c) 2013-2017, Milosz Krajewski Copyright (c) 2016-2017, Matthieu Darbois Copyright (c) The Internet Society (2003) Copyright (c) .NET Foundation Contributors +(c) 1995-2024 Jean-loup Gailly and Mark Adler Copyright (c) 2020 Mara Bos Copyright (c) .NET Foundation and Contributors Copyright (c) 2012 - present, Victor Zverovich @@ -3361,12 +3384,12 @@ Copyright (c) 2006 Jb Evain (jbevain@gmail.com) Copyright (c) 2008-2020 Advanced Micro Devices, Inc. Copyright (c) 2019 Microsoft Corporation, Daan Leijen Copyright (c) 2011 Novell, Inc (http://www.novell.com) -Copyright (c) 1995-2022 Jean-loup Gailly and Mark Adler Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com) Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc. -Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers +Portions (c) International Organization for Standardization 1986 +Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip Copyright (c) 1980, 1986, 1993 The Regents of the University of California Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California @@ -3401,7 +3424,7 @@ SOFTWARE. --------------------------------------------------------- -System.Drawing.Common 8.0.10 - MIT +System.Drawing.Common 9.0.0 - MIT (c) Microsoft Corporation @@ -3436,19 +3459,22 @@ SOFTWARE. --------------------------------------------------------- -System.IO.Packaging 8.0.1 - MIT +System.IO.Packaging 9.0.0 - MIT +Copyright (c) 2021 Copyright (c) Six Labors (c) Microsoft Corporation +Copyright (c) 2022 FormatJS Copyright (c) Andrew Arnott Copyright 2019 LLVM Project +Copyright (c) 1998 Microsoft Copyright 2018 Daniel Lemire Copyright (c) .NET Foundation Copyright (c) 2011, Google Inc. Copyright (c) 2020 Dan Shechter (c) 1997-2005 Sean Eron Anderson -Copyright (c) 1998 Microsoft. To +Copyright (c) 2015 Andrew Gallant Copyright (c) 2022, Wojciech Mula Copyright (c) 2017 Yoshifumi Kawai Copyright (c) 2022, Geoff Langdale @@ -3458,23 +3484,24 @@ Copyright (c) Microsoft Corporation Copyright (c) 2007 James Newton-King Copyright (c) 1991-2022 Unicode, Inc. Copyright (c) 2013-2017, Alfred Klomp +Copyright (c) 2018 Nemanja Mijailovic Copyright 2012 the V8 project authors Copyright (c) 1999 Lucent Technologies Copyright (c) 2008-2016, Wojciech Mula Copyright (c) 2011-2020 Microsoft Corp Copyright (c) 2015-2017, Wojciech Mula -Copyright (c) 2021 csFastFloat authors +Copyright (c) 2015-2018, Wojciech Mula Copyright (c) 2005-2007, Nick Galbreath Copyright (c) 2015 The Chromium Authors Copyright (c) 2018 Alexander Chermyanin Copyright (c) The Internet Society 1997 -Portions (c) International Organization Copyright (c) 2004-2006 Intel Corporation Copyright (c) 2011-2015 Intel Corporation Copyright (c) 2013-2017, Milosz Krajewski Copyright (c) 2016-2017, Matthieu Darbois Copyright (c) The Internet Society (2003) Copyright (c) .NET Foundation Contributors +(c) 1995-2024 Jean-loup Gailly and Mark Adler Copyright (c) 2020 Mara Bos Copyright (c) .NET Foundation and Contributors Copyright (c) 2012 - present, Victor Zverovich @@ -3482,12 +3509,12 @@ Copyright (c) 2006 Jb Evain (jbevain@gmail.com) Copyright (c) 2008-2020 Advanced Micro Devices, Inc. Copyright (c) 2019 Microsoft Corporation, Daan Leijen Copyright (c) 2011 Novell, Inc (http://www.novell.com) -Copyright (c) 1995-2022 Jean-loup Gailly and Mark Adler Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com) Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc. -Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers +Portions (c) International Organization for Standardization 1986 +Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip Copyright (c) 1980, 1986, 1993 The Regents of the University of California Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California @@ -3522,19 +3549,22 @@ SOFTWARE. --------------------------------------------------------- -System.IO.Ports 8.0.0 - MIT +System.IO.Ports 9.0.0 - MIT +Copyright (c) 2021 Copyright (c) Six Labors (c) Microsoft Corporation +Copyright (c) 2022 FormatJS Copyright (c) Andrew Arnott Copyright 2019 LLVM Project +Copyright (c) 1998 Microsoft Copyright 2018 Daniel Lemire Copyright (c) .NET Foundation Copyright (c) 2011, Google Inc. Copyright (c) 2020 Dan Shechter (c) 1997-2005 Sean Eron Anderson -Copyright (c) 1998 Microsoft. To +Copyright (c) 2015 Andrew Gallant Copyright (c) 2022, Wojciech Mula Copyright (c) 2017 Yoshifumi Kawai Copyright (c) 2022, Geoff Langdale @@ -3544,23 +3574,24 @@ Copyright (c) Microsoft Corporation Copyright (c) 2007 James Newton-King Copyright (c) 1991-2022 Unicode, Inc. Copyright (c) 2013-2017, Alfred Klomp +Copyright (c) 2018 Nemanja Mijailovic Copyright 2012 the V8 project authors Copyright (c) 1999 Lucent Technologies Copyright (c) 2008-2016, Wojciech Mula Copyright (c) 2011-2020 Microsoft Corp Copyright (c) 2015-2017, Wojciech Mula -Copyright (c) 2021 csFastFloat authors +Copyright (c) 2015-2018, Wojciech Mula Copyright (c) 2005-2007, Nick Galbreath Copyright (c) 2015 The Chromium Authors Copyright (c) 2018 Alexander Chermyanin Copyright (c) The Internet Society 1997 -Portions (c) International Organization Copyright (c) 2004-2006 Intel Corporation Copyright (c) 2011-2015 Intel Corporation Copyright (c) 2013-2017, Milosz Krajewski Copyright (c) 2016-2017, Matthieu Darbois Copyright (c) The Internet Society (2003) Copyright (c) .NET Foundation Contributors +(c) 1995-2024 Jean-loup Gailly and Mark Adler Copyright (c) 2020 Mara Bos Copyright (c) .NET Foundation and Contributors Copyright (c) 2012 - present, Victor Zverovich @@ -3568,12 +3599,12 @@ Copyright (c) 2006 Jb Evain (jbevain@gmail.com) Copyright (c) 2008-2020 Advanced Micro Devices, Inc. Copyright (c) 2019 Microsoft Corporation, Daan Leijen Copyright (c) 2011 Novell, Inc (http://www.novell.com) -Copyright (c) 1995-2022 Jean-loup Gailly and Mark Adler Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com) Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc. -Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers +Portions (c) International Organization for Standardization 1986 +Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip Copyright (c) 1980, 1986, 1993 The Regents of the University of California Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California @@ -3608,19 +3639,22 @@ SOFTWARE. --------------------------------------------------------- -System.Management 8.0.0 - MIT +System.Management 9.0.0 - MIT +Copyright (c) 2021 Copyright (c) Six Labors (c) Microsoft Corporation +Copyright (c) 2022 FormatJS Copyright (c) Andrew Arnott Copyright 2019 LLVM Project +Copyright (c) 1998 Microsoft Copyright 2018 Daniel Lemire Copyright (c) .NET Foundation Copyright (c) 2011, Google Inc. Copyright (c) 2020 Dan Shechter (c) 1997-2005 Sean Eron Anderson -Copyright (c) 1998 Microsoft. To +Copyright (c) 2015 Andrew Gallant Copyright (c) 2022, Wojciech Mula Copyright (c) 2017 Yoshifumi Kawai Copyright (c) 2022, Geoff Langdale @@ -3630,23 +3664,24 @@ Copyright (c) Microsoft Corporation Copyright (c) 2007 James Newton-King Copyright (c) 1991-2022 Unicode, Inc. Copyright (c) 2013-2017, Alfred Klomp +Copyright (c) 2018 Nemanja Mijailovic Copyright 2012 the V8 project authors Copyright (c) 1999 Lucent Technologies Copyright (c) 2008-2016, Wojciech Mula Copyright (c) 2011-2020 Microsoft Corp Copyright (c) 2015-2017, Wojciech Mula -Copyright (c) 2021 csFastFloat authors +Copyright (c) 2015-2018, Wojciech Mula Copyright (c) 2005-2007, Nick Galbreath Copyright (c) 2015 The Chromium Authors Copyright (c) 2018 Alexander Chermyanin Copyright (c) The Internet Society 1997 -Portions (c) International Organization Copyright (c) 2004-2006 Intel Corporation Copyright (c) 2011-2015 Intel Corporation Copyright (c) 2013-2017, Milosz Krajewski Copyright (c) 2016-2017, Matthieu Darbois Copyright (c) The Internet Society (2003) Copyright (c) .NET Foundation Contributors +(c) 1995-2024 Jean-loup Gailly and Mark Adler Copyright (c) 2020 Mara Bos Copyright (c) .NET Foundation and Contributors Copyright (c) 2012 - present, Victor Zverovich @@ -3654,12 +3689,12 @@ Copyright (c) 2006 Jb Evain (jbevain@gmail.com) Copyright (c) 2008-2020 Advanced Micro Devices, Inc. Copyright (c) 2019 Microsoft Corporation, Daan Leijen Copyright (c) 2011 Novell, Inc (http://www.novell.com) -Copyright (c) 1995-2022 Jean-loup Gailly and Mark Adler Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com) Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc. -Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers +Portions (c) International Organization for Standardization 1986 +Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip Copyright (c) 1980, 1986, 1993 The Regents of the University of California Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California @@ -3694,19 +3729,22 @@ SOFTWARE. --------------------------------------------------------- -System.Net.Http.WinHttpHandler 8.0.2 - MIT +System.Net.Http.WinHttpHandler 9.0.0 - MIT +Copyright (c) 2021 Copyright (c) Six Labors (c) Microsoft Corporation +Copyright (c) 2022 FormatJS Copyright (c) Andrew Arnott Copyright 2019 LLVM Project +Copyright (c) 1998 Microsoft Copyright 2018 Daniel Lemire Copyright (c) .NET Foundation Copyright (c) 2011, Google Inc. Copyright (c) 2020 Dan Shechter (c) 1997-2005 Sean Eron Anderson -Copyright (c) 1998 Microsoft. To +Copyright (c) 2015 Andrew Gallant Copyright (c) 2022, Wojciech Mula Copyright (c) 2017 Yoshifumi Kawai Copyright (c) 2022, Geoff Langdale @@ -3716,23 +3754,24 @@ Copyright (c) Microsoft Corporation Copyright (c) 2007 James Newton-King Copyright (c) 1991-2022 Unicode, Inc. Copyright (c) 2013-2017, Alfred Klomp +Copyright (c) 2018 Nemanja Mijailovic Copyright 2012 the V8 project authors Copyright (c) 1999 Lucent Technologies Copyright (c) 2008-2016, Wojciech Mula Copyright (c) 2011-2020 Microsoft Corp Copyright (c) 2015-2017, Wojciech Mula -Copyright (c) 2021 csFastFloat authors +Copyright (c) 2015-2018, Wojciech Mula Copyright (c) 2005-2007, Nick Galbreath Copyright (c) 2015 The Chromium Authors Copyright (c) 2018 Alexander Chermyanin Copyright (c) The Internet Society 1997 -Portions (c) International Organization Copyright (c) 2004-2006 Intel Corporation Copyright (c) 2011-2015 Intel Corporation Copyright (c) 2013-2017, Milosz Krajewski Copyright (c) 2016-2017, Matthieu Darbois Copyright (c) The Internet Society (2003) Copyright (c) .NET Foundation Contributors +(c) 1995-2024 Jean-loup Gailly and Mark Adler Copyright (c) 2020 Mara Bos Copyright (c) .NET Foundation and Contributors Copyright (c) 2012 - present, Victor Zverovich @@ -3740,12 +3779,12 @@ Copyright (c) 2006 Jb Evain (jbevain@gmail.com) Copyright (c) 2008-2020 Advanced Micro Devices, Inc. Copyright (c) 2019 Microsoft Corporation, Daan Leijen Copyright (c) 2011 Novell, Inc (http://www.novell.com) -Copyright (c) 1995-2022 Jean-loup Gailly and Mark Adler Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com) Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc. -Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers +Portions (c) International Organization for Standardization 1986 +Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip Copyright (c) 1980, 1986, 1993 The Regents of the University of California Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California @@ -3865,19 +3904,22 @@ SOFTWARE. --------------------------------------------------------- -System.Reflection.Context 8.0.0 - MIT +System.Reflection.Context 9.0.0 - MIT +Copyright (c) 2021 Copyright (c) Six Labors (c) Microsoft Corporation +Copyright (c) 2022 FormatJS Copyright (c) Andrew Arnott Copyright 2019 LLVM Project +Copyright (c) 1998 Microsoft Copyright 2018 Daniel Lemire Copyright (c) .NET Foundation Copyright (c) 2011, Google Inc. Copyright (c) 2020 Dan Shechter (c) 1997-2005 Sean Eron Anderson -Copyright (c) 1998 Microsoft. To +Copyright (c) 2015 Andrew Gallant Copyright (c) 2022, Wojciech Mula Copyright (c) 2017 Yoshifumi Kawai Copyright (c) 2022, Geoff Langdale @@ -3887,23 +3929,24 @@ Copyright (c) Microsoft Corporation Copyright (c) 2007 James Newton-King Copyright (c) 1991-2022 Unicode, Inc. Copyright (c) 2013-2017, Alfred Klomp +Copyright (c) 2018 Nemanja Mijailovic Copyright 2012 the V8 project authors Copyright (c) 1999 Lucent Technologies Copyright (c) 2008-2016, Wojciech Mula Copyright (c) 2011-2020 Microsoft Corp Copyright (c) 2015-2017, Wojciech Mula -Copyright (c) 2021 csFastFloat authors +Copyright (c) 2015-2018, Wojciech Mula Copyright (c) 2005-2007, Nick Galbreath Copyright (c) 2015 The Chromium Authors Copyright (c) 2018 Alexander Chermyanin Copyright (c) The Internet Society 1997 -Portions (c) International Organization Copyright (c) 2004-2006 Intel Corporation Copyright (c) 2011-2015 Intel Corporation Copyright (c) 2013-2017, Milosz Krajewski Copyright (c) 2016-2017, Matthieu Darbois Copyright (c) The Internet Society (2003) Copyright (c) .NET Foundation Contributors +(c) 1995-2024 Jean-loup Gailly and Mark Adler Copyright (c) 2020 Mara Bos Copyright (c) .NET Foundation and Contributors Copyright (c) 2012 - present, Victor Zverovich @@ -3911,12 +3954,12 @@ Copyright (c) 2006 Jb Evain (jbevain@gmail.com) Copyright (c) 2008-2020 Advanced Micro Devices, Inc. Copyright (c) 2019 Microsoft Corporation, Daan Leijen Copyright (c) 2011 Novell, Inc (http://www.novell.com) -Copyright (c) 1995-2022 Jean-loup Gailly and Mark Adler Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com) Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc. -Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers +Portions (c) International Organization for Standardization 1986 +Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip Copyright (c) 1980, 1986, 1993 The Regents of the University of California Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California @@ -4091,19 +4134,22 @@ SOFTWARE. --------------------------------------------------------- -System.Runtime.Caching 8.0.1 - MIT +System.Runtime.Caching 9.0.0 - MIT +Copyright (c) 2021 Copyright (c) Six Labors (c) Microsoft Corporation +Copyright (c) 2022 FormatJS Copyright (c) Andrew Arnott Copyright 2019 LLVM Project +Copyright (c) 1998 Microsoft Copyright 2018 Daniel Lemire Copyright (c) .NET Foundation Copyright (c) 2011, Google Inc. Copyright (c) 2020 Dan Shechter (c) 1997-2005 Sean Eron Anderson -Copyright (c) 1998 Microsoft. To +Copyright (c) 2015 Andrew Gallant Copyright (c) 2022, Wojciech Mula Copyright (c) 2017 Yoshifumi Kawai Copyright (c) 2022, Geoff Langdale @@ -4113,23 +4159,24 @@ Copyright (c) Microsoft Corporation Copyright (c) 2007 James Newton-King Copyright (c) 1991-2022 Unicode, Inc. Copyright (c) 2013-2017, Alfred Klomp +Copyright (c) 2018 Nemanja Mijailovic Copyright 2012 the V8 project authors Copyright (c) 1999 Lucent Technologies Copyright (c) 2008-2016, Wojciech Mula Copyright (c) 2011-2020 Microsoft Corp Copyright (c) 2015-2017, Wojciech Mula -Copyright (c) 2021 csFastFloat authors +Copyright (c) 2015-2018, Wojciech Mula Copyright (c) 2005-2007, Nick Galbreath Copyright (c) 2015 The Chromium Authors Copyright (c) 2018 Alexander Chermyanin Copyright (c) The Internet Society 1997 -Portions (c) International Organization Copyright (c) 2004-2006 Intel Corporation Copyright (c) 2011-2015 Intel Corporation Copyright (c) 2013-2017, Milosz Krajewski Copyright (c) 2016-2017, Matthieu Darbois Copyright (c) The Internet Society (2003) Copyright (c) .NET Foundation Contributors +(c) 1995-2024 Jean-loup Gailly and Mark Adler Copyright (c) 2020 Mara Bos Copyright (c) .NET Foundation and Contributors Copyright (c) 2012 - present, Victor Zverovich @@ -4137,12 +4184,12 @@ Copyright (c) 2006 Jb Evain (jbevain@gmail.com) Copyright (c) 2008-2020 Advanced Micro Devices, Inc. Copyright (c) 2019 Microsoft Corporation, Daan Leijen Copyright (c) 2011 Novell, Inc (http://www.novell.com) -Copyright (c) 1995-2022 Jean-loup Gailly and Mark Adler Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com) Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc. -Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers +Portions (c) International Organization for Standardization 1986 +Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip Copyright (c) 1980, 1986, 1993 The Regents of the University of California Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California @@ -4252,19 +4299,22 @@ SOFTWARE. --------------------------------------------------------- -System.Security.Cryptography.Pkcs 8.0.1 - MIT +System.Security.Cryptography.Pkcs 9.0.0 - MIT +Copyright (c) 2021 Copyright (c) Six Labors (c) Microsoft Corporation +Copyright (c) 2022 FormatJS Copyright (c) Andrew Arnott Copyright 2019 LLVM Project +Copyright (c) 1998 Microsoft Copyright 2018 Daniel Lemire Copyright (c) .NET Foundation Copyright (c) 2011, Google Inc. Copyright (c) 2020 Dan Shechter (c) 1997-2005 Sean Eron Anderson -Copyright (c) 1998 Microsoft. To +Copyright (c) 2015 Andrew Gallant Copyright (c) 2022, Wojciech Mula Copyright (c) 2017 Yoshifumi Kawai Copyright (c) 2022, Geoff Langdale @@ -4274,23 +4324,24 @@ Copyright (c) Microsoft Corporation Copyright (c) 2007 James Newton-King Copyright (c) 1991-2022 Unicode, Inc. Copyright (c) 2013-2017, Alfred Klomp +Copyright (c) 2018 Nemanja Mijailovic Copyright 2012 the V8 project authors Copyright (c) 1999 Lucent Technologies Copyright (c) 2008-2016, Wojciech Mula Copyright (c) 2011-2020 Microsoft Corp Copyright (c) 2015-2017, Wojciech Mula -Copyright (c) 2021 csFastFloat authors +Copyright (c) 2015-2018, Wojciech Mula Copyright (c) 2005-2007, Nick Galbreath Copyright (c) 2015 The Chromium Authors Copyright (c) 2018 Alexander Chermyanin Copyright (c) The Internet Society 1997 -Portions (c) International Organization Copyright (c) 2004-2006 Intel Corporation Copyright (c) 2011-2015 Intel Corporation Copyright (c) 2013-2017, Milosz Krajewski Copyright (c) 2016-2017, Matthieu Darbois Copyright (c) The Internet Society (2003) Copyright (c) .NET Foundation Contributors +(c) 1995-2024 Jean-loup Gailly and Mark Adler Copyright (c) 2020 Mara Bos Copyright (c) .NET Foundation and Contributors Copyright (c) 2012 - present, Victor Zverovich @@ -4298,12 +4349,12 @@ Copyright (c) 2006 Jb Evain (jbevain@gmail.com) Copyright (c) 2008-2020 Advanced Micro Devices, Inc. Copyright (c) 2019 Microsoft Corporation, Daan Leijen Copyright (c) 2011 Novell, Inc (http://www.novell.com) -Copyright (c) 1995-2022 Jean-loup Gailly and Mark Adler Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com) Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc. -Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers +Portions (c) International Organization for Standardization 1986 +Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip Copyright (c) 1980, 1986, 1993 The Regents of the University of California Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California @@ -4338,19 +4389,22 @@ SOFTWARE. --------------------------------------------------------- -System.Security.Cryptography.ProtectedData 8.0.0 - MIT +System.Security.Cryptography.ProtectedData 9.0.0 - MIT +Copyright (c) 2021 Copyright (c) Six Labors (c) Microsoft Corporation +Copyright (c) 2022 FormatJS Copyright (c) Andrew Arnott Copyright 2019 LLVM Project +Copyright (c) 1998 Microsoft Copyright 2018 Daniel Lemire Copyright (c) .NET Foundation Copyright (c) 2011, Google Inc. Copyright (c) 2020 Dan Shechter (c) 1997-2005 Sean Eron Anderson -Copyright (c) 1998 Microsoft. To +Copyright (c) 2015 Andrew Gallant Copyright (c) 2022, Wojciech Mula Copyright (c) 2017 Yoshifumi Kawai Copyright (c) 2022, Geoff Langdale @@ -4360,23 +4414,24 @@ Copyright (c) Microsoft Corporation Copyright (c) 2007 James Newton-King Copyright (c) 1991-2022 Unicode, Inc. Copyright (c) 2013-2017, Alfred Klomp +Copyright (c) 2018 Nemanja Mijailovic Copyright 2012 the V8 project authors Copyright (c) 1999 Lucent Technologies Copyright (c) 2008-2016, Wojciech Mula Copyright (c) 2011-2020 Microsoft Corp Copyright (c) 2015-2017, Wojciech Mula -Copyright (c) 2021 csFastFloat authors +Copyright (c) 2015-2018, Wojciech Mula Copyright (c) 2005-2007, Nick Galbreath Copyright (c) 2015 The Chromium Authors Copyright (c) 2018 Alexander Chermyanin Copyright (c) The Internet Society 1997 -Portions (c) International Organization Copyright (c) 2004-2006 Intel Corporation Copyright (c) 2011-2015 Intel Corporation Copyright (c) 2013-2017, Milosz Krajewski Copyright (c) 2016-2017, Matthieu Darbois Copyright (c) The Internet Society (2003) Copyright (c) .NET Foundation Contributors +(c) 1995-2024 Jean-loup Gailly and Mark Adler Copyright (c) 2020 Mara Bos Copyright (c) .NET Foundation and Contributors Copyright (c) 2012 - present, Victor Zverovich @@ -4384,12 +4439,12 @@ Copyright (c) 2006 Jb Evain (jbevain@gmail.com) Copyright (c) 2008-2020 Advanced Micro Devices, Inc. Copyright (c) 2019 Microsoft Corporation, Daan Leijen Copyright (c) 2011 Novell, Inc (http://www.novell.com) -Copyright (c) 1995-2022 Jean-loup Gailly and Mark Adler Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com) Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc. -Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers +Portions (c) International Organization for Standardization 1986 +Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip Copyright (c) 1980, 1986, 1993 The Regents of the University of California Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California @@ -4424,19 +4479,22 @@ SOFTWARE. --------------------------------------------------------- -System.Security.Cryptography.Xml 8.0.2 - MIT +System.Security.Cryptography.Xml 9.0.0 - MIT +Copyright (c) 2021 Copyright (c) Six Labors (c) Microsoft Corporation +Copyright (c) 2022 FormatJS Copyright (c) Andrew Arnott Copyright 2019 LLVM Project +Copyright (c) 1998 Microsoft Copyright 2018 Daniel Lemire Copyright (c) .NET Foundation Copyright (c) 2011, Google Inc. Copyright (c) 2020 Dan Shechter (c) 1997-2005 Sean Eron Anderson -Copyright (c) 1998 Microsoft. To +Copyright (c) 2015 Andrew Gallant Copyright (c) 2022, Wojciech Mula Copyright (c) 2017 Yoshifumi Kawai Copyright (c) 2022, Geoff Langdale @@ -4446,23 +4504,24 @@ Copyright (c) Microsoft Corporation Copyright (c) 2007 James Newton-King Copyright (c) 1991-2022 Unicode, Inc. Copyright (c) 2013-2017, Alfred Klomp +Copyright (c) 2018 Nemanja Mijailovic Copyright 2012 the V8 project authors Copyright (c) 1999 Lucent Technologies Copyright (c) 2008-2016, Wojciech Mula Copyright (c) 2011-2020 Microsoft Corp Copyright (c) 2015-2017, Wojciech Mula -Copyright (c) 2021 csFastFloat authors +Copyright (c) 2015-2018, Wojciech Mula Copyright (c) 2005-2007, Nick Galbreath Copyright (c) 2015 The Chromium Authors Copyright (c) 2018 Alexander Chermyanin Copyright (c) The Internet Society 1997 -Portions (c) International Organization Copyright (c) 2004-2006 Intel Corporation Copyright (c) 2011-2015 Intel Corporation Copyright (c) 2013-2017, Milosz Krajewski Copyright (c) 2016-2017, Matthieu Darbois Copyright (c) The Internet Society (2003) Copyright (c) .NET Foundation Contributors +(c) 1995-2024 Jean-loup Gailly and Mark Adler Copyright (c) 2020 Mara Bos Copyright (c) .NET Foundation and Contributors Copyright (c) 2012 - present, Victor Zverovich @@ -4470,12 +4529,12 @@ Copyright (c) 2006 Jb Evain (jbevain@gmail.com) Copyright (c) 2008-2020 Advanced Micro Devices, Inc. Copyright (c) 2019 Microsoft Corporation, Daan Leijen Copyright (c) 2011 Novell, Inc (http://www.novell.com) -Copyright (c) 1995-2022 Jean-loup Gailly and Mark Adler Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com) Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc. -Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers +Portions (c) International Organization for Standardization 1986 +Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip Copyright (c) 1980, 1986, 1993 The Regents of the University of California Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California @@ -4510,19 +4569,22 @@ SOFTWARE. --------------------------------------------------------- -System.Security.Permissions 8.0.0 - MIT +System.Security.Permissions 9.0.0 - MIT +Copyright (c) 2021 Copyright (c) Six Labors (c) Microsoft Corporation +Copyright (c) 2022 FormatJS Copyright (c) Andrew Arnott Copyright 2019 LLVM Project +Copyright (c) 1998 Microsoft Copyright 2018 Daniel Lemire Copyright (c) .NET Foundation Copyright (c) 2011, Google Inc. Copyright (c) 2020 Dan Shechter (c) 1997-2005 Sean Eron Anderson -Copyright (c) 1998 Microsoft. To +Copyright (c) 2015 Andrew Gallant Copyright (c) 2022, Wojciech Mula Copyright (c) 2017 Yoshifumi Kawai Copyright (c) 2022, Geoff Langdale @@ -4532,23 +4594,24 @@ Copyright (c) Microsoft Corporation Copyright (c) 2007 James Newton-King Copyright (c) 1991-2022 Unicode, Inc. Copyright (c) 2013-2017, Alfred Klomp +Copyright (c) 2018 Nemanja Mijailovic Copyright 2012 the V8 project authors Copyright (c) 1999 Lucent Technologies Copyright (c) 2008-2016, Wojciech Mula Copyright (c) 2011-2020 Microsoft Corp Copyright (c) 2015-2017, Wojciech Mula -Copyright (c) 2021 csFastFloat authors +Copyright (c) 2015-2018, Wojciech Mula Copyright (c) 2005-2007, Nick Galbreath Copyright (c) 2015 The Chromium Authors Copyright (c) 2018 Alexander Chermyanin Copyright (c) The Internet Society 1997 -Portions (c) International Organization Copyright (c) 2004-2006 Intel Corporation Copyright (c) 2011-2015 Intel Corporation Copyright (c) 2013-2017, Milosz Krajewski Copyright (c) 2016-2017, Matthieu Darbois Copyright (c) The Internet Society (2003) Copyright (c) .NET Foundation Contributors +(c) 1995-2024 Jean-loup Gailly and Mark Adler Copyright (c) 2020 Mara Bos Copyright (c) .NET Foundation and Contributors Copyright (c) 2012 - present, Victor Zverovich @@ -4556,12 +4619,12 @@ Copyright (c) 2006 Jb Evain (jbevain@gmail.com) Copyright (c) 2008-2020 Advanced Micro Devices, Inc. Copyright (c) 2019 Microsoft Corporation, Daan Leijen Copyright (c) 2011 Novell, Inc (http://www.novell.com) -Copyright (c) 1995-2022 Jean-loup Gailly and Mark Adler Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com) Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc. -Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers +Portions (c) International Organization for Standardization 1986 +Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip Copyright (c) 1980, 1986, 1993 The Regents of the University of California Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California @@ -4845,19 +4908,22 @@ SOFTWARE. --------------------------------------------------------- -System.ServiceModel.Syndication 8.0.0 - MIT +System.ServiceModel.Syndication 9.0.0 - MIT +Copyright (c) 2021 Copyright (c) Six Labors (c) Microsoft Corporation +Copyright (c) 2022 FormatJS Copyright (c) Andrew Arnott Copyright 2019 LLVM Project +Copyright (c) 1998 Microsoft Copyright 2018 Daniel Lemire Copyright (c) .NET Foundation Copyright (c) 2011, Google Inc. Copyright (c) 2020 Dan Shechter (c) 1997-2005 Sean Eron Anderson -Copyright (c) 1998 Microsoft. To +Copyright (c) 2015 Andrew Gallant Copyright (c) 2022, Wojciech Mula Copyright (c) 2017 Yoshifumi Kawai Copyright (c) 2022, Geoff Langdale @@ -4867,23 +4933,24 @@ Copyright (c) Microsoft Corporation Copyright (c) 2007 James Newton-King Copyright (c) 1991-2022 Unicode, Inc. Copyright (c) 2013-2017, Alfred Klomp +Copyright (c) 2018 Nemanja Mijailovic Copyright 2012 the V8 project authors Copyright (c) 1999 Lucent Technologies Copyright (c) 2008-2016, Wojciech Mula Copyright (c) 2011-2020 Microsoft Corp Copyright (c) 2015-2017, Wojciech Mula -Copyright (c) 2021 csFastFloat authors +Copyright (c) 2015-2018, Wojciech Mula Copyright (c) 2005-2007, Nick Galbreath Copyright (c) 2015 The Chromium Authors Copyright (c) 2018 Alexander Chermyanin Copyright (c) The Internet Society 1997 -Portions (c) International Organization Copyright (c) 2004-2006 Intel Corporation Copyright (c) 2011-2015 Intel Corporation Copyright (c) 2013-2017, Milosz Krajewski Copyright (c) 2016-2017, Matthieu Darbois Copyright (c) The Internet Society (2003) Copyright (c) .NET Foundation Contributors +(c) 1995-2024 Jean-loup Gailly and Mark Adler Copyright (c) 2020 Mara Bos Copyright (c) .NET Foundation and Contributors Copyright (c) 2012 - present, Victor Zverovich @@ -4891,12 +4958,12 @@ Copyright (c) 2006 Jb Evain (jbevain@gmail.com) Copyright (c) 2008-2020 Advanced Micro Devices, Inc. Copyright (c) 2019 Microsoft Corporation, Daan Leijen Copyright (c) 2011 Novell, Inc (http://www.novell.com) -Copyright (c) 1995-2022 Jean-loup Gailly and Mark Adler Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com) Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc. -Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers +Portions (c) International Organization for Standardization 1986 +Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip Copyright (c) 1980, 1986, 1993 The Regents of the University of California Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California @@ -4931,19 +4998,22 @@ SOFTWARE. --------------------------------------------------------- -System.ServiceProcess.ServiceController 8.0.1 - MIT +System.ServiceProcess.ServiceController 9.0.0 - MIT +Copyright (c) 2021 Copyright (c) Six Labors (c) Microsoft Corporation +Copyright (c) 2022 FormatJS Copyright (c) Andrew Arnott Copyright 2019 LLVM Project +Copyright (c) 1998 Microsoft Copyright 2018 Daniel Lemire Copyright (c) .NET Foundation Copyright (c) 2011, Google Inc. Copyright (c) 2020 Dan Shechter (c) 1997-2005 Sean Eron Anderson -Copyright (c) 1998 Microsoft. To +Copyright (c) 2015 Andrew Gallant Copyright (c) 2022, Wojciech Mula Copyright (c) 2017 Yoshifumi Kawai Copyright (c) 2022, Geoff Langdale @@ -4953,23 +5023,24 @@ Copyright (c) Microsoft Corporation Copyright (c) 2007 James Newton-King Copyright (c) 1991-2022 Unicode, Inc. Copyright (c) 2013-2017, Alfred Klomp +Copyright (c) 2018 Nemanja Mijailovic Copyright 2012 the V8 project authors Copyright (c) 1999 Lucent Technologies Copyright (c) 2008-2016, Wojciech Mula Copyright (c) 2011-2020 Microsoft Corp Copyright (c) 2015-2017, Wojciech Mula -Copyright (c) 2021 csFastFloat authors +Copyright (c) 2015-2018, Wojciech Mula Copyright (c) 2005-2007, Nick Galbreath Copyright (c) 2015 The Chromium Authors Copyright (c) 2018 Alexander Chermyanin Copyright (c) The Internet Society 1997 -Portions (c) International Organization Copyright (c) 2004-2006 Intel Corporation Copyright (c) 2011-2015 Intel Corporation Copyright (c) 2013-2017, Milosz Krajewski Copyright (c) 2016-2017, Matthieu Darbois Copyright (c) The Internet Society (2003) Copyright (c) .NET Foundation Contributors +(c) 1995-2024 Jean-loup Gailly and Mark Adler Copyright (c) 2020 Mara Bos Copyright (c) .NET Foundation and Contributors Copyright (c) 2012 - present, Victor Zverovich @@ -4977,12 +5048,12 @@ Copyright (c) 2006 Jb Evain (jbevain@gmail.com) Copyright (c) 2008-2020 Advanced Micro Devices, Inc. Copyright (c) 2019 Microsoft Corporation, Daan Leijen Copyright (c) 2011 Novell, Inc (http://www.novell.com) -Copyright (c) 1995-2022 Jean-loup Gailly and Mark Adler Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com) Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc. -Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers +Portions (c) International Organization for Standardization 1986 +Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip Copyright (c) 1980, 1986, 1993 The Regents of the University of California Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California @@ -5017,19 +5088,22 @@ SOFTWARE. --------------------------------------------------------- -System.Speech 8.0.0 - MIT +System.Speech 9.0.0 - MIT +Copyright (c) 2021 Copyright (c) Six Labors (c) Microsoft Corporation +Copyright (c) 2022 FormatJS Copyright (c) Andrew Arnott Copyright 2019 LLVM Project +Copyright (c) 1998 Microsoft Copyright 2018 Daniel Lemire Copyright (c) .NET Foundation Copyright (c) 2011, Google Inc. Copyright (c) 2020 Dan Shechter (c) 1997-2005 Sean Eron Anderson -Copyright (c) 1998 Microsoft. To +Copyright (c) 2015 Andrew Gallant Copyright (c) 2022, Wojciech Mula Copyright (c) 2017 Yoshifumi Kawai Copyright (c) 2022, Geoff Langdale @@ -5039,23 +5113,24 @@ Copyright (c) Microsoft Corporation Copyright (c) 2007 James Newton-King Copyright (c) 1991-2022 Unicode, Inc. Copyright (c) 2013-2017, Alfred Klomp +Copyright (c) 2018 Nemanja Mijailovic Copyright 2012 the V8 project authors Copyright (c) 1999 Lucent Technologies Copyright (c) 2008-2016, Wojciech Mula Copyright (c) 2011-2020 Microsoft Corp Copyright (c) 2015-2017, Wojciech Mula -Copyright (c) 2021 csFastFloat authors +Copyright (c) 2015-2018, Wojciech Mula Copyright (c) 2005-2007, Nick Galbreath Copyright (c) 2015 The Chromium Authors Copyright (c) 2018 Alexander Chermyanin Copyright (c) The Internet Society 1997 -Portions (c) International Organization Copyright (c) 2004-2006 Intel Corporation Copyright (c) 2011-2015 Intel Corporation Copyright (c) 2013-2017, Milosz Krajewski Copyright (c) 2016-2017, Matthieu Darbois Copyright (c) The Internet Society (2003) Copyright (c) .NET Foundation Contributors +(c) 1995-2024 Jean-loup Gailly and Mark Adler Copyright (c) 2020 Mara Bos Copyright (c) .NET Foundation and Contributors Copyright (c) 2012 - present, Victor Zverovich @@ -5063,12 +5138,12 @@ Copyright (c) 2006 Jb Evain (jbevain@gmail.com) Copyright (c) 2008-2020 Advanced Micro Devices, Inc. Copyright (c) 2019 Microsoft Corporation, Daan Leijen Copyright (c) 2011 Novell, Inc (http://www.novell.com) -Copyright (c) 1995-2022 Jean-loup Gailly and Mark Adler Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com) Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc. -Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers +Portions (c) International Organization for Standardization 1986 +Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip Copyright (c) 1980, 1986, 1993 The Regents of the University of California Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California @@ -5103,9 +5178,66 @@ SOFTWARE. --------------------------------------------------------- -System.Text.Encoding.CodePages 8.0.0 - MIT +System.Text.Encoding.CodePages 9.0.0 - MIT +Copyright (c) 2021 +Copyright (c) Six Labors +(c) Microsoft Corporation +Copyright (c) 2022 FormatJS +Copyright (c) Andrew Arnott +Copyright 2019 LLVM Project +Copyright (c) 1998 Microsoft +Copyright 2018 Daniel Lemire +Copyright (c) .NET Foundation +Copyright (c) 2011, Google Inc. +Copyright (c) 2020 Dan Shechter +(c) 1997-2005 Sean Eron Anderson +Copyright (c) 2015 Andrew Gallant +Copyright (c) 2022, Wojciech Mula +Copyright (c) 2017 Yoshifumi Kawai +Copyright (c) 2022, Geoff Langdale +Copyright (c) 2005-2020 Rich Felker +Copyright (c) 2012-2021 Yann Collet +Copyright (c) Microsoft Corporation +Copyright (c) 2007 James Newton-King +Copyright (c) 1991-2022 Unicode, Inc. +Copyright (c) 2013-2017, Alfred Klomp +Copyright (c) 2018 Nemanja Mijailovic +Copyright 2012 the V8 project authors +Copyright (c) 1999 Lucent Technologies +Copyright (c) 2008-2016, Wojciech Mula +Copyright (c) 2011-2020 Microsoft Corp +Copyright (c) 2015-2017, Wojciech Mula +Copyright (c) 2015-2018, Wojciech Mula +Copyright (c) 2005-2007, Nick Galbreath +Copyright (c) 2015 The Chromium Authors +Copyright (c) 2018 Alexander Chermyanin +Copyright (c) The Internet Society 1997 +Copyright (c) 2004-2006 Intel Corporation +Copyright (c) 2011-2015 Intel Corporation +Copyright (c) 2013-2017, Milosz Krajewski +Copyright (c) 2016-2017, Matthieu Darbois +Copyright (c) The Internet Society (2003) +Copyright (c) .NET Foundation Contributors +(c) 1995-2024 Jean-loup Gailly and Mark Adler +Copyright (c) 2020 Mara Bos +Copyright (c) .NET Foundation and Contributors +Copyright (c) 2012 - present, Victor Zverovich +Copyright (c) 2006 Jb Evain (jbevain@gmail.com) +Copyright (c) 2008-2020 Advanced Micro Devices, Inc. +Copyright (c) 2019 Microsoft Corporation, Daan Leijen +Copyright (c) 2011 Novell, Inc (http://www.novell.com) +Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com) +Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors +Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com +Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc. +Portions (c) International Organization for Standardization 1986 +Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers +Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip +Copyright (c) 1980, 1986, 1993 The Regents of the University of California +Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California +Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass The MIT License (MIT) @@ -5136,19 +5268,22 @@ SOFTWARE. --------------------------------------------------------- -System.Text.Encodings.Web 8.0.0 - MIT +System.Text.Encodings.Web 9.0.0 - MIT +Copyright (c) 2021 Copyright (c) Six Labors (c) Microsoft Corporation +Copyright (c) 2022 FormatJS Copyright (c) Andrew Arnott Copyright 2019 LLVM Project +Copyright (c) 1998 Microsoft Copyright 2018 Daniel Lemire Copyright (c) .NET Foundation Copyright (c) 2011, Google Inc. Copyright (c) 2020 Dan Shechter (c) 1997-2005 Sean Eron Anderson -Copyright (c) 1998 Microsoft. To +Copyright (c) 2015 Andrew Gallant Copyright (c) 2022, Wojciech Mula Copyright (c) 2017 Yoshifumi Kawai Copyright (c) 2022, Geoff Langdale @@ -5158,23 +5293,24 @@ Copyright (c) Microsoft Corporation Copyright (c) 2007 James Newton-King Copyright (c) 1991-2022 Unicode, Inc. Copyright (c) 2013-2017, Alfred Klomp +Copyright (c) 2018 Nemanja Mijailovic Copyright 2012 the V8 project authors Copyright (c) 1999 Lucent Technologies Copyright (c) 2008-2016, Wojciech Mula Copyright (c) 2011-2020 Microsoft Corp Copyright (c) 2015-2017, Wojciech Mula -Copyright (c) 2021 csFastFloat authors +Copyright (c) 2015-2018, Wojciech Mula Copyright (c) 2005-2007, Nick Galbreath Copyright (c) 2015 The Chromium Authors Copyright (c) 2018 Alexander Chermyanin Copyright (c) The Internet Society 1997 -Portions (c) International Organization Copyright (c) 2004-2006 Intel Corporation Copyright (c) 2011-2015 Intel Corporation Copyright (c) 2013-2017, Milosz Krajewski Copyright (c) 2016-2017, Matthieu Darbois Copyright (c) The Internet Society (2003) Copyright (c) .NET Foundation Contributors +(c) 1995-2024 Jean-loup Gailly and Mark Adler Copyright (c) 2020 Mara Bos Copyright (c) .NET Foundation and Contributors Copyright (c) 2012 - present, Victor Zverovich @@ -5182,12 +5318,12 @@ Copyright (c) 2006 Jb Evain (jbevain@gmail.com) Copyright (c) 2008-2020 Advanced Micro Devices, Inc. Copyright (c) 2019 Microsoft Corporation, Daan Leijen Copyright (c) 2011 Novell, Inc (http://www.novell.com) -Copyright (c) 1995-2022 Jean-loup Gailly and Mark Adler Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com) Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc. -Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers +Portions (c) International Organization for Standardization 1986 +Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip Copyright (c) 1980, 1986, 1993 The Regents of the University of California Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California @@ -5222,19 +5358,22 @@ SOFTWARE. --------------------------------------------------------- -System.Threading.AccessControl 8.0.0 - MIT +System.Threading.AccessControl 9.0.0 - MIT +Copyright (c) 2021 Copyright (c) Six Labors (c) Microsoft Corporation +Copyright (c) 2022 FormatJS Copyright (c) Andrew Arnott Copyright 2019 LLVM Project +Copyright (c) 1998 Microsoft Copyright 2018 Daniel Lemire Copyright (c) .NET Foundation Copyright (c) 2011, Google Inc. Copyright (c) 2020 Dan Shechter (c) 1997-2005 Sean Eron Anderson -Copyright (c) 1998 Microsoft. To +Copyright (c) 2015 Andrew Gallant Copyright (c) 2022, Wojciech Mula Copyright (c) 2017 Yoshifumi Kawai Copyright (c) 2022, Geoff Langdale @@ -5244,23 +5383,24 @@ Copyright (c) Microsoft Corporation Copyright (c) 2007 James Newton-King Copyright (c) 1991-2022 Unicode, Inc. Copyright (c) 2013-2017, Alfred Klomp +Copyright (c) 2018 Nemanja Mijailovic Copyright 2012 the V8 project authors Copyright (c) 1999 Lucent Technologies Copyright (c) 2008-2016, Wojciech Mula Copyright (c) 2011-2020 Microsoft Corp Copyright (c) 2015-2017, Wojciech Mula -Copyright (c) 2021 csFastFloat authors +Copyright (c) 2015-2018, Wojciech Mula Copyright (c) 2005-2007, Nick Galbreath Copyright (c) 2015 The Chromium Authors Copyright (c) 2018 Alexander Chermyanin Copyright (c) The Internet Society 1997 -Portions (c) International Organization Copyright (c) 2004-2006 Intel Corporation Copyright (c) 2011-2015 Intel Corporation Copyright (c) 2013-2017, Milosz Krajewski Copyright (c) 2016-2017, Matthieu Darbois Copyright (c) The Internet Society (2003) Copyright (c) .NET Foundation Contributors +(c) 1995-2024 Jean-loup Gailly and Mark Adler Copyright (c) 2020 Mara Bos Copyright (c) .NET Foundation and Contributors Copyright (c) 2012 - present, Victor Zverovich @@ -5268,12 +5408,12 @@ Copyright (c) 2006 Jb Evain (jbevain@gmail.com) Copyright (c) 2008-2020 Advanced Micro Devices, Inc. Copyright (c) 2019 Microsoft Corporation, Daan Leijen Copyright (c) 2011 Novell, Inc (http://www.novell.com) -Copyright (c) 1995-2022 Jean-loup Gailly and Mark Adler Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com) Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc. -Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers +Portions (c) International Organization for Standardization 1986 +Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip Copyright (c) 1980, 1986, 1993 The Regents of the University of California Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California @@ -5344,19 +5484,22 @@ SOFTWARE. --------------------------------------------------------- -System.Windows.Extensions 8.0.0 - MIT +System.Windows.Extensions 9.0.0 - MIT +Copyright (c) 2021 Copyright (c) Six Labors (c) Microsoft Corporation +Copyright (c) 2022 FormatJS Copyright (c) Andrew Arnott Copyright 2019 LLVM Project +Copyright (c) 1998 Microsoft Copyright 2018 Daniel Lemire Copyright (c) .NET Foundation Copyright (c) 2011, Google Inc. Copyright (c) 2020 Dan Shechter (c) 1997-2005 Sean Eron Anderson -Copyright (c) 1998 Microsoft. To +Copyright (c) 2015 Andrew Gallant Copyright (c) 2022, Wojciech Mula Copyright (c) 2017 Yoshifumi Kawai Copyright (c) 2022, Geoff Langdale @@ -5366,23 +5509,24 @@ Copyright (c) Microsoft Corporation Copyright (c) 2007 James Newton-King Copyright (c) 1991-2022 Unicode, Inc. Copyright (c) 2013-2017, Alfred Klomp +Copyright (c) 2018 Nemanja Mijailovic Copyright 2012 the V8 project authors Copyright (c) 1999 Lucent Technologies Copyright (c) 2008-2016, Wojciech Mula Copyright (c) 2011-2020 Microsoft Corp Copyright (c) 2015-2017, Wojciech Mula -Copyright (c) 2021 csFastFloat authors +Copyright (c) 2015-2018, Wojciech Mula Copyright (c) 2005-2007, Nick Galbreath Copyright (c) 2015 The Chromium Authors Copyright (c) 2018 Alexander Chermyanin Copyright (c) The Internet Society 1997 -Portions (c) International Organization Copyright (c) 2004-2006 Intel Corporation Copyright (c) 2011-2015 Intel Corporation Copyright (c) 2013-2017, Milosz Krajewski Copyright (c) 2016-2017, Matthieu Darbois Copyright (c) The Internet Society (2003) Copyright (c) .NET Foundation Contributors +(c) 1995-2024 Jean-loup Gailly and Mark Adler Copyright (c) 2020 Mara Bos Copyright (c) .NET Foundation and Contributors Copyright (c) 2012 - present, Victor Zverovich @@ -5390,12 +5534,12 @@ Copyright (c) 2006 Jb Evain (jbevain@gmail.com) Copyright (c) 2008-2020 Advanced Micro Devices, Inc. Copyright (c) 2019 Microsoft Corporation, Daan Leijen Copyright (c) 2011 Novell, Inc (http://www.novell.com) -Copyright (c) 1995-2022 Jean-loup Gailly and Mark Adler Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com) Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc. -Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers +Portions (c) International Organization for Standardization 1986 +Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip Copyright (c) 1980, 1986, 1993 The Regents of the University of California Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California From be6dfe3480e41af4776286d6777dee450675b605 Mon Sep 17 00:00:00 2001 From: Aditya Patwardhan Date: Wed, 13 Nov 2024 18:24:46 -0800 Subject: [PATCH 051/173] Update change log for v7.5.0-rc.1 (#24584) --- CHANGELOG/preview.md | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/CHANGELOG/preview.md b/CHANGELOG/preview.md index 847ca7a2919..3ffbdcae65b 100644 --- a/CHANGELOG/preview.md +++ b/CHANGELOG/preview.md @@ -1,5 +1,40 @@ # Preview Changelog +## [7.5.0-rc.1] - 2024-11-14 + +### Build and Packaging Improvements + +
+ + + +

Bump to .NET 9.0.100

+ +
+ +
    +
  • Update ThirdPartyNotices file (#24582) (#24536)
  • +
  • Bump to .NET 9.0.100 (#24576) (#24535)
  • +
  • Add a way to use only NuGet feed sources (#24528) (#24530)
  • +
  • Update PSResourceGet to v1.1.0-RC2 (#24512) (#24525)
  • +
  • Add PMC mapping for debian 12 (bookworm) (#24413) (#24518)
  • +
  • Bump .NET to 9.0.100-rc.2.24474.11 (#24509) (#24522)
  • +
  • Keep the roff file when gzipping it. (#24450) (#24520)
  • +
  • Checkin generated manpage (#24423) (#24519)
  • +
  • Update PSReadLine to 2.3.6 (#24380) (#24517)
  • +
  • Download package from package build for generating vpack (#24481) (#24521)
  • +
  • Delete the msix blob if it's already there (#24353) (#24516)
  • +
  • Add CodeQL scanning to APIScan build (#24303) (#24515)
  • +
  • Update vpack pipeline (#24281) (#24514)
  • +
  • Fix seed max value for Container Linux CI (#24510) (#24511)
  • +
  • Bring preview.5 release fixes to release/v7.5 (#24379) (#24368)
  • +
  • Add BaseUrl to buildinfo json file (#24376) (#24377)
  • +
+ +
+ +[7.5.0-rc.1]: https://github.com/PowerShell/PowerShell/compare/v7.5.0-preview.5...v7.5.0-rc.1 + ## [7.5.0-preview.5] - 2024-10-01 ### Breaking Changes From 2800f895f59272e97583fddec9285cd773142f5b Mon Sep 17 00:00:00 2001 From: Aditya Patwardhan Date: Thu, 14 Nov 2024 14:14:58 -0800 Subject: [PATCH 052/173] Update machine pool for copy blob and upload buildinfo stage (#24587) (#24588) --- .pipelines/PowerShell-Release-Official.yml | 6 +++--- .pipelines/templates/release-MakeBlobPublic.yml | 9 +++++++++ .pipelines/templates/release-upload-buildinfo.yml | 9 +++++++-- 3 files changed, 19 insertions(+), 5 deletions(-) diff --git a/.pipelines/PowerShell-Release-Official.yml b/.pipelines/PowerShell-Release-Official.yml index 2538d1b5370..195491ef161 100644 --- a/.pipelines/PowerShell-Release-Official.yml +++ b/.pipelines/PowerShell-Release-Official.yml @@ -79,12 +79,12 @@ resources: extends: template: v2/OneBranch.Official.CrossPlat.yml@templates parameters: - # still using KS2 because we are not yet using a Box Product Deployment + # using Monitor as copy blob is being blocked by the network featureFlags: LinuxHostVersion: - Network: KS2 + Network: Monitor WindowsHostVersion: - Network: KS2 + Network: Monitor cloudvault: enabled: false globalSdl: diff --git a/.pipelines/templates/release-MakeBlobPublic.yml b/.pipelines/templates/release-MakeBlobPublic.yml index f9afbebb909..84a02c9e0f0 100644 --- a/.pipelines/templates/release-MakeBlobPublic.yml +++ b/.pipelines/templates/release-MakeBlobPublic.yml @@ -17,7 +17,12 @@ jobs: dependsOn: CopyReleaseBlobApproval condition: and(succeeded(), ne('${{ parameters.SkipPSInfraInstallers }}', true)) pool: + name: PowerShell1ES type: windows + isCustom: true + demands: + - ImageOverride -equals PSMMS2019-Secure + variables: - group: 'PSInfraStorage' @@ -113,7 +118,11 @@ jobs: displayName: Copy global tools to PSInfra storage dependsOn: CopyBlobApproval pool: + name: PowerShell1ES type: windows + isCustom: true + demands: + - ImageOverride -equals PSMMS2019-Secure variables: - group: 'PSInfraStorage' diff --git a/.pipelines/templates/release-upload-buildinfo.yml b/.pipelines/templates/release-upload-buildinfo.yml index f2b06cd2010..ea7b90db8e3 100644 --- a/.pipelines/templates/release-upload-buildinfo.yml +++ b/.pipelines/templates/release-upload-buildinfo.yml @@ -8,7 +8,11 @@ jobs: displayName: Publish BuildInfo condition: succeeded() pool: + name: PowerShell1ES type: windows + isCustom: true + demands: + - ImageOverride -equals PSMMS2019-Secure variables: - name: runCodesignValidationInjection value: false @@ -45,14 +49,15 @@ jobs: displayName: Download build info artifact - pwsh: | - Import-Module '$(Build.SourcesDirectory)/PowerShell/tools/ci.psm1' + $toolsDirectory = '$(Build.SourcesDirectory)/tools' + Import-Module "$toolsDirectory/ci.psm1" $jsonFile = Get-Item "$ENV:PIPELINE_WORKSPACE/PSPackagesOfficial/BuildInfoJson/*.json" $fileName = Split-Path $jsonFile -Leaf $dateTime = [datetime]::UtcNow $dateTime = [datetime]::new($dateTime.Ticks - ($dateTime.Ticks % [timespan]::TicksPerSecond), $dateTime.Kind) - $metadata = Get-Content -LiteralPath '$(Build.SourcesDirectory)/PowerShell/tools/metadata.json' -ErrorAction Stop | ConvertFrom-Json + $metadata = Get-Content -LiteralPath "$toolsDirectory/metadata.json" -ErrorAction Stop | ConvertFrom-Json $stableRelease = $metadata.StableRelease.Latest $ltsRelease = $metadata.LTSRelease.Latest From 9aa6e06ce65a9c55601f6b4109d9812bd78de7e1 Mon Sep 17 00:00:00 2001 From: Travis Plunk Date: Fri, 15 Nov 2024 15:26:12 -0800 Subject: [PATCH 053/173] Added Deploy Box Product Pathway to GitHub Release and NuGet Release Pipelines (#24583) (#24595) Co-authored-by: Justin Chung <124807742+jshigetomi@users.noreply.github.com> --- .pipelines/PowerShell-Release-Official.yml | 99 +++++--- .../templates/release-checkout-pwsh-repo.yml | 13 + .../templates/release-download-packages.yml | 122 ++++++++++ .pipelines/templates/release-githubtasks.yml | 222 +++++++----------- .pipelines/templates/release-install-pwsh.yml | 34 +++ .../templates/release-publish-nuget.yml | 42 ++-- .pipelines/templates/uploadToAzure.yml | 20 ++ .../templates/variable/release-shared.yml | 32 +++ 8 files changed, 394 insertions(+), 190 deletions(-) create mode 100644 .pipelines/templates/release-checkout-pwsh-repo.yml create mode 100644 .pipelines/templates/release-download-packages.yml create mode 100644 .pipelines/templates/release-install-pwsh.yml create mode 100644 .pipelines/templates/variable/release-shared.yml diff --git a/.pipelines/PowerShell-Release-Official.yml b/.pipelines/PowerShell-Release-Official.yml index 195491ef161..f025c42f460 100644 --- a/.pipelines/PowerShell-Release-Official.yml +++ b/.pipelines/PowerShell-Release-Official.yml @@ -50,7 +50,7 @@ variables: - name: ob_outputDirectory value: '$(Build.ArtifactStagingDirectory)/ONEBRANCH_ARTIFACT' - name: WindowsContainerImage - value: 'onebranch.azurecr.io/windows/ltsc2019/vse2022:latest' + value: 'onebranch.azurecr.io/windows/ltsc2022/vse2022:latest' - name: LinuxContainerImage value: mcr.microsoft.com/onebranch/cbl-mariner/build:2.0 - name: ReleaseTagVar @@ -79,12 +79,12 @@ resources: extends: template: v2/OneBranch.Official.CrossPlat.yml@templates parameters: - # using Monitor as copy blob is being blocked by the network + release: + category: NonAzure featureFlags: - LinuxHostVersion: - Network: Monitor WindowsHostVersion: - Network: Monitor + Version: 2022 + Network: Netlock cloudvault: enabled: false globalSdl: @@ -110,13 +110,23 @@ extends: tsaOptionsFile: .config\tsaoptions.json stages: + - stage: DownloadPackages + displayName: 'Download Packages' + dependsOn: [] + jobs: + - template: /.pipelines/templates/release-download-packages.yml@self + - stage: msixbundle displayName: 'Create MSIX Bundle' + dependsOn: [] + variables: + ob_release_environment: Test jobs: - template: /.pipelines/templates/release-create-msix.yml@self - stage: validateSdk displayName: 'Validate SDK' + dependsOn: [] jobs: - template: /.pipelines/templates/release-validate-sdk.yml@self parameters: @@ -141,6 +151,7 @@ extends: - stage: gbltool displayName: 'Validate Global tools' + dependsOn: [] jobs: - template: /.pipelines/templates/release-validate-globaltools.yml@self parameters: @@ -158,6 +169,7 @@ extends: - stage: fxdpackages displayName: 'Validate FXD Packages' + dependsOn: [] jobs: - template: /.pipelines/templates/release-validate-fxdpackages.yml@self parameters: @@ -194,6 +206,7 @@ extends: - stage: validatePackages displayName: 'Validate Packages' + dependsOn: [] jobs: - template: /.pipelines/templates/release-validate-packagenames.yml@self @@ -262,23 +275,50 @@ extends: Update and merge the changelog for the release. This step is required for creating GitHub draft release. + - stage: PublishGitHubRelease + displayName: Publish GitHub Release + dependsOn: + - DownloadPackages + - UpdateChangeLog + variables: + ob_release_environment: Production + jobs: + - template: /.pipelines/templates/release-githubtasks.yml@self + + - stage: PushGitTagAndMakeDraftPublic + displayName: Push Git Tag and Make Draft Public + dependsOn: PublishGitHubRelease + jobs: + - template: /.pipelines/templates/approvalJob.yml@self + parameters: + displayName: Push Git Tag + jobName: PushGitTag + instructions: | + Push the git tag to upstream + + - template: /.pipelines/templates/approvalJob.yml@self + parameters: + displayName: Make Draft Public + dependsOnJob: PushGitTag + jobName: DraftPublic + instructions: | + Make the GitHub Release Draft Public + - stage: BlobPublic displayName: Make Blob Public - dependsOn: UpdateChangeLog + dependsOn: + - UpdateChangeLog + - PushGitTagAndMakeDraftPublic jobs: - template: /.pipelines/templates/release-MakeBlobPublic.yml@self parameters: - SkipPSInfraInstallers: ${{ parameters.SkipPSInfraInstallers }} - - - stage: PublishGitHubRelease - displayName: Publish GitHub Release - dependsOn: BlobPublic - jobs: - - template: /.pipelines/templates/release-githubtasks.yml@self - + SkipPSInfraInstallers: ${{ parameters.SkipPSInfraInstallers }} + - stage: PublishNuGet displayName: Publish NuGet - dependsOn: PublishGitHubRelease + dependsOn: PushGitTagAndMakeDraftPublic + variables: + ob_release_environment: Production jobs: - template: /.pipelines/templates/release-publish-nuget.yml@self parameters: @@ -286,14 +326,14 @@ extends: - stage: PublishPMC displayName: Publish PMC - dependsOn: PublishGitHubRelease + dependsOn: PushGitTagAndMakeDraftPublic jobs: - template: /.pipelines/templates/release-publish-pmc.yml@self parameters: skipPublish: ${{ parameters.SkipPMCPublish }} - stage: ReleaseDocker - dependsOn: PublishGitHubRelease + dependsOn: PushGitTagAndMakeDraftPublic displayName: 'Docker Release' jobs: - template: /.pipelines/templates/approvalJob.yml@self @@ -312,7 +352,7 @@ extends: Kickoff docker release - stage: UpdateDotnetDocker - dependsOn: PublishGitHubRelease + dependsOn: PushGitTagAndMakeDraftPublic displayName: Update DotNet SDK Docker images jobs: - template: /.pipelines/templates/approvalJob.yml@self @@ -327,7 +367,7 @@ extends: 4. create PR targeting nightly branch - stage: UpdateWinGet - dependsOn: PublishGitHubRelease + dependsOn: PushGitTagAndMakeDraftPublic displayName: Add manifest entry to winget jobs: - template: /.pipelines/templates/approvalJob.yml@self @@ -338,7 +378,7 @@ extends: This is typically done by the community 1-2 days after the release. - stage: PublishMsix - dependsOn: PublishGitHubRelease + dependsOn: PushGitTagAndMakeDraftPublic displayName: Publish MSIX to store jobs: - template: /.pipelines/templates/approvalJob.yml@self @@ -349,7 +389,7 @@ extends: Ask Steve to release MSIX bundle package to Store - stage: PublishVPack - dependsOn: PublishGitHubRelease + dependsOn: PushGitTagAndMakeDraftPublic displayName: Release vPack jobs: - template: /.pipelines/templates/approvalJob.yml@self @@ -367,20 +407,22 @@ extends: # - template: templates/release-UpdateDepsJson.yml - stage: UploadBuildInfoJson - dependsOn: PublishGitHubRelease + dependsOn: PushGitTagAndMakeDraftPublic displayName: Upload BuildInfo.json jobs: - template: /.pipelines/templates/release-upload-buildinfo.yml@self - stage: ReleaseSymbols - dependsOn: PublishGitHubRelease + dependsOn: PushGitTagAndMakeDraftPublic displayName: Release Symbols jobs: - template: /.pipelines/templates/release-symbols.yml@self - stage: ChangesToMaster displayName: Ensure changes are in GH master - dependsOn: ['PublishNuGet', 'PublishPMC'] + dependsOn: + - PublishNuGet + - PublishPMC jobs: - template: /.pipelines/templates/approvalJob.yml@self parameters: @@ -391,7 +433,7 @@ extends: - stage: ReleaseSnap displayName: Release Snap - dependsOn: 'ChangesToMaster' + dependsOn: ChangesToMaster jobs: - template: /.pipelines/templates/approvalJob.yml@self parameters: @@ -402,7 +444,7 @@ extends: - stage: ReleaseToMU displayName: Release to MU - dependsOn: ['PublishNuGet', 'PublishPMC', 'ChangesToMaster'] + dependsOn: PushGitTagAndMakeDraftPublic # This only needs the blob to be available jobs: - template: /.pipelines/templates/approvalJob.yml@self parameters: @@ -412,7 +454,10 @@ extends: - stage: ReleaseClose displayName: Finish Release - dependsOn: ['ReleaseToMU', 'ReleaseSymbols', 'ReleaseSnap'] + dependsOn: + - ReleaseToMU + - ReleaseSymbols + - ReleaseSnap jobs: - template: /.pipelines/templates/approvalJob.yml@self parameters: diff --git a/.pipelines/templates/release-checkout-pwsh-repo.yml b/.pipelines/templates/release-checkout-pwsh-repo.yml new file mode 100644 index 00000000000..9a7486887a6 --- /dev/null +++ b/.pipelines/templates/release-checkout-pwsh-repo.yml @@ -0,0 +1,13 @@ +steps: + - pwsh: | + Write-Verbose -Verbose "Deploy Box Product Pathway Does Not Support the `"checkout`" task" + if ($ENV:BUILD_REASON -eq 'PullRequest') { + throw 'We dont support PRs' + } + + Write-Verbose -Verbose $ENV:BUILD_SOURCEBRANCH + $branchName = $ENV:BUILD_SOURCEBRANCH -replace '^refs/heads/' + Write-Verbose -Verbose "Branch Name: $branchName" + git clone --depth 1 --branch $branchName https://$(mscodehubCodeReadPat)@mscodehub.visualstudio.com/PowerShellCore/_git/PowerShell '$(Pipeline.Workspace)/PowerShell' + cd $(Pipeline.Workspace)/PowerShell + displayName: Checkout Powershell Repository diff --git a/.pipelines/templates/release-download-packages.yml b/.pipelines/templates/release-download-packages.yml new file mode 100644 index 00000000000..27a3098d1e1 --- /dev/null +++ b/.pipelines/templates/release-download-packages.yml @@ -0,0 +1,122 @@ +jobs: +- job: upload_packages + displayName: Upload packages + condition: succeeded() + pool: + type: windows + variables: + - template: ./variable/release-shared.yml@self + parameters: + REPOROOT: $(Build.SourcesDirectory) + SBOM: true + + steps: + - pwsh: | + Get-ChildItem -Path env: | Out-String -width 9999 -Stream | write-Verbose -Verbose + displayName: Capture environment variables + + - download: PSPackagesOfficial + artifact: drop_linux_package_deb + displayName: Download linux deb packages + + - download: PSPackagesOfficial + artifact: drop_linux_package_fxdependent + displayName: Download linux fx packages + + - download: PSPackagesOfficial + artifact: drop_linux_package_mariner_arm64 + displayName: Download linux mariner packages + + - download: PSPackagesOfficial + artifact: drop_linux_package_mariner_x64 + displayName: Download linux mariner x64 packages + + - download: PSPackagesOfficial + artifact: drop_linux_package_minSize + displayName: Download linux min packages + + - download: PSPackagesOfficial + artifact: drop_linux_package_rpm + displayName: Download linux rpm packages + + - download: PSPackagesOfficial + artifact: drop_linux_package_tar + displayName: Download linux tar packages + + - download: PSPackagesOfficial + artifact: drop_linux_package_tar_alpine + displayName: Download linux tar alpine packages + + - download: PSPackagesOfficial + artifact: drop_linux_package_tar_alpine_fxd + displayName: Download linux tar alpine fxd packages + + - download: PSPackagesOfficial + artifact: drop_linux_package_tar_arm + displayName: Download linux tar arm packages + + - download: PSPackagesOfficial + artifact: drop_linux_package_tar_arm64 + displayName: Download linux tar arm 64 packages + + - download: PSPackagesOfficial + artifact: drop_nupkg_build_nupkg + displayName: Download nupkg packages + + - download: PSPackagesOfficial + artifact: drop_windows_package_package_win_arm64 + displayName: Download windows arm64 packages + + - download: PSPackagesOfficial + artifact: drop_windows_package_package_win_fxdependent + displayName: Download windows fxdependent packages + + - download: PSPackagesOfficial + artifact: drop_windows_package_package_win_fxdependentWinDesktop + displayName: Download windows fxdependentWinDesktop packages + + - download: PSPackagesOfficial + artifact: drop_windows_package_package_win_minsize + displayName: Download windows minsize packages + + - download: PSPackagesOfficial + artifact: drop_windows_package_package_win_x64 + displayName: Download windows x64 packages + + - download: PSPackagesOfficial + artifact: drop_windows_package_package_win_x86 + displayName: Download windows x86 packages + + - download: PSPackagesOfficial + artifact: macos-pkgs + displayName: Download macos tar packages + + - download: PSPackagesOfficial + artifact: drop_mac_package_sign_package_macos_arm64 + displayName: Download macos arm packages + + - download: PSPackagesOfficial + artifact: drop_mac_package_sign_package_macos_x64 + displayName: Download macos x64 packages + + - pwsh: | + Get-ChildItem '$(Pipeline.Workspace)/PSPackagesOfficial' -Recurse | Select-Object -ExpandProperty FullName + displayName: 'Capture downloads' + + - pwsh: | + $PackagesPath = '$(Pipeline.Workspace)/PSPackagesOfficial' + Write-Verbose -Verbose "Copying Github Release files in $PackagesPath to use in Release Pipeline" + + Write-Verbose -Verbose "Creating output directory for GitHub Release files: $(ob_outputDirectory)/GitHubPackages" + New-Item -Path $(ob_outputDirectory)/GitHubPackages -ItemType Directory -Force + Get-ChildItem -Path "$PackagesPath/*" -Recurse | + Where-Object { $_.Extension -notin '.msix', '.nupkg' } | + Where-Object { $_.Extension -in '.gz', '.pkg', '.msi', '.zip', '.deb', '.rpm', '.zip' } | + Copy-Item -Destination $(ob_outputDirectory)/GitHubPackages -Recurse -Verbose + + Write-Verbose -Verbose "Creating output directory for NuGet packages: $(ob_outputDirectory)/NuGetPackages" + New-Item -Path $(ob_outputDirectory)/NuGetPackages -ItemType Directory -Force + Get-ChildItem -Path "$PackagesPath/*" -Recurse | + Where-Object { $_.Extension -eq '.nupkg' } | + Copy-Item -Destination $(ob_outputDirectory)/NuGetPackages -Recurse -Verbose + displayName: Copy downloads to Artifacts diff --git a/.pipelines/templates/release-githubtasks.yml b/.pipelines/templates/release-githubtasks.yml index c1e5d1a06a7..bfc500585b0 100644 --- a/.pipelines/templates/release-githubtasks.yml +++ b/.pipelines/templates/release-githubtasks.yml @@ -3,162 +3,114 @@ jobs: displayName: Create GitHub Release Draft condition: succeeded() pool: - type: windows + type: release + os: windows + templateContext: + inputs: + - input: pipelineArtifact + artifactName: drop_DownloadPackages_upload_packages variables: - - name: runCodesignValidationInjection - value: false - - name: NugetSecurityAnalysisWarningLevel - value: none - - name: DOTNET_SKIP_FIRST_TIME_EXPERIENCE - value: 1 - - group: 'mscodehub-code-read-akv' - - group: 'Azure Blob variable group' - - group: 'GitHubTokens' - - name: ob_outputDirectory - value: '$(Build.ArtifactStagingDirectory)/ONEBRANCH_ARTIFACT' - - name: ob_sdl_codeSignValidation_enabled - value: false - - name: ob_sdl_binskim_enabled - value: false - - name: ob_sdl_tsa_configFile - value: $(Build.SourcesDirectory)\PowerShell\.config\tsaoptions.json - - name: ob_sdl_credscan_suppressionsFile - value: $(Build.SourcesDirectory)\PowerShell\.config\suppress.json + - template: ./variable/release-shared.yml@self steps: - - checkout: self - clean: true - env: - ob_restore_phase: true # This ensures checkout is done at the beginning of the restore phase - - - template: release-SetReleaseTagAndContainerName.yml - - - pwsh: | - Get-ChildItem Env: + - task: PowerShell@2 + inputs: + targetType: inline + script: | + Get-ChildItem Env: | Out-String -Stream | write-Verbose -Verbose displayName: 'Capture Environment Variables' - - pwsh: | - # Uninstall Azure RM modules - $azRmModules = Get-Module -Name AzureRM* -ListAvailable - if ($azRmModules) { - $azRmModules | Remove-Module -Force - } - - # Install Az.Storage module if not already installed - if (-not (Get-Module -Name Az.Storage -ListAvailable)) { - Install-Module -Name Az.Storage -Force -AllowClobber -Scope CurrentUser -Verbose - } - displayName: Install Az.Storage module - - - task: AzurePowerShell@5 - displayName: Download packages from Azure Storage - inputs: - azureSubscription: az-blob-cicd-infra - scriptType: inlineScript - azurePowerShellVersion: LatestVersion - pwsh: true - inline: | - $storageAccount = "$(StorageAccount)" - $containerName = "$(AzureVersion)" - $destinationPath = "$(System.ArtifactsDirectory)" - - # Get storage account context - $storageContext = New-AzStorageContext -StorageAccountName $storageAccount - - $blobList = Get-AzStorageBlob -Container $containerName -Context $storageContext - foreach ($blob in $blobList) { - $blobName = $blob.Name - $destinationFile = Join-Path -Path $destinationPath -ChildPath $blobName - Get-AzStorageBlobContent -Container $containerName -Blob $blobName -Destination $destinationFile -Context $storageContext -Force - Write-Output "Downloaded $blobName to $destinationFile" - } + - template: release-install-pwsh.yml - $packagesPath = Get-ChildItem -Path $destinationPath\*.deb -Recurse -File | Select-Object -First 1 -ExpandProperty DirectoryName - Write-Host "sending -- vso[task.setvariable variable=PackagesRoot]$packagesPath" - Write-Host "##vso[task.setvariable variable=PackagesRoot]$packagesPath" + - template: release-checkout-pwsh-repo.yml - - pwsh: | - Get-ChildItem $(System.ArtifactsDirectory)\* -recurse | Select-Object -ExpandProperty FullName - displayName: Capture downloaded artifacts + - template: release-SetReleaseTagAndContainerName.yml - - pwsh: | - git clone https://$(mscodehubCodeReadPat)@mscodehub.visualstudio.com/PowerShellCore/_git/Internal-PowerShellTeam-Tools '$(Pipeline.Workspace)/tools' + - task: PowerShell@2 + inputs: + targetType: inline + pwsh: true + script: | + git clone --depth 1 https://$(mscodehubCodeReadPat)@mscodehub.visualstudio.com/PowerShellCore/_git/Internal-PowerShellTeam-Tools '$(Pipeline.Workspace)/tools' displayName: Clone Internal-Tools repository - - pwsh: | - $Path = "$(System.ArtifactsDirectory)" - $OutputPath = Join-Path $Path 'hashes.sha256' - $srcPaths = @($Path) - $packages = Get-ChildItem -Path $srcPaths -Include * -Recurse -File - $checksums = $packages | - ForEach-Object { - Write-Verbose -Verbose "Generating checksum file for $($_.FullName)" - $packageName = $_.Name - $hash = (Get-FileHash -Path $_.FullName -Algorithm SHA256).Hash.ToLower() - # the '*' before the packagename signifies it is a binary - "$hash *$packageName" - } - $checksums | Out-File -FilePath $OutputPath -Force - $fileContent = Get-Content -Path $OutputPath -Raw | Out-String - Write-Verbose -Verbose -Message $fileContent + - task: PowerShell@2 + inputs: + targetType: inline + pwsh: true + script: | + $Path = "$(Pipeline.Workspace)/GitHubPackages" + $OutputPath = Join-Path $Path 'hashes.sha256' + $packages = Get-ChildItem -Path $Path -Include * -Recurse -File + $checksums = $packages | + ForEach-Object { + Write-Verbose -Verbose "Generating checksum file for $($_.FullName)" + $packageName = $_.Name + $hash = (Get-FileHash -Path $_.FullName -Algorithm SHA256).Hash.ToLower() + # the '*' before the packagename signifies it is a binary + "$hash *$packageName" + } + $checksums | Out-File -FilePath $OutputPath -Force + $fileContent = Get-Content -Path $OutputPath -Raw | Out-String + Write-Verbose -Verbose -Message $fileContent displayName: Add sha256 hashes - - pwsh: | - $releaseVersion = '$(ReleaseTag)' -replace '^v','' - $vstsCommandString = "vso[task.setvariable variable=ReleaseVersion]$releaseVersion" - Write-Host "sending " + $vstsCommandString - Write-Host "##$vstsCommandString" + - task: PowerShell@2 + inputs: + targetType: inline + pwsh: true + script: | + $releaseVersion = '$(ReleaseTag)' -replace '^v','' + $vstsCommandString = "vso[task.setvariable variable=ReleaseVersion]$releaseVersion" + Write-Host "sending " + $vstsCommandString + Write-Host "##$vstsCommandString" displayName: 'Set release version' - - pwsh: | - Import-module '$(Pipeline.Workspace)/tools/Scripts/GitHubRelease.psm1' - $releaseVersion = '$(ReleaseTag)' -replace '^v','' - $semanticVersion = [System.Management.Automation.SemanticVersion]$releaseVersion + - task: PowerShell@2 + inputs: + targetType: inline + pwsh: true + script: | + Get-ChildItem $(Pipeline.Workspace) -recurse | Select-Object -ExpandProperty FullName + displayName: List all files in the workspace + + - task: PowerShell@2 + inputs: + targetType: inline + pwsh: true + script: | + Import-module '$(Pipeline.Workspace)/tools/Scripts/GitHubRelease.psm1' + $releaseVersion = '$(ReleaseTag)' -replace '^v','' + $semanticVersion = [System.Management.Automation.SemanticVersion]$releaseVersion - $isPreview = $semanticVersion.PreReleaseLabel -ne $null + $isPreview = $semanticVersion.PreReleaseLabel -ne $null - $fileName = if ($isPreview) { - "preview.md" - } - else { - $semanticVersion.Major.ToString() + "." + $semanticVersion.Minor.ToString() + ".md" - } + $fileName = if ($isPreview) { + "preview.md" + } + else { + $semanticVersion.Major.ToString() + "." + $semanticVersion.Minor.ToString() + ".md" + } - $filePath = "$env:BUILD_SOURCESDIRECTORY/PowerShell/CHANGELOG/$fileName" - Write-Verbose -Verbose "Selected Log file: $filePath" + $filePath = "$(Pipeline.Workspace)/PowerShell/CHANGELOG/$fileName" + Write-Verbose -Verbose "Selected Log file: $filePath" - if (-not (Test-Path $filePath)) { - throw "$filePath not found" - } + if (-not (Test-Path $filePath)) { + throw "$filePath not found" + } - $changelog = Get-Content -Path $filePath + $changelog = Get-Content -Path $filePath - $startPattern = "^## \[" + ([regex]::Escape($releaseVersion)) + "\]" - $endPattern = "^## \[{0}\.{1}\.{2}*" -f $semanticVersion.Major, $semanticVersion.Minor, $semanticVersion.Patch + $startPattern = "^## \[" + ([regex]::Escape($releaseVersion)) + "\]" + $endPattern = "^## \[{0}\.{1}\.{2}*" -f $semanticVersion.Major, $semanticVersion.Minor, $semanticVersion.Patch - $clContent = $changelog | ForEach-Object { - if ($_ -match $startPattern) { $outputLine = $true } - elseif ($_ -match $endPattern) { $outputLine = $false } - if ($outputLine) { $_} - } | Out-String + $clContent = $changelog | ForEach-Object { + if ($_ -match $startPattern) { $outputLine = $true } + elseif ($_ -match $endPattern) { $outputLine = $false } + if ($outputLine) { $_} + } | Out-String - Write-Verbose -Verbose "Selected content: `n$clContent" + Write-Verbose -Verbose "Selected content: `n$clContent" - Publish-ReleaseDraft -Tag '$(ReleaseTag)' -Name '$(ReleaseTag) Release of PowerShell' -Description $clContent -User PowerShell -Repository PowerShell -PackageFolder $(PackagesRoot) -Token $(GitHubReleasePat) + Publish-ReleaseDraft -Tag '$(ReleaseTag)' -Name '$(ReleaseTag) Release of PowerShell' -Description $clContent -User PowerShell -Repository PowerShell -PackageFolder "$(Pipeline.Workspace)/GitHubPackages" -Token $(GitHubReleasePat) displayName: Publish Release Draft - -- template: /.pipelines/templates/approvalJob.yml@self - parameters: - displayName: Push Git Tag - jobName: PushGitTag - dependsOnJob: GithubReleaseDraft - instructions: | - Push the git tag to upstream - -- template: /.pipelines/templates/approvalJob.yml@self - parameters: - displayName: Make Draft Public - jobName: DraftPublic - dependsOnJob: PushGitTag - instructions: | - Make the GitHub Release Draft Public diff --git a/.pipelines/templates/release-install-pwsh.yml b/.pipelines/templates/release-install-pwsh.yml new file mode 100644 index 00000000000..9d7080a7e78 --- /dev/null +++ b/.pipelines/templates/release-install-pwsh.yml @@ -0,0 +1,34 @@ +steps: + - task: PowerShell@2 + inputs: + targetType: inline + script: | + $localInstallerPath = Get-ChildItem -Path "$(Pipeline.Workspace)/GitHubPackages" -Filter '*win-x64.msi' | Select-Object -First 1 -ExpandProperty FullName + if (Test-Path -Path $localInstallerPath) { + Write-Verbose -Verbose "Installer found at $localInstallerPath" + } else { + throw "Installer not found" + } + Write-Verbose -Verbose "Installing PowerShell via msiexec" + Start-Process -FilePath msiexec -ArgumentList "/package $localInstallerPath /quiet REGISTER_MANIFEST=1" -Wait -NoNewWindow + $pwshPath = Get-ChildItem -Directory -Path 'C:\Program Files\PowerShell\7*' | Select-Object -First 1 -ExpandProperty FullName + if (Test-Path -Path $pwshPath) { + Write-Verbose -Verbose "PowerShell installed at $pwshPath" + Write-Verbose -Verbose "Adding pwsh to env:PATH" + Write-Host "##vso[task.prependpath]$pwshPath" + } else { + throw "PowerShell not installed" + } + displayName: Install pwsh 7 + + - task: PowerShell@2 + inputs: + targetType: inline + pwsh: true + script: | + Write-Verbose -Verbose "Pwsh 7 Installed" + Write-Verbose -Verbose "env:Path: " + $env:PATH -split ';' | ForEach-Object { + Write-Verbose -Verbose $_ + } + displayName: Check pwsh 7 installation diff --git a/.pipelines/templates/release-publish-nuget.yml b/.pipelines/templates/release-publish-nuget.yml index e9bebf5d93e..b29f29c3dd5 100644 --- a/.pipelines/templates/release-publish-nuget.yml +++ b/.pipelines/templates/release-publish-nuget.yml @@ -8,31 +8,20 @@ jobs: displayName: Publish to NuGet condition: succeeded() pool: - type: windows + type: release + os: windows + templateContext: + inputs: + - input: pipelineArtifact + pipeline: PSPackagesOfficial + artifactName: drop_upload_upload_packages variables: - - name: runCodesignValidationInjection - value: false - - name: NugetSecurityAnalysisWarningLevel - value: none - - name: DOTNET_SKIP_FIRST_TIME_EXPERIENCE - value: 1 - - group: 'mscodehub-code-read-akv' - - name: ob_outputDirectory - value: '$(Build.ArtifactStagingDirectory)/ONEBRANCH_ARTIFACT' - - name: ob_sdl_codeSignValidation_enabled - value: false - - name: ob_sdl_binskim_enabled - value: false - - name: ob_sdl_tsa_configFile - value: $(Build.SourcesDirectory)\PowerShell\.config\tsaoptions.json - - name: ob_sdl_credscan_suppressionsFile - value: $(Build.SourcesDirectory)\PowerShell\.config\suppress.json + - template: ./variable/release-shared.yml@self steps: - - checkout: self - clean: true - env: - ob_restore_phase: true # This ensures checkout is done at the beginning of the restore phase + - template: release-install-pwsh.yml + + - template: release-checkout-pwsh-repo.yml - template: release-SetReleaseTagAndContainerName.yml @@ -40,23 +29,20 @@ jobs: Get-ChildItem Env: displayName: 'Capture Environment Variables' - - download: PSPackagesOfficial - artifact: drop_nupkg_build_nupkg - displayName: Download nuget packages - - pwsh: | #Exclude all global tool packages. Their names start with 'PowerShell.' $null = New-Item -ItemType Directory -Path "$(Pipeline.Workspace)/release" - Copy-Item "$ENV:PIPELINE_WORKSPACE/PSPackagesOfficial/drop_nupkg_build_nupkg/*.nupkg" -Destination "$(Pipeline.Workspace)/release" -Exclude "PowerShell.*.nupkg" -Force -Verbose + Copy-Item "$(Pipeline.Workspace)/NuGetPackages/*.nupkg" -Destination "$(Pipeline.Workspace)/release" -Exclude "PowerShell.*.nupkg" -Force -Verbose $releaseVersion = '$(VERSION)' - $globalToolPath = "$ENV:PIPELINE_WORKSPACE/PSPackagesOfficial/drop_nupkg_build_nupkg/PowerShell.$releaseVersion.nupkg" + $globalToolPath = "$(Pipeline.Workspace)/NuGetPackages/PowerShell.$releaseVersion.nupkg" if ($releaseVersion -notlike '*-*') { # Copy the global tool package for stable releases Copy-Item $globalToolPath -Destination "$(Pipeline.Workspace)/release" } + Write-Verbose -Verbose "The .nupkgs below will be pushed:" Get-ChildItem "$(Pipeline.Workspace)/release" -recurse displayName: Download and capture nupkgs condition: and(ne('${{ parameters.skipPublish }}', 'false'), succeeded()) diff --git a/.pipelines/templates/uploadToAzure.yml b/.pipelines/templates/uploadToAzure.yml index 2bb48767ae4..50a4a676fee 100644 --- a/.pipelines/templates/uploadToAzure.yml +++ b/.pipelines/templates/uploadToAzure.yml @@ -5,6 +5,8 @@ jobs: pool: type: windows variables: + - name: ob_sdl_sbom_enabled + value: false - name: runCodesignValidationInjection value: false - name: NugetSecurityAnalysisWarningLevel @@ -233,6 +235,24 @@ jobs: Get-ChildItem '$(Build.ArtifactStagingDirectory)/downloads' | Select-Object -ExpandProperty FullName displayName: 'Capture downloads' + # - pwsh: | + # Write-Verbose -Verbose "Copying Github Release files in $(Build.ArtifactStagingDirectory)/downloads to use in Release Pipeline" + # + # Write-Verbose -Verbose "Creating output directory for GitHub Release files: $(ob_outputDirectory)/GitHubPackages" + # New-Item -Path $(ob_outputDirectory)/GitHubPackages -ItemType Directory -Force + # Get-ChildItem -Path "$(Build.ArtifactStagingDirectory)/downloads/*" -Recurse | + # Where-Object { $_.Extension -notin '.msix', '.nupkg' } | + # ForEach-Object { Write-Verbose -Verbose $_.FullName ; $_ } | + # Copy-Item -Destination $(ob_outputDirectory)/GitHubPackages -Recurse + # + # Write-Verbose -Verbose "Creating output directory for NuGet packages: $(ob_outputDirectory)/NuGetPackages" + # New-Item -Path $(ob_outputDirectory)/NuGetPackages -ItemType Directory -Force + # Get-ChildItem -Path "$(Build.ArtifactStagingDirectory)/downloads/*" -Recurse | + # Where-Object { $_.Extension -eq '.nupkg' } | + # ForEach-Object { Write-Verbose -Verbose $_.FullName ; $_ } | + # Copy-Item -Destination $(ob_outputDirectory)/NuGetPackages -Recurse + # displayName: Copy downloads to Artifacts + - pwsh: | # Create output directory for packages which have been uploaded to blob storage New-Item -Path $(Build.ArtifactStagingDirectory)/uploaded -ItemType Directory -Force diff --git a/.pipelines/templates/variable/release-shared.yml b/.pipelines/templates/variable/release-shared.yml new file mode 100644 index 00000000000..92ab56199d4 --- /dev/null +++ b/.pipelines/templates/variable/release-shared.yml @@ -0,0 +1,32 @@ +parameters: + - name: REPOROOT + type: string + default: $(Build.SourcesDirectory)\PowerShell + - name: SBOM + type: boolean + default: false + +variables: + - name: ob_signing_setup_enabled + value: false + - name: ob_sdl_sbom_enabled + value: ${{ parameters.SBOM }} + - name: runCodesignValidationInjection + value: false + - name: DOTNET_SKIP_FIRST_TIME_EXPERIENCE + value: 1 + - group: 'mscodehub-code-read-akv' + - group: 'Azure Blob variable group' + - group: 'GitHubTokens' + - name: ob_outputDirectory + value: '$(Build.ArtifactStagingDirectory)/ONEBRANCH_ARTIFACT' + - name: ob_sdl_codeSignValidation_enabled + value: false + - name: ob_sdl_binskim_enabled + value: false + - name: ob_sdl_tsa_configFile + value: ${{ parameters.REPOROOT }}\.config\tsaoptions.json + - name: ob_sdl_credscan_suppressionsFile + value: ${{ parameters.REPOROOT }}\.config\suppress.json + - name: ob_sdl_codeql_compiled_enabled + value: false From 0e5c5aa8f629b386ef413c685a3eb1c96db9105d Mon Sep 17 00:00:00 2001 From: Aditya Patwardhan Date: Fri, 15 Nov 2024 15:46:51 -0800 Subject: [PATCH 054/173] Update nuget publish to use Deploy Box (#24596) (#24597) --- .pipelines/templates/release-publish-nuget.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.pipelines/templates/release-publish-nuget.yml b/.pipelines/templates/release-publish-nuget.yml index b29f29c3dd5..db0978e0b0b 100644 --- a/.pipelines/templates/release-publish-nuget.yml +++ b/.pipelines/templates/release-publish-nuget.yml @@ -13,8 +13,8 @@ jobs: templateContext: inputs: - input: pipelineArtifact - pipeline: PSPackagesOfficial - artifactName: drop_upload_upload_packages + artifactName: drop_DownloadPackages_upload_packages + variables: - template: ./variable/release-shared.yml@self From c2353537f81c94072d326141cf048b4035b2c0fa Mon Sep 17 00:00:00 2001 From: Travis Plunk Date: Tue, 14 Jan 2025 13:34:25 -0800 Subject: [PATCH 055/173] Update machine pool for copy blob and upload buildinfo stage (#24587) (#24776) Co-authored-by: Aditya Patwardhan --- .pipelines/PowerShell-Release-Official.yml | 24 +++++++++++----------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/.pipelines/PowerShell-Release-Official.yml b/.pipelines/PowerShell-Release-Official.yml index f025c42f460..03defa5d128 100644 --- a/.pipelines/PowerShell-Release-Official.yml +++ b/.pipelines/PowerShell-Release-Official.yml @@ -79,7 +79,7 @@ resources: extends: template: v2/OneBranch.Official.CrossPlat.yml@templates parameters: - release: + release: category: NonAzure featureFlags: WindowsHostVersion: @@ -277,14 +277,14 @@ extends: - stage: PublishGitHubRelease displayName: Publish GitHub Release - dependsOn: + dependsOn: - DownloadPackages - UpdateChangeLog variables: ob_release_environment: Production jobs: - template: /.pipelines/templates/release-githubtasks.yml@self - + - stage: PushGitTagAndMakeDraftPublic displayName: Push Git Tag and Make Draft Public dependsOn: PublishGitHubRelease @@ -294,8 +294,8 @@ extends: displayName: Push Git Tag jobName: PushGitTag instructions: | - Push the git tag to upstream - + Push the git tag to upstream + - template: /.pipelines/templates/approvalJob.yml@self parameters: displayName: Make Draft Public @@ -303,17 +303,17 @@ extends: jobName: DraftPublic instructions: | Make the GitHub Release Draft Public - + - stage: BlobPublic displayName: Make Blob Public - dependsOn: + dependsOn: - UpdateChangeLog - PushGitTagAndMakeDraftPublic jobs: - template: /.pipelines/templates/release-MakeBlobPublic.yml@self parameters: - SkipPSInfraInstallers: ${{ parameters.SkipPSInfraInstallers }} - + SkipPSInfraInstallers: ${{ parameters.SkipPSInfraInstallers }} + - stage: PublishNuGet displayName: Publish NuGet dependsOn: PushGitTagAndMakeDraftPublic @@ -420,8 +420,8 @@ extends: - stage: ChangesToMaster displayName: Ensure changes are in GH master - dependsOn: - - PublishNuGet + dependsOn: + - PublishNuGet - PublishPMC jobs: - template: /.pipelines/templates/approvalJob.yml@self @@ -454,7 +454,7 @@ extends: - stage: ReleaseClose displayName: Finish Release - dependsOn: + dependsOn: - ReleaseToMU - ReleaseSymbols - ReleaseSnap From 7979599d32df0b6370190ad74d095b64627da5bc Mon Sep 17 00:00:00 2001 From: Travis Plunk Date: Wed, 15 Jan 2025 09:52:49 -0800 Subject: [PATCH 056/173] Update `HelpInfoUri` for 7.5 (#24610) (#24777) Co-authored-by: Sean Wheeler --- .../Microsoft.PowerShell.Host.psd1 | 2 +- .../Microsoft.PowerShell.Management.psd1 | 2 +- .../Microsoft.PowerShell.Security.psd1 | 2 +- .../Microsoft.PowerShell.Utility.psd1 | 2 +- src/Modules/Windows/CimCmdlets/CimCmdlets.psd1 | 2 +- .../Microsoft.PowerShell.Diagnostics.psd1 | 2 +- .../Microsoft.PowerShell.Management.psd1 | 2 +- .../Microsoft.PowerShell.Security.psd1 | 2 +- .../Microsoft.PowerShell.Utility.psd1 | 2 +- .../Microsoft.WSMan.Management.psd1 | 2 +- .../Windows/PSDiagnostics/PSDiagnostics.psd1 | 2 +- .../help/UpdatableHelpCommandBase.cs | 14 +++++++------- 12 files changed, 18 insertions(+), 18 deletions(-) diff --git a/src/Modules/Shared/Microsoft.PowerShell.Host/Microsoft.PowerShell.Host.psd1 b/src/Modules/Shared/Microsoft.PowerShell.Host/Microsoft.PowerShell.Host.psd1 index e6d616aa61d..3c2581795f7 100644 --- a/src/Modules/Shared/Microsoft.PowerShell.Host/Microsoft.PowerShell.Host.psd1 +++ b/src/Modules/Shared/Microsoft.PowerShell.Host/Microsoft.PowerShell.Host.psd1 @@ -10,5 +10,5 @@ FunctionsToExport = @() CmdletsToExport="Start-Transcript", "Stop-Transcript" AliasesToExport = @() NestedModules="Microsoft.PowerShell.ConsoleHost.dll" -HelpInfoURI = 'https://aka.ms/powershell73-help' +HelpInfoURI = 'https://aka.ms/powershell75-help' } diff --git a/src/Modules/Unix/Microsoft.PowerShell.Management/Microsoft.PowerShell.Management.psd1 b/src/Modules/Unix/Microsoft.PowerShell.Management/Microsoft.PowerShell.Management.psd1 index 6eb576cdf03..21563c1da7c 100644 --- a/src/Modules/Unix/Microsoft.PowerShell.Management/Microsoft.PowerShell.Management.psd1 +++ b/src/Modules/Unix/Microsoft.PowerShell.Management/Microsoft.PowerShell.Management.psd1 @@ -7,7 +7,7 @@ ModuleVersion="7.0.0.0" CompatiblePSEditions = @("Core") PowerShellVersion="3.0" NestedModules="Microsoft.PowerShell.Commands.Management.dll" -HelpInfoURI = 'https://aka.ms/powershell73-help' +HelpInfoURI = 'https://aka.ms/powershell75-help' FunctionsToExport = @() AliasesToExport = @("gcb", "gtz", "scb") CmdletsToExport=@("Add-Content", diff --git a/src/Modules/Unix/Microsoft.PowerShell.Security/Microsoft.PowerShell.Security.psd1 b/src/Modules/Unix/Microsoft.PowerShell.Security/Microsoft.PowerShell.Security.psd1 index 8268326aa74..adab0df2849 100644 --- a/src/Modules/Unix/Microsoft.PowerShell.Security/Microsoft.PowerShell.Security.psd1 +++ b/src/Modules/Unix/Microsoft.PowerShell.Security/Microsoft.PowerShell.Security.psd1 @@ -10,5 +10,5 @@ FunctionsToExport = @() CmdletsToExport = "Get-Credential", "Get-ExecutionPolicy", "Set-ExecutionPolicy", "ConvertFrom-SecureString", "ConvertTo-SecureString", "Get-PfxCertificate" , "Protect-CmsMessage", "Unprotect-CmsMessage", "Get-CmsMessage" AliasesToExport = @() NestedModules = "Microsoft.PowerShell.Security.dll" -HelpInfoURI = 'https://aka.ms/powershell73-help' +HelpInfoURI = 'https://aka.ms/powershell75-help' } diff --git a/src/Modules/Unix/Microsoft.PowerShell.Utility/Microsoft.PowerShell.Utility.psd1 b/src/Modules/Unix/Microsoft.PowerShell.Utility/Microsoft.PowerShell.Utility.psd1 index 1d31d5889e8..df841837696 100644 --- a/src/Modules/Unix/Microsoft.PowerShell.Utility/Microsoft.PowerShell.Utility.psd1 +++ b/src/Modules/Unix/Microsoft.PowerShell.Utility/Microsoft.PowerShell.Utility.psd1 @@ -31,5 +31,5 @@ CmdletsToExport = @( FunctionsToExport = @() AliasesToExport = @('fhx') NestedModules = @("Microsoft.PowerShell.Commands.Utility.dll") -HelpInfoURI = 'https://aka.ms/powershell73-help' +HelpInfoURI = 'https://aka.ms/powershell75-help' } diff --git a/src/Modules/Windows/CimCmdlets/CimCmdlets.psd1 b/src/Modules/Windows/CimCmdlets/CimCmdlets.psd1 index 93c68321ca1..734fe45016d 100644 --- a/src/Modules/Windows/CimCmdlets/CimCmdlets.psd1 +++ b/src/Modules/Windows/CimCmdlets/CimCmdlets.psd1 @@ -14,5 +14,5 @@ CmdletsToExport= "Get-CimAssociatedInstance", "Get-CimClass", "Get-CimInstance", "Remove-CimSession","Set-CimInstance", "Export-BinaryMiLog","Import-BinaryMiLog" AliasesToExport = "gcim","scim","ncim", "rcim","icim","gcai","rcie","ncms","rcms","gcms","ncso","gcls" -HelpInfoUri="https://aka.ms/powershell73-help" +HelpInfoUri="https://aka.ms/powershell75-help" } diff --git a/src/Modules/Windows/Microsoft.PowerShell.Diagnostics/Microsoft.PowerShell.Diagnostics.psd1 b/src/Modules/Windows/Microsoft.PowerShell.Diagnostics/Microsoft.PowerShell.Diagnostics.psd1 index 50282d8d5b8..7f77777b137 100644 --- a/src/Modules/Windows/Microsoft.PowerShell.Diagnostics/Microsoft.PowerShell.Diagnostics.psd1 +++ b/src/Modules/Windows/Microsoft.PowerShell.Diagnostics/Microsoft.PowerShell.Diagnostics.psd1 @@ -12,5 +12,5 @@ AliasesToExport = @() NestedModules="Microsoft.PowerShell.Commands.Diagnostics.dll" TypesToProcess="GetEvent.types.ps1xml" FormatsToProcess="Event.format.ps1xml", "Diagnostics.format.ps1xml" -HelpInfoURI = 'https://aka.ms/powershell73-help' +HelpInfoURI = 'https://aka.ms/powershell75-help' } diff --git a/src/Modules/Windows/Microsoft.PowerShell.Management/Microsoft.PowerShell.Management.psd1 b/src/Modules/Windows/Microsoft.PowerShell.Management/Microsoft.PowerShell.Management.psd1 index 0b49f178b25..f7582920935 100644 --- a/src/Modules/Windows/Microsoft.PowerShell.Management/Microsoft.PowerShell.Management.psd1 +++ b/src/Modules/Windows/Microsoft.PowerShell.Management/Microsoft.PowerShell.Management.psd1 @@ -7,7 +7,7 @@ ModuleVersion="7.0.0.0" CompatiblePSEditions = @("Core") PowerShellVersion="3.0" NestedModules="Microsoft.PowerShell.Commands.Management.dll" -HelpInfoURI = 'https://aka.ms/powershell73-help' +HelpInfoURI = 'https://aka.ms/powershell75-help' FunctionsToExport = @() AliasesToExport = @("gcb", "gin", "gtz", "scb", "stz") CmdletsToExport=@("Add-Content", diff --git a/src/Modules/Windows/Microsoft.PowerShell.Security/Microsoft.PowerShell.Security.psd1 b/src/Modules/Windows/Microsoft.PowerShell.Security/Microsoft.PowerShell.Security.psd1 index 7470c795fdc..0953b2d1cca 100644 --- a/src/Modules/Windows/Microsoft.PowerShell.Security/Microsoft.PowerShell.Security.psd1 +++ b/src/Modules/Windows/Microsoft.PowerShell.Security/Microsoft.PowerShell.Security.psd1 @@ -14,5 +14,5 @@ NestedModules = "Microsoft.PowerShell.Security.dll" # We declare 'Microsoft.PowerShell.Security.dll' in 'RequiredAssemblies' so as to make sure it's loaded before the type file processing. RequiredAssemblies = "Microsoft.PowerShell.Security.dll" TypesToProcess = "Security.types.ps1xml" -HelpInfoURI = 'https://aka.ms/powershell73-help' +HelpInfoURI = 'https://aka.ms/powershell75-help' } diff --git a/src/Modules/Windows/Microsoft.PowerShell.Utility/Microsoft.PowerShell.Utility.psd1 b/src/Modules/Windows/Microsoft.PowerShell.Utility/Microsoft.PowerShell.Utility.psd1 index 33db09feb9c..2043543a8a5 100644 --- a/src/Modules/Windows/Microsoft.PowerShell.Utility/Microsoft.PowerShell.Utility.psd1 +++ b/src/Modules/Windows/Microsoft.PowerShell.Utility/Microsoft.PowerShell.Utility.psd1 @@ -29,5 +29,5 @@ CmdletsToExport = @( FunctionsToExport = @() AliasesToExport = @('fhx') NestedModules = @("Microsoft.PowerShell.Commands.Utility.dll") -HelpInfoURI = 'https://aka.ms/powershell73-help' +HelpInfoURI = 'https://aka.ms/powershell75-help' } diff --git a/src/Modules/Windows/Microsoft.WSMan.Management/Microsoft.WSMan.Management.psd1 b/src/Modules/Windows/Microsoft.WSMan.Management/Microsoft.WSMan.Management.psd1 index 5eb367b7e7f..ced706c9fde 100644 --- a/src/Modules/Windows/Microsoft.WSMan.Management/Microsoft.WSMan.Management.psd1 +++ b/src/Modules/Windows/Microsoft.WSMan.Management/Microsoft.WSMan.Management.psd1 @@ -11,5 +11,5 @@ CmdletsToExport="Disable-WSManCredSSP", "Enable-WSManCredSSP", "Get-WSManCredSSP AliasesToExport = @() NestedModules="Microsoft.WSMan.Management.dll" FormatsToProcess="WSMan.format.ps1xml" -HelpInfoURI = 'https://aka.ms/powershell73-help' +HelpInfoURI = 'https://aka.ms/powershell75-help' } diff --git a/src/Modules/Windows/PSDiagnostics/PSDiagnostics.psd1 b/src/Modules/Windows/PSDiagnostics/PSDiagnostics.psd1 index 6185b589a82..3b53d6740e5 100644 --- a/src/Modules/Windows/PSDiagnostics/PSDiagnostics.psd1 +++ b/src/Modules/Windows/PSDiagnostics/PSDiagnostics.psd1 @@ -10,5 +10,5 @@ FunctionsToExport="Disable-PSTrace","Disable-PSWSManCombinedTrace","Disable-WSManTrace","Enable-PSTrace","Enable-PSWSManCombinedTrace","Enable-WSManTrace","Get-LogProperties","Set-LogProperties","Start-Trace","Stop-Trace" CmdletsToExport = @() AliasesToExport = @() - HelpInfoUri="https://aka.ms/powershell73-help" + HelpInfoUri="https://aka.ms/powershell75-help" } diff --git a/src/System.Management.Automation/help/UpdatableHelpCommandBase.cs b/src/System.Management.Automation/help/UpdatableHelpCommandBase.cs index dad75a6b69c..687faa68246 100644 --- a/src/System.Management.Automation/help/UpdatableHelpCommandBase.cs +++ b/src/System.Management.Automation/help/UpdatableHelpCommandBase.cs @@ -179,13 +179,13 @@ static UpdatableHelpCommandBase() // NOTE: The HelpInfoUri must be updated with each release. - s_metadataCache.Add("Microsoft.PowerShell.Diagnostics", "https://aka.ms/powershell73-help"); - s_metadataCache.Add("Microsoft.PowerShell.Core", "https://aka.ms/powershell73-help"); - s_metadataCache.Add("Microsoft.PowerShell.Utility", "https://aka.ms/powershell73-help"); - s_metadataCache.Add("Microsoft.PowerShell.Host", "https://aka.ms/powershell73-help"); - s_metadataCache.Add("Microsoft.PowerShell.Management", "https://aka.ms/powershell73-help"); - s_metadataCache.Add("Microsoft.PowerShell.Security", "https://aka.ms/powershell73-help"); - s_metadataCache.Add("Microsoft.WSMan.Management", "https://aka.ms/powershell73-help"); + s_metadataCache.Add("Microsoft.PowerShell.Diagnostics", "https://aka.ms/powershell75-help"); + s_metadataCache.Add("Microsoft.PowerShell.Core", "https://aka.ms/powershell75-help"); + s_metadataCache.Add("Microsoft.PowerShell.Utility", "https://aka.ms/powershell75-help"); + s_metadataCache.Add("Microsoft.PowerShell.Host", "https://aka.ms/powershell75-help"); + s_metadataCache.Add("Microsoft.PowerShell.Management", "https://aka.ms/powershell75-help"); + s_metadataCache.Add("Microsoft.PowerShell.Security", "https://aka.ms/powershell75-help"); + s_metadataCache.Add("Microsoft.WSMan.Management", "https://aka.ms/powershell75-help"); } /// From aa8f9a3bd7928b7bb8453ea6a6dc893b3e189407 Mon Sep 17 00:00:00 2001 From: Travis Plunk Date: Wed, 15 Jan 2025 10:02:50 -0800 Subject: [PATCH 057/173] Deploy Box Update (#24632) (#24779) * reverted one time changes * added ob_outputDirectory * added mscode variable group * forgot to move psm1 to ToolArtifact folder * added pipeline name and passing toolartifact through context * added tools * PSPackagesOfficial * removed tools clone * added uploading CL * verbose statements for release tag and release version * trying to regerence variable with step name * checking REPOROOT * removed get child item * Deploy box update * nuget template context pipeline name correction * changed other instances of releasetag * added -Verbose to Copy-Item * checkout task, instead of git clone * changed to Build.SourcesDirectory * removed path specification * removed path * added tsa and credscan * not copying tools to artifacts * official and production --------- Co-authored-by: Justin Chung <124807742+jshigetomi@users.noreply.github.com> Co-authored-by: Justin Chung --- .pipelines/PowerShell-Release-Official.yml | 19 +++-- .../release-SetReleaseTagandContainerName.yml | 6 +- .../templates/release-SetTagAndTools.yml | 75 +++++++++++++++++++ .pipelines/templates/release-githubtasks.yml | 53 ++++--------- .../templates/release-publish-nuget.yml | 15 ++-- .../release-validate-packagenames.yml | 2 +- .pipelines/templates/uploadToAzure.yml | 32 ++++---- .../templates/variable/release-shared.yml | 10 +++ 8 files changed, 136 insertions(+), 76 deletions(-) create mode 100644 .pipelines/templates/release-SetTagAndTools.yml diff --git a/.pipelines/PowerShell-Release-Official.yml b/.pipelines/PowerShell-Release-Official.yml index 03defa5d128..6a17139e05e 100644 --- a/.pipelines/PowerShell-Release-Official.yml +++ b/.pipelines/PowerShell-Release-Official.yml @@ -63,6 +63,10 @@ resources: type: git name: OneBranch.Pipelines/GovernedTemplates ref: refs/heads/main + - repository: PSInternalTools + type: git + name: PowerShellCore/Internal-PowerShellTeam-Tools + ref: refs/heads/master pipelines: - pipeline: CoOrdinatedBuildPipeline @@ -110,17 +114,14 @@ extends: tsaOptionsFile: .config\tsaoptions.json stages: - - stage: DownloadPackages - displayName: 'Download Packages' - dependsOn: [] + - stage: setReleaseTagAndUploadTools + displayName: 'Set Release Tag and Upload Tools' jobs: - - template: /.pipelines/templates/release-download-packages.yml@self + - template: /.pipelines/templates/release-SetTagAndTools.yml@self - stage: msixbundle displayName: 'Create MSIX Bundle' dependsOn: [] - variables: - ob_release_environment: Test jobs: - template: /.pipelines/templates/release-create-msix.yml@self @@ -278,7 +279,7 @@ extends: - stage: PublishGitHubRelease displayName: Publish GitHub Release dependsOn: - - DownloadPackages + - setReleaseTagAndUploadTools - UpdateChangeLog variables: ob_release_environment: Production @@ -316,7 +317,9 @@ extends: - stage: PublishNuGet displayName: Publish NuGet - dependsOn: PushGitTagAndMakeDraftPublic + dependsOn: + - setReleaseTagAndUploadTools + - PushGitTagAndMakeDraftPublic variables: ob_release_environment: Production jobs: diff --git a/.pipelines/templates/release-SetReleaseTagandContainerName.yml b/.pipelines/templates/release-SetReleaseTagandContainerName.yml index 7e88624b45c..667132f5f90 100644 --- a/.pipelines/templates/release-SetReleaseTagandContainerName.yml +++ b/.pipelines/templates/release-SetReleaseTagandContainerName.yml @@ -8,9 +8,10 @@ steps: } $releaseTag = $Branch -replace '^.*((release|rebuild)/)' - $vstsCommandString = "vso[task.setvariable variable=$Variable]$releaseTag" + $vstsCommandString = "vso[task.setvariable variable=$Variable;isOutput=true]$releaseTag" Write-Verbose -Message "setting $Variable to $releaseTag" -Verbose Write-Host -Object "##$vstsCommandString" + name: OutputReleaseTag displayName: Set Release Tag - pwsh: | @@ -20,7 +21,8 @@ steps: Write-Host "##$vstsCommandString" $version = '$(ReleaseTag)'.ToLowerInvariant().Substring(1) - $vstsCommandString = "vso[task.setvariable variable=Version]$version" + $vstsCommandString = "vso[task.setvariable variable=Version;isOutput=true]$version" Write-Host ("sending " + $vstsCommandString) Write-Host "##$vstsCommandString" + name: OutputVersion displayName: Set container name diff --git a/.pipelines/templates/release-SetTagAndTools.yml b/.pipelines/templates/release-SetTagAndTools.yml new file mode 100644 index 00000000000..7b8a946e323 --- /dev/null +++ b/.pipelines/templates/release-SetTagAndTools.yml @@ -0,0 +1,75 @@ +jobs: +- job: SetTagAndTools + displayName: Set Tag and Tools + condition: succeeded() + pool: + type: windows + variables: + - group: 'mscodehub-code-read-akv' + - name: ob_outputDirectory + value: '$(Build.ArtifactStagingDirectory)/ONEBRANCH_ARTIFACT' + - name: ob_sdl_credscan_suppressionsFile + value: $(Build.SourcesDirectory)\PowerShell\.config\suppress.json + - name: ob_sdl_tsa_configFile + value: $(Build.SourcesDirectory)\PowerShell\.config\tsaoptions.json + steps: + - template: release-SetReleaseTagandContainerName.yml@self + + - checkout: self + clean: true + env: + ob_restore_phase: true + + - checkout: PSInternalTools + clean: true + env: + ob_restore_phase: true + + - pwsh: | + New-Item -ItemType Directory -Path '$(Pipeline.Workspace)/ToolArtifact' + Get-ChildItem -Path '$(Build.SourcesDirectory)/Internal-PowerShellTeam-Tools/Scripts' -Filter 'GitHubRelease.psm1' -ErrorAction SilentlyContinue | + Copy-Item -Destination '$(Pipeline.Workspace)/ToolArtifact' -Verbose + displayName: Move GitHub Tool + + - task: onebranch.pipeline.signing@1 + displayName: Sign Tools + inputs: + command: 'sign' + signing_profile: internal_azure_service + files_to_sign: '*.ps1;*.psm1' + search_root: '$(Pipeline.Workspace)/ToolArtifact' + + - pwsh: | + Write-Verbose -Verbose "Creating output directory for release tools: $(ob_outputDirectory)/ToolArtifact" + New-Item -Path $(ob_outputDirectory)/ToolArtifact -ItemType Directory -Force + Get-ChildItem -Path "$(Pipeline.Workspace)/ToolArtifact/*" -Recurse | + Copy-Item -Destination $(ob_outputDirectory)/ToolArtifact -Recurse -Verbose + displayName: Upload Tools + + - pwsh: | + Write-Verbose -Verbose "Release Tag: $(OutputReleaseTag.releaseTag)" + $releaseVersion = '$(OutputReleaseTag.releaseTag)' -replace '^v','' + Write-Verbose -Verbose "Release Version: $releaseVersion" + $semanticVersion = [System.Management.Automation.SemanticVersion]$releaseVersion + + $isPreview = $semanticVersion.PreReleaseLabel -ne $null + + $fileName = if ($isPreview) { + "preview.md" + } + else { + $semanticVersion.Major.ToString() + "." + $semanticVersion.Minor.ToString() + ".md" + } + + $filePath = "$(Build.SourcesDirectory)/PowerShell/CHANGELOG/$fileName" + Write-Verbose -Verbose "Selected Log file: $filePath" + + if (-not (Test-Path -Path $filePath)) { + Write-Error "Changelog file not found: $filePath" + exit 1 + } + + Write-Verbose -Verbose "Creating output directory for CHANGELOG: $(ob_outputDirectory)/CHANGELOG" + New-Item -Path $(ob_outputDirectory)/CHANGELOG -ItemType Directory -Force + Copy-Item -Path $filePath -Destination $(ob_outputDirectory)/CHANGELOG + displayName: Upload Changelog diff --git a/.pipelines/templates/release-githubtasks.yml b/.pipelines/templates/release-githubtasks.yml index bfc500585b0..ed3ae028934 100644 --- a/.pipelines/templates/release-githubtasks.yml +++ b/.pipelines/templates/release-githubtasks.yml @@ -8,32 +8,26 @@ jobs: templateContext: inputs: - input: pipelineArtifact - artifactName: drop_DownloadPackages_upload_packages + artifactName: drop_setReleaseTagAndUploadTools_SetTagAndTools + - input: pipelineArtifact + pipeline: PSPackagesOfficial + artifactName: drop_upload_upload_packages variables: - - template: ./variable/release-shared.yml@self + - template: ./variable/release-shared.yml@self + parameters: + RELEASETAG: $[ stageDependencies.setReleaseTagAndUploadTools.SetTagAndTools.outputs['OutputReleaseTag.releaseTag'] ] steps: - task: PowerShell@2 inputs: targetType: inline script: | - Get-ChildItem Env: | Out-String -Stream | write-Verbose -Verbose + Write-Verbose -Verbose "Release Tag: $(ReleaseTag)" + Get-ChildItem Env: | Out-String -Stream | Write-Verbose -Verbose displayName: 'Capture Environment Variables' - template: release-install-pwsh.yml - - template: release-checkout-pwsh-repo.yml - - - template: release-SetReleaseTagAndContainerName.yml - - - task: PowerShell@2 - inputs: - targetType: inline - pwsh: true - script: | - git clone --depth 1 https://$(mscodehubCodeReadPat)@mscodehub.visualstudio.com/PowerShellCore/_git/Internal-PowerShellTeam-Tools '$(Pipeline.Workspace)/tools' - displayName: Clone Internal-Tools repository - - task: PowerShell@2 inputs: targetType: inline @@ -55,17 +49,6 @@ jobs: Write-Verbose -Verbose -Message $fileContent displayName: Add sha256 hashes - - task: PowerShell@2 - inputs: - targetType: inline - pwsh: true - script: | - $releaseVersion = '$(ReleaseTag)' -replace '^v','' - $vstsCommandString = "vso[task.setvariable variable=ReleaseVersion]$releaseVersion" - Write-Host "sending " + $vstsCommandString - Write-Host "##$vstsCommandString" - displayName: 'Set release version' - - task: PowerShell@2 inputs: targetType: inline @@ -79,21 +62,11 @@ jobs: targetType: inline pwsh: true script: | - Import-module '$(Pipeline.Workspace)/tools/Scripts/GitHubRelease.psm1' - $releaseVersion = '$(ReleaseTag)' -replace '^v','' - $semanticVersion = [System.Management.Automation.SemanticVersion]$releaseVersion - - $isPreview = $semanticVersion.PreReleaseLabel -ne $null - - $fileName = if ($isPreview) { - "preview.md" - } - else { - $semanticVersion.Major.ToString() + "." + $semanticVersion.Minor.ToString() + ".md" - } + Import-module '$(Pipeline.Workspace)/ToolArtifact/GitHubRelease.psm1' + Write-Verbose -Verbose "Available modules: " + Get-Module | Write-Verbose -Verbose - $filePath = "$(Pipeline.Workspace)/PowerShell/CHANGELOG/$fileName" - Write-Verbose -Verbose "Selected Log file: $filePath" + $filePath = Get-ChildItem -Path "$(Pipeline.Workspace)/CHANGELOG" -Filter '*.md' | Select-Object -First 1 -ExpandProperty FullName if (-not (Test-Path $filePath)) { throw "$filePath not found" diff --git a/.pipelines/templates/release-publish-nuget.yml b/.pipelines/templates/release-publish-nuget.yml index db0978e0b0b..78338d7d87c 100644 --- a/.pipelines/templates/release-publish-nuget.yml +++ b/.pipelines/templates/release-publish-nuget.yml @@ -13,20 +13,19 @@ jobs: templateContext: inputs: - input: pipelineArtifact - artifactName: drop_DownloadPackages_upload_packages - + pipeline: PSPackagesOfficial + artifactName: drop_upload_upload_packages variables: - template: ./variable/release-shared.yml@self + parameters: + VERSION: $[ stageDependencies.setReleaseTagAndUploadTools.SetTagAndTools.outputs['OutputVersion.Version'] ] steps: - template: release-install-pwsh.yml - - template: release-checkout-pwsh-repo.yml - - - template: release-SetReleaseTagAndContainerName.yml - - pwsh: | - Get-ChildItem Env: + Write-Verbose -Verbose "Version: $(Version)" + Get-ChildItem Env: | Out-String -width 9999 -Stream | write-Verbose -Verbose displayName: 'Capture Environment Variables' - pwsh: | @@ -34,7 +33,7 @@ jobs: $null = New-Item -ItemType Directory -Path "$(Pipeline.Workspace)/release" Copy-Item "$(Pipeline.Workspace)/NuGetPackages/*.nupkg" -Destination "$(Pipeline.Workspace)/release" -Exclude "PowerShell.*.nupkg" -Force -Verbose - $releaseVersion = '$(VERSION)' + $releaseVersion = '$(Version)' $globalToolPath = "$(Pipeline.Workspace)/NuGetPackages/PowerShell.$releaseVersion.nupkg" if ($releaseVersion -notlike '*-*') { diff --git a/.pipelines/templates/release-validate-packagenames.yml b/.pipelines/templates/release-validate-packagenames.yml index cadf0c1ba12..8b08f8d8436 100644 --- a/.pipelines/templates/release-validate-packagenames.yml +++ b/.pipelines/templates/release-validate-packagenames.yml @@ -23,7 +23,7 @@ jobs: displayName: Capture environment - pwsh: | - $name = "{0}_{1:x}" -f '$(releaseTag)', (Get-Date).Ticks + $name = "{0}_{1:x}" -f '$(OutputReleaseTag.releaseTag)', (Get-Date).Ticks Write-Host $name Write-Host "##vso[build.updatebuildnumber]$name" displayName: Set Release Name diff --git a/.pipelines/templates/uploadToAzure.yml b/.pipelines/templates/uploadToAzure.yml index 50a4a676fee..35a11ec383c 100644 --- a/.pipelines/templates/uploadToAzure.yml +++ b/.pipelines/templates/uploadToAzure.yml @@ -235,23 +235,21 @@ jobs: Get-ChildItem '$(Build.ArtifactStagingDirectory)/downloads' | Select-Object -ExpandProperty FullName displayName: 'Capture downloads' - # - pwsh: | - # Write-Verbose -Verbose "Copying Github Release files in $(Build.ArtifactStagingDirectory)/downloads to use in Release Pipeline" - # - # Write-Verbose -Verbose "Creating output directory for GitHub Release files: $(ob_outputDirectory)/GitHubPackages" - # New-Item -Path $(ob_outputDirectory)/GitHubPackages -ItemType Directory -Force - # Get-ChildItem -Path "$(Build.ArtifactStagingDirectory)/downloads/*" -Recurse | - # Where-Object { $_.Extension -notin '.msix', '.nupkg' } | - # ForEach-Object { Write-Verbose -Verbose $_.FullName ; $_ } | - # Copy-Item -Destination $(ob_outputDirectory)/GitHubPackages -Recurse - # - # Write-Verbose -Verbose "Creating output directory for NuGet packages: $(ob_outputDirectory)/NuGetPackages" - # New-Item -Path $(ob_outputDirectory)/NuGetPackages -ItemType Directory -Force - # Get-ChildItem -Path "$(Build.ArtifactStagingDirectory)/downloads/*" -Recurse | - # Where-Object { $_.Extension -eq '.nupkg' } | - # ForEach-Object { Write-Verbose -Verbose $_.FullName ; $_ } | - # Copy-Item -Destination $(ob_outputDirectory)/NuGetPackages -Recurse - # displayName: Copy downloads to Artifacts + - pwsh: | + Write-Verbose -Verbose "Copying Github Release files in $(Build.ArtifactStagingDirectory)/downloads to use in Release Pipeline" + + Write-Verbose -Verbose "Creating output directory for GitHub Release files: $(ob_outputDirectory)/GitHubPackages" + New-Item -Path $(ob_outputDirectory)/GitHubPackages -ItemType Directory -Force + Get-ChildItem -Path "$(Build.ArtifactStagingDirectory)/downloads/*" -Recurse | + Where-Object { $_.Extension -notin '.msix', '.nupkg' } | + Copy-Item -Destination $(ob_outputDirectory)/GitHubPackages -Recurse -Verbose + + Write-Verbose -Verbose "Creating output directory for NuGet packages: $(ob_outputDirectory)/NuGetPackages" + New-Item -Path $(ob_outputDirectory)/NuGetPackages -ItemType Directory -Force + Get-ChildItem -Path "$(Build.ArtifactStagingDirectory)/downloads/*" -Recurse | + Where-Object { $_.Extension -eq '.nupkg' } | + Copy-Item -Destination $(ob_outputDirectory)/NuGetPackages -Recurse -Verbose + displayName: Copy downloads to Artifacts - pwsh: | # Create output directory for packages which have been uploaded to blob storage diff --git a/.pipelines/templates/variable/release-shared.yml b/.pipelines/templates/variable/release-shared.yml index 92ab56199d4..f944639a908 100644 --- a/.pipelines/templates/variable/release-shared.yml +++ b/.pipelines/templates/variable/release-shared.yml @@ -5,6 +5,12 @@ parameters: - name: SBOM type: boolean default: false + - name: RELEASETAG + type: string + default: 'Not Initialized' + - name: VERSION + type: string + default: 'Not Initialized' variables: - name: ob_signing_setup_enabled @@ -30,3 +36,7 @@ variables: value: ${{ parameters.REPOROOT }}\.config\suppress.json - name: ob_sdl_codeql_compiled_enabled value: false + - name: ReleaseTag + value: ${{ parameters.RELEASETAG }} + - name: Version + value: ${{ parameters.VERSION }} From f4c17e489265c0c0df4afc5993199fe1b622a828 Mon Sep 17 00:00:00 2001 From: Travis Plunk Date: Wed, 15 Jan 2025 11:10:15 -0800 Subject: [PATCH 058/173] Make the `AssemblyVersion` not change for servicing releases (#24667) (#24783) Co-authored-by: Dongbo Wang --- .pipelines/templates/nupkg.yml | 4 ++-- PowerShell.Common.props | 7 ++++++- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/.pipelines/templates/nupkg.yml b/.pipelines/templates/nupkg.yml index f9238bb09e8..be4b704557e 100644 --- a/.pipelines/templates/nupkg.yml +++ b/.pipelines/templates/nupkg.yml @@ -120,7 +120,7 @@ jobs: $refAssemblyFolder = Join-Path '$(System.ArtifactsDirectory)' 'RefAssembly' $null = New-Item -Path $refAssemblyFolder -Force -Verbose -Type Directory - Start-PSBuild -Clean -Runtime linux-x64 -Configuration Release + Start-PSBuild -Clean -Runtime linux-x64 -Configuration Release -ReleaseTag $(ReleaseTagVar) $sharedModules | Foreach-Object { $refFile = Get-ChildItem -Path "$(PowerShellRoot)\src\$_\obj\Release\net9.0\refint\$_.dll" @@ -136,7 +136,7 @@ jobs: } } - Start-PSBuild -Clean -Runtime win7-x64 -Configuration Release + Start-PSBuild -Clean -Runtime win7-x64 -Configuration Release -ReleaseTag $(ReleaseTagVar) $winOnlyModules | Foreach-Object { $refFile = Get-ChildItem -Path "$(PowerShellRoot)\src\$_\obj\Release\net9.0\refint\*.dll" diff --git a/PowerShell.Common.props b/PowerShell.Common.props index b73b3e60a7b..28bc08cc5db 100644 --- a/PowerShell.Common.props +++ b/PowerShell.Common.props @@ -58,6 +58,11 @@ $(ReleaseTagVersionPart).$(ReleaseTagSemVersionPart) $(ReleaseTagVersionPart).$(GAIncrementValue) + + $(PSCoreFileVersion) + $([System.Version]::Parse($(PSCoreFileVersion)).Major).$([System.Version]::Parse($(PSCoreFileVersion)).Minor).0.$([System.Version]::Parse($(PSCoreFileVersion)).Revision) @@ -84,7 +89,7 @@ --> $(PSCoreFileVersion) From 7fd9e974d56bf39761ad55500b056f514ad16256 Mon Sep 17 00:00:00 2001 From: Travis Plunk Date: Wed, 15 Jan 2025 13:09:39 -0800 Subject: [PATCH 059/173] Update `Microsoft.PowerShell.PSResourceGet` to `1.1.0` (#24767) (#24785) Co-authored-by: Anam Navied --- src/Modules/PSGalleryModules.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Modules/PSGalleryModules.csproj b/src/Modules/PSGalleryModules.csproj index 9df1121f38b..5f9f89a4563 100644 --- a/src/Modules/PSGalleryModules.csproj +++ b/src/Modules/PSGalleryModules.csproj @@ -13,7 +13,7 @@ - + From 39b96b5d9afab13cbdea0ef859efac0f4a2e11de Mon Sep 17 00:00:00 2001 From: PowerShell Team Bot <69177312+pwshBot@users.noreply.github.com> Date: Wed, 15 Jan 2025 13:47:32 -0800 Subject: [PATCH 060/173] [release/v7.5] Update branch for release - Transitive - true - minor (#24786) * Update .NET SDK to latest version * Update package references * Update cgmanifest --- DotnetRuntimeMetadata.json | 2 +- global.json | 2 +- ...oft.PowerShell.Commands.Diagnostics.csproj | 4 +- ...soft.PowerShell.Commands.Management.csproj | 4 +- ...crosoft.PowerShell.Commands.Utility.csproj | 6 +- ...crosoft.PowerShell.CoreCLR.Eventing.csproj | 2 +- .../Microsoft.PowerShell.SDK.csproj | 80 ++++++++------ .../Microsoft.WSMan.Management.csproj | 4 +- .../System.Management.Automation.csproj | 24 ++--- .../BenchmarkDotNet.Extensions.csproj | 2 +- .../ResultsComparer/ResultsComparer.csproj | 2 +- ...soft.PowerShell.NamedPipeConnection.csproj | 24 ++--- test/tools/TestService/TestService.csproj | 78 ++++++++------ test/tools/WebListener/WebListener.csproj | 6 +- test/xUnit/xUnit.tests.csproj | 8 +- tools/cgmanifest.json | 102 +++++++++--------- 16 files changed, 191 insertions(+), 159 deletions(-) diff --git a/DotnetRuntimeMetadata.json b/DotnetRuntimeMetadata.json index 472b5958a8c..644b79dcd7a 100644 --- a/DotnetRuntimeMetadata.json +++ b/DotnetRuntimeMetadata.json @@ -4,7 +4,7 @@ "quality": "daily", "qualityFallback": "preview", "packageVersionPattern": "9.0.0-preview.6", - "sdkImageVersion": "9.0.100", + "sdkImageVersion": "9.0.102", "nextChannel": "9.0.0-preview.7", "azureFeed": "", "sdkImageOverride": "" diff --git a/global.json b/global.json index 65324522984..ee2876ea570 100644 --- a/global.json +++ b/global.json @@ -1,5 +1,5 @@ { "sdk": { - "version": "9.0.100" + "version": "9.0.102" } } diff --git a/src/Microsoft.PowerShell.Commands.Diagnostics/Microsoft.PowerShell.Commands.Diagnostics.csproj b/src/Microsoft.PowerShell.Commands.Diagnostics/Microsoft.PowerShell.Commands.Diagnostics.csproj index e575d8ef567..d17d99b190d 100644 --- a/src/Microsoft.PowerShell.Commands.Diagnostics/Microsoft.PowerShell.Commands.Diagnostics.csproj +++ b/src/Microsoft.PowerShell.Commands.Diagnostics/Microsoft.PowerShell.Commands.Diagnostics.csproj @@ -7,9 +7,9 @@ - + - + diff --git a/src/Microsoft.PowerShell.Commands.Management/Microsoft.PowerShell.Commands.Management.csproj b/src/Microsoft.PowerShell.Commands.Management/Microsoft.PowerShell.Commands.Management.csproj index 748df04b328..a4cb9ad9dfb 100644 --- a/src/Microsoft.PowerShell.Commands.Management/Microsoft.PowerShell.Commands.Management.csproj +++ b/src/Microsoft.PowerShell.Commands.Management/Microsoft.PowerShell.Commands.Management.csproj @@ -47,8 +47,8 @@ - - + + diff --git a/src/Microsoft.PowerShell.Commands.Utility/Microsoft.PowerShell.Commands.Utility.csproj b/src/Microsoft.PowerShell.Commands.Utility/Microsoft.PowerShell.Commands.Utility.csproj index e60c27d28a6..bc15337da1f 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/Microsoft.PowerShell.Commands.Utility.csproj +++ b/src/Microsoft.PowerShell.Commands.Utility/Microsoft.PowerShell.Commands.Utility.csproj @@ -13,7 +13,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive all - + @@ -41,8 +41,8 @@ - - + + diff --git a/src/Microsoft.PowerShell.CoreCLR.Eventing/Microsoft.PowerShell.CoreCLR.Eventing.csproj b/src/Microsoft.PowerShell.CoreCLR.Eventing/Microsoft.PowerShell.CoreCLR.Eventing.csproj index 5c28e4fe256..bd8754bff4d 100644 --- a/src/Microsoft.PowerShell.CoreCLR.Eventing/Microsoft.PowerShell.CoreCLR.Eventing.csproj +++ b/src/Microsoft.PowerShell.CoreCLR.Eventing/Microsoft.PowerShell.CoreCLR.Eventing.csproj @@ -8,7 +8,7 @@ - + diff --git a/src/Microsoft.PowerShell.SDK/Microsoft.PowerShell.SDK.csproj b/src/Microsoft.PowerShell.SDK/Microsoft.PowerShell.SDK.csproj index bc5206ea9fa..75492f49c6c 100644 --- a/src/Microsoft.PowerShell.SDK/Microsoft.PowerShell.SDK.csproj +++ b/src/Microsoft.PowerShell.SDK/Microsoft.PowerShell.SDK.csproj @@ -17,39 +17,55 @@ - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - + + + + + + - - - - - - - - - - - - - - + + + + + + + + + + + + + + - - + + diff --git a/src/Microsoft.WSMan.Management/Microsoft.WSMan.Management.csproj b/src/Microsoft.WSMan.Management/Microsoft.WSMan.Management.csproj index 5a379621c85..c9d448a5091 100644 --- a/src/Microsoft.WSMan.Management/Microsoft.WSMan.Management.csproj +++ b/src/Microsoft.WSMan.Management/Microsoft.WSMan.Management.csproj @@ -7,11 +7,11 @@ - + - + diff --git a/src/System.Management.Automation/System.Management.Automation.csproj b/src/System.Management.Automation/System.Management.Automation.csproj index 12177ffd61c..d0e81fddb6d 100644 --- a/src/System.Management.Automation/System.Management.Automation.csproj +++ b/src/System.Management.Automation/System.Management.Automation.csproj @@ -32,25 +32,25 @@ - - - - - - + + + + + + - + - - - - + + + + - + diff --git a/test/perf/dotnet-tools/BenchmarkDotNet.Extensions/BenchmarkDotNet.Extensions.csproj b/test/perf/dotnet-tools/BenchmarkDotNet.Extensions/BenchmarkDotNet.Extensions.csproj index 4c1975ac342..427245af6d8 100644 --- a/test/perf/dotnet-tools/BenchmarkDotNet.Extensions/BenchmarkDotNet.Extensions.csproj +++ b/test/perf/dotnet-tools/BenchmarkDotNet.Extensions/BenchmarkDotNet.Extensions.csproj @@ -13,7 +13,7 @@ - + diff --git a/test/perf/dotnet-tools/ResultsComparer/ResultsComparer.csproj b/test/perf/dotnet-tools/ResultsComparer/ResultsComparer.csproj index 61a9818dc23..f4874cfa6d7 100644 --- a/test/perf/dotnet-tools/ResultsComparer/ResultsComparer.csproj +++ b/test/perf/dotnet-tools/ResultsComparer/ResultsComparer.csproj @@ -13,7 +13,7 @@ - + diff --git a/test/tools/NamedPipeConnection/src/code/Microsoft.PowerShell.NamedPipeConnection.csproj b/test/tools/NamedPipeConnection/src/code/Microsoft.PowerShell.NamedPipeConnection.csproj index 0acf5c81d43..8bf1139db7d 100644 --- a/test/tools/NamedPipeConnection/src/code/Microsoft.PowerShell.NamedPipeConnection.csproj +++ b/test/tools/NamedPipeConnection/src/code/Microsoft.PowerShell.NamedPipeConnection.csproj @@ -20,18 +20,18 @@ - - - - - - - + + + + + + + - - - - - + + + + + diff --git a/test/tools/TestService/TestService.csproj b/test/tools/TestService/TestService.csproj index e96e4defa48..68452edfdb5 100644 --- a/test/tools/TestService/TestService.csproj +++ b/test/tools/TestService/TestService.csproj @@ -15,40 +15,56 @@ - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - + + + + + - - - - - - - - + + + + + + + + - + diff --git a/test/tools/WebListener/WebListener.csproj b/test/tools/WebListener/WebListener.csproj index fc11e328e7e..7117e235557 100644 --- a/test/tools/WebListener/WebListener.csproj +++ b/test/tools/WebListener/WebListener.csproj @@ -7,9 +7,9 @@ - - + + - + diff --git a/test/xUnit/xUnit.tests.csproj b/test/xUnit/xUnit.tests.csproj index 2b04741dba8..114c1f8114d 100644 --- a/test/xUnit/xUnit.tests.csproj +++ b/test/xUnit/xUnit.tests.csproj @@ -26,13 +26,13 @@ - - + + runtime; build; native; contentfiles; analyzers; buildtransitive all - - + + runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/tools/cgmanifest.json b/tools/cgmanifest.json index 4abc0cd4000..bb4fd3edb1c 100644 --- a/tools/cgmanifest.json +++ b/tools/cgmanifest.json @@ -115,7 +115,7 @@ "Type": "nuget", "Nuget": { "Name": "Microsoft.Extensions.ObjectPool", - "Version": "8.0.11" + "Version": "8.0.12" } }, "DevelopmentDependency": false @@ -185,7 +185,7 @@ "Type": "nuget", "Nuget": { "Name": "Microsoft.Win32.Registry.AccessControl", - "Version": "9.0.0" + "Version": "9.0.1" } }, "DevelopmentDependency": false @@ -205,7 +205,7 @@ "Type": "nuget", "Nuget": { "Name": "Microsoft.Win32.SystemEvents", - "Version": "9.0.0" + "Version": "9.0.1" } }, "DevelopmentDependency": false @@ -215,7 +215,7 @@ "Type": "nuget", "Nuget": { "Name": "Microsoft.Windows.Compatibility", - "Version": "9.0.0" + "Version": "9.0.1" } }, "DevelopmentDependency": false @@ -235,7 +235,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.android-arm.runtime.native.System.IO.Ports", - "Version": "9.0.0" + "Version": "9.0.1" } }, "DevelopmentDependency": false @@ -245,7 +245,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.android-arm64.runtime.native.System.IO.Ports", - "Version": "9.0.0" + "Version": "9.0.1" } }, "DevelopmentDependency": false @@ -255,7 +255,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.android-x64.runtime.native.System.IO.Ports", - "Version": "9.0.0" + "Version": "9.0.1" } }, "DevelopmentDependency": false @@ -265,7 +265,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.android-x86.runtime.native.System.IO.Ports", - "Version": "9.0.0" + "Version": "9.0.1" } }, "DevelopmentDependency": false @@ -275,7 +275,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.linux-arm.runtime.native.System.IO.Ports", - "Version": "9.0.0" + "Version": "9.0.1" } }, "DevelopmentDependency": false @@ -285,7 +285,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.linux-arm64.runtime.native.System.IO.Ports", - "Version": "9.0.0" + "Version": "9.0.1" } }, "DevelopmentDependency": false @@ -295,7 +295,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.linux-bionic-arm64.runtime.native.System.IO.Ports", - "Version": "9.0.0" + "Version": "9.0.1" } }, "DevelopmentDependency": false @@ -305,7 +305,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.linux-bionic-x64.runtime.native.System.IO.Ports", - "Version": "9.0.0" + "Version": "9.0.1" } }, "DevelopmentDependency": false @@ -315,7 +315,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.linux-musl-arm.runtime.native.System.IO.Ports", - "Version": "9.0.0" + "Version": "9.0.1" } }, "DevelopmentDependency": false @@ -325,7 +325,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.linux-musl-arm64.runtime.native.System.IO.Ports", - "Version": "9.0.0" + "Version": "9.0.1" } }, "DevelopmentDependency": false @@ -335,7 +335,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.linux-musl-x64.runtime.native.System.IO.Ports", - "Version": "9.0.0" + "Version": "9.0.1" } }, "DevelopmentDependency": false @@ -345,7 +345,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.linux-x64.runtime.native.System.IO.Ports", - "Version": "9.0.0" + "Version": "9.0.1" } }, "DevelopmentDependency": false @@ -355,7 +355,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.maccatalyst-arm64.runtime.native.System.IO.Ports", - "Version": "9.0.0" + "Version": "9.0.1" } }, "DevelopmentDependency": false @@ -365,7 +365,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.maccatalyst-x64.runtime.native.System.IO.Ports", - "Version": "9.0.0" + "Version": "9.0.1" } }, "DevelopmentDependency": false @@ -385,7 +385,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.native.System.IO.Ports", - "Version": "9.0.0" + "Version": "9.0.1" } }, "DevelopmentDependency": false @@ -395,7 +395,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.osx-arm64.runtime.native.System.IO.Ports", - "Version": "9.0.0" + "Version": "9.0.1" } }, "DevelopmentDependency": false @@ -405,7 +405,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.osx-x64.runtime.native.System.IO.Ports", - "Version": "9.0.0" + "Version": "9.0.1" } }, "DevelopmentDependency": false @@ -465,7 +465,7 @@ "Type": "nuget", "Nuget": { "Name": "System.CodeDom", - "Version": "9.0.0" + "Version": "9.0.1" } }, "DevelopmentDependency": false @@ -485,7 +485,7 @@ "Type": "nuget", "Nuget": { "Name": "System.ComponentModel.Composition.Registration", - "Version": "9.0.0" + "Version": "9.0.1" } }, "DevelopmentDependency": false @@ -495,7 +495,7 @@ "Type": "nuget", "Nuget": { "Name": "System.ComponentModel.Composition", - "Version": "9.0.0" + "Version": "9.0.1" } }, "DevelopmentDependency": false @@ -505,7 +505,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Configuration.ConfigurationManager", - "Version": "9.0.0" + "Version": "9.0.1" } }, "DevelopmentDependency": false @@ -515,7 +515,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Data.Odbc", - "Version": "9.0.0" + "Version": "9.0.1" } }, "DevelopmentDependency": false @@ -525,7 +525,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Data.OleDb", - "Version": "9.0.0" + "Version": "9.0.1" } }, "DevelopmentDependency": false @@ -545,7 +545,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Diagnostics.DiagnosticSource", - "Version": "9.0.0" + "Version": "9.0.1" } }, "DevelopmentDependency": false @@ -555,7 +555,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Diagnostics.EventLog", - "Version": "9.0.0" + "Version": "9.0.1" } }, "DevelopmentDependency": false @@ -565,7 +565,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Diagnostics.PerformanceCounter", - "Version": "9.0.0" + "Version": "9.0.1" } }, "DevelopmentDependency": false @@ -575,7 +575,7 @@ "Type": "nuget", "Nuget": { "Name": "System.DirectoryServices.AccountManagement", - "Version": "9.0.0" + "Version": "9.0.1" } }, "DevelopmentDependency": false @@ -585,7 +585,7 @@ "Type": "nuget", "Nuget": { "Name": "System.DirectoryServices.Protocols", - "Version": "9.0.0" + "Version": "9.0.1" } }, "DevelopmentDependency": false @@ -595,7 +595,7 @@ "Type": "nuget", "Nuget": { "Name": "System.DirectoryServices", - "Version": "9.0.0" + "Version": "9.0.1" } }, "DevelopmentDependency": false @@ -605,7 +605,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Drawing.Common", - "Version": "9.0.0" + "Version": "9.0.1" } }, "DevelopmentDependency": false @@ -615,7 +615,7 @@ "Type": "nuget", "Nuget": { "Name": "System.IO.Packaging", - "Version": "9.0.0" + "Version": "9.0.1" } }, "DevelopmentDependency": false @@ -625,7 +625,7 @@ "Type": "nuget", "Nuget": { "Name": "System.IO.Ports", - "Version": "9.0.0" + "Version": "9.0.1" } }, "DevelopmentDependency": false @@ -635,7 +635,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Management", - "Version": "9.0.0" + "Version": "9.0.1" } }, "DevelopmentDependency": false @@ -645,7 +645,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Net.Http.WinHttpHandler", - "Version": "9.0.0" + "Version": "9.0.1" } }, "DevelopmentDependency": false @@ -675,7 +675,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Reflection.Context", - "Version": "9.0.0" + "Version": "9.0.1" } }, "DevelopmentDependency": false @@ -705,7 +705,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Runtime.Caching", - "Version": "9.0.0" + "Version": "9.0.1" } }, "DevelopmentDependency": false @@ -725,7 +725,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Security.Cryptography.Pkcs", - "Version": "9.0.0" + "Version": "9.0.1" } }, "DevelopmentDependency": false @@ -735,7 +735,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Security.Cryptography.ProtectedData", - "Version": "9.0.0" + "Version": "9.0.1" } }, "DevelopmentDependency": false @@ -745,7 +745,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Security.Cryptography.Xml", - "Version": "9.0.0" + "Version": "9.0.1" } }, "DevelopmentDependency": false @@ -755,7 +755,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Security.Permissions", - "Version": "9.0.0" + "Version": "9.0.1" } }, "DevelopmentDependency": false @@ -825,7 +825,7 @@ "Type": "nuget", "Nuget": { "Name": "System.ServiceModel.Syndication", - "Version": "9.0.0" + "Version": "9.0.1" } }, "DevelopmentDependency": false @@ -835,7 +835,7 @@ "Type": "nuget", "Nuget": { "Name": "System.ServiceProcess.ServiceController", - "Version": "9.0.0" + "Version": "9.0.1" } }, "DevelopmentDependency": false @@ -845,7 +845,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Speech", - "Version": "9.0.0" + "Version": "9.0.1" } }, "DevelopmentDependency": false @@ -855,7 +855,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Text.Encoding.CodePages", - "Version": "9.0.0" + "Version": "9.0.1" } }, "DevelopmentDependency": false @@ -865,7 +865,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Text.Encodings.Web", - "Version": "9.0.0" + "Version": "9.0.1" } }, "DevelopmentDependency": false @@ -875,7 +875,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Threading.AccessControl", - "Version": "9.0.0" + "Version": "9.0.1" } }, "DevelopmentDependency": false @@ -895,7 +895,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Windows.Extensions", - "Version": "9.0.0" + "Version": "9.0.1" } }, "DevelopmentDependency": false From a0d00d805631ce92cf2234990d088da584d908c3 Mon Sep 17 00:00:00 2001 From: Travis Plunk Date: Wed, 15 Jan 2025 14:43:54 -0800 Subject: [PATCH 061/173] Mark build as latest stable (#24789) --- tools/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/metadata.json b/tools/metadata.json index c4cb3dd7bd3..1da6d7f42e7 100644 --- a/tools/metadata.json +++ b/tools/metadata.json @@ -6,5 +6,5 @@ "LTSReleaseTag" : ["v7.2.22", "v7.4.4"], "NextReleaseTag": "v7.5.0-preview.4", "LTSRelease": { "Latest": false, "Package": false }, - "StableRelease": { "Latest": false, "Package": false } + "StableRelease": { "Latest": true, "Package": true } } From dd66a64db7d3e2adadaca603c385803d158b549b Mon Sep 17 00:00:00 2001 From: Travis Plunk Date: Wed, 15 Jan 2025 14:52:20 -0800 Subject: [PATCH 062/173] Fix Changelog content grab during GitHub Release (#24788) (#24791) Co-authored-by: Justin Chung <124807742+jshigetomi@users.noreply.github.com> Co-authored-by: Justin Chung --- .pipelines/templates/release-githubtasks.yml | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/.pipelines/templates/release-githubtasks.yml b/.pipelines/templates/release-githubtasks.yml index ed3ae028934..4af3c973205 100644 --- a/.pipelines/templates/release-githubtasks.yml +++ b/.pipelines/templates/release-githubtasks.yml @@ -74,14 +74,12 @@ jobs: $changelog = Get-Content -Path $filePath - $startPattern = "^## \[" + ([regex]::Escape($releaseVersion)) + "\]" - $endPattern = "^## \[{0}\.{1}\.{2}*" -f $semanticVersion.Major, $semanticVersion.Minor, $semanticVersion.Patch + $headingPattern = "^## \[\d+\.\d+\.\d+" + $headingStartLines = $changelog | Select-String -Pattern $headingPattern | Select-Object -ExpandProperty LineNumber + $startLine = $headingStartLines[0] + $endLine = $headingStartLines[1] - 1 - $clContent = $changelog | ForEach-Object { - if ($_ -match $startPattern) { $outputLine = $true } - elseif ($_ -match $endPattern) { $outputLine = $false } - if ($outputLine) { $_} - } | Out-String + $clContent = $changelog | Select-Object -Skip ($startLine-1) -First ($endLine - $startLine) | Out-String Write-Verbose -Verbose "Selected content: `n$clContent" From 4fc335669732c348fb3ef1167ed72c0145fffd7b Mon Sep 17 00:00:00 2001 From: Travis Plunk Date: Wed, 15 Jan 2025 14:53:53 -0800 Subject: [PATCH 063/173] Add tool package download in publish nuget stage (#24790) (#24792) Co-authored-by: Justin Chung <124807742+jshigetomi@users.noreply.github.com> Co-authored-by: Justin Chung --- .pipelines/templates/release-publish-nuget.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.pipelines/templates/release-publish-nuget.yml b/.pipelines/templates/release-publish-nuget.yml index 78338d7d87c..98249844d4c 100644 --- a/.pipelines/templates/release-publish-nuget.yml +++ b/.pipelines/templates/release-publish-nuget.yml @@ -12,6 +12,8 @@ jobs: os: windows templateContext: inputs: + - input: pipelineArtifact + artifactName: drop_setReleaseTagAndUploadTools_SetTagAndTools - input: pipelineArtifact pipeline: PSPackagesOfficial artifactName: drop_upload_upload_packages From 7c35f34553d27730710092eb3682fd2c9bc50a56 Mon Sep 17 00:00:00 2001 From: Travis Plunk Date: Thu, 16 Jan 2025 11:55:27 -0800 Subject: [PATCH 064/173] Update the TPN (#24797) --- ThirdPartyNotices.txt | 159 ++++++++++++++++++++++++++++-------------- 1 file changed, 108 insertions(+), 51 deletions(-) diff --git a/ThirdPartyNotices.txt b/ThirdPartyNotices.txt index a11a42b0aab..4abb1717d67 100644 --- a/ThirdPartyNotices.txt +++ b/ThirdPartyNotices.txt @@ -284,7 +284,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI --------------------------------------------------------- -Microsoft.Extensions.ObjectPool 8.0.11 - MIT +Microsoft.Extensions.ObjectPool 8.0.12 - MIT Copyright Jorn Zaefferer @@ -446,7 +446,7 @@ SOFTWARE. --------------------------------------------------------- -Microsoft.Win32.Registry.AccessControl 9.0.0 - MIT +Microsoft.Win32.Registry.AccessControl 9.0.1 - MIT Copyright (c) 2021 @@ -536,7 +536,7 @@ SOFTWARE. --------------------------------------------------------- -Microsoft.Win32.SystemEvents 9.0.0 - MIT +Microsoft.Win32.SystemEvents 9.0.1 - MIT Copyright (c) 2021 @@ -626,7 +626,7 @@ SOFTWARE. --------------------------------------------------------- -Microsoft.Windows.Compatibility 9.0.0 - MIT +Microsoft.Windows.Compatibility 9.0.1 - MIT (c) Microsoft Corporation @@ -679,7 +679,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. --------------------------------------------------------- -runtime.android-arm.runtime.native.System.IO.Ports 9.0.0 - MIT +runtime.android-arm.runtime.native.System.IO.Ports 9.0.1 - MIT Copyright (c) 2021 @@ -769,7 +769,7 @@ SOFTWARE. --------------------------------------------------------- -runtime.android-arm64.runtime.native.System.IO.Ports 9.0.0 - MIT +runtime.android-arm64.runtime.native.System.IO.Ports 9.0.1 - MIT Copyright (c) 2021 @@ -859,7 +859,7 @@ SOFTWARE. --------------------------------------------------------- -runtime.android-x64.runtime.native.System.IO.Ports 9.0.0 - MIT +runtime.android-x64.runtime.native.System.IO.Ports 9.0.1 - MIT Copyright (c) 2021 @@ -949,7 +949,7 @@ SOFTWARE. --------------------------------------------------------- -runtime.android-x86.runtime.native.System.IO.Ports 9.0.0 - MIT +runtime.android-x86.runtime.native.System.IO.Ports 9.0.1 - MIT Copyright (c) 2021 @@ -1039,7 +1039,7 @@ SOFTWARE. --------------------------------------------------------- -runtime.linux-arm.runtime.native.System.IO.Ports 9.0.0 - MIT +runtime.linux-arm.runtime.native.System.IO.Ports 9.0.1 - MIT Copyright (c) 2021 @@ -1129,7 +1129,7 @@ SOFTWARE. --------------------------------------------------------- -runtime.linux-arm64.runtime.native.System.IO.Ports 9.0.0 - MIT +runtime.linux-arm64.runtime.native.System.IO.Ports 9.0.1 - MIT Copyright (c) 2021 @@ -1219,7 +1219,7 @@ SOFTWARE. --------------------------------------------------------- -runtime.linux-bionic-arm64.runtime.native.System.IO.Ports 9.0.0 - MIT +runtime.linux-bionic-arm64.runtime.native.System.IO.Ports 9.0.1 - MIT Copyright (c) 2021 @@ -1309,7 +1309,7 @@ SOFTWARE. --------------------------------------------------------- -runtime.linux-bionic-x64.runtime.native.System.IO.Ports 9.0.0 - MIT +runtime.linux-bionic-x64.runtime.native.System.IO.Ports 9.0.1 - MIT Copyright (c) 2021 @@ -1399,7 +1399,7 @@ SOFTWARE. --------------------------------------------------------- -runtime.linux-musl-arm.runtime.native.System.IO.Ports 9.0.0 - MIT +runtime.linux-musl-arm.runtime.native.System.IO.Ports 9.0.1 - MIT Copyright (c) 2021 @@ -1489,7 +1489,7 @@ SOFTWARE. --------------------------------------------------------- -runtime.linux-musl-arm64.runtime.native.System.IO.Ports 9.0.0 - MIT +runtime.linux-musl-arm64.runtime.native.System.IO.Ports 9.0.1 - MIT Copyright (c) 2021 @@ -1579,7 +1579,7 @@ SOFTWARE. --------------------------------------------------------- -runtime.linux-musl-x64.runtime.native.System.IO.Ports 9.0.0 - MIT +runtime.linux-musl-x64.runtime.native.System.IO.Ports 9.0.1 - MIT Copyright (c) 2021 @@ -1669,7 +1669,7 @@ SOFTWARE. --------------------------------------------------------- -runtime.linux-x64.runtime.native.System.IO.Ports 9.0.0 - MIT +runtime.linux-x64.runtime.native.System.IO.Ports 9.0.1 - MIT Copyright (c) 2021 @@ -1759,7 +1759,7 @@ SOFTWARE. --------------------------------------------------------- -runtime.maccatalyst-arm64.runtime.native.System.IO.Ports 9.0.0 - MIT +runtime.maccatalyst-arm64.runtime.native.System.IO.Ports 9.0.1 - MIT Copyright (c) 2021 @@ -1849,7 +1849,7 @@ SOFTWARE. --------------------------------------------------------- -runtime.maccatalyst-x64.runtime.native.System.IO.Ports 9.0.0 - MIT +runtime.maccatalyst-x64.runtime.native.System.IO.Ports 9.0.1 - MIT Copyright (c) 2021 @@ -1992,7 +1992,7 @@ SOFTWARE. --------------------------------------------------------- -runtime.native.System.IO.Ports 9.0.0 - MIT +runtime.native.System.IO.Ports 9.0.1 - MIT Copyright (c) 2021 @@ -2082,7 +2082,7 @@ SOFTWARE. --------------------------------------------------------- -runtime.osx-arm64.runtime.native.System.IO.Ports 9.0.0 - MIT +runtime.osx-arm64.runtime.native.System.IO.Ports 9.0.1 - MIT Copyright (c) 2021 @@ -2172,7 +2172,7 @@ SOFTWARE. --------------------------------------------------------- -runtime.osx-x64.runtime.native.System.IO.Ports 9.0.0 - MIT +runtime.osx-x64.runtime.native.System.IO.Ports 9.0.1 - MIT Copyright (c) 2021 @@ -2262,7 +2262,7 @@ SOFTWARE. --------------------------------------------------------- -System.CodeDom 9.0.0 - MIT +System.CodeDom 9.0.1 - MIT Copyright (c) 2021 @@ -2438,7 +2438,7 @@ SOFTWARE. --------------------------------------------------------- -System.ComponentModel.Composition 9.0.0 - MIT +System.ComponentModel.Composition 9.0.1 - MIT Copyright (c) 2021 @@ -2528,7 +2528,7 @@ SOFTWARE. --------------------------------------------------------- -System.ComponentModel.Composition.Registration 9.0.0 - MIT +System.ComponentModel.Composition.Registration 9.0.1 - MIT Copyright (c) 2021 @@ -2618,7 +2618,7 @@ SOFTWARE. --------------------------------------------------------- -System.Configuration.ConfigurationManager 9.0.0 - MIT +System.Configuration.ConfigurationManager 9.0.1 - MIT Copyright (c) 2021 @@ -2708,7 +2708,7 @@ SOFTWARE. --------------------------------------------------------- -System.Data.Odbc 9.0.0 - MIT +System.Data.Odbc 9.0.1 - MIT Copyright (c) 2021 @@ -2798,7 +2798,7 @@ SOFTWARE. --------------------------------------------------------- -System.Data.OleDb 9.0.0 - MIT +System.Data.OleDb 9.0.1 - MIT Copyright (c) 2021 @@ -2941,9 +2941,66 @@ SOFTWARE. --------------------------------------------------------- -System.Diagnostics.DiagnosticSource 9.0.0 - MIT +System.Diagnostics.DiagnosticSource 9.0.1 - MIT +Copyright (c) 2021 +Copyright (c) Six Labors +(c) Microsoft Corporation +Copyright (c) 2022 FormatJS +Copyright (c) Andrew Arnott +Copyright 2019 LLVM Project +Copyright (c) 1998 Microsoft +Copyright 2018 Daniel Lemire +Copyright (c) .NET Foundation +Copyright (c) 2011, Google Inc. +Copyright (c) 2020 Dan Shechter +(c) 1997-2005 Sean Eron Anderson +Copyright (c) 2015 Andrew Gallant +Copyright (c) 2022, Wojciech Mula +Copyright (c) 2017 Yoshifumi Kawai +Copyright (c) 2022, Geoff Langdale +Copyright (c) 2005-2020 Rich Felker +Copyright (c) 2012-2021 Yann Collet +Copyright (c) Microsoft Corporation +Copyright (c) 2007 James Newton-King +Copyright (c) 1991-2022 Unicode, Inc. +Copyright (c) 2013-2017, Alfred Klomp +Copyright (c) 2018 Nemanja Mijailovic +Copyright 2012 the V8 project authors +Copyright (c) 1999 Lucent Technologies +Copyright (c) 2008-2016, Wojciech Mula +Copyright (c) 2011-2020 Microsoft Corp +Copyright (c) 2015-2017, Wojciech Mula +Copyright (c) 2015-2018, Wojciech Mula +Copyright (c) 2005-2007, Nick Galbreath +Copyright (c) 2015 The Chromium Authors +Copyright (c) 2018 Alexander Chermyanin +Copyright (c) The Internet Society 1997 +Copyright (c) 2004-2006 Intel Corporation +Copyright (c) 2011-2015 Intel Corporation +Copyright (c) 2013-2017, Milosz Krajewski +Copyright (c) 2016-2017, Matthieu Darbois +Copyright (c) The Internet Society (2003) +Copyright (c) .NET Foundation Contributors +(c) 1995-2024 Jean-loup Gailly and Mark Adler +Copyright (c) 2020 Mara Bos +Copyright (c) .NET Foundation and Contributors +Copyright (c) 2012 - present, Victor Zverovich +Copyright (c) 2006 Jb Evain (jbevain@gmail.com) +Copyright (c) 2008-2020 Advanced Micro Devices, Inc. +Copyright (c) 2019 Microsoft Corporation, Daan Leijen +Copyright (c) 2011 Novell, Inc (http://www.novell.com) +Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com) +Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors +Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com +Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc. +Portions (c) International Organization for Standardization 1986 +Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers +Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip +Copyright (c) 1980, 1986, 1993 The Regents of the University of California +Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California +Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass The MIT License (MIT) @@ -2974,7 +3031,7 @@ SOFTWARE. --------------------------------------------------------- -System.Diagnostics.EventLog 9.0.0 - MIT +System.Diagnostics.EventLog 9.0.1 - MIT Copyright (c) 2021 @@ -3064,7 +3121,7 @@ SOFTWARE. --------------------------------------------------------- -System.Diagnostics.PerformanceCounter 9.0.0 - MIT +System.Diagnostics.PerformanceCounter 9.0.1 - MIT Copyright (c) 2021 @@ -3154,7 +3211,7 @@ SOFTWARE. --------------------------------------------------------- -System.DirectoryServices 9.0.0 - MIT +System.DirectoryServices 9.0.1 - MIT Copyright (c) 2021 @@ -3244,7 +3301,7 @@ SOFTWARE. --------------------------------------------------------- -System.DirectoryServices.AccountManagement 9.0.0 - MIT +System.DirectoryServices.AccountManagement 9.0.1 - MIT Copyright (c) 2021 @@ -3334,7 +3391,7 @@ SOFTWARE. --------------------------------------------------------- -System.DirectoryServices.Protocols 9.0.0 - MIT +System.DirectoryServices.Protocols 9.0.1 - MIT Copyright (c) 2021 @@ -3424,7 +3481,7 @@ SOFTWARE. --------------------------------------------------------- -System.Drawing.Common 9.0.0 - MIT +System.Drawing.Common 9.0.1 - MIT (c) Microsoft Corporation @@ -3459,7 +3516,7 @@ SOFTWARE. --------------------------------------------------------- -System.IO.Packaging 9.0.0 - MIT +System.IO.Packaging 9.0.1 - MIT Copyright (c) 2021 @@ -3549,7 +3606,7 @@ SOFTWARE. --------------------------------------------------------- -System.IO.Ports 9.0.0 - MIT +System.IO.Ports 9.0.1 - MIT Copyright (c) 2021 @@ -3639,7 +3696,7 @@ SOFTWARE. --------------------------------------------------------- -System.Management 9.0.0 - MIT +System.Management 9.0.1 - MIT Copyright (c) 2021 @@ -3729,7 +3786,7 @@ SOFTWARE. --------------------------------------------------------- -System.Net.Http.WinHttpHandler 9.0.0 - MIT +System.Net.Http.WinHttpHandler 9.0.1 - MIT Copyright (c) 2021 @@ -3904,7 +3961,7 @@ SOFTWARE. --------------------------------------------------------- -System.Reflection.Context 9.0.0 - MIT +System.Reflection.Context 9.0.1 - MIT Copyright (c) 2021 @@ -4134,7 +4191,7 @@ SOFTWARE. --------------------------------------------------------- -System.Runtime.Caching 9.0.0 - MIT +System.Runtime.Caching 9.0.1 - MIT Copyright (c) 2021 @@ -4299,7 +4356,7 @@ SOFTWARE. --------------------------------------------------------- -System.Security.Cryptography.Pkcs 9.0.0 - MIT +System.Security.Cryptography.Pkcs 9.0.1 - MIT Copyright (c) 2021 @@ -4389,7 +4446,7 @@ SOFTWARE. --------------------------------------------------------- -System.Security.Cryptography.ProtectedData 9.0.0 - MIT +System.Security.Cryptography.ProtectedData 9.0.1 - MIT Copyright (c) 2021 @@ -4479,7 +4536,7 @@ SOFTWARE. --------------------------------------------------------- -System.Security.Cryptography.Xml 9.0.0 - MIT +System.Security.Cryptography.Xml 9.0.1 - MIT Copyright (c) 2021 @@ -4569,7 +4626,7 @@ SOFTWARE. --------------------------------------------------------- -System.Security.Permissions 9.0.0 - MIT +System.Security.Permissions 9.0.1 - MIT Copyright (c) 2021 @@ -4908,7 +4965,7 @@ SOFTWARE. --------------------------------------------------------- -System.ServiceModel.Syndication 9.0.0 - MIT +System.ServiceModel.Syndication 9.0.1 - MIT Copyright (c) 2021 @@ -4998,7 +5055,7 @@ SOFTWARE. --------------------------------------------------------- -System.ServiceProcess.ServiceController 9.0.0 - MIT +System.ServiceProcess.ServiceController 9.0.1 - MIT Copyright (c) 2021 @@ -5088,7 +5145,7 @@ SOFTWARE. --------------------------------------------------------- -System.Speech 9.0.0 - MIT +System.Speech 9.0.1 - MIT Copyright (c) 2021 @@ -5178,7 +5235,7 @@ SOFTWARE. --------------------------------------------------------- -System.Text.Encoding.CodePages 9.0.0 - MIT +System.Text.Encoding.CodePages 9.0.1 - MIT Copyright (c) 2021 @@ -5268,7 +5325,7 @@ SOFTWARE. --------------------------------------------------------- -System.Text.Encodings.Web 9.0.0 - MIT +System.Text.Encodings.Web 9.0.1 - MIT Copyright (c) 2021 @@ -5358,7 +5415,7 @@ SOFTWARE. --------------------------------------------------------- -System.Threading.AccessControl 9.0.0 - MIT +System.Threading.AccessControl 9.0.1 - MIT Copyright (c) 2021 @@ -5484,7 +5541,7 @@ SOFTWARE. --------------------------------------------------------- -System.Windows.Extensions 9.0.0 - MIT +System.Windows.Extensions 9.0.1 - MIT Copyright (c) 2021 From 99dab561892364d82d4965068f7f8b175e768b1b Mon Sep 17 00:00:00 2001 From: Travis Plunk Date: Thu, 16 Jan 2025 12:08:46 -0800 Subject: [PATCH 065/173] Add a parameter that skips verify packages step (#24763) (#24784) * added a parameter that skips verify packages step * fix parameter string to boolean value --------- Co-authored-by: Justin Chung <124807742+jshigetomi@users.noreply.github.com> Co-authored-by: Justin Chung --- .pipelines/apiscan-gen-notice.yml | 4 ++++ .pipelines/templates/compliance/generateNotice.yml | 5 +++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/.pipelines/apiscan-gen-notice.yml b/.pipelines/apiscan-gen-notice.yml index f469a49eef5..f4fd167d7a0 100644 --- a/.pipelines/apiscan-gen-notice.yml +++ b/.pipelines/apiscan-gen-notice.yml @@ -8,6 +8,9 @@ parameters: displayName: Debugging - Enable CodeQL and set cadence to 1 hour type: boolean default: false + - name: SkipVerifyPackages + type: boolean + default: false variables: - name: ob_outputDirectory @@ -103,3 +106,4 @@ extends: - template: /.pipelines/templates/compliance/generateNotice.yml@self parameters: parentJobs: [] + SkipVerifyPackages: ${{ parameters.SkipVerifyPackages }} diff --git a/.pipelines/templates/compliance/generateNotice.yml b/.pipelines/templates/compliance/generateNotice.yml index 0c1282ea8ce..9a00ed6f01d 100644 --- a/.pipelines/templates/compliance/generateNotice.yml +++ b/.pipelines/templates/compliance/generateNotice.yml @@ -4,6 +4,8 @@ parameters: - name: parentJobs type: jobList + - name: SkipVerifyPackages + type: boolean jobs: - job: generateNotice @@ -60,7 +62,7 @@ jobs: - pwsh: | $(repoRoot)/tools/clearlyDefined/ClearlyDefined.ps1 -TestAndHarvest displayName: Verify that packages have license data - + condition: eq(${{ parameters.SkipVerifyPackages }}, false) - task: msospo.ospo-extension.8d7f9abb-6896-461d-9e25-4f74ed65ddb2.notice@0 displayName: 'NOTICE File Generator' @@ -71,7 +73,6 @@ jobs: # this isn't working # additionaldata: $(Build.SourcesDirectory)\assets\additionalAttributions.txt - - pwsh: | Get-Content -Raw -Path $(repoRoot)\assets\additionalAttributions.txt | Out-File '$(ob_outputDirectory)\ThirdPartyNotices.txt' -Encoding utf8NoBOM -Force -Append Get-Content -Raw -Path $(repoRoot)\assets\additionalAttributions.txt From 3031ef7e6f020947a0c9d808783ca7a16ab67df7 Mon Sep 17 00:00:00 2001 From: Travis Plunk Date: Fri, 17 Jan 2025 12:52:12 -0800 Subject: [PATCH 066/173] Create changelog for v7.5.0 (#24808) (#24811) * Add changelog for 7.5.0 * move 7.5 history to the 7.5 changelog * Update CHANGELOG/7.5.md * Update CHANGELOG/7.5.md * Update changelog for 7.5.0-rc.1 release * Update CHANGELOG/7.5.md --------- Co-authored-by: Justin Chung --- CHANGELOG/7.5.md | 622 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 622 insertions(+) create mode 100644 CHANGELOG/7.5.md diff --git a/CHANGELOG/7.5.md b/CHANGELOG/7.5.md new file mode 100644 index 00000000000..702c60346e7 --- /dev/null +++ b/CHANGELOG/7.5.md @@ -0,0 +1,622 @@ +# 7.5 Changelog + +## [7.5.0] + +### Build and Packaging Improvements + +
+ + + +

Update .NET SDK to 9.0.102

+ +
+ +
    +
  • Add tool package download in publish nuget stage (#24790) (#24792)
  • +
  • Fix Changelog content grab during GitHub Release (#24788) (#24791)
  • +
  • Mark build as latest stable (#24789)
  • +
  • [release/v7.5] Update branch for release - Transitive - true - minor (#24786)
  • +
  • Update Microsoft.PowerShell.PSResourceGet to 1.1.0 (#24767) (#24785)
  • +
  • Make the AssemblyVersion not change for servicing releases (#24667) (#24783)
  • +
  • Deploy Box Update (#24632) (#24779)
  • +
  • Update machine pool for copy blob and upload buildinfo stage (#24587) (#24776)
  • +
  • Update nuget publish to use Deploy Box (#24596) (#24597)
  • +
  • Added Deploy Box Product Pathway to GitHub Release and NuGet Release Pipelines (#24583) (#24595)
  • +
+ +
+ +### Documentation and Help Content + +- Update `HelpInfoUri` for 7.5 (#24610) (#24777) + +[7.5.0]: https://github.com/PowerShell/PowerShell/compare/v7.5.0-rc.1...v7.5.0 + +## [7.5.0-rc.1] - 2024-11-14 + +**NOTE:** Due to technical issues, release of packages to packages.microsoft.com ~and release to NuGet.org~ is delayed. + +### Build and Packaging Improvements + +
+ + + +

Bump to .NET 9.0.100

+ +
+ +
    +
  • Update ThirdPartyNotices file (#24582) (#24536)
  • +
  • Bump to .NET 9.0.100 (#24576) (#24535)
  • +
  • Add a way to use only NuGet feed sources (#24528) (#24530)
  • +
  • Update PSResourceGet to v1.1.0-RC2 (#24512) (#24525)
  • +
  • Add PMC mapping for debian 12 (bookworm) (#24413) (#24518)
  • +
  • Bump .NET to 9.0.100-rc.2.24474.11 (#24509) (#24522)
  • +
  • Keep the roff file when gzipping it. (#24450) (#24520)
  • +
  • Checkin generated manpage (#24423) (#24519)
  • +
  • Update PSReadLine to 2.3.6 (#24380) (#24517)
  • +
  • Download package from package build for generating vpack (#24481) (#24521)
  • +
  • Delete the msix blob if it's already there (#24353) (#24516)
  • +
  • Add CodeQL scanning to APIScan build (#24303) (#24515)
  • +
  • Update vpack pipeline (#24281) (#24514)
  • +
  • Fix seed max value for Container Linux CI (#24510) (#24511)
  • +
  • Bring preview.5 release fixes to release/v7.5 (#24379) (#24368)
  • +
  • Add BaseUrl to buildinfo json file (#24376) (#24377)
  • +
+ +
+ +[7.5.0-rc.1]: https://github.com/PowerShell/PowerShell/compare/v7.5.0-preview.5...v7.5.0-rc.1 + +## [7.5.0-preview.5] - 2024-10-01 + +### Breaking Changes + +- Treat large `Enum` values as numbers in `ConvertTo-Json` (#20999) (#24304) + +### Engine Updates and Fixes + +- Fix how processor architecture is validated in `Import-Module` (#24265) (#24317) + +### Experimental Features + +### General Cmdlet Updates and Fixes + +- Add `-Force` parameter to `Resolve-Path` and `Convert-Path` cmdlets to support wildcard hidden files (#20981) (#24344) +- Add telemetry to track the use of features (#24247) (#24331) +- Treat large `Enum` values as numbers in `ConvertTo-Json` (#20999) (#24304) +- Make features `PSCommandNotFoundSuggestion`, `PSCommandWithArgs`, and `PSModuleAutoLoadSkipOfflineFiles` stable (#24246) (#24310) +- Handle global tool when prepending `$PSHome` to `PATH` (#24228) (#24307) + +### Tests + +- Fix cleanup in `PSResourceGet` test (#24339) (#24345) + +### Build and Packaging Improvements + +
+ + + +

Bump .NET SDK to 9.0.100-rc.1.24452.12

+ +
+ +
    +
  • Fixed Test Scenario for Compress-PSResource (Internal 32696)
  • +
  • Add back local NuGet source for test packages (Internal 32693)
  • +
  • Fix typo in release-MakeBlobPublic.yml (Internal 32689)
  • +
  • Copy to static site instead of making blob public (#24269) (#24343)
  • +
  • Update Microsoft.PowerShell.PSResourceGet to 1.1.0-preview2 (#24300) (#24337)
  • +
  • Remove the MD5 branch in the strong name signing token calculation (#24288) (#24321)
  • +
  • Update experimental-feature json files (#24271) (#24319)
  • +
  • Add updated libicu dependency for Debian packages (#24301) (#24324)
  • +
  • Add mapping to AzureLinux repo (#24290) (#24322)
  • +
  • Update and add new NuGet package sources for different environments. (#24264) (#24316)
  • +
  • Bump .NET 9 to 9.0.100-rc.1.24452.12 (#24273) (#24320)
  • +
  • Make some release tests run in a hosted pools (#24270) (#24318)
  • +
  • Do not build the exe for Global tool shim project (#24263) (#24315)
  • +
  • Delete assets/AppImageThirdPartyNotices.txt (#24256) (#24313)
  • +
  • Create new pipeline for compliance (#24252) (#24312)
  • +
  • Add specific path for issues in tsaconfig (#24244) (#24309)
  • +
  • Use Managed Identity for APIScan authentication (#24243) (#24308)
  • +
  • Add Windows signing for pwsh.exe (#24219) (#24306)
  • +
  • Check Create and Submit in vPack build by default (#24181) (#24305)
  • +
+ +
+ +### Documentation and Help Content + +- Delete demos directory (#24258) (#24314) + +[7.5.0-preview.5]: https://github.com/PowerShell/PowerShell/compare/v7.5.0-preview.4...v7.5.0-preview.5 + +## [7.5.0-preview.4] - 2024-08-28 + +### Engine Updates and Fixes + +- RecommendedAction: Explicitly start and stop ANSI Error Color (#24065) (Thanks @JustinGrote!) +- Improve .NET overload definition of generic methods (#21326) (Thanks @jborean93!) +- Optimize the `+=` operation for a collection when it's an object array (#23901) (Thanks @jborean93!) +- Allow redirecting to a variable as experimental feature `PSRedirectToVariable` (#20381) + +### General Cmdlet Updates and Fixes + +- Change type of `LineNumber` to `ulong` in `Select-String` (#24075) (Thanks @Snowman-25!) +- Fix `Invoke-RestMethod` to allow `-PassThru` and `-Outfile` work together (#24086) (Thanks @jshigetomi!) +- Fix Hyper-V Remoting when the module is imported via implicit remoting (#24032) (Thanks @jborean93!) +- Add `ConvertTo-CliXml` and `ConvertFrom-CliXml` cmdlets (#21063) (Thanks @ArmaanMcleod!) +- Add `OutFile` property in `WebResponseObject` (#24047) (Thanks @jshigetomi!) +- Show filename in `Invoke-WebRequest -OutFile -Verbose` (#24041) (Thanks @jshigetomi!) +- `Set-Acl`: Do not fail on untranslatable SID (#21096) (Thanks @jborean93!) +- Fix the extent of the parser error when a number constant is invalid (#24024) +- Fix `Move-Item` to throw error when moving into itself (#24004) +- Fix up .NET method invocation with `Optional` argument (#21387) (Thanks @jborean93!) +- Fix progress calculation on `Remove-Item` (#23869) (Thanks @jborean93!) +- Fix WebCmdlets when `-Body` is specified but `ContentType` is not (#23952) (Thanks @CarloToso!) +- Enable `-NoRestart` to work with `Register-PSSessionConfiguration` (#23891) +- Add `IgnoreComments` and `AllowTrailingCommas` options to `Test-Json` cmdlet (#23817) (Thanks @ArmaanMcleod!) +- Get-Help may report parameters with `ValueFromRemainingArguments` attribute as pipeline-able (#23871) + +### Code Cleanup + +
+ + + +

We thank the following contributors!

+

@xtqqczze, @eltociear

+ +
+ +
    +
  • Minor cleanup on local variable names within a method (#24105)
  • +
  • Remove explicit IDE1005 suppressions (#21217) (Thanks @xtqqczze!)
  • +
  • Fix a typo in WebRequestSession.cs (#23963) (Thanks @eltociear!)
  • +
+ +
+ +### Tools + +- devcontainers: mount workspace in /PowerShell (#23857) (Thanks @rzippo!) + +### Tests + +- Add debugging to the MTU size test (#21463) + +### Build and Packaging Improvements + +
+ + + +

We thank the following contributors!

+

@bosesubham2011

+ +
+ +
    +
  • Update third party notices (Internal 32128)
  • +
  • Update cgmanifest (#24163)
  • +
  • Fixes to Azure Public feed usage (#24149)
  • +
  • Add support for back porting PRs from GitHub or the Private Azure Repos (#20670)
  • +
  • Move to 9.0.0-preview.6.24327.7 (#24133)
  • +
  • update path (#24134)
  • +
  • Update to the latest NOTICES file (#24131)
  • +
  • Fix semver issue with updating cgmanifest (#24132)
  • +
  • Add ability to capture MSBuild Binary logs when restore fails (#24128)
  • +
  • add ability to skip windows stage (#24116)
  • +
  • chore: Refactor Nuget package source creation to use New-NugetPackageSource function (#24104)
  • +
  • Make Microsoft feeds the default (#24098)
  • +
  • Cleanup unused csproj (#23951)
  • +
  • Add script to update SDK version during release (#24034)
  • +
  • Enumerate over all signed zip packages (#24063)
  • +
  • Update metadata.json for PowerShell July releases (#24082)
  • +
  • Add macos signing for package files (#24015)
  • +
  • Update install-powershell.sh to support azure-linux (#23955) (Thanks @bosesubham2011!)
  • +
  • Skip build steps that do not have exe packages (#23945)
  • +
  • Update metadata.json for PowerShell June releases (#23973)
  • +
  • Create powershell.config.json for PowerShell.Windows.x64 global tool (#23941)
  • +
  • Fix error in the vPack release, debug script that blocked release (#23904)
  • +
  • Add vPack release (#23898)
  • +
  • Fix exe signing with third party signing for WiX engine (#23878)
  • +
  • Update wix installation in CI (#23870)
  • +
  • Add checkout to fix TSA config paths (#23865)
  • +
  • Merge the v7.5.0-preview.3 release branch to GitHub master branch
  • +
  • Update metadata.json for the v7.5.0-preview.3 release (#23862)
  • +
  • Bump PSResourceGet to 1.1.0-preview1 (#24129)
  • +
  • Bump github/codeql-action from 3.25.8 to 3.26.0 (#23953) (#23999) (#24053) (#24069) (#24095) (#24118)
  • +
  • Bump actions/upload-artifact from 4.3.3 to 4.3.6 (#24019) (#24113) (#24119)
  • +
  • Bump agrc/create-reminder-action from 1.1.13 to 1.1.15 (#24029) (#24043)
  • +
  • Bump agrc/reminder-action from 1.0.12 to 1.0.14 (#24028) (#24042)
  • +
  • Bump super-linter/super-linter from 5.7.2 to 6.8.0 (#23809) (#23856) (#23894) (#24030) (#24103)
  • +
  • Bump ossf/scorecard-action from 2.3.1 to 2.4.0 (#23802) (#24096)
  • +
  • Bump actions/dependency-review-action from 4.3.2 to 4.3.4 (#23897) (#24046)
  • +
  • Bump actions/checkout from 4.1.5 to 4.1.7 (#23813) (#23947)
  • +
  • Bump github/codeql-action from 3.25.4 to 3.25.8 (#23801) (#23893)
  • +
+ +
+ +### Documentation and Help Content + +- Update docs sample nuget.config (#24109) +- Update Code of Conduct and Security Policy (#23811) +- Update working-group-definitions.md for the Security WG (#23884) +- Fix up broken links in Markdown files (#23863) +- Update Engine Working Group Members (#23803) (Thanks @kilasuit!) +- Remove outdated and contradictory information from `README` (#23812) + +[7.5.0-preview.4]: https://github.com/PowerShell/PowerShell/compare/v7.5.0-preview.3...v7.5.0-preview.4 + +## [7.5.0-preview.3] - 2024-05-16 + +### Breaking Changes + +- Remember installation options and used them to initialize options for the next installation (#20420) (Thanks @reduckted!) +- `ConvertTo-Json`: Serialize `BigInteger` as a number (#21000) (Thanks @jborean93!) + +### Engine Updates and Fixes + +- Fix generating `OutputType` when running in Constrained Language Mode (#21605) +- Revert the PR #17856 (Do not preserve temporary results when no need to do so) (#21368) +- Make sure the assembly/library resolvers are registered at early stage (#21361) +- Fix PowerShell class to support deriving from an abstract class with abstract properties (#21331) +- Fix error formatting for pipeline enumeration exceptions (#20211) + +### General Cmdlet Updates and Fixes + +- Added progress bar for `Remove-Item` cmdlet (#20778) (Thanks @ArmaanMcleod!) +- Expand `~` to `$home` on Windows with tab completion (#21529) +- Separate DSC configuration parser check for ARM processor (#21395) (Thanks @dkontyko!) +- Fix `[semver]` type to pass `semver.org` tests (#21401) +- Don't complete when declaring parameter name and class member (#21182) (Thanks @MartinGC94!) +- Add `RecommendedAction` to `ConciseView` of the error reporting (#20826) (Thanks @JustinGrote!) +- Fix the error when using `Start-Process -Credential` without the admin privilege (#21393) (Thanks @jborean93!) +- Fix `Test-Path -IsValid` to check for invalid path and filename characters (#21358) +- Fix build failure due to missing reference in `GlobalToolShim.cs` (#21388) +- Fix argument passing in `GlobalToolShim` (#21333) (Thanks @ForNeVeR!) +- Make sure both stdout and stderr can be redirected from a native executable (#20997) +- Handle the case that `Runspace.DefaultRunspace == null` when logging for WDAC Audit (#21344) +- Fix a typo in `releaseTools.psm1` (#21306) (Thanks @eltociear!) +- `Get-Process`: Remove admin requirement for `-IncludeUserName` (#21302) (Thanks @jborean93!) +- Fall back to type inference when hashtable key-value cannot be retrieved from safe expression (#21184) (Thanks @MartinGC94!) +- Fix the regression when doing type inference for `$_` (#21223) (Thanks @MartinGC94!) +- Revert "Adjust PUT method behavior to POST one for default content type in WebCmdlets" (#21049) +- Fix a regression in `Format-Table` when header label is empty (#21156) + +### Code Cleanup + +
+ + + +

We thank the following contributors!

+

@xtqqczze

+ +
+ +
    +
  • Enable CA1868: Unnecessary call to 'Contains' for sets (#21165) (Thanks @xtqqczze!)
  • +
  • Remove JetBrains.Annotations attributes (#21246) (Thanks @xtqqczze!)
  • +
+ +
+ +### Tests + +- Update `metadata.json` and `README.md` (#21454) +- Skip test on Windows Server 2012 R2 for `no-nl` (#21265) + +### Build and Packaging Improvements + +
+ + + +

Bump to .NET 9.0.0-preview.3

+

We thank the following contributors!

+

@alerickson, @tgauth, @step-security-bot, @xtqqczze

+ +
+ +
    +
  • Fix PMC publish and the file path for msixbundle
  • +
  • Fix release version and stage issues in build and packaging
  • +
  • Add release tag if the environment variable is set
  • +
  • Update installation on Wix module (#23808)
  • +
  • Updates to package and release pipelines (#23800)
  • +
  • Update PSResourceGet to 1.0.5 (#23796)
  • +
  • Bump actions/upload-artifact from 4.3.2 to 4.3.3 (#21520)
  • +
  • Bump actions/dependency-review-action from 4.2.5 to 4.3.2 (#21560)
  • +
  • Bump actions/checkout from 4.1.2 to 4.1.5 (#21613)
  • +
  • Bump github/codeql-action from 3.25.1 to 3.25.4 (#22071)
  • +
  • Use feed with Microsoft Wix toolset (#21651) (Thanks @tgauth!)
  • +
  • Bump to .NET 9 preview 3 (#21782)
  • +
  • Use PSScriptRoot to find path to Wix module (#21611)
  • +
  • Create the Windows.x64 global tool with shim for signing (#21559)
  • +
  • Update Wix package install (#21537) (Thanks @tgauth!)
  • +
  • Add branch counter variables for daily package builds (#21523)
  • +
  • Use correct signing certificates for RPM and DEBs (#21522)
  • +
  • Revert to version available on Nuget for Microsoft.CodeAnalysis.Analyzers (#21515)
  • +
  • Official PowerShell Package pipeline (#21504)
  • +
  • Add a PAT for fetching PMC cli (#21503)
  • +
  • Bump ossf/scorecard-action from 2.0.6 to 2.3.1 (#21485)
  • +
  • Apply security best practices (#21480) (Thanks @step-security-bot!)
  • +
  • Bump Microsoft.CodeAnalysis.Analyzers (#21449)
  • +
  • Fix package build to not check some files for a signature. (#21458)
  • +
  • Update PSResourceGet version from 1.0.2 to 1.0.4.1 (#21439) (Thanks @alerickson!)
  • +
  • Verify environment variable for OneBranch before we try to copy (#21441)
  • +
  • Add back two transitive dependency packages (#21415)
  • +
  • Multiple fixes in official build pipeline (#21408)
  • +
  • Update PSReadLine to v2.3.5 (#21414)
  • +
  • PowerShell co-ordinated build OneBranch pipeline (#21364)
  • +
  • Add file description to pwsh.exe (#21352)
  • +
  • Suppress MacOS package manager output (#21244) (Thanks @xtqqczze!)
  • +
  • Update metadata.json and README.md (#21264)
  • +
+ +
+ +### Documentation and Help Content + +- Update the doc about how to build PowerShell (#21334) (Thanks @ForNeVeR!) +- Update the member lists for the Engine and Interactive-UX working groups (#20991) (Thanks @kilasuit!) +- Update CHANGELOG for `v7.2.19`, `v7.3.12` and `v7.4.2` (#21462) +- Fix grammar in `FAQ.md` (#21468) (Thanks @CodingGod987!) +- Fix typo in `SessionStateCmdletAPIs.cs` (#21413) (Thanks @eltociear!) +- Fix typo in a test (#21337) (Thanks @testwill!) +- Fix typo in `ast.cs` (#21350) (Thanks @eltociear!) +- Adding Working Group membership template (#21153) + +[7.5.0-preview.3]: https://github.com/PowerShell/PowerShell/compare/v7.5.0-preview.2...v7.5.0-preview.3 + +## [7.5.0-preview.2] - 2024-02-22 + +### Engine Updates and Fixes + +- Fix `using assembly` to use `Path.Combine` when constructing assembly paths (#21169) +- Validate the value for `using namespace` during semantic checks to prevent declaring invalid namespaces (#21162) + +### General Cmdlet Updates and Fixes + +- Add `WinGetCommandNotFound` and `CompletionPredictor` modules to track usage (#21040) +- `ConvertFrom-Json`: Add `-DateKind` parameter (#20925) (Thanks @jborean93!) +- Add tilde expansion for windows native executables (#20402) (Thanks @domsleee!) +- Add `DirectoryInfo` to the `OutputType` for `New-Item` (#21126) (Thanks @MartinGC94!) +- Fix `Get-Error` serialization of array values (#21085) (Thanks @jborean93!) + +### Code Cleanup + +
+ + + +

We thank the following contributors!

+

@eltociear

+ +
+ +
    +
  • Fix a typo in CoreAdapter.cs (#21179) (Thanks @eltociear!)
  • +
  • Remove PSScheduledJob module source code (#21189)
  • +
+ +
+ +### Tests + +- Rewrite the mac syslog tests to make them less flaky (#21174) + +### Build and Packaging Improvements + +
+ + +

Bump to .NET 9 Preview 1

+

We thank the following contributors!

+

@gregsdennis

+ +
+ +
    +
  • Bump to .NET 9 Preview 1 (#21229)
  • +
  • Add dotnet-runtime-9.0 as a dependency for the Mariner package
  • +
  • Add dotenv install as latest version does not work with current Ruby version (#21239)
  • +
  • Remove surrogateFile setting of APIScan (#21238)
  • +
  • Update experimental-feature json files (#21213)
  • +
  • Update to the latest NOTICES file (#21236)(#21177)
  • +
  • Update the cgmanifest (#21237)(#21093)
  • +
  • Update the cgmanifest (#21178)
  • +
  • Bump XunitXml.TestLogger from 3.1.17 to 3.1.20 (#21207)
  • +
  • Update versions of PSResourceGet (#21190)
  • +
  • Generate MSI for win-arm64 installer (#20516)
  • +
  • Bump JsonSchema.Net to v5.5.1 (#21120) (Thanks @gregsdennis!)
  • +
+ +
+ +### Documentation and Help Content + +- Update `README.md` and `metadata.json` for v7.5.0-preview.1 release (#21094) +- Fix incorrect examples in XML docs in `PowerShell.cs` (#21173) +- Update WG members (#21091) +- Update changelog for v7.4.1 (#21098) + +[7.5.0-preview.2]: https://github.com/PowerShell/PowerShell/compare/v7.5.0-preview.1...v7.5.0-preview.2 + +## [7.5.0-preview.1] - 2024-01-18 + +### Breaking Changes + +- Fix `-OlderThan` and `-NewerThan` parameters for `Test-Path` when using `PathType` and date range (#20942) (Thanks @ArmaanMcleod!) +- Previously `-OlderThan` would be ignored if specified together +- Change `New-FileCatalog -CatalogVersion` default to 2 (#20428) (Thanks @ThomasNieto!) + +### General Cmdlet Updates and Fixes + +- Fix completion crash for the SCCM provider (#20815, #20919, #20915) (Thanks @MartinGC94!) +- Fix regression in `Get-Content` when `-Tail 0` and `-Wait` are used together (#20734) (Thanks @CarloToso!) +- Add `Aliases` to the properties shown up when formatting the help content of the parameter returned by `Get-Help` (#20994) +- Add implicit localization fallback to `Import-LocalizedData` (#19896) (Thanks @chrisdent-de!) +- Change `Test-FileCatalog` to use `File.OpenRead` to better handle the case where the file is being used (#20939) (Thanks @dxk3355!) +- Added `-Module` completion for `Save-Help` and `Update-Help` commands (#20678) (Thanks @ArmaanMcleod!) +- Add argument completer to `-Verb` for `Start-Process` (#20415) (Thanks @ArmaanMcleod!) +- Add argument completer to `-Scope` for `*-Variable`, `*-Alias` & `*-PSDrive` commands (#20451) (Thanks @ArmaanMcleod!) +- Add argument completer to `-Verb` for `Get-Verb` and `Get-Command` (#20286) (Thanks @ArmaanMcleod!) +- Fixing incorrect formatting string in `CommandSearcher` trace logging (#20928) (Thanks @powercode!) +- Ensure the filename is not null when logging WDAC ETW events (#20910) (Thanks @jborean93!) +- Fix four regressions introduced by the WDAC logging feature (#20913) +- Leave the input, output, and error handles unset when they are not redirected (#20853) +- Fix `Start-Process -PassThru` to make sure the `ExitCode` property is accessible for the returned `Process` object (#20749) (Thanks @CodeCyclone!) +- Fix `Group-Object` output using interpolated strings (#20745) (Thanks @mawosoft!) +- Fix rendering of `DisplayRoot` for network `PSDrive` (#20793) +- Fix `Invoke-WebRequest` to report correct size when `-Resume` is specified (#20207) (Thanks @LNKLEO!) +- Add `PSAdapter` and `ConsoleGuiTools` to module load telemetry allow list (#20641) +- Fix Web Cmdlets to allow `WinForm` apps to work correctly (#20606) +- Block getting help from network locations in restricted remoting sessions (#20593) +- Fix `Group-Object` to use current culture for its output (#20608) +- Add argument completer to `-Version` for `Set-StrictMode` (#20554) (Thanks @ArmaanMcleod!) +- Fix `Copy-Item` progress to only show completed when all files are copied (#20517) +- Fix UNC path completion regression (#20419) (Thanks @MartinGC94!) +- Add telemetry to check for specific tags when importing a module (#20371) +- Report error if invalid `-ExecutionPolicy` is passed to `pwsh` (#20460) +- Add `HelpUri` to `Remove-Service` (#20476) +- Fix `unixmode` to handle `setuid` and `sticky` when file is not an executable (#20366) +- Fix `Test-Connection` due to .NET 8 changes (#20369) +- Fix implicit remoting proxy cmdlets to act on common parameters (#20367) +- Set experimental features to stable for 7.4 release (#20285) +- Revert changes to continue using `BinaryFormatter` for `Out-GridView` (#20300) +- Fix `Get-Service` non-terminating error message to include category (#20276) +- Prevent `Export-CSV` from flushing with every input (#20282) (Thanks @Chris--A!) +- Fix a regression in DSC (#20268) +- Include the module version in error messages when module is not found (#20144) (Thanks @ArmaanMcleod!) +- Add `-Empty` and `-InputObject` parameters to `New-Guid` (#20014) (Thanks @CarloToso!) +- Remove the comment trigger from feedback provider (#20136) +- Prevent fallback to file completion when tab completing type names (#20084) (Thanks @MartinGC94!) +- Add the alias `r` to the parameter `-Recurse` for the `Get-ChildItem` command (#20100) (Thanks @kilasuit!) + +### Code Cleanup + +
+ + + +

We thank the following contributors!

+

@eltociear, @ImportTaste, @ThomasNieto, @0o001

+ +
+ +
    +
  • Fix typos in the code base (#20147, #20492, #20632, #21015, #20838) (Thanks @eltociear!)
  • +
  • Add the missing alias LP to -LiteralPath for some cmdlets (#20820) (Thanks @ImportTaste!)
  • +
  • Remove parenthesis for empty attribute parameters (#20087) (Thanks @ThomasNieto!)
  • +
  • Add space around keyword according to the CodeFactor rule (#20090) (Thanks @ThomasNieto!)
  • +
  • Remove blank lines as instructed by CodeFactor rules (#20086) (Thanks @ThomasNieto!)
  • +
  • Remove trailing whitespace (#20085) (Thanks @ThomasNieto!)
  • +
  • Fix typo in error message (#20145) (Thanks @0o001!)
  • +
+ +
+ +### Tools + +- Make sure feedback link in the bot's comment is clickable (#20878) (Thanks @floh96!) +- Fix bot so anyone who comments will remove the "Resolution-No Activity" label (#20788) +- Fix bot configuration to prevent multiple comments about "no activity" (#20758) +- Add bot logic for closing GitHub issues after 6 months of "no activity" (#20525) +- Refactor bot for easier use and updating (#20805) +- Configure bot to add survey comment for closed issues (#20397) + +### Tests + +- Suppress error output from `Set-Location` tests (#20499) +- Fix typo in `FileCatalog.Tests.ps1` (#20329) (Thanks @eltociear!) +- Continue to improve tests for release automation (#20182) +- Skip the test on x86 as `InstallDate` is not visible on `Wow64` (#20165) +- Harden some problematic release tests (#20155) + +### Build and Packaging Improvements + +
+ + + +

We thank the following contributors!

+

@alerickson, @Zhoneym, @0o001

+ +
+ +
    +
  • Bump .NET SDK to 8.0.101 (#21084)
  • +
  • Update the cgmanifest (#20083, #20436, #20523, #20560, #20627, #20764, #20906, #20933, #20955, #21047)
  • +
  • Update to the latest NOTICES file (#20074, #20161, #20385, #20453, #20576, #20590, #20880, #20905)
  • +
  • Bump StyleCop.Analyzers from 1.2.0-beta.507 to 1.2.0-beta.556 (#20953)
  • +
  • Bump xUnit to 2.6.6 (#21071)
  • +
  • Bump JsonSchema.Net to 5.5.0 (#21027)
  • +
  • Fix failures in GitHub action markdown-link-check (#20996)
  • +
  • Bump xunit.runner.visualstudio to 2.5.6 (#20966)
  • +
  • Bump github/codeql-action from 2 to 3 (#20927)
  • +
  • Bump Markdig.Signed to 0.34.0 (#20926)
  • +
  • Bump Microsoft.ApplicationInsights from 2.21.0 to 2.22.0 (#20888)
  • +
  • Bump Microsoft.NET.Test.Sdk to 17.8.0 (#20660)
  • +
  • Update apiscan.yml to have access to the AzDevOpsArtifacts variable group (#20671)
  • +
  • Set the ollForwardOnNoCandidateFx in runtimeconfig.json to roll forward only on minor and patch versions (#20689)
  • +
  • Sign the global tool shim executable (#20794)
  • +
  • Bump actions/github-script from 6 to 7 (#20682)
  • +
  • Remove RHEL7 publishing to packages.microsoft.com as it's no longer supported (#20849)
  • +
  • Bump Microsoft.CodeAnalysis.CSharp to 4.8.0 (#20751)
  • +
  • Add internal nuget feed to compliance build (#20669)
  • +
  • Copy azure blob with PowerShell global tool to private blob and move to CDN during release (#20659)
  • +
  • Fix release build by making the internal SDK parameter optional (#20658)
  • +
  • Update PSResourceGet version to 1.0.1 (#20652)
  • +
  • Make internal .NET SDK URL as a parameter for release builld (#20655)
  • +
  • Fix setting of variable to consume internal SDK source (#20644)
  • +
  • Bump Microsoft.Management.Infrastructure to v3.0.0 (#20642)
  • +
  • Bump Microsoft.PowerShell.Native to v7.4.0 (#20617)
  • +
  • Bump Microsoft.Security.Extensions from 1.2.0 to 1.3.0 (#20556)
  • +
  • Fix package version for .NET nuget packages (#20551)
  • +
  • Add SBOM for release pipeline (#20519)
  • +
  • Block any preview vPack release (#20243)
  • +
  • Only registry App Path for release package (#20478)
  • +
  • Increase timeout when publishing packages to pacakages.microsoft.com (#20470)
  • +
  • Fix alpine tar package name and do not crossgen alpine fxdependent package (#20459)
  • +
  • Bump PSReadLine from 2.2.6 to 2.3.4 (#20305)
  • +
  • Remove the ref folder before running compliance (#20373)
  • +
  • Updates RIDs used to generate component Inventory (#20370)
  • +
  • Bump XunitXml.TestLogger from 3.1.11 to 3.1.17 (#20293)
  • +
  • Update experimental-feature json files (#20335)
  • +
  • Use fxdependent-win-desktop runtime for compliance runs (#20326)
  • +
  • Release build: Change the names of the PATs (#20307)
  • +
  • Add mapping for mariner arm64 stable (#20213)
  • +
  • Put the calls to Set-AzDoProjectInfo and Set-AzDoAuthToken in the right order (#20306)
  • +
  • Enable vPack provenance data (#20220)
  • +
  • Bump actions/checkout from 3 to 4 (#20205)
  • +
  • Start using new packages.microsoft.com cli (#20140, #20141)
  • +
  • Add mariner arm64 to PMC release (#20176)
  • +
  • Fix typo donet to dotnet in build scripts and pipelines (#20122) (Thanks @0o001!)
  • +
  • Install the pmc cli
  • +
  • Add skip publish parameter
  • +
  • Add verbose to clone
  • +
+ +
+ +### Documentation and Help Content + +- Include information about upgrading in readme (#20993) +- Expand "iff" to "if-and-only-if" in XML doc content (#20852) +- Update LTS links in README.md to point to the v7.4 packages (#20839) (Thanks @kilasuit!) +- Update `README.md` to improve readability (#20553) (Thanks @AnkitaSikdar005!) +- Fix link in `docs/community/governance.md` (#20515) (Thanks @suravshresth!) +- Update `ADOPTERS.md` (#20555) (Thanks @AnkitaSikdar005!) +- Fix a typo in `ADOPTERS.md` (#20504, #20520) (Thanks @shruti-sen2004!) +- Correct grammatical errors in `README.md` (#20509) (Thanks @alienishi!) +- Add 7.3 changelog URL to readme (#20473) (Thanks @Saibamen!) +- Clarify some comments and documentation (#20462) (Thanks @darkstar!) + +[7.5.0-preview.1]: https://github.com/PowerShell/PowerShell/compare/v7.4.1...v7.5.0-preview.1 From a6525aa080d9949073ce8a7a94e817aa5c591ff3 Mon Sep 17 00:00:00 2001 From: Travis Plunk Date: Fri, 17 Jan 2025 13:26:45 -0800 Subject: [PATCH 067/173] Fixed release pipeline errors and switched to KS3 (#24751) (#24815) * Fixed an error in the release pipeline * Fixed ReleaseTag and Version variable in validate packages * Switched from Netlock to KS3 --------- Co-authored-by: Justin Chung <124807742+jshigetomi@users.noreply.github.com> Co-authored-by: Justin Chung --- .pipelines/PowerShell-Release-Official.yml | 2 +- .../templates/release-SetReleaseTagandContainerName.yml | 6 +++--- .pipelines/templates/release-create-msix.yml | 2 +- .pipelines/templates/release-githubtasks.yml | 1 + .pipelines/templates/release-validate-globaltools.yml | 4 ++-- .pipelines/templates/release-validate-packagenames.yml | 2 +- .pipelines/templates/release-validate-sdk.yml | 2 +- 7 files changed, 10 insertions(+), 9 deletions(-) diff --git a/.pipelines/PowerShell-Release-Official.yml b/.pipelines/PowerShell-Release-Official.yml index 6a17139e05e..30c820cabcc 100644 --- a/.pipelines/PowerShell-Release-Official.yml +++ b/.pipelines/PowerShell-Release-Official.yml @@ -88,7 +88,7 @@ extends: featureFlags: WindowsHostVersion: Version: 2022 - Network: Netlock + Network: KS3 cloudvault: enabled: false globalSdl: diff --git a/.pipelines/templates/release-SetReleaseTagandContainerName.yml b/.pipelines/templates/release-SetReleaseTagandContainerName.yml index 667132f5f90..407a3a8f91d 100644 --- a/.pipelines/templates/release-SetReleaseTagandContainerName.yml +++ b/.pipelines/templates/release-SetReleaseTagandContainerName.yml @@ -15,12 +15,12 @@ steps: displayName: Set Release Tag - pwsh: | - $azureVersion = '$(ReleaseTag)'.ToLowerInvariant() -replace '\.', '-' - $vstsCommandString = "vso[task.setvariable variable=AzureVersion]$azureVersion" + $azureVersion = '$(OutputReleaseTag.ReleaseTag)'.ToLowerInvariant() -replace '\.', '-' + $vstsCommandString = "vso[task.setvariable variable=AzureVersion;isOutput=true]$azureVersion" Write-Host "sending " + $vstsCommandString Write-Host "##$vstsCommandString" - $version = '$(ReleaseTag)'.ToLowerInvariant().Substring(1) + $version = '$(OutputReleaseTag.ReleaseTag)'.ToLowerInvariant().Substring(1) $vstsCommandString = "vso[task.setvariable variable=Version;isOutput=true]$version" Write-Host ("sending " + $vstsCommandString) Write-Host "##$vstsCommandString" diff --git a/.pipelines/templates/release-create-msix.yml b/.pipelines/templates/release-create-msix.yml index 448a46c1194..3b1573d9777 100644 --- a/.pipelines/templates/release-create-msix.yml +++ b/.pipelines/templates/release-create-msix.yml @@ -96,7 +96,7 @@ jobs: azurePowerShellVersion: LatestVersion pwsh: true inline: | - $containerName = '$(AzureVersion)-private' + $containerName = '$(OutputVersion.AzureVersion)-private' $storageAccount = '$(StorageAccount)' $storageContext = New-AzStorageContext -StorageAccountName $storageAccount -UseConnectedAccount diff --git a/.pipelines/templates/release-githubtasks.yml b/.pipelines/templates/release-githubtasks.yml index 4af3c973205..31e66b793a4 100644 --- a/.pipelines/templates/release-githubtasks.yml +++ b/.pipelines/templates/release-githubtasks.yml @@ -63,6 +63,7 @@ jobs: pwsh: true script: | Import-module '$(Pipeline.Workspace)/ToolArtifact/GitHubRelease.psm1' + $releaseVersion = '$(ReleaseTag)' -replace '^v','' Write-Verbose -Verbose "Available modules: " Get-Module | Write-Verbose -Verbose diff --git a/.pipelines/templates/release-validate-globaltools.yml b/.pipelines/templates/release-validate-globaltools.yml index fba8b7b3f91..0820e5591f6 100644 --- a/.pipelines/templates/release-validate-globaltools.yml +++ b/.pipelines/templates/release-validate-globaltools.yml @@ -85,7 +85,7 @@ jobs: $packageName = '${{ parameters.globalToolPackageName }}' Write-Verbose -Verbose "Installing $packageName" - dotnet tool install --add-source "$ENV:PIPELINE_WORKSPACE/PSPackagesOfficial/drop_nupkg_build_nupkg" --tool-path $toolPath --version '$(Version)' $packageName + dotnet tool install --add-source "$ENV:PIPELINE_WORKSPACE/PSPackagesOfficial/drop_nupkg_build_nupkg" --tool-path $toolPath --version '$(OutputVersion.Version)' $packageName Get-ChildItem -Path $toolPath @@ -133,7 +133,7 @@ jobs: $versionFound = & $toolPath -c '$PSVersionTable.PSVersion.ToString()' - if ( '$(Version)' -ne $versionFound) + if ( '$(OutputVersion.Version)' -ne $versionFound) { throw "Expected version of global tool not found. Installed version is $versionFound" } diff --git a/.pipelines/templates/release-validate-packagenames.yml b/.pipelines/templates/release-validate-packagenames.yml index 8b08f8d8436..3e2987591aa 100644 --- a/.pipelines/templates/release-validate-packagenames.yml +++ b/.pipelines/templates/release-validate-packagenames.yml @@ -50,7 +50,7 @@ jobs: inline: | $storageAccount = Get-AzStorageAccount -ResourceGroupName '$(StorageResourceGroup)' -Name '$(StorageAccount)' $ctx = $storageAccount.Context - $container = '$(AzureVersion)' + $container = '$(OutputVersion.AzureVersion)' $destinationPath = '$(System.ArtifactsDirectory)' $blobList = Get-AzStorageBlob -Container $container -Context $ctx diff --git a/.pipelines/templates/release-validate-sdk.yml b/.pipelines/templates/release-validate-sdk.yml index db3f550b965..3f365f5ebb9 100644 --- a/.pipelines/templates/release-validate-sdk.yml +++ b/.pipelines/templates/release-validate-sdk.yml @@ -95,7 +95,7 @@ jobs: "@ - $releaseVersion = '$(Version)' + $releaseVersion = '$(OutputVersion.Version)' Write-Verbose -Message "Release Version: $releaseVersion" -Verbose From 713e77f15f63bae9f23fb02045c7843ad6a8769b Mon Sep 17 00:00:00 2001 From: Justin Chung Date: Thu, 23 Jan 2025 14:15:16 -0600 Subject: [PATCH 068/173] Finish 7.5.0 release From 8f315cdec5a7a5d00f7b90cd7367e80454d95ea9 Mon Sep 17 00:00:00 2001 From: Justin Chung <124807742+jshigetomi@users.noreply.github.com> Date: Thu, 23 Jan 2025 14:22:52 -0600 Subject: [PATCH 069/173] Finish 7.5.0 release (#24855) Co-authored-by: Justin Chung From 06997b40057bbddb9f7cec7bca2c2a418296a2c2 Mon Sep 17 00:00:00 2001 From: Anam Navied Date: Thu, 23 Jan 2025 17:02:32 -0500 Subject: [PATCH 070/173] [release/v7.5]Add EV2 support for publishing PowerShell packages to PMC (#24856) Signed-off-by: dependabot[bot] Co-authored-by: Justin Chung Co-authored-by: Justin Chung Co-authored-by: Justin Chung <124807742+jshigetomi@users.noreply.github.com> Co-authored-by: Aditya Patwardhan Co-authored-by: alerickson <25858831+alerickson@users.noreply.github.com> Co-authored-by: Patrick Meinecke Co-authored-by: Travis Plunk Co-authored-by: PowerShell Team Bot <69177312+pwshBot@users.noreply.github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Jordan Borean --- .../ServiceGroupRoot/RolloutSpec.json | 28 ++ .../ServiceGroupRoot/ScopeBindings.json | 23 ++ .../ServiceGroupRoot/ServiceModel.json | 51 +++ .../ServiceGroupRoot/Shell/Run/Run.ps1 | 384 ++++++++++++++++++ .../ServiceGroupRoot/UploadLinux.Rollout.json | 54 +++ .../EV2Specs/ServiceGroupRoot/buildVer.txt | 1 + .../PowerShell-Release-Official-Azure.yml | 101 +++++ .../release-SetReleaseTagandContainerName.yml | 8 + .pipelines/templates/release-prep-for-ev2.yml | 237 +++++++++++ .pipelines/templates/release-publish-pmc.yml | 125 ++---- 10 files changed, 923 insertions(+), 89 deletions(-) create mode 100644 .pipelines/EV2Specs/ServiceGroupRoot/RolloutSpec.json create mode 100644 .pipelines/EV2Specs/ServiceGroupRoot/ScopeBindings.json create mode 100644 .pipelines/EV2Specs/ServiceGroupRoot/ServiceModel.json create mode 100644 .pipelines/EV2Specs/ServiceGroupRoot/Shell/Run/Run.ps1 create mode 100644 .pipelines/EV2Specs/ServiceGroupRoot/UploadLinux.Rollout.json create mode 100644 .pipelines/EV2Specs/ServiceGroupRoot/buildVer.txt create mode 100644 .pipelines/PowerShell-Release-Official-Azure.yml create mode 100644 .pipelines/templates/release-prep-for-ev2.yml diff --git a/.pipelines/EV2Specs/ServiceGroupRoot/RolloutSpec.json b/.pipelines/EV2Specs/ServiceGroupRoot/RolloutSpec.json new file mode 100644 index 00000000000..9ed971068cc --- /dev/null +++ b/.pipelines/EV2Specs/ServiceGroupRoot/RolloutSpec.json @@ -0,0 +1,28 @@ +{ + "$schema": "https://ev2schema.azure.net/schemas/2020-01-01/rolloutSpecification.json", + "contentVersion": "1.0.0.0", + "rolloutMetadata": { + "serviceModelPath": "ServiceModel.json", + "ScopeBindingsPath": "ScopeBindings.json", + "name": "OneBranch-Demo-Container-Deployment", + "rolloutType": "Major", + "buildSource": { + "parameters": { + "versionFile": "buildver.txt" + } + }, + "Notification": { + "Email": { + "To": "default" + } + } + }, + "orchestratedSteps": [ + { + "name": "UploadLinuxContainer", + "targetType": "ServiceResource", + "targetName": "LinuxContainerUpload", + "actions": ["Shell/Run"] + } + ] +} diff --git a/.pipelines/EV2Specs/ServiceGroupRoot/ScopeBindings.json b/.pipelines/EV2Specs/ServiceGroupRoot/ScopeBindings.json new file mode 100644 index 00000000000..c3a98555867 --- /dev/null +++ b/.pipelines/EV2Specs/ServiceGroupRoot/ScopeBindings.json @@ -0,0 +1,23 @@ +{ + "$schema": "https://ev2schema.azure.net/schemas/2020-01-01/scopeBindings.json", + "contentVersion": "0.0.0.1", + "scopeBindings": [ + { + "scopeTagName": "Global", + "bindings": [ + { + "find": "__SUBSCRIPTION_ID__", + "replaceWith": "$azureSubscriptionId()" + }, + { + "find": "__RESOURCE_GROUP__", + "replaceWith": "$azureResourceGroup()" + }, + { + "find": "__BUILD_VERSION__", + "replaceWith": "$buildVersion()" + } + ] + } + ] +} diff --git a/.pipelines/EV2Specs/ServiceGroupRoot/ServiceModel.json b/.pipelines/EV2Specs/ServiceGroupRoot/ServiceModel.json new file mode 100644 index 00000000000..00555349c35 --- /dev/null +++ b/.pipelines/EV2Specs/ServiceGroupRoot/ServiceModel.json @@ -0,0 +1,51 @@ +{ + "$schema": "https://ev2schema.azure.net/schemas/2020-01-01/serviceModel.json", + "contentVersion": "1.0.0.0", + "serviceMetadata": { + "serviceGroup": "OneBranch-PowerShellDocker", + "environment": "Test" + }, + "serviceResourceGroupDefinitions": [ + { + "name": "OneBranch-PowerShellDocker-RGDef", + "serviceResourceDefinitions": [ + { + "name": "OneBranch-PowerShellDocker.Shell-SRDef", + "composedOf": { + "extension": { + "shell": [ + { + "type": "Run", + "properties": { + "imageName": "adm-mariner-20-l", + "imageVersion": "v11" + } + } + ] + } + } + } + ] + } + ], + "serviceResourceGroups": [ + { + "azureResourceGroupName": "default", + "location": "West US 3", + "instanceOf": "OneBranch-PowerShellDocker-RGDef", + "azureSubscriptionId": "default", + "scopeTags": [ + { + "name": "Global" + } + ], + "serviceResources": [ + { + "Name": "LinuxContainerUpload", + "InstanceOf": "OneBranch-PowerShellDocker.Shell-SRDef", + "RolloutParametersPath": "UploadLinux.Rollout.json" + } + ] + } + ] +} diff --git a/.pipelines/EV2Specs/ServiceGroupRoot/Shell/Run/Run.ps1 b/.pipelines/EV2Specs/ServiceGroupRoot/Shell/Run/Run.ps1 new file mode 100644 index 00000000000..fc00c871c94 --- /dev/null +++ b/.pipelines/EV2Specs/ServiceGroupRoot/Shell/Run/Run.ps1 @@ -0,0 +1,384 @@ +<# +This function gets info from pmc's derived list of all repositories and from mapping.json (which contains info on just the repositories powershell publishes packages to, their package formats, etc) +to create a list of repositories PowerShell cares about along with repository Ids, repository full Urls and associated package that will be published to it. +#> +function Get-MappedRepositoryIds { + param( + [Parameter(Mandatory)] + [hashtable] + $Mapping, + + [Parameter(Mandatory)] + $RepoList, + + # LTS is not consider a package in this context. + # LTS is just another package name. + [Parameter(Mandatory)] + [ValidateSet('stable', 'preview')] + $Channel + ) + + $mappedReposUsedByPwsh = @() + foreach ($package in $Mapping.Packages) + { + Write-Verbose "package: $package" + $packageChannel = $package.channel + if (!$packageChannel) { + $packageChannel = 'all' + } + + Write-Verbose "package channel: $packageChannel" + if ($packageChannel -eq 'all' -or $packageChannel -eq $Channel) + { + $repoIds = [System.Collections.Generic.List[string]]::new() + $packageFormat = $package.PackageFormat + Write-Verbose "package format: $packageFormat" -Verbose + $extension = [System.io.path]::GetExtension($packageFormat) + $packageType = $extension -replace '^\.' + + if ($package.distribution.count -gt 1) { + throw "Package $($package | out-string) has more than one Distribution." + } + + foreach ($distribution in $package.distribution) + { + $urlGlob = $package.url + switch ($packageType) + { + 'deb' { + $urlGlob = $urlGlob + '-apt' + } + 'rpm' { + $urlGlob = $urlGlob + '-yum' + } + default { + throw "Unknown package type: $packageType" + } + } + + Write-Verbose "---Finding repo id for: $urlGlob---" -Verbose + $repos = $RepoList | Where-Object { $_.name -eq $urlGlob } + + if ($repos.id) { + Write-Verbose "Found repo id: $($repos.id)" -Verbose + $repoIds.AddRange(([string[]]$repos.id)) + } + else { + Write-Failure "Could not find repo for $urlGlob" + } + + if ($repoIds.Count -gt 0) { + $mappedReposUsedByPwsh += ($package + @{ "RepoId" = $repoIds.ToArray() }) + } + } + } + } + + Write-Verbose -Verbose "mapped repos length: $($mappedReposUsedByPwsh.Length)" + return $mappedReposUsedByPwsh +} + +<# +This function creates package objects for the packages to be published, +with the package name (ie package name format resolve with channel based PackageName and pwsh version), repoId, distribution and package path. +#> +function Get-PackageObjects() { + param( + [Parameter(Mandatory)] + [psobject[]] + $RepoObjects, + + [Parameter(Mandatory)] + [string] + $ReleaseVersion, + + [Parameter(Mandatory)] + [string[]] + $PackageName + ) + + $packages = @() + + foreach ($pkg in $RepoObjects) + { + if ($pkg.RepoId.count -gt 1) { + throw "Package $($pkg.name) has more than one repo id." + } + + if ($pkg.Distribution.count -gt 1) { + throw "Package $($pkg.name) has more than one Distribution." + } + + $pkgRepo = $pkg.RepoId | Select-Object -First 1 + $pkgDistribution = $pkg.Distribution | Select-Object -First 1 + + foreach ($name in $PackageName) { + $pkgName = $pkg.PackageFormat.Replace('PACKAGE_NAME', $name).Replace('POWERSHELL_RELEASE', $ReleaseVersion) + + if ($pkgName.EndsWith('.rpm')) { + $pkgName = $pkgName.Replace($ReleaseVersion, $ReleaseVersion.Replace('-', '_')) + } + + $packagePath = "$pwshPackagesFolder/$pkgName" + $packagePathExists = Test-Path -Path $packagePath + if (!$packagePathExists) + { + throw "package path $packagePath does not exist" + } + + Write-Verbose "Creating package info object for package '$pkgName' for repo '$pkgRepo'" + $packages += @{ + PackagePath = $packagePath + PackageName = $pkgName + RepoId = $pkgRepo + Distribution = $pkgDistribution + } + + Write-Verbose -Verbose "package info obj: Name: $pkgName RepoId: $pkgRepo Distribution: $pkgDistribution PackagePath: $packagePath" + } + } + + Write-Verbose -Verbose "count of packages objects: $($packages.Length)" + return $packages +} + +<# +This function stages, uploads and publishes the powershell packages to their associated repositories in PMC. +#> +function Publish-PackageToPMC() { + param( + [Parameter(Mandatory)] + [pscustomobject[]] + $PackageObject, + + [Parameter(Mandatory)] + [string] + $ConfigPath, + + [Parameter(Mandatory)] + [bool] + $SkipPublish + ) + + # Don't fail outright when an error occurs, but instead pool them until + # after attempting to publish every package. That way we can choose to + # proceed for a partial failure. + $errorMessage = [System.Collections.Generic.List[string]]::new() + foreach ($finalPackage in $PackageObject) + { + Write-Verbose "---Staging package: $($finalPackage.PackageName)---" -Verbose + $packagePath = $finalPackage.PackagePath + $pkgRepo = $finalPackage.RepoId + + $extension = [System.io.path]::GetExtension($packagePath) + $packageType = $extension -replace '^\.' + Write-Verbose "packageType: $packageType" -Verbose + + $packageListJson = pmc --config $ConfigPath package $packageType list --file $packagePath + $list = $packageListJson | ConvertFrom-Json + + $packageId = @() + if ($list.count -ne 0) + { + Write-Verbose "Package '$packagePath' already exists, skipping upload" -Verbose + $packageId = $list.results.id | Select-Object -First 1 + } + else { + # PMC UPLOAD COMMAND + Write-Verbose -Verbose "Uploading package, config: '$ConfigPath' package: '$packagePath'" + $uploadResult = $null + try { + $uploadResult = pmc --config $ConfigPath package upload $packagePath --type $packageType + } + catch { + $errorMessage.Add("Uploading package $($finalPackage.PackageName) to $pkgRepo failed. See errors above for details.") + continue + } + + $packageId = ($uploadResult | ConvertFrom-Json).id + } + + Write-Verbose "Got package ID: '$packageId'" -Verbose + $distribution = $finalPackage.Distribution | select-object -First 1 + Write-Verbose "distribution: $distribution" -Verbose + + if (!$SkipPublish) + { + Write-Verbose "---Publishing package: $($finalPackage.PackageName) to $pkgRepo---" -Verbose + + if (($packageType -ne 'rpm') -and ($packageType -ne 'deb')) + { + throw "Unsupported package type: $packageType" + return 1 + } + else { + # PMC UPDATE COMMAND + $rawUpdateResponse = $null + try { + if ($packageType -eq 'rpm') { + $rawUpdateResponse = pmc --config $ConfigPath repo package update $pkgRepo --add-packages $packageId + } elseif ($packageType -eq 'deb') { + $rawUpdateResponse = pmc --config $ConfigPath repo package update $pkgRepo $distribution --add-packages $packageId + } + } + catch { + $errorMessage.Add("Invoking update for package $($finalPackage.PackageName) to $pkgRepo failed. See errors above for details.") + continue + } + + $state = $rawUpdateResponse.state + if ($state -ne 'Completed') { + $errorMessage.Add("Publishing package $($finalPackage.PackageName) to $pkgRepo failed: $rawUpdateResponse") + continue + } + } + + # PMC PUBLISH COMMAND + # The CLI outputs messages and JSON in the same stream, so we must sift through it for now + # This is planned to be fixed with a switch in a later release + Write-Verbose -Verbose ([pscustomobject]($package + @{ + PackageId = $packageId + })) + + # At this point, the changes are staged and will eventually be publish. + # Running publish, causes them to go live "immediately" + try { + pmc --config $ConfigPath repo publish $pkgRepo + } + catch { + $errorMessage.Add("Running final publish for package $($finalPackage.PackageName) to $pkgRepo failed. See errors above for details.") + continue + } + } else { + Write-Verbose -Verbose "Skipping Uploading package --config-file '$ConfigPath' package add '$packagePath' --repoID '$pkgRepo'" + } + } + + if ($errorMessage) { + throw $errorMessage -join [Environment]::NewLine + } +} + +if ($null -eq $env:MAPPING_FILE) +{ + Write-Verbose -Verbose "MAPPING_FILE variable didn't get passed correctly" + return 1 +} + +if ($null -eq $env:PWSH_PACKAGES_TARGZIP) +{ + Write-Verbose -Verbose "PWSH_PACKAGES_TARGZIP variable didn't get passed correctly" + return 1 +} + +if ($null -eq $env:PMC_METADATA) +{ + Write-Verbose -Verbose "PMC_METADATA variable didn't get passed correctly" + return 1 +} + +try { + Write-Verbose -Verbose "Downloading files" + Invoke-WebRequest -Uri $env:MAPPING_FILE -OutFile mapping.json + Invoke-WebRequest -Uri $env:PWSH_PACKAGES_TARGZIP -OutFile packages.tar.gz + Invoke-WebRequest -Uri $env:PMC_METADATA -OutFile pmcMetadata.json + + # create variables to those paths and test them + $mappingFilePath = Join-Path "/package/unarchive/" -ChildPath "mapping.json" + $mappingFilePathExists = Test-Path $mappingFilePath + if (!$mappingFilePathExists) + { + Write-Verbose -Verbose "mapping.json expected at $mappingFilePath does not exist" + return 1 + } + + $packagesTarPath = Join-Path -Path "/package/unarchive/" -ChildPath "packages.tar.gz" + $packagesTarPathExists = Test-Path $packagesTarPath + if (!$packagesTarPathExists) + { + Write-Verbose -Verbose "packages.tar.gz expected at $packagesTarPath does not exist" + return 1 + } + + # Extract files from 'packages.tar.gz' + Write-Verbose -Verbose "---Extracting files from packages.tar.gz---" + $pwshPackagesFolder = Join-Path -Path "/package/unarchive/" -ChildPath "packages" + New-Item -Path $pwshPackagesFolder -ItemType Directory + tar -xzvf $packagesTarPath -C $pwshPackagesFolder --force-local + Get-ChildItem $pwshPackagesFolder -Recurse + + $metadataFilePath = Join-Path -Path "/package/unarchive/" -ChildPath "pmcMetadata.json" + $metadataFilePathExists = Test-Path $metadataFilePath + if (!$metadataFilePathExists) + { + Write-Verbose -Verbose "pmcMetadata.json expected at $metadataFilePath does not exist" + return 1 + } + + # files in the extracted Run dir + $configPath = Join-Path '/package/unarchive/Run' -ChildPath 'settings.toml' + $configPathExists = Test-Path -Path $configPath + if (!$configPathExists) + { + Write-Verbose -Verbose "settings.toml expected at $configPath does not exist" + return 1 + } + + $pythonDlFolder = Join-Path '/package/unarchive/Run' -ChildPath 'python_dl' + $pyPathExists = Test-Path -Path $pythonDlFolder + if (!$pyPathExists) + { + Write-Verbose -Verbose "python_dl expected at $pythonDlFolder does not exist" + return 1 + } + + Write-Verbose -Verbose "Installing pmc-cli" + pip install --upgrade pip + pip --version --verbose + pip install /package/unarchive/Run/python_dl/*.whl + + # Get metadata + $channel = "" + $packageNames = @() + $metadataContent = Get-Content -Path $metadataFilePath | ConvertFrom-Json + $releaseVersion = $metadataContent.ReleaseTag.TrimStart('v') + $skipPublish = $metadataContent.SkipPublish + $lts = $metadataContent.LTS + + if ($releaseVersion.Contains('-')) { + $channel = 'preview' + $packageNames = @('powershell-preview') + } + else { + $channel = 'stable' + $packageNames = @('powershell') + } + + if ($lts) { + $packageNames += @('powershell-lts') + } + + Write-Verbose -Verbose "---Getting repository list---" + $rawResponse = pmc --config $configPath repo list --limit 800 + $response = $rawResponse | ConvertFrom-Json + $limit = $($response.limit) + $count = $($response.count) + Write-Verbose -Verbose "'pmc repo list' limit is: $limit and count is: $count" + $repoList = $response.results + + Write-Verbose -Verbose "---Getting package info---" + + + Write-Verbose "Reading mapping file from '$mappingFilePath'" -Verbose + $mapping = Get-Content -Raw -LiteralPath $mappingFilePath | ConvertFrom-Json -AsHashtable + $mappedReposUsedByPwsh = Get-MappedRepositoryIds -Mapping $mapping -RepoList $repoList -Channel $channel + $packageObjects = Get-PackageObjects -RepoObjects $mappedReposUsedByPwsh -PackageName $packageNames -ReleaseVersion $releaseVersion + Write-Verbose -Verbose "skip publish $skipPublish" + Publish-PackageToPMC -PackageObject $packageObjects -ConfigPath $configPath -SkipPublish $skipPublish +} +catch { + Write-Error -ErrorAction Stop $_.Exception.Message + return 1 +} + +return 0 diff --git a/.pipelines/EV2Specs/ServiceGroupRoot/UploadLinux.Rollout.json b/.pipelines/EV2Specs/ServiceGroupRoot/UploadLinux.Rollout.json new file mode 100644 index 00000000000..d7c75c2e216 --- /dev/null +++ b/.pipelines/EV2Specs/ServiceGroupRoot/UploadLinux.Rollout.json @@ -0,0 +1,54 @@ +{ + "$schema": "https://ev2schema.azure.net/schemas/2020-01-01/rolloutParameters.json", + "contentVersion": "1.0.0.0", + "shellExtensions": [ + { + "name": "Run", + "type": "Run", + "properties": { + "maxExecutionTime": "PT2H" + }, + "package": { + "reference": { + "path": "Shell/Run.tar" + } + }, + "launch": { + "command": [ + "/bin/bash", + "-c", + "pwsh ./Run/Run.ps1" + ], + "environmentVariables": [ + { + "name": "MAPPING_FILE", + "reference": + { + "path": "Parameters\\mapping.json" + } + }, + { + "name": "PWSH_PACKAGES_TARGZIP", + "reference": + { + "path": "Parameters\\packages.tar.gz" + } + }, + { + "name": "PMC_METADATA", + "reference": + { + "path": "Parameters\\pmcMetadata.json" + } + } + ], + "identity": { + "type": "userAssigned", + "userAssignedIdentities": [ + "default" + ] + } + } + } + ] +} diff --git a/.pipelines/EV2Specs/ServiceGroupRoot/buildVer.txt b/.pipelines/EV2Specs/ServiceGroupRoot/buildVer.txt new file mode 100644 index 00000000000..7dea76edb3d --- /dev/null +++ b/.pipelines/EV2Specs/ServiceGroupRoot/buildVer.txt @@ -0,0 +1 @@ +1.0.1 diff --git a/.pipelines/PowerShell-Release-Official-Azure.yml b/.pipelines/PowerShell-Release-Official-Azure.yml new file mode 100644 index 00000000000..db6b114d901 --- /dev/null +++ b/.pipelines/PowerShell-Release-Official-Azure.yml @@ -0,0 +1,101 @@ +trigger: none + +parameters: # parameters are shown up in ADO UI in a build queue time + - name: 'debug' + displayName: 'Enable debug output' + type: boolean + default: false + - name: skipPublish + displayName: Skip PMC Publish + type: boolean + default: false + - name: SKIP_SIGNING + displayName: Skip Signing + type: string + default: 'NO' + +variables: + - name: CDP_DEFINITION_BUILD_COUNT + value: $[counter('', 0)] + - name: system.debug + value: ${{ parameters.debug }} + - name: ENABLE_PRS_DELAYSIGN + value: 1 + - name: ROOT + value: $(Build.SourcesDirectory) + - name: REPOROOT + value: $(Build.SourcesDirectory) + - name: OUTPUTROOT + value: $(REPOROOT)\out + - name: NUGET_XMLDOC_MODE + value: none + - name: nugetMultiFeedWarnLevel + value: none + - name: NugetSecurityAnalysisWarningLevel + value: none + - name: skipNugetSecurityAnalysis + value: true + - name: ob_outputDirectory + value: '$(Build.ArtifactStagingDirectory)/ONEBRANCH_ARTIFACT' + - name: ob_sdl_tsa_configFile + value: $(Build.SourcesDirectory)\.config\tsaoptions.json + - name: WindowsContainerImage + value: 'onebranch.azurecr.io/windows/ltsc2022/vse2022:latest' + - name: LinuxContainerImage + value: mcr.microsoft.com/onebranch/cbl-mariner/build:2.0 + - group: PoolNames + +resources: + repositories: + - repository: templates + type: git + name: OneBranch.Pipelines/GovernedTemplates + ref: refs/heads/main + + pipelines: + - pipeline: CoOrdinatedBuildPipeline + source: 'PowerShell-Coordinated Packages-Official' + + - pipeline: PSPackagesOfficial + source: 'PowerShell-Packages-Official' + trigger: + branches: + include: + - master + - releases/* + +extends: + template: v2/OneBranch.Official.CrossPlat.yml@templates + parameters: + featureFlags: + WindowsHostVersion: + Version: 2022 + Network: Netlock + linuxEsrpSigning: true + cloudvault: + enabled: false + globalSdl: + disableLegacyManifest: true + # disabled Armory as we dont have any ARM templates to scan. It fails on some sample ARM templates. + armory: + enabled: false + asyncSdl: + enabled: true + tsaOptionsFile: .config/tsaoptions.json + tsa: + enabled: true + credscan: + enabled: true + scanFolder: $(Build.SourcesDirectory) + suppressionsFile: $(Build.SourcesDirectory)\.config\suppress.json + binskim: + break: false # always break the build on binskim issues in addition to TSA upload + policheck: + break: true # always break the build on policheck issues. You can disable it by setting to 'false' + tsaOptionsFile: .config\tsaoptions.json + stages: + - template: /.pipelines/templates/release-prep-for-ev2.yml@self + parameters: + skipPublish: ${{ parameters.skipPublish }} + + - template: /.pipelines/templates/release-publish-pmc.yml@self diff --git a/.pipelines/templates/release-SetReleaseTagandContainerName.yml b/.pipelines/templates/release-SetReleaseTagandContainerName.yml index 407a3a8f91d..d40551353d2 100644 --- a/.pipelines/templates/release-SetReleaseTagandContainerName.yml +++ b/.pipelines/templates/release-SetReleaseTagandContainerName.yml @@ -1,3 +1,7 @@ +parameters: +- name: restorePhase + default: false + steps: - pwsh: | $variable = 'releaseTag' @@ -13,6 +17,8 @@ steps: Write-Host -Object "##$vstsCommandString" name: OutputReleaseTag displayName: Set Release Tag + env: + ob_restore_phase: ${{ parameters.restorePhase }} - pwsh: | $azureVersion = '$(OutputReleaseTag.ReleaseTag)'.ToLowerInvariant() -replace '\.', '-' @@ -26,3 +32,5 @@ steps: Write-Host "##$vstsCommandString" name: OutputVersion displayName: Set container name + env: + ob_restore_phase: ${{ parameters.restorePhase }} diff --git a/.pipelines/templates/release-prep-for-ev2.yml b/.pipelines/templates/release-prep-for-ev2.yml new file mode 100644 index 00000000000..cf7982cd5e1 --- /dev/null +++ b/.pipelines/templates/release-prep-for-ev2.yml @@ -0,0 +1,237 @@ +parameters: +- name: skipPublish + type: boolean + default: false + +stages: +- stage: PrepForEV2 + displayName: 'Copy and prep all files needed for EV2 stage' + jobs: + - job: CopyEV2FilesToArtifact + displayName: 'Copy EV2 Files to Artifact' + pool: + type: linux + variables: + - name: ob_outputDirectory + value: '$(Build.ArtifactStagingDirectory)/ONEBRANCH_ARTIFACT' + - name: repoRoot + value: '$(Build.SourcesDirectory)/PowerShell' + - name: ev2ServiceGroupRootFolder + value: '$(Build.SourcesDirectory)/PowerShell/.pipelines/EV2Specs/ServiceGroupRoot' + - name: ev2ParametersFolder + value: '$(Build.SourcesDirectory)/PowerShell/.pipelines/EV2Specs/ServiceGroupRoot/Parameters' + - group: 'mscodehub-code-read-akv' + - group: 'packages.microsoft.com' + - name: ob_sdl_credscan_suppressionsFile + value: $(Build.SourcesDirectory)\PowerShell\.config\suppress.json + steps: + - checkout: self ## the global setting on lfs didn't work + lfs: false + env: + ob_restore_phase: true + + - template: release-SetReleaseTagandContainerName.yml + parameters: + restorePhase: true + + - pwsh: | + $packageVersion = '$(OutputReleaseTag.ReleaseTag)'.ToLowerInvariant() -replace '^v','' + $vstsCommandString = "vso[task.setvariable variable=packageVersion]$packageVersion" + Write-Host "sending " + $vstsCommandString + Write-Host "##$vstsCommandString" + displayName: Set Package version + env: + ob_restore_phase: true + + - pwsh: | + $branch = 'mirror-target' + $gitArgs = "clone", + "--verbose", + "--branch", + "$branch", + "https://$(mscodehubCodeReadPat)@mscodehub.visualstudio.com/PowerShellCore/_git/Internal-PowerShellTeam-Tools", + '$(Pipeline.Workspace)/tools' + $gitArgs | Write-Verbose -Verbose + git $gitArgs + displayName: Clone Internal-PowerShellTeam-Tools from MSCodeHub + env: + ob_restore_phase: true + + - pwsh: | + Get-ChildItem Env: | Out-String -Stream | write-Verbose -Verbose + displayName: 'Capture Environment Variables' + env: + ob_restore_phase: true + + - pwsh: | + Get-ChildItem '$(Build.SourcesDirectory)' + displayName: 'Capture BuildDirectory' + env: + ob_restore_phase: true + + - pwsh: | + Get-ChildItem '$(Pipeline.Workspace)' -Recurse | Out-String -Stream | write-Verbose -Verbose + displayName: 'Capture Workspace' + env: + ob_restore_phase: true + + - pwsh: | + New-Item -Path '$(ev2ParametersFolder)' -ItemType Directory + displayName: 'Create Parameters folder under EV2Specs folder' + env: + ob_restore_phase: true + + - task: PipAuthenticate@1 + inputs: + artifactFeeds: 'PowerShellCore/PowerShellCore_PublicPackages' + displayName: 'Pip Authenticate' + env: + ob_restore_phase: true + + - pwsh: | + python3 -m pip install --upgrade pip + pip --version --verbose + + Write-Verbose -Verbose "Download pmc-cli to folder without installing it" + $pythonDlFolderPath = Join-Path '$(ev2ServiceGroupRootFolder)/Shell/Run' -ChildPath "python_dl" + pip download -d $pythonDlFolderPath pmc-cli --platform=manylinux_2_17_x86_64 --only-binary=:all: --verbose + displayName: 'Download pmc-cli package' + env: + ob_restore_phase: true + + - download: PSPackagesOfficial + artifact: 'drop_linux_package_deb' + displayName: 'Download artifact containing .deb_amd64.deb file from PSPackagesOfficial triggering pipeline' + env: + ob_restore_phase: true + + - download: PSPackagesOfficial + artifact: 'drop_linux_package_rpm' + displayName: 'Download artifact containing .rh.x64_86.rpm file from PSPackagesOfficial triggering pipeline' + env: + ob_restore_phase: true + + - download: PSPackagesOfficial + artifact: 'drop_linux_package_mariner_x64' + displayName: 'Download artifact containing .cm.x86_64.rpm file from PSPackagesOfficial triggering pipeline' + env: + ob_restore_phase: true + + - download: PSPackagesOfficial + artifact: 'drop_linux_package_mariner_arm64' + displayName: 'Download artifact containing .cm.aarch64.rpm file from PSPackagesOfficial triggering pipeline' + env: + ob_restore_phase: true + + - pwsh: | + Write-Verbose -Verbose "Copy ESRP signed .deb and .rpm packages" + $downloadedPipelineFolder = Join-Path '$(Pipeline.Workspace)' -ChildPath 'PSPackagesOfficial' + $srcFilesFolder = Join-Path -Path '$(Pipeline.Workspace)' -ChildPath 'SourceFiles' + New-Item -Path $srcFilesFolder -ItemType Directory + $packagesFolder = Join-Path -Path $srcFilesFolder -ChildPath 'packages' + New-Item -Path $packagesFolder -ItemType Directory + + $packageFiles = Get-ChildItem -Path $downloadedPipelineFolder -Recurse -Directory -Filter "drop_*" | Get-ChildItem -File -Include *.deb, *.rpm + foreach ($file in $packageFiles) + { + Write-Verbose -Verbose "copying file: $($file.FullName)" + Copy-Item -Path $($file.FullName) -Destination $packagesFolder -Verbose + } + + $packagesTarGzDestination = Join-Path -Path '$(ev2ParametersFolder)' -ChildPath 'packages.tar.gz' + tar -czvf $packagesTarGzDestination -C $packagesFolder . + displayName: 'Copy signed .deb and .rpm packages to .tar.gz to pass as a file var to shell extension' + env: + ob_restore_phase: true + + - pwsh: | + $pathToPMCMetadataFile = Join-Path -Path '$(ev2ParametersFolder)' -ChildPath 'pmcMetadata.json' + + $metadata = Get-Content -Path "$(repoRoot)/tools/metadata.json" -Raw | ConvertFrom-Json + $metadataHash = @{} + $skipPublishValue = '${{ parameters.skipPublish }}' + $metadataHash["ReleaseTag"] = '$(OutputReleaseTag.ReleaseTag)' + $metadataHash["LTS"] = $metadata.LTSRelease.Latest + $metadataHash["ForProduction"] = $true + $metadataHash["SkipPublish"] = [System.Convert]::ToBoolean($skipPublishValue) + + $metadataHash | ConvertTo-Json | Out-File $pathToPMCMetadataFile + + $mappingFilePath = Join-Path -Path '$(repoRoot)/tools/packages.microsoft.com' -ChildPath 'mapping.json' + $mappingFilePathExists = Test-Path $mappingFilePath + $mappingFileEV2Path = Join-Path -Path '$(ev2ParametersFolder)' -ChildPath "mapping.json" + Write-Verbose -Verbose "Copy mapping.json file at: $mappingFilePath which exists: $mappingFilePathExists to: $mappingFileEV2Path" + Copy-Item -Path $mappingFilePath -Destination $mappingFileEV2Path + displayName: 'Create pmcScriptMetadata.json and mapping.json file' + env: + ob_restore_phase: true + + - pwsh: | + $pathToJsonFile = Join-Path -Path '$(ev2ServiceGroupRootFolder)' -ChildPath 'RolloutSpec.json' + $content = Get-Content -Path $pathToJsonFile | ConvertFrom-Json + $content.RolloutMetadata.Notification.Email.To = '$(PmcEV2SupportEmail)' + Remove-Item -Path $pathToJsonFile + $content | ConvertTo-Json -Depth 4 | Out-File $pathToJsonFile + displayName: 'Replace values in RolloutSpecPath.json' + env: + ob_restore_phase: true + + - pwsh: | + $pathToJsonFile = Join-Path -Path '$(ev2ServiceGroupRootFolder)' -ChildPath 'UploadLinux.Rollout.json' + $content = Get-Content -Path $pathToJsonFile | ConvertFrom-Json + + $identityString = "/subscriptions/$(PmcSubscription)/resourcegroups/$(PmcResourceGroup)/providers/Microsoft.ManagedIdentity/userAssignedIdentities/$(PmcMIName)" + $content.shellExtensions.launch.identity.userAssignedIdentities[0] = $identityString + + Remove-Item -Path $pathToJsonFile + $content | ConvertTo-Json -Depth 6 | Out-File $pathToJsonFile + displayName: 'Replace values in UploadLinux.Rollout.json file' + env: + ob_restore_phase: true + + - pwsh: | + $pathToJsonFile = Join-Path -Path '$(ev2ServiceGroupRootFolder)' -ChildPath 'ServiceModel.json' + $content = Get-Content -Path $pathToJsonFile | ConvertFrom-Json + $content.ServiceResourceGroups[0].AzureResourceGroupName = '$(PmcResourceGroup)' + $content.ServiceResourceGroups[0].AzureSubscriptionId = '$(PmcSubscription)' + + Remove-Item -Path $pathToJsonFile + $content | ConvertTo-Json -Depth 9 | Out-File $pathToJsonFile + displayName: 'Replace values in ServiceModel.json' + env: + ob_restore_phase: true + + - pwsh: | + $settingFilePath = Join-Path '$(ev2ServiceGroupRootFolder)/Shell/Run' -ChildPath 'settings.toml' + New-Item -Path $settingFilePath -ItemType File + $pmcMIClientID = '$(PmcMIClientID)' + $pmcEndpoint = '$(PmcEndpointUrl)' + + Add-Content -Path $settingFilePath -Value "[default]" + Add-Content -Path $settingFilePath -Value "base_url = `"$pmcEndpoint`"" + Add-Content -Path $settingFilePath -Value "auth_type = `"msi`"" + Add-Content -Path $settingFilePath -Value "client_id = `"$pmcMIClientID`"" + displayName: 'Create settings.toml file with MI clientId populated' + env: + ob_restore_phase: true + + - task: onebranch.pipeline.signing@1 + inputs: + command: 'sign' + signing_profile: external_distribution + files_to_sign: '*.ps1' + search_root: '$(repoRoot)/.pipelines/EV2Specs/ServiceGroupRoot/Shell/Run' + displayName: Sign Run.ps1 + + - pwsh: | + # folder to tar must have: Run.ps1, settings.toml, python_dl + $srcPath = Join-Path '$(ev2ServiceGroupRootFolder)' -ChildPath 'Shell' + $pathToRunTarFile = Join-Path $srcPath -ChildPath "Run.tar" + tar -cvf $pathToRunTarFile -C $srcPath ./Run + displayName: 'Create archive for the shell extension' + + - task: CopyFiles@2 + inputs: + SourceFolder: '$(repoRoot)/.pipelines' + Contents: 'EV2Specs/**' + TargetFolder: $(ob_outputDirectory) diff --git a/.pipelines/templates/release-publish-pmc.yml b/.pipelines/templates/release-publish-pmc.yml index 27311611e61..d5454845211 100644 --- a/.pipelines/templates/release-publish-pmc.yml +++ b/.pipelines/templates/release-publish-pmc.yml @@ -1,90 +1,37 @@ -parameters: - - name: skipPublish - default: false - type: boolean - -jobs: -- job: PMCPublish - displayName: Publish to PMC - condition: succeeded() - pool: - type: linux - isCustom: true - name: PowerShell1ES - demands: - - ImageOverride -equals PSMMSUbuntu20.04-Secure +stages: +- stage: 'Prod_Release' + displayName: 'Deploy packages to PMC with EV2' + dependsOn: + - PrepForEV2 variables: - - name: runCodesignValidationInjection - value: false - - name: NugetSecurityAnalysisWarningLevel - value: none - - name: DOTNET_SKIP_FIRST_TIME_EXPERIENCE - value: 1 - - group: 'mscodehub-code-read-akv' - - group: 'packages.microsoft.com' - - name: ob_outputDirectory - value: '$(Build.ArtifactStagingDirectory)/ONEBRANCH_ARTIFACT' - - name: ob_sdl_codeSignValidation_enabled - value: false - - name: ob_sdl_binskim_enabled - value: false - - name: ob_sdl_tsa_configFile - value: $(Build.SourcesDirectory)\PowerShell\.config\tsaoptions.json - - name: ob_sdl_credscan_suppressionsFile - value: $(Build.SourcesDirectory)\PowerShell\.config\suppress.json - - steps: - - checkout: self ## the global setting on lfs didn't work - lfs: false - - - template: release-SetReleaseTagAndContainerName.yml - - - pwsh: | - $packageVersion = '$(ReleaseTag)'.ToLowerInvariant() -replace '^v','' - $vstsCommandString = "vso[task.setvariable variable=packageVersion]$packageVersion" - Write-Host "sending " + $vstsCommandString - Write-Host "##$vstsCommandString" - displayName: Set Package version - - - pwsh: | - $branch = 'mirror-target' - $gitArgs = "clone", - "--verbose", - "--branch", - "$branch", - "https://$(mscodehubCodeReadPat)@mscodehub.visualstudio.com/PowerShellCore/_git/Internal-PowerShellTeam-Tools", - '$(Pipeline.Workspace)/tools' - $gitArgs | Write-Verbose -Verbose - git $gitArgs - displayName: Clone Internal-PowerShellTeam-Tools from MSCodeHub - - - task: PipAuthenticate@1 - inputs: - artifactFeeds: 'pmc' - pythonDownloadServiceConnections: pmcDownload - - - pwsh: | - pip install pmc-cli==1.12.0 - - $newPath = (resolve-path '~/.local/bin').providerpath - $vstsCommandString = "vso[task.setvariable variable=PATH]${env:PATH}:$newPath" - Write-Host "sending " + $vstsCommandString - Write-Host "##$vstsCommandString" - displayName: Install pmc cli - - - pwsh: | - $metadata = Get-Content -Path "$(Build.SourcesDirectory)/tools/metadata.json" -Raw | ConvertFrom-Json - $params = @{ - ReleaseTag = "$(ReleaseTag)" - AadClientId = "$(PmcCliClientID)" - BlobFolderName = "$(ReleaseTag)" - LTS = $metadata.LTSRelease.Latest - ForProduction = $true - SkipPublish = $${{ parameters.skipPublish }} - MappingFilePath = '$(System.DefaultWorkingDirectory)/tools/packages.microsoft.com/mapping.json' - } - - $params | Out-String -width 9999 -Stream | write-Verbose -Verbose - - & '$(Pipeline.Workspace)/tools/packages.microsoft.com-v4/releaseLinuxPackages.ps1' @params - displayName: Run release script + - name: ob_release_environment + value: "Production" + - name: repoRoot + value: $(Build.SourcesDirectory) + jobs: + - job: Prod_ReleaseJob + displayName: Publish to PMC + pool: + type: release + + steps: + - task: DownloadPipelineArtifact@2 + inputs: + targetPath: '$(Pipeline.Workspace)' + artifact: drop_PrepForEV2_CopyEv2FilesToArtifact + displayName: 'Download drop_PrepForEV2_CopyEv2FilesToArtifact artifact that has all files needed' + + - task: DownloadPipelineArtifact@2 + inputs: + buildType: 'current' + targetPath: '$(Pipeline.Workspace)' + displayName: 'Download to get EV2 Files' + + - task: vsrm-ev2.vss-services-ev2.adm-release-task.ExpressV2Internal@1 + displayName: 'Ev2: Push to PMC' + inputs: + UseServerMonitorTask: true + EndpointProviderType: ApprovalService + ApprovalServiceEnvironment: Production + ServiceRootPath: '$(Pipeline.Workspace)/drop_PrepForEV2_CopyEV2FilesToArtifact/EV2Specs/ServiceGroupRoot' + RolloutSpecPath: '$(Pipeline.Workspace)/drop_PrepForEV2_CopyEV2FilesToArtifact/EV2Specs/ServiceGroupRoot/RolloutSpec.json' From 9b348193d94d972c73462e6d9b4e73369071f9b8 Mon Sep 17 00:00:00 2001 From: Anam Navied Date: Thu, 23 Jan 2025 17:22:59 -0500 Subject: [PATCH 071/173] [release/v7.5]PMC parse state correctly from update command's response (#24859) --- .../EV2Specs/ServiceGroupRoot/Shell/Run/Run.ps1 | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/.pipelines/EV2Specs/ServiceGroupRoot/Shell/Run/Run.ps1 b/.pipelines/EV2Specs/ServiceGroupRoot/Shell/Run/Run.ps1 index fc00c871c94..25a5686b33e 100644 --- a/.pipelines/EV2Specs/ServiceGroupRoot/Shell/Run/Run.ps1 +++ b/.pipelines/EV2Specs/ServiceGroupRoot/Shell/Run/Run.ps1 @@ -226,8 +226,9 @@ function Publish-PackageToPMC() { continue } - $state = $rawUpdateResponse.state - if ($state -ne 'Completed') { + $state = ($rawUpdateResponse | ConvertFrom-Json).state + Write-Verbose -Verbose "update response state: $state" + if ($state -ne 'completed') { $errorMessage.Add("Publishing package $($finalPackage.PackageName) to $pkgRepo failed: $rawUpdateResponse") continue } @@ -242,11 +243,19 @@ function Publish-PackageToPMC() { # At this point, the changes are staged and will eventually be publish. # Running publish, causes them to go live "immediately" + $rawPublishResponse = $null try { - pmc --config $ConfigPath repo publish $pkgRepo + $rawPublishResponse = pmc --config $ConfigPath repo publish $pkgRepo } catch { - $errorMessage.Add("Running final publish for package $($finalPackage.PackageName) to $pkgRepo failed. See errors above for details.") + $errorMessage.Add("Invoking final publish for package $($finalPackage.PackageName) to $pkgRepo failed. See errors above for details.") + continue + } + + $publishState = ($rawPublishResponse | ConvertFrom-Json).state + Write-Verbose -Verbose "publish response state: $publishState" + if ($publishState -ne 'completed') { + $errorMessage.Add("Final publishing of package $($finalPackage.PackageName) to $pkgRepo failed: $rawPublishResponse") continue } } else { From cf8256680c0285d47a3cc066141c8ecbc6a514f4 Mon Sep 17 00:00:00 2001 From: Travis Plunk Date: Tue, 4 Feb 2025 14:26:09 -0800 Subject: [PATCH 072/173] [release/v7.5]Convert powershell/PowerShell-Windows-CI to GitHub Actions (#24931) --- .github/actions/build/ci/action.yml | 49 ++++++++ .github/actions/test/verify_xunit/action.yml | 21 ++++ .github/actions/test/windows/action.yml | 107 ++++++++++++++++ .github/workflows/AssignPrs.yml | 3 +- .github/workflows/rebase.yml | 39 ------ .github/workflows/windows-ci.yml | 124 +++++++++++++++++++ .gitignore | 7 ++ build.psm1 | 10 ++ tools/ci.psm1 | 40 +++++- 9 files changed, 356 insertions(+), 44 deletions(-) create mode 100644 .github/actions/build/ci/action.yml create mode 100644 .github/actions/test/verify_xunit/action.yml create mode 100644 .github/actions/test/windows/action.yml delete mode 100644 .github/workflows/rebase.yml create mode 100644 .github/workflows/windows-ci.yml diff --git a/.github/actions/build/ci/action.yml b/.github/actions/build/ci/action.yml new file mode 100644 index 00000000000..90968d81cfe --- /dev/null +++ b/.github/actions/build/ci/action.yml @@ -0,0 +1,49 @@ +name: CI Build +description: 'Builds PowerShell' +runs: + using: composite + steps: + - name: Capture Environment + if: success() || failure() + run: 'Get-ChildItem -Path env: | Out-String -width 9999 -Stream | write-Verbose -Verbose' + shell: pwsh + - name: Set Build Name for Non-PR + if: github.event_name != 'PullRequest' + run: Write-Host "##vso[build.updatebuildnumber]$env:BUILD_SOURCEBRANCHNAME-$env:BUILD_SOURCEVERSION-$((get-date).ToString("yyyyMMddhhmmss"))" + shell: pwsh + - name: Bootstrap + if: success() + run: |- + Write-Verbose -Verbose "Running Bootstrap..." + Import-Module .\tools\ci.psm1 + Invoke-CIInstall -SkipUser + Write-Verbose -Verbose "Start Sync-PSTags" + Sync-PSTags -AddRemoteIfMissing + Write-Verbose -Verbose "End Sync-PSTags" + shell: pwsh + - name: Build + if: success() + run: |- + Write-Verbose -Verbose "Running Build..." + Import-Module .\tools\ci.psm1 + Invoke-CIBuild + shell: pwsh + - name: xUnit Tests + if: success() + continue-on-error: true + run: |- + Write-Verbose -Verbose "Running xUnit tests..." + Import-Module .\tools\ci.psm1 + Restore-PSOptions + Invoke-CIxUnit -SkipFailing + shell: pwsh + - name: Upload build artifact + uses: actions/upload-artifact@v4 + with: + name: build + path: ${{ runner.workspace }}/build + - name: Upload xunit artifact + uses: actions/upload-artifact@v4 + with: + name: testResults-xunit + path: ${{ runner.workspace }}/xunit diff --git a/.github/actions/test/verify_xunit/action.yml b/.github/actions/test/verify_xunit/action.yml new file mode 100644 index 00000000000..fccca27182f --- /dev/null +++ b/.github/actions/test/verify_xunit/action.yml @@ -0,0 +1,21 @@ +name: verify_xunit +description: 'Verify xUnit Results' + +runs: + using: composite + steps: + - name: Download build artifacts + uses: actions/download-artifact@v4 + with: + path: "${{ github.workspace }}" + - name: Capture artifacts directory + continue-on-error: true + run: dir "${{ github.workspace }}\testResults-xunit\*" -Recurse + shell: pwsh + - name: Test + if: success() + run: |- + Import-Module .\tools\ci.psm1 + $xUnitTestResultsFile = "${{ github.workspace }}\testResults-xunit\xUnitTestResults.xml" + Test-XUnitTestResults -TestResultsFile $xUnitTestResultsFile + shell: pwsh diff --git a/.github/actions/test/windows/action.yml b/.github/actions/test/windows/action.yml new file mode 100644 index 00000000000..6cb5cbc1d74 --- /dev/null +++ b/.github/actions/test/windows/action.yml @@ -0,0 +1,107 @@ +name: windows_test +description: 'Test PowerShell on Windows' + +inputs: + purpose: + required: false + default: '' + type: string + tagSet: + required: false + default: CI + type: string + ctrfFolder: + required: false + default: ctrf + type: string + +runs: + using: composite + steps: + - name: Capture Environment + if: success() || failure() + run: 'Get-ChildItem -Path env: | Out-String -width 9999 -Stream | write-Verbose -Verbose' + shell: pwsh + - name: Download Build Artifacts + uses: actions/download-artifact@v4 + with: + path: "${{ github.workspace }}" + - name: Capture Artifacts Directory + continue-on-error: true + run: Get-ChildItem "${{ github.workspace }}\build\*" -Recurse + shell: pwsh + + - name: Bootstrap + shell: powershell + run: |- + # Remove "Program Files\dotnet" from the env variable PATH, so old SDKs won't affect us. + Write-Host "Old Path:" + Write-Host $env:Path + $dotnetPath = Join-Path $env:SystemDrive 'Program Files\dotnet' + $paths = $env:Path -split ";" | Where-Object { -not $_.StartsWith($dotnetPath) } + $env:Path = $paths -join ";" + Write-Host "New Path:" + Write-Host $env:Path + # Bootstrap + Import-Module .\tools\ci.psm1 + Invoke-CIInstall + + - name: Test + if: success() + run: |- + Import-Module .\build.psm1 -force + Start-PSBootstrap + Import-Module .\tools\ci.psm1 + Restore-PSOptions -PSOptionsPath '${{ github.workspace }}\build\psoptions.json' + $options = (Get-PSOptions) + $path = split-path -path $options.Output + $rootPath = split-Path -path $path + Expand-Archive -Path '${{ github.workspace }}\build\build.zip' -DestinationPath $rootPath -Force + Invoke-CITest -Purpose '${{ inputs.purpose }}' -TagSet '${{ inputs.tagSet }}' -OutputFormat JUnitXml + shell: pwsh + + - name: Convert JUnit to CTRF + run: |- + Get-ChildItem -Path "${{ runner.workspace }}/testResults/*.xml" -Recurse | ForEach-Object { + npx --yes junit-to-ctrf $_.FullName --output .\${{ inputs.ctrfFolder }}\$($_.BaseName).json --tool Pester --env 'Windows ${{ inputs.purpose }} ${{ inputs.tagSet }}' + } + shell: powershell + + # this task only takes / as directory separators + - name: Publish Test Report + uses: ctrf-io/github-test-reporter@v1 + with: + report-path: './${{ inputs.ctrfFolder }}/*.json' + exit-on-fail: true + summary-report: true + test-report: false + test-list-report: false + failed-report: false + fail-rate-report: false + flaky-report: false + flaky-rate-report: false + failed-folded-report: true + previous-results-report: false + ai-report: true + skipped-report: false + suite-folded-report: false + suite-list-report: false + pull-request-report: false + commit-report: false + custom-report: false + + if: always() + + - name: Upload testResults artifact + if: always() + uses: actions/upload-artifact@v4 + with: + name: junit-pester-${{ inputs.purpose }}-${{ inputs.tagSet }} + path: ${{ runner.workspace }}\testResults + + - name: Upload ctrf artifact + if: always() + uses: actions/upload-artifact@v4 + with: + name: ctrf-pester-${{ inputs.purpose }}-${{ inputs.tagSet }} + path: ${{ inputs.ctrfFolder }} diff --git a/.github/workflows/AssignPrs.yml b/.github/workflows/AssignPrs.yml index 419d704ce1d..d398cd7cffe 100644 --- a/.github/workflows/AssignPrs.yml +++ b/.github/workflows/AssignPrs.yml @@ -1,6 +1,6 @@ name: Auto Assign PR Maintainer on: - pull_request: + issues: types: [opened, edited] permissions: contents: read @@ -13,6 +13,7 @@ jobs: pull-requests: write steps: - uses: wow-actions/auto-assign@67fafa03df61d7e5f201734a2fa60d1ab111880d # v3.0.2 + if: github.event.issue.pull_request with: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # using the `org/team_slug` or `/team_slug` syntax to add git team as reviewers diff --git a/.github/workflows/rebase.yml b/.github/workflows/rebase.yml deleted file mode 100644 index df5b4789fb3..00000000000 --- a/.github/workflows/rebase.yml +++ /dev/null @@ -1,39 +0,0 @@ -# This cannot rebase workflow changes into a PR -# It also only works if the GITHUB_TOKEN has permission to push to the branch -# see: https://github.com/cirrus-actions/rebase/issues/12#issuecomment-632594995 -on: - issue_comment: - types: [created] -name: Automatic Rebase -permissions: - contents: read - -jobs: - rebase: - permissions: - contents: write # for cirrus-actions/rebase to push code to rebase - pull-requests: write # for actions/github-script to create PR comment - name: Rebase - if: github.event.issue.pull_request != '' && contains(github.event.comment.body, '/rebase') - runs-on: ubuntu-latest - steps: - - name: Checkout the latest code - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 - with: - fetch-depth: 0 - - name: Post rebase started comment to pull request - uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1 - continue-on-error: true - with: - script: | - const backport_start_body = `Started rebase: https://github.com/${context.repo.owner}/${context.repo.repo}/actions/runs/${process.env.GITHUB_RUN_ID}`; - await github.issues.createComment({ - issue_number: context.issue.number, - owner: context.repo.owner, - repo: context.repo.repo, - body: backport_start_body - }); - - name: Automatic Rebase - uses: cirrus-actions/rebase@b87d48154a87a85666003575337e27b8cd65f691 # 1.8 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/windows-ci.yml b/.github/workflows/windows-ci.yml new file mode 100644 index 00000000000..010c775ee53 --- /dev/null +++ b/.github/workflows/windows-ci.yml @@ -0,0 +1,124 @@ +name: Windows-CI +on: + workflow_dispatch: + push: + branches: + - master + - release/** + - feature* + paths: + - "*" + - "!.vsts-ci/misc-analysis.yml" + - "!.github/ISSUE_TEMPLATE/*" + - "!.github/workflows/*" + - "!.dependabot/config.yml" + - "!test/perf/*" + - "!.pipelines/*" + pull_request: + branches: + - master + - release/** + - feature* + paths: + - ".vsts-ci/templates/*" + - ".vsts-ci/windows.yml" + - "*.props" + - build.psm1 + - src/* + - test/* + - tools/buildCommon/* + - tools/ci.psm1 + - tools/WindowsCI.psm1 + - "!test/common/markdown/*" + - "!test/perf/*" +permissions: + contents: read + +run-name: "${{ github.ref_name }} - ${{ github.run_number }}" + +env: + DOTNET_CLI_TELEMETRY_OPTOUT: 1 + DOTNET_SKIP_FIRST_TIME_EXPERIENCE: 1 + GIT_CONFIG_PARAMETERS: "'core.autocrlf=false'" + NugetSecurityAnalysisWarningLevel: none + POWERSHELL_TELEMETRY_OPTOUT: 1 + __SuppressAnsiEscapeSequences: 1 + nugetMultiFeedWarnLevel: none +jobs: + ci_build: + name: Build PowerShell + runs-on: windows-latest + steps: + - name: checkout + uses: actions/checkout@v4.1.0 + with: + fetch-depth: 1000 + - name: Build + uses: "./.github/actions/build/ci" + windows_test: + name: Windows Unelevated CI + needs: ci_build + runs-on: windows-latest + steps: + - name: checkout + uses: actions/checkout@v4.1.0 + with: + fetch-depth: 1000 + - name: Windows Unelevated CI + uses: "./.github/actions/test/windows" + with: + purpose: UnelevatedPesterTests + tagSet: CI + windows_test_2: + name: Windows Elevated CI + needs: ci_build + runs-on: windows-latest + steps: + - name: checkout + uses: actions/checkout@v4.1.0 + with: + fetch-depth: 1000 + - name: Windows Elevated CI + uses: "./.github/actions/test/windows" + with: + purpose: ElevatedPesterTests + tagSet: CI + windows_test_3: + name: Windows Unelevated Others + needs: ci_build + runs-on: windows-latest + steps: + - name: checkout + uses: actions/checkout@v4.1.0 + with: + fetch-depth: 1000 + - name: Windows Unelevated Others + uses: "./.github/actions/test/windows" + with: + purpose: UnelevatedPesterTests + tagSet: Others + windows_test_4: + name: Windows Elevated Others + needs: ci_build + runs-on: windows-latest + steps: + - name: checkout + uses: actions/checkout@v4.1.0 + with: + fetch-depth: 1000 + - name: Windows Elevated Others + uses: "./.github/actions/test/windows" + with: + purpose: ElevatedPesterTests + tagSet: Others + verify_xunit: + name: Verify xUnit test results + needs: ci_build + runs-on: windows-latest + steps: + - name: checkout + uses: actions/checkout@v4.1.0 + with: + fetch-depth: 1000 + - name: Verify xUnit test results + uses: "./.github/actions/test/verify_xunit" diff --git a/.gitignore b/.gitignore index cb12a297984..ccadde27182 100644 --- a/.gitignore +++ b/.gitignore @@ -111,3 +111,10 @@ msbuild.binlog # Ignore gzip files in the manpage folder assets/manpage/*.gz + +# Ignore files and folders generated by some gh cli extensions +tmp/* +.env.local + +# Ignore CTRF report files +crtf/* diff --git a/build.psm1 b/build.psm1 index e21194c9af9..e05b5639af1 100644 --- a/build.psm1 +++ b/build.psm1 @@ -1758,6 +1758,16 @@ function Publish-TestResults $resolvedPath = (Resolve-Path -Path $Path).ProviderPath Write-Host "##vso[artifact.upload containerfolder=testResults;artifactname=testResults]$resolvedPath" + } elseif ($env:GITHUB_WORKFLOW -and $env:RUNNER_WORKSPACE) { + # In GitHub Actions + $destinationPath = Join-Path -Path $env:RUNNER_WORKSPACE -ChildPath 'testResults' + + # Create the folder if it does not exist + if (!(Test-Path -Path $destinationPath)) { + $null = New-Item -ItemType Directory -Path $destinationPath -Force + } + + Copy-Item -Path $Path -Destination $destinationPath -Force -Verbose } } diff --git a/tools/ci.psm1 b/tools/ci.psm1 index 6628d54e043..7dda90f14f3 100644 --- a/tools/ci.psm1 +++ b/tools/ci.psm1 @@ -17,8 +17,15 @@ if(Test-Path $dotNetPath) # import build into the global scope so it can be used by packaging # argumentList $true says ignore tha we may not be able to build -Import-Module (Join-Path $repoRoot 'build.psm1') -Verbose -Scope Global -ArgumentList $true -Import-Module (Join-Path $repoRoot 'tools\packaging') -Verbose -Scope Global +Write-Verbose "Importing build.psm1" -Verbose +Import-Module (Join-Path $repoRoot 'build.psm1') -Scope Global -ArgumentList $true +$buildCommands = Get-Command -Module build +Write-Verbose "Imported build.psm1 commands: $($buildCommands.Count)" -Verbose + +Write-Verbose "Importing packaging.psm1" -Verbose +Import-Module (Join-Path $repoRoot 'tools\packaging') -Scope Global +$packagingCommands = Get-Command -Module packaging +Write-Verbose "Imported packaging.psm1 commands: $($packagingCommands.Count)" -Verbose # import the windows specific functcion only in Windows PowerShell or on Windows if($PSVersionTable.PSEdition -eq 'Desktop' -or $IsWindows) @@ -224,9 +231,12 @@ function Invoke-CITest [string] $Purpose, [ValidateSet('CI', 'Others')] [string] $TagSet, - [string] $TitlePrefix + [string] $TitlePrefix, + [string] $OutputFormat = "NUnitXml" ) + Write-Verbose -Verbose "CI test: OutputFormat: $OutputFormat" + # Set locale correctly for Linux CIs Set-CorrectLocale @@ -281,12 +291,14 @@ function Invoke-CITest Terse = $true Tag = @() ExcludeTag = $ExcludeTag + 'RequireAdminOnWindows' + OutputFormat = $OutputFormat } $title = "Pester Unelevated - $TagSet" if ($TitlePrefix) { $title = "$TitlePrefix - $title" } + Write-Verbose -Verbose "Starting Pester with output format $($arguments.OutputFormat)" Start-PSPester @arguments -Title $title # Fail the build, if tests failed @@ -314,7 +326,10 @@ function Invoke-CITest if ($TitlePrefix) { $title = "$TitlePrefix - $title" } - Start-PSPester @arguments -Title $title + + # We just built the test tools, we don't need to rebuild them + Write-Verbose -Verbose "Starting Pester with output format $($arguments.OutputFormat)" + Start-PSPester @arguments -Title $title -SkipTestToolBuild # Fail the build, if tests failed Test-PSPesterResults -TestResultsFile $expFeatureTestResultFile @@ -328,12 +343,15 @@ function Invoke-CITest OutputFile = $testResultsAdminFile Tag = @('RequireAdminOnWindows') ExcludeTag = $ExcludeTag + OutputFormat = $OutputFormat } $title = "Pester Elevated - $TagSet" if ($TitlePrefix) { $title = "$TitlePrefix - $title" } + + Write-Verbose -Verbose "Starting Pester with output format $($arguments.OutputFormat)" Start-PSPester @arguments -Title $title # Fail the build, if tests failed @@ -364,6 +382,8 @@ function Invoke-CITest if ($TitlePrefix) { $title = "$TitlePrefix - $title" } + + Write-Verbose -Verbose "Starting Pester with output format $($arguments.OutputFormat)" Start-PSPester @arguments -Title $title # Fail the build, if tests failed @@ -437,6 +457,18 @@ function Push-Artifact if ($env:TF_BUILD) { # In Azure DevOps Write-Host "##vso[artifact.upload containerfolder=$artifactName;artifactname=$artifactName;]$Path" + } elseif ($env:GITHUB_WORKFLOW -and $env:RUNNER_WORKSPACE) { + # In GitHub Actions + $destinationPath = Join-Path -Path $env:RUNNER_WORKSPACE -ChildPath $artifactName + + # Create the folder if it does not exist + if (!(Test-Path -Path $destinationPath)) { + $null = New-Item -ItemType Directory -Path $destinationPath -Force + } + + Copy-Item -Path $Path -Destination $destinationPath -Force -Verbose + } else { + Write-Warning "Push-Artifact is not supported in this environment." } } From 5492f07de0396d84e0ded369e36572a2c11df64e Mon Sep 17 00:00:00 2001 From: Travis Plunk Date: Wed, 5 Feb 2025 11:32:01 -0800 Subject: [PATCH 073/173] [release/v7.5]Convert powershell/PowerShell-CI-linux to GitHub Actions (#24946) --- .../actions/test/linux-packaging/action.yml | 95 ++++++++++++ .github/actions/test/nix/action.yml | 91 +++++++++++ .../test/process-pester-results/action.yml | 64 ++++++++ .github/actions/test/windows/action.yml | 49 +----- .github/workflows/linux-ci.yml | 141 ++++++++++++++++++ .github/workflows/windows-ci.yml | 25 ++-- tools/ci.psm1 | 28 ++-- 7 files changed, 425 insertions(+), 68 deletions(-) create mode 100644 .github/actions/test/linux-packaging/action.yml create mode 100644 .github/actions/test/nix/action.yml create mode 100644 .github/actions/test/process-pester-results/action.yml create mode 100644 .github/workflows/linux-ci.yml diff --git a/.github/actions/test/linux-packaging/action.yml b/.github/actions/test/linux-packaging/action.yml new file mode 100644 index 00000000000..61d23742056 --- /dev/null +++ b/.github/actions/test/linux-packaging/action.yml @@ -0,0 +1,95 @@ +name: linux_packaging +description: 'Test very basic Linux packaging' + +# This isn't working yet +# It fails with + +# ERROR: While executing gem ... (Gem::FilePermissionError) +# You don't have write permissions for the /var/lib/gems/2.7.0 directory. +# WARNING: Installation of gem dotenv 2.8.1 failed! Must resolve manually. + +runs: + using: composite + steps: + - name: Capture Environment + if: success() || failure() + run: 'Get-ChildItem -Path env: | Out-String -width 9999 -Stream | write-Verbose -Verbose' + shell: pwsh + - name: Download Build Artifacts + uses: actions/download-artifact@v4 + with: + path: "${{ github.workspace }}" + - name: Capture Artifacts Directory + continue-on-error: true + run: Get-ChildItem "${{ github.workspace }}/build/*" -Recurse + shell: pwsh + + - name: Bootstrap + run: |- + Import-Module ./build.psm1 + Start-PSBootstrap -Package + shell: pwsh + - name: Capture Artifacts Directory + continue-on-error: true + run: Import-Module ./build.psm1 + shell: pwsh + - name: Extract Files + uses: actions/github-script@v7.0.0 + env: + DESTINATION_FOLDER: "${{ github.workspace }}/bins" + ARCHIVE_FILE_PATTERNS: "${{ github.workspace }}/build/build.zip" + with: + script: |- + const fs = require('fs').promises + const path = require('path') + const target = path.resolve(process.env.DESTINATION_FOLDER) + const patterns = process.env.ARCHIVE_FILE_PATTERNS + const globber = await glob.create(patterns) + await io.mkdirP(path.dirname(target)) + for await (const file of globber.globGenerator()) { + if ((await fs.lstat(file)).isDirectory()) continue + await exec.exec(`7z x ${file} -o${target} -aoa`) + } + - name: Fix permissions + continue-on-error: true + run: |- + find "${{ github.workspace }}/bins" -type d -exec chmod +rwx {} \; + find "${{ github.workspace }}/bins" -type f -exec chmod +rw {} \; + shell: bash + - name: Capture Extracted Build ZIP + continue-on-error: true + run: Get-ChildItem "${{ github.workspace }}/bins/*" -Recurse -ErrorAction SilentlyContinue + shell: pwsh + - name: Packaging Tests + if: success() + run: |- + Import-Module ./tools/ci.psm1 + Restore-PSOptions -PSOptionsPath '${{ github.workspace }}/build/psoptions.json' + $options = (Get-PSOptions) + $rootPath = '${{ github.workspace }}/bins' + $originalRootPath = Split-Path -path $options.Output + $path = Join-Path -path $rootPath -ChildPath (split-path -leaf -path $originalRootPath) + $pwshPath = Join-Path -path $path -ChildPath 'pwsh' + chmod a+x $pwshPath + $options.Output = $pwshPath + Set-PSOptions $options + Invoke-CIFinish + shell: pwsh + - name: Upload packages + run: |- + Get-ChildItem "${env:BUILD_ARTIFACTSTAGINGDIRECTORY}/*.deb" -Recurse | ForEach-Object { + $packagePath = $_.FullName + Write-Host "Uploading $packagePath" + Write-Host "##vso[artifact.upload containerfolder=deb;artifactname=deb]$packagePath" + } + Get-ChildItem "${env:BUILD_ARTIFACTSTAGINGDIRECTORY}/*.rpm" -Recurse | ForEach-Object { + $packagePath = $_.FullName + Write-Host "Uploading $packagePath" + Write-Host "##vso[artifact.upload containerfolder=rpm;artifactname=rpm]$packagePath" + } + Get-ChildItem "${env:BUILD_ARTIFACTSTAGINGDIRECTORY}/*.tar.gz" -Recurse | ForEach-Object { + $packagePath = $_.FullName + Write-Host "Uploading $packagePath" + Write-Host "##vso[artifact.upload containerfolder=rpm;artifactname=rpm]$packagePath" + } + shell: pwsh diff --git a/.github/actions/test/nix/action.yml b/.github/actions/test/nix/action.yml new file mode 100644 index 00000000000..97575b6b54d --- /dev/null +++ b/.github/actions/test/nix/action.yml @@ -0,0 +1,91 @@ +name: nix_test +description: 'Test PowerShell on non-Windows platforms' + +inputs: + purpose: + required: false + default: '' + type: string + tagSet: + required: false + default: CI + type: string + ctrfFolder: + required: false + default: ctrf + type: string + +runs: + using: composite + steps: + - name: Capture Environment + if: success() || failure() + run: 'Get-ChildItem -Path env: | Out-String -width 9999 -Stream | write-Verbose -Verbose' + shell: pwsh + - name: Download Build Artifacts + uses: actions/download-artifact@v4 + with: + path: "${{ github.workspace }}" + - name: Capture Artifacts Directory + continue-on-error: true + run: Get-ChildItem "${{ github.workspace }}/build/*" -Recurse + shell: pwsh + + - name: Bootstrap + shell: pwsh + run: |- + Import-Module ./tools/ci.psm1 + Invoke-CIInstall -SkipUser + + - name: Extract Files + uses: actions/github-script@v7.0.0 + env: + DESTINATION_FOLDER: "${{ github.workspace }}/bins" + ARCHIVE_FILE_PATTERNS: "${{ github.workspace }}/build/build.zip" + with: + script: |- + const fs = require('fs').promises + const path = require('path') + const target = path.resolve(process.env.DESTINATION_FOLDER) + const patterns = process.env.ARCHIVE_FILE_PATTERNS + const globber = await glob.create(patterns) + await io.mkdirP(path.dirname(target)) + for await (const file of globber.globGenerator()) { + if ((await fs.lstat(file)).isDirectory()) continue + await exec.exec(`7z x ${file} -o${target} -aoa`) + } + + - name: Fix permissions + continue-on-error: true + run: |- + find "${{ github.workspace }}/bins" -type d -exec chmod +rwx {} \; + find "${{ github.workspace }}/bins" -type f -exec chmod +rw {} \; + shell: bash + + - name: Capture Extracted Build ZIP + continue-on-error: true + run: Get-ChildItem "${{ github.workspace }}/bins/*" -Recurse -ErrorAction SilentlyContinue + shell: pwsh + + - name: Test + if: success() + run: |- + Import-Module ./tools/ci.psm1 + Restore-PSOptions -PSOptionsPath '${{ github.workspace }}/build/psoptions.json' + $options = (Get-PSOptions) + $rootPath = '${{ github.workspace }}/bins' + $originalRootPath = Split-Path -path $options.Output + $path = Join-Path -path $rootPath -ChildPath (split-path -leaf -path $originalRootPath) + $pwshPath = Join-Path -path $path -ChildPath 'pwsh' + chmod a+x $pwshPath + $options.Output = $pwshPath + Set-PSOptions $options + Invoke-CITest -Purpose '${{ inputs.purpose }}' -TagSet '${{ inputs.tagSet }}' -TitlePrefix '${{ inputs.buildName }}' -OutputFormat JUnitXml + shell: pwsh + + - name: Convert, Publish, and Upload Pester Test Results + uses: "./.github/actions/test/process-pester-results" + with: + name: "${{ inputs.purpose }}-${{ inputs.tagSet }}" + testResultsFolder: "${{ runner.workspace }}/testResults" + ctrfFolder: "${{ inputs.ctrfFolder }}" diff --git a/.github/actions/test/process-pester-results/action.yml b/.github/actions/test/process-pester-results/action.yml new file mode 100644 index 00000000000..758bbdfc353 --- /dev/null +++ b/.github/actions/test/process-pester-results/action.yml @@ -0,0 +1,64 @@ +name: process-pester-test-results +description: 'Process Pester test results' + +inputs: + name: + required: true + default: '' + type: string + testResultsFolder: + required: false + default: "${{ runner.workspace }}/testResults" + type: string + ctrfFolder: + required: false + default: ctrf + type: string + +runs: + using: composite + steps: + - name: Convert JUnit to CTRF + run: |- + Get-ChildItem -Path "${{ inputs.testResultsFolder }}/*.xml" -Recurse | ForEach-Object { + npx --yes junit-to-ctrf $_.FullName --output ./${{ inputs.ctrfFolder }}/$($_.BaseName).json --tool Pester + } + shell: pwsh + + # this task only takes / as directory separators + - name: Publish Test Report + uses: ctrf-io/github-test-reporter@v1 + with: + report-path: './${{ inputs.ctrfFolder }}/*.json' + exit-on-fail: true + summary-report: true + test-report: false + test-list-report: false + failed-report: false + fail-rate-report: false + flaky-report: false + flaky-rate-report: false + failed-folded-report: true + previous-results-report: false + ai-report: true + skipped-report: false + suite-folded-report: false + suite-list-report: false + pull-request-report: false + commit-report: false + custom-report: false + if: always() + + - name: Upload testResults artifact + if: always() + uses: actions/upload-artifact@v4 + with: + name: junit-pester-${{ inputs.name }} + path: ${{ runner.workspace }}/testResults + + - name: Upload ctrf artifact + if: always() + uses: actions/upload-artifact@v4 + with: + name: ctrf-pester-${{ inputs.name }} + path: ${{ inputs.ctrfFolder }} diff --git a/.github/actions/test/windows/action.yml b/.github/actions/test/windows/action.yml index 6cb5cbc1d74..c8e1c86024a 100644 --- a/.github/actions/test/windows/action.yml +++ b/.github/actions/test/windows/action.yml @@ -60,48 +60,9 @@ runs: Invoke-CITest -Purpose '${{ inputs.purpose }}' -TagSet '${{ inputs.tagSet }}' -OutputFormat JUnitXml shell: pwsh - - name: Convert JUnit to CTRF - run: |- - Get-ChildItem -Path "${{ runner.workspace }}/testResults/*.xml" -Recurse | ForEach-Object { - npx --yes junit-to-ctrf $_.FullName --output .\${{ inputs.ctrfFolder }}\$($_.BaseName).json --tool Pester --env 'Windows ${{ inputs.purpose }} ${{ inputs.tagSet }}' - } - shell: powershell - - # this task only takes / as directory separators - - name: Publish Test Report - uses: ctrf-io/github-test-reporter@v1 - with: - report-path: './${{ inputs.ctrfFolder }}/*.json' - exit-on-fail: true - summary-report: true - test-report: false - test-list-report: false - failed-report: false - fail-rate-report: false - flaky-report: false - flaky-rate-report: false - failed-folded-report: true - previous-results-report: false - ai-report: true - skipped-report: false - suite-folded-report: false - suite-list-report: false - pull-request-report: false - commit-report: false - custom-report: false - - if: always() - - - name: Upload testResults artifact - if: always() - uses: actions/upload-artifact@v4 - with: - name: junit-pester-${{ inputs.purpose }}-${{ inputs.tagSet }} - path: ${{ runner.workspace }}\testResults - - - name: Upload ctrf artifact - if: always() - uses: actions/upload-artifact@v4 + - name: Convert, Publish, and Upload Pester Test Results + uses: "./.github/actions/test/process-pester-results" with: - name: ctrf-pester-${{ inputs.purpose }}-${{ inputs.tagSet }} - path: ${{ inputs.ctrfFolder }} + name: "${{ inputs.purpose }}-${{ inputs.tagSet }}" + testResultsFolder: ${{ runner.workspace }}\testResults + ctrfFolder: "${{ inputs.ctrfFolder }}" diff --git a/.github/workflows/linux-ci.yml b/.github/workflows/linux-ci.yml new file mode 100644 index 00000000000..8bb61c2c541 --- /dev/null +++ b/.github/workflows/linux-ci.yml @@ -0,0 +1,141 @@ +name: Linux-CI + +run-name: "${{ github.ref_name }} - ${{ github.run_number }}" + +on: + workflow_dispatch: + + push: + branches: + - master + - release* + - feature* + paths: + - "**" + - "!.github/ISSUE_TEMPLATE/**" + - "!.dependabot/config.yml" + - "!.pipelines/**" + - "!test/perf/**" + pull_request: + branches: + - master + - release/** + - feature* + paths: + - ".github/actions/**" + - ".github/workflows/linux-ci.yml" + - "**.props" + - build.psm1 + - src/** + - test/** + - tools/buildCommon/** + - tools/ci.psm1 + - tools/WindowsCI.psm1 + - "!test/common/markdown/**" + - "!test/perf/**" +env: + DOTNET_CLI_TELEMETRY_OPTOUT: 1 + DOTNET_SKIP_FIRST_TIME_EXPERIENCE: 1 + FORCE_FEATURE: 'False' + FORCE_PACKAGE: 'False' + NUGET_KEY: none + POWERSHELL_TELEMETRY_OPTOUT: 1 + __SuppressAnsiEscapeSequences: 1 + nugetMultiFeedWarnLevel: none + system_debug: 'false' +jobs: + ci_build: + name: Build PowerShell + runs-on: ubuntu-20.04 + steps: + - name: checkout + uses: actions/checkout@v4.1.0 + with: + fetch-depth: 1000 + - name: Build + uses: "./.github/actions/build/ci" + linux_test_unelevated_ci: + name: Linux Unelevated CI + needs: ci_build + runs-on: ubuntu-20.04 + steps: + - name: checkout + uses: actions/checkout@v4.1.0 + with: + fetch-depth: 1000 + - name: Linux Unelevated CI + uses: "./.github/actions/test/nix" + with: + purpose: UnelevatedPesterTests + tagSet: CI + linux_test_elevated_ci: + name: Linux Elevated CI + needs: ci_build + runs-on: ubuntu-20.04 + steps: + - name: checkout + uses: actions/checkout@v4.1.0 + with: + fetch-depth: 1000 + - name: Linux Elevated CI + uses: "./.github/actions/test/nix" + with: + purpose: ElevatedPesterTests + tagSet: CI + linux_test_unelevated_others: + name: Linux Unelevated Others + needs: ci_build + runs-on: ubuntu-20.04 + steps: + - name: checkout + uses: actions/checkout@v4.1.0 + with: + fetch-depth: 1000 + - name: Linux Unelevated Others + uses: "./.github/actions/test/nix" + with: + purpose: UnelevatedPesterTests + tagSet: Others + linux_test_elevated_others: + name: Linux Elevated Others + needs: ci_build + runs-on: ubuntu-20.04 + steps: + - name: checkout + uses: actions/checkout@v4.1.0 + with: + fetch-depth: 1000 + - name: Linux Elevated Others + uses: "./.github/actions/test/nix" + with: + purpose: ElevatedPesterTests + tagSet: Others + verify_xunit: + name: Verify xUnit test results + needs: ci_build + runs-on: ubuntu-latest + steps: + - name: checkout + uses: actions/checkout@v4.1.0 + with: + fetch-depth: 1000 + - name: Verify xUnit test results + uses: "./.github/actions/test/verify_xunit" + + # TODO: Enable this when we have a Linux packaging workflow + + # ERROR: While executing gem ... (Gem::FilePermissionError) + # You don't have write permissions for the /var/lib/gems/2.7.0 directory. + # WARNING: Installation of gem dotenv 2.8.1 failed! Must resolve manually. + + # linux_packaging: + # name: Attempt Linux Packaging + # needs: ci_build + # runs-on: ubuntu-20.04 + # steps: + # - name: checkout + # uses: actions/checkout@v4.1.0 + # with: + # fetch-depth: 1000 + # - name: Verify xUnit test results + # uses: "./.github/actions/test/linux-packaging" diff --git a/.github/workflows/windows-ci.yml b/.github/workflows/windows-ci.yml index 010c775ee53..958ee26b6d4 100644 --- a/.github/workflows/windows-ci.yml +++ b/.github/workflows/windows-ci.yml @@ -7,30 +7,29 @@ on: - release/** - feature* paths: - - "*" + - "**" - "!.vsts-ci/misc-analysis.yml" - - "!.github/ISSUE_TEMPLATE/*" - - "!.github/workflows/*" + - "!.github/ISSUE_TEMPLATE/**" - "!.dependabot/config.yml" - - "!test/perf/*" - - "!.pipelines/*" + - "!test/perf/**" + - "!.pipelines/**" pull_request: branches: - master - release/** - feature* paths: - - ".vsts-ci/templates/*" - - ".vsts-ci/windows.yml" - - "*.props" + - ".github/actions/**" + - ".github/workflows/windows-ci.yml" + - "**.props" - build.psm1 - - src/* - - test/* - - tools/buildCommon/* + - src/** + - test/** + - tools/buildCommon/** - tools/ci.psm1 - tools/WindowsCI.psm1 - - "!test/common/markdown/*" - - "!test/perf/*" + - "!test/common/markdown/**" + - "!test/perf/**" permissions: contents: read diff --git a/tools/ci.psm1 b/tools/ci.psm1 index 7dda90f14f3..f09d159b4c8 100644 --- a/tools/ci.psm1 +++ b/tools/ci.psm1 @@ -259,7 +259,7 @@ function Invoke-CITest if($IsLinux -or $IsMacOS) { - return Invoke-LinuxTestsCore -Purpose $Purpose -ExcludeTag $ExcludeTag -TagSet $TagSet -TitlePrefix $TitlePrefix + return Invoke-LinuxTestsCore -Purpose $Purpose -ExcludeTag $ExcludeTag -TagSet $TagSet -TitlePrefix $TitlePrefix -OutputFormat $OutputFormat } # CoreCLR @@ -384,7 +384,8 @@ function Invoke-CITest } Write-Verbose -Verbose "Starting Pester with output format $($arguments.OutputFormat)" - Start-PSPester @arguments -Title $title + # We just built the test tools, we don't need to rebuild them + Start-PSPester @arguments -Title $title -SkipTestToolBuild # Fail the build, if tests failed Test-PSPesterResults -TestResultsFile $expFeatureTestResultFile @@ -702,7 +703,8 @@ function Invoke-LinuxTestsCore [string] $Purpose = 'All', [string[]] $ExcludeTag = @('Slow', 'Feature', 'Scenario'), [string] $TagSet = 'CI', - [string] $TitlePrefix + [string] $TitlePrefix, + [string] $OutputFormat = "NUnitXml" ) $output = Split-Path -Parent (Get-PSOutput -Options (Get-PSOptions)) @@ -715,12 +717,13 @@ function Invoke-LinuxTestsCore $sudoResultsWithExpFeatures = $null $noSudoPesterParam = @{ - 'BinDir' = $output - 'PassThru' = $true - 'Terse' = $true - 'Tag' = @() - 'ExcludeTag' = $testExcludeTag - 'OutputFile' = $testResultsNoSudo + 'BinDir' = $output + 'PassThru' = $true + 'Terse' = $true + 'Tag' = @() + 'ExcludeTag' = $testExcludeTag + 'OutputFile' = $testResultsNoSudo + 'OutputFormat' = $OutputFormat } # Get the experimental feature names and the tests associated with them @@ -758,7 +761,7 @@ function Invoke-LinuxTestsCore if ($TitlePrefix) { $title = "$TitlePrefix - $title" } - $passThruResult = Start-PSPester @noSudoPesterParam -Title $title + $passThruResult = Start-PSPester @noSudoPesterParam -Title $title -SkipTestToolBuild $noSudoResultsWithExpFeatures += $passThruResult } @@ -773,6 +776,7 @@ function Invoke-LinuxTestsCore $sudoPesterParam['ExcludeTag'] = $ExcludeTag $sudoPesterParam['Sudo'] = $true $sudoPesterParam['OutputFile'] = $testResultsSudo + $sudoPesterParam['OutputFormat'] = $OutputFormat $title = "Pester Sudo - $TagSet" if ($TitlePrefix) { @@ -805,7 +809,9 @@ function Invoke-LinuxTestsCore if ($TitlePrefix) { $title = "$TitlePrefix - $title" } - $passThruResult = Start-PSPester @sudoPesterParam -Title $title + + # We just built the test tools for the main test run, we don't need to rebuild them + $passThruResult = Start-PSPester @sudoPesterParam -Title $title -SkipTestToolBuild $sudoResultsWithExpFeatures += $passThruResult } From 7103b6f58a51e20577c53a4713cc3ce6aff4e527 Mon Sep 17 00:00:00 2001 From: Travis Plunk Date: Wed, 5 Feb 2025 13:57:27 -0800 Subject: [PATCH 074/173] [release/v7.5]Convert powershell/PowerShell-CI-macos to GitHub Actions (#24954) --- .github/workflows/codeql-analysis.yml | 69 ---------- .github/workflows/linux-ci.yml | 139 ++++++++++++++++--- .github/workflows/macos-ci.yml | 188 ++++++++++++++++++++++++++ .github/workflows/windows-ci.yml | 92 ++++++++++--- .vsts-ci/linux.yml | 87 ------------ 5 files changed, 381 insertions(+), 194 deletions(-) delete mode 100644 .github/workflows/codeql-analysis.yml create mode 100644 .github/workflows/macos-ci.yml diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml deleted file mode 100644 index 37a76edfeef..00000000000 --- a/.github/workflows/codeql-analysis.yml +++ /dev/null @@ -1,69 +0,0 @@ -name: "CodeQL" - -on: - push: - branches: [master] - pull_request: - # The branches below must be a subset of the branches above - branches: [master] - -defaults: - run: - shell: pwsh - -env: - DOTNET_SKIP_FIRST_TIME_EXPERIENCE: 1 - -permissions: - contents: read - -jobs: - analyze: - permissions: - actions: read # for github/codeql-action/init to get workflow details - contents: read # for actions/checkout to fetch code - security-events: write # for github/codeql-action/analyze to upload SARIF results - name: Analyze - runs-on: ubuntu-latest - - strategy: - fail-fast: false - matrix: - # Override automatic language detection by changing the below list - # Supported options are ['csharp', 'cpp', 'go', 'java', 'javascript', 'python'] - language: ['csharp'] - # Learn more... - # https://docs.github.com/en/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#overriding-automatic-language-detection - - steps: - - name: Checkout repository - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 - with: - fetch-depth: '0' - - # Initializes the CodeQL tools for scanning. - - name: Initialize CodeQL - uses: github/codeql-action/init@eb055d739abdc2e8de2e5f4ba1a8b246daa779aa # v3.26.0 - with: - languages: ${{ matrix.language }} - # If you wish to specify custom queries, you can do so here or in a config file. - # By default, queries listed here will override any specified in a config file. - # Prefix the list here with "+" to use these queries and those in the config file. - # queries: ./path/to/local/query, your-org/your-repo/queries@main - - - run: | - Get-ChildItem -Path env: - name: Capture Environment - - - run: | - Import-Module .\tools\ci.psm1 - Invoke-CIInstall -SkipUser - name: Bootstrap - - - run: | - Import-Module .\tools\ci.psm1 - Invoke-CIBuild - name: Build - - - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@eb055d739abdc2e8de2e5f4ba1a8b246daa779aa # v3.26.0 diff --git a/.github/workflows/linux-ci.yml b/.github/workflows/linux-ci.yml index 8bb61c2c541..25437e70fc8 100644 --- a/.github/workflows/linux-ci.yml +++ b/.github/workflows/linux-ci.yml @@ -21,18 +21,12 @@ on: - master - release/** - feature* - paths: - - ".github/actions/**" - - ".github/workflows/linux-ci.yml" - - "**.props" - - build.psm1 - - src/** - - test/** - - tools/buildCommon/** - - tools/ci.psm1 - - tools/WindowsCI.psm1 - - "!test/common/markdown/**" - - "!test/perf/**" +# Path filters for PRs need to go into the changes job + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: ${{ contains(github.ref, 'merge')}} + env: DOTNET_CLI_TELEMETRY_OPTOUT: 1 DOTNET_SKIP_FIRST_TIME_EXPERIENCE: 1 @@ -44,9 +38,37 @@ env: nugetMultiFeedWarnLevel: none system_debug: 'false' jobs: + changes: + name: Change Detection + runs-on: ubuntu-latest + # Required permissions + permissions: + pull-requests: read + # Set job outputs to values from filter step + outputs: + source: ${{ steps.filter.outputs.source }} + steps: + # For pull requests it's not necessary to checkout the code + - uses: dorny/paths-filter@v3 + id: filter + with: + filters: | + source: + - ".github/actions/**" + - ".github/workflows/linux-ci.yml" + - "**.props" + - build.psm1 + - src/** + - test/** + - tools/buildCommon/** + - tools/ci.psm1 + - "!test/common/markdown/**" + - "!test/perf/**" ci_build: name: Build PowerShell runs-on: ubuntu-20.04 + needs: changes + if: ${{ needs.changes.outputs.source == 'true' }} steps: - name: checkout uses: actions/checkout@v4.1.0 @@ -56,7 +78,10 @@ jobs: uses: "./.github/actions/build/ci" linux_test_unelevated_ci: name: Linux Unelevated CI - needs: ci_build + needs: + - ci_build + - changes + if: ${{ needs.changes.outputs.source == 'true' }} runs-on: ubuntu-20.04 steps: - name: checkout @@ -70,7 +95,10 @@ jobs: tagSet: CI linux_test_elevated_ci: name: Linux Elevated CI - needs: ci_build + needs: + - ci_build + - changes + if: ${{ needs.changes.outputs.source == 'true' }} runs-on: ubuntu-20.04 steps: - name: checkout @@ -84,7 +112,10 @@ jobs: tagSet: CI linux_test_unelevated_others: name: Linux Unelevated Others - needs: ci_build + needs: + - ci_build + - changes + if: ${{ needs.changes.outputs.source == 'true' }} runs-on: ubuntu-20.04 steps: - name: checkout @@ -98,7 +129,10 @@ jobs: tagSet: Others linux_test_elevated_others: name: Linux Elevated Others - needs: ci_build + needs: + - ci_build + - changes + if: ${{ needs.changes.outputs.source == 'true' }} runs-on: ubuntu-20.04 steps: - name: checkout @@ -112,7 +146,10 @@ jobs: tagSet: Others verify_xunit: name: Verify xUnit test results - needs: ci_build + needs: + - ci_build + - changes + if: ${{ needs.changes.outputs.source == 'true' }} runs-on: ubuntu-latest steps: - name: checkout @@ -122,6 +159,74 @@ jobs: - name: Verify xUnit test results uses: "./.github/actions/test/verify_xunit" + analyze: + permissions: + actions: read # for github/codeql-action/init to get workflow details + contents: read # for actions/checkout to fetch code + security-events: write # for github/codeql-action/analyze to upload SARIF results + name: Analyze + runs-on: ubuntu-latest + needs: changes + if: ${{ needs.changes.outputs.source == 'true' }} + + strategy: + fail-fast: false + matrix: + # Override automatic language detection by changing the below list + # Supported options are ['csharp', 'cpp', 'go', 'java', 'javascript', 'python'] + language: ['csharp'] + # Learn more... + # https://docs.github.com/en/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#overriding-automatic-language-detection + + steps: + - name: Checkout repository + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + fetch-depth: '0' + + # Initializes the CodeQL tools for scanning. + - name: Initialize CodeQL + uses: github/codeql-action/init@df409f7d9260372bd5f19e5b04e83cb3c43714ae # v3.27.9 + with: + languages: ${{ matrix.language }} + # If you wish to specify custom queries, you can do so here or in a config file. + # By default, queries listed here will override any specified in a config file. + # Prefix the list here with "+" to use these queries and those in the config file. + # queries: ./path/to/local/query, your-org/your-repo/queries@main + + - run: | + Get-ChildItem -Path env: | Out-String -width 9999 -Stream | write-Verbose -Verbose + name: Capture Environment + shell: pwsh + + - run: | + Import-Module .\tools\ci.psm1 + Invoke-CIInstall -SkipUser + name: Bootstrap + shell: pwsh + + - run: | + Import-Module .\tools\ci.psm1 + Invoke-CIBuild + name: Build + shell: pwsh + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@df409f7d9260372bd5f19e5b04e83cb3c43714ae # v3.27.9 + + ready_to_merge: + name: Linux ready to merge + needs: + - verify_xunit + - linux_test_elevated_ci + - linux_test_elevated_others + - linux_test_unelevated_ci + - linux_test_unelevated_others + - analyze + if: always() + uses: PowerShell/compliance/.github/workflows/ready-to-merge.yml@master + with: + needs_context: ${{ toJson(needs) }} # TODO: Enable this when we have a Linux packaging workflow # ERROR: While executing gem ... (Gem::FilePermissionError) diff --git a/.github/workflows/macos-ci.yml b/.github/workflows/macos-ci.yml new file mode 100644 index 00000000000..5a497114b90 --- /dev/null +++ b/.github/workflows/macos-ci.yml @@ -0,0 +1,188 @@ +name: macOS-CI + +run-name: "${{ github.ref_name }} - ${{ github.run_number }}" + +on: + push: + branches: + - master + - release/** + - feature* + paths: + - "**" + - "!.github/ISSUE_TEMPLATE/**" + - "!.dependabot/config.yml" + - "!.pipelines/**" + - "!test/perf/**" + pull_request: + branches: + - master + - release/** + - feature* +# Path filters for PRs need to go into the changes job + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: ${{ contains(github.ref, 'merge')}} + +env: + DOTNET_CLI_TELEMETRY_OPTOUT: 1 + DOTNET_SKIP_FIRST_TIME_EXPERIENCE: 1 + FORCE_FEATURE: 'False' + FORCE_PACKAGE: 'False' + HOMEBREW_NO_ANALYTICS: 1 + NUGET_KEY: none + POWERSHELL_TELEMETRY_OPTOUT: 1 + __SuppressAnsiEscapeSequences: 1 + nugetMultiFeedWarnLevel: none + system_debug: 'false' +jobs: + changes: + name: Change Detection + runs-on: ubuntu-latest + # Required permissions + permissions: + pull-requests: read + # Set job outputs to values from filter step + outputs: + source: ${{ steps.filter.outputs.source }} + steps: + # For pull requests it's not necessary to checkout the code + - uses: dorny/paths-filter@v3 + id: filter + with: + filters: | + source: + - ".github/actions/**" + - ".github/workflows/macos-ci.yml" + - "**.props" + - build.psm1 + - src/** + - test/** + - tools/buildCommon/** + - tools/ci.psm1 + - "!test/common/markdown/**" + - "!test/perf/**" + ci_build: + name: Build PowerShell + runs-on: macos-latest + needs: changes + if: ${{ needs.changes.outputs.source == 'true' }} + steps: + - name: checkout + uses: actions/checkout@v4.1.0 + with: + fetch-depth: 1000 + - name: Build + uses: "./.github/actions/build/ci" + macos_test_unelevated_ci: + name: macos Unelevated CI + needs: + - ci_build + - changes + if: ${{ needs.changes.outputs.source == 'true' }} + runs-on: macos-latest + steps: + - name: checkout + uses: actions/checkout@v4.1.0 + with: + fetch-depth: 1000 + - name: macOS Unelevated CI + uses: "./.github/actions/test/nix" + with: + purpose: UnelevatedPesterTests + tagSet: CI + macos_test_elevated_ci: + name: macOS Elevated CI + needs: + - ci_build + - changes + if: ${{ needs.changes.outputs.source == 'true' }} + runs-on: macos-latest + steps: + - name: checkout + uses: actions/checkout@v4.1.0 + with: + fetch-depth: 1000 + - name: macOS Elevated CI + uses: "./.github/actions/test/nix" + with: + purpose: ElevatedPesterTests + tagSet: CI + macos_test_unelevated_others: + name: macOS Unelevated Others + needs: + - ci_build + - changes + if: ${{ needs.changes.outputs.source == 'true' }} + runs-on: macos-latest + steps: + - name: checkout + uses: actions/checkout@v4.1.0 + with: + fetch-depth: 1000 + - name: macOS Unelevated Others + uses: "./.github/actions/test/nix" + with: + purpose: UnelevatedPesterTests + tagSet: Others + macos_test_elevated_others: + name: macOS Elevated Others + needs: + - ci_build + - changes + if: ${{ needs.changes.outputs.source == 'true' }} + runs-on: macos-latest + steps: + - name: checkout + uses: actions/checkout@v4.1.0 + with: + fetch-depth: 1000 + - name: macOS Elevated Others + uses: "./.github/actions/test/nix" + with: + purpose: ElevatedPesterTests + tagSet: Others + verify_xunit: + name: Verify xUnit test results + needs: + - ci_build + - changes + if: ${{ needs.changes.outputs.source == 'true' }} + runs-on: ubuntu-latest + steps: + - name: checkout + uses: actions/checkout@v4.1.0 + with: + fetch-depth: 1000 + - name: Verify xUnit test results + uses: "./.github/actions/test/verify_xunit" + PackageMac-macos_packaging: + name: macOS packaging (bootstrap only) + needs: + - changes + if: ${{ needs.changes.outputs.source == 'true' }} + runs-on: + - macos-latest + steps: + - name: checkout + uses: actions/checkout@v4.1.0 + - name: Bootstrap packaging + if: success() || failure() + run: |- + import-module ./build.psm1 + start-psbootstrap -package + shell: pwsh + ready_to_merge: + name: macos ready to merge + needs: + - verify_xunit + - PackageMac-macos_packaging + - macos_test_elevated_ci + - macos_test_elevated_others + - macos_test_unelevated_ci + - macos_test_unelevated_others + if: always() + uses: PowerShell/compliance/.github/workflows/ready-to-merge.yml@master + with: + needs_context: ${{ toJson(needs) }} diff --git a/.github/workflows/windows-ci.yml b/.github/workflows/windows-ci.yml index 958ee26b6d4..2801a4f2bdc 100644 --- a/.github/workflows/windows-ci.yml +++ b/.github/workflows/windows-ci.yml @@ -18,18 +18,12 @@ on: - master - release/** - feature* - paths: - - ".github/actions/**" - - ".github/workflows/windows-ci.yml" - - "**.props" - - build.psm1 - - src/** - - test/** - - tools/buildCommon/** - - tools/ci.psm1 - - tools/WindowsCI.psm1 - - "!test/common/markdown/**" - - "!test/perf/**" +# Path filters for PRs need to go into the changes job + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: ${{ contains(github.ref, 'merge')}} + permissions: contents: read @@ -44,8 +38,37 @@ env: __SuppressAnsiEscapeSequences: 1 nugetMultiFeedWarnLevel: none jobs: + changes: + name: Change Detection + runs-on: ubuntu-latest + # Required permissions + permissions: + pull-requests: read + # Set job outputs to values from filter step + outputs: + source: ${{ steps.filter.outputs.source }} + steps: + # For pull requests it's not necessary to checkout the code + - uses: dorny/paths-filter@v3 + id: filter + with: + filters: | + source: + - ".github/actions/**" + - ".github/workflows/windows-ci.yml" + - "**.props" + - build.psm1 + - src/** + - test/** + - tools/buildCommon/** + - tools/ci.psm1 + - tools/WindowsCI.psm1 + - "!test/common/markdown/**" + - "!test/perf/**" ci_build: name: Build PowerShell + needs: changes + if: ${{ needs.changes.outputs.source == 'true' }} runs-on: windows-latest steps: - name: checkout @@ -54,9 +77,12 @@ jobs: fetch-depth: 1000 - name: Build uses: "./.github/actions/build/ci" - windows_test: + windows_test_unelevated_ci: name: Windows Unelevated CI - needs: ci_build + needs: + - ci_build + - changes + if: ${{ needs.changes.outputs.source == 'true' }} runs-on: windows-latest steps: - name: checkout @@ -68,9 +94,12 @@ jobs: with: purpose: UnelevatedPesterTests tagSet: CI - windows_test_2: + windows_test_elevated_ci: name: Windows Elevated CI - needs: ci_build + needs: + - ci_build + - changes + if: ${{ needs.changes.outputs.source == 'true' }} runs-on: windows-latest steps: - name: checkout @@ -82,9 +111,12 @@ jobs: with: purpose: ElevatedPesterTests tagSet: CI - windows_test_3: + windows_test_unelevated_others: name: Windows Unelevated Others - needs: ci_build + needs: + - ci_build + - changes + if: ${{ needs.changes.outputs.source == 'true' }} runs-on: windows-latest steps: - name: checkout @@ -96,9 +128,12 @@ jobs: with: purpose: UnelevatedPesterTests tagSet: Others - windows_test_4: + windows_test_elevated_others: name: Windows Elevated Others - needs: ci_build + needs: + - ci_build + - changes + if: ${{ needs.changes.outputs.source == 'true' }} runs-on: windows-latest steps: - name: checkout @@ -112,7 +147,10 @@ jobs: tagSet: Others verify_xunit: name: Verify xUnit test results - needs: ci_build + needs: + - ci_build + - changes + if: ${{ needs.changes.outputs.source == 'true' }} runs-on: windows-latest steps: - name: checkout @@ -121,3 +159,15 @@ jobs: fetch-depth: 1000 - name: Verify xUnit test results uses: "./.github/actions/test/verify_xunit" + ready_to_merge: + name: windows ready to merge + needs: + - verify_xunit + - windows_test_elevated_ci + - windows_test_elevated_others + - windows_test_unelevated_ci + - windows_test_unelevated_others + if: always() + uses: PowerShell/compliance/.github/workflows/ready-to-merge.yml@master + with: + needs_context: ${{ toJson(needs) }} diff --git a/.vsts-ci/linux.yml b/.vsts-ci/linux.yml index c1a1fd5c0ab..b1bb74197a0 100644 --- a/.vsts-ci/linux.yml +++ b/.vsts-ci/linux.yml @@ -79,93 +79,6 @@ stages: jobName: linux_build displayName: linux Build -- stage: TestUbuntu - displayName: Test for Ubuntu - dependsOn: [BuildLinuxStage] - jobs: - - template: templates/nix-test.yml - parameters: - name: Ubuntu - pool: ubuntu-20.04 - purpose: UnelevatedPesterTests - tagSet: CI - - - template: templates/nix-test.yml - parameters: - name: Ubuntu - pool: ubuntu-20.04 - purpose: ElevatedPesterTests - tagSet: CI - - - template: templates/nix-test.yml - parameters: - name: Ubuntu - pool: ubuntu-20.04 - purpose: UnelevatedPesterTests - tagSet: Others - - - template: templates/nix-test.yml - parameters: - name: Ubuntu - pool: ubuntu-20.04 - purpose: ElevatedPesterTests - tagSet: Others - - - template: templates/verify-xunit.yml - parameters: - pool: ubuntu-20.04 - -- stage: TestContainer - displayName: Test in a container - dependsOn: [BuildLinuxStage] - jobs: - - job: getContainerJob - displayName: Choose a container - pool: - vmImage: ubuntu-20.04 - steps: - - checkout: self - clean: true - - - checkout: Docker - clean: true - - - pwsh: | - # Initialize container test stage - Import-Module ./PowerShell/tools/ci.psm1 - Invoke-InitializeContainerStage -ContainerPattern '${{ parameters.ContainerPattern }}' - name: getContainerTask - displayName: Initialize Container Stage - continueOnError: true - - - template: templates/test/nix-container-test.yml - parameters: - name: container - pool: ubuntu-20.04 - purpose: UnelevatedPesterTests - tagSet: CI - - - template: templates/test/nix-container-test.yml - parameters: - name: container - pool: ubuntu-20.04 - purpose: ElevatedPesterTests - tagSet: CI - - - template: templates/test/nix-container-test.yml - parameters: - name: container - pool: ubuntu-20.04 - purpose: UnelevatedPesterTests - tagSet: Others - - - template: templates/test/nix-container-test.yml - parameters: - name: container - pool: ubuntu-20.04 - purpose: ElevatedPesterTests - tagSet: Others - - stage: PackageLinux displayName: Package Linux dependsOn: ["BuildLinuxStage"] From caa937a1dc037f067b7545856fa1e38cc99b4b07 Mon Sep 17 00:00:00 2001 From: Travis Plunk Date: Wed, 5 Feb 2025 14:57:50 -0800 Subject: [PATCH 075/173] [release/v7.5]Fix release branch filters (#24959) --- .github/workflows/linux-ci.yml | 4 +--- .github/workflows/macos-ci.yml | 2 -- .github/workflows/windows-ci.yml | 2 -- 3 files changed, 1 insertion(+), 7 deletions(-) diff --git a/.github/workflows/linux-ci.yml b/.github/workflows/linux-ci.yml index 25437e70fc8..2ab1d8adab5 100644 --- a/.github/workflows/linux-ci.yml +++ b/.github/workflows/linux-ci.yml @@ -8,8 +8,7 @@ on: push: branches: - master - - release* - - feature* + - release/** paths: - "**" - "!.github/ISSUE_TEMPLATE/**" @@ -20,7 +19,6 @@ on: branches: - master - release/** - - feature* # Path filters for PRs need to go into the changes job concurrency: diff --git a/.github/workflows/macos-ci.yml b/.github/workflows/macos-ci.yml index 5a497114b90..47b4c73667a 100644 --- a/.github/workflows/macos-ci.yml +++ b/.github/workflows/macos-ci.yml @@ -7,7 +7,6 @@ on: branches: - master - release/** - - feature* paths: - "**" - "!.github/ISSUE_TEMPLATE/**" @@ -18,7 +17,6 @@ on: branches: - master - release/** - - feature* # Path filters for PRs need to go into the changes job concurrency: diff --git a/.github/workflows/windows-ci.yml b/.github/workflows/windows-ci.yml index 2801a4f2bdc..b0f65c15bba 100644 --- a/.github/workflows/windows-ci.yml +++ b/.github/workflows/windows-ci.yml @@ -5,7 +5,6 @@ on: branches: - master - release/** - - feature* paths: - "**" - "!.vsts-ci/misc-analysis.yml" @@ -17,7 +16,6 @@ on: branches: - master - release/** - - feature* # Path filters for PRs need to go into the changes job concurrency: From 7be439282abcca43b59bf091a742469d32a90e0b Mon Sep 17 00:00:00 2001 From: Travis Plunk Date: Wed, 5 Feb 2025 15:09:25 -0800 Subject: [PATCH 076/173] [release/v7.5]Fix GitHub Action filter overmatching (#24958) --- .github/action-filters.yml | 23 +++++++++++++++++++ .github/workflows/linux-ci.yml | 37 +++++++++++++++++-------------- .github/workflows/macos-ci.yml | 37 +++++++++++++++++-------------- .github/workflows/windows-ci.yml | 38 ++++++++++++++++++-------------- 4 files changed, 86 insertions(+), 49 deletions(-) create mode 100644 .github/action-filters.yml diff --git a/.github/action-filters.yml b/.github/action-filters.yml new file mode 100644 index 00000000000..9a61bc1947b --- /dev/null +++ b/.github/action-filters.yml @@ -0,0 +1,23 @@ +github: &github + - .github/actions/** + - .github/workflows/**-ci.yml +tools: &tools + - tools/buildCommon/** + - tools/ci.psm1 +props: &props + - '**.props' +tests: &tests + - test/powershell/** + - test/tools/** + - test/xUnit/** +mainSource: &mainSource + - src/** +buildModule: &buildModule + - build.psm1 +source: + - *github + - *tools + - *props + - *buildModule + - *mainSource + - *tests diff --git a/.github/workflows/linux-ci.yml b/.github/workflows/linux-ci.yml index 2ab1d8adab5..8f15e9a080d 100644 --- a/.github/workflows/linux-ci.yml +++ b/.github/workflows/linux-ci.yml @@ -46,22 +46,27 @@ jobs: outputs: source: ${{ steps.filter.outputs.source }} steps: - # For pull requests it's not necessary to checkout the code - - uses: dorny/paths-filter@v3 - id: filter - with: - filters: | - source: - - ".github/actions/**" - - ".github/workflows/linux-ci.yml" - - "**.props" - - build.psm1 - - src/** - - test/** - - tools/buildCommon/** - - tools/ci.psm1 - - "!test/common/markdown/**" - - "!test/perf/**" + - name: checkout + uses: actions/checkout@v4.1.0 + + # For pull requests it's not necessary to checkout the code + - uses: dorny/paths-filter@v3 + id: filter + with: + list-files: json + filters: .github/action-filters.yml + + - name: Capture outputs + run: | + "source: ${{ steps.filter.outputs.source }}" + "github: ${{ steps.filter.outputs.github }}" + "tools: ${{ steps.filter.outputs.tools }}" + "props: ${{ steps.filter.outputs.props }}" + "tests: ${{ steps.filter.outputs.tests }}" + "mainSource: ${{ steps.filter.outputs.mainSource }}" + "buildModule: ${{ steps.filter.outputs.buildModule }}" + shell: pwsh + ci_build: name: Build PowerShell runs-on: ubuntu-20.04 diff --git a/.github/workflows/macos-ci.yml b/.github/workflows/macos-ci.yml index 47b4c73667a..fafb6140285 100644 --- a/.github/workflows/macos-ci.yml +++ b/.github/workflows/macos-ci.yml @@ -45,22 +45,27 @@ jobs: outputs: source: ${{ steps.filter.outputs.source }} steps: - # For pull requests it's not necessary to checkout the code - - uses: dorny/paths-filter@v3 - id: filter - with: - filters: | - source: - - ".github/actions/**" - - ".github/workflows/macos-ci.yml" - - "**.props" - - build.psm1 - - src/** - - test/** - - tools/buildCommon/** - - tools/ci.psm1 - - "!test/common/markdown/**" - - "!test/perf/**" + - name: checkout + uses: actions/checkout@v4.1.0 + + # For pull requests it's not necessary to checkout the code + - uses: dorny/paths-filter@v3 + id: filter + with: + list-files: json + filters: .github/action-filters.yml + + - name: Capture outputs + run: | + "source: ${{ steps.filter.outputs.source }}" + "github: ${{ steps.filter.outputs.github }}" + "tools: ${{ steps.filter.outputs.tools }}" + "props: ${{ steps.filter.outputs.props }}" + "tests: ${{ steps.filter.outputs.tests }}" + "mainSource: ${{ steps.filter.outputs.mainSource }}" + "buildModule: ${{ steps.filter.outputs.buildModule }}" + shell: pwsh + ci_build: name: Build PowerShell runs-on: macos-latest diff --git a/.github/workflows/windows-ci.yml b/.github/workflows/windows-ci.yml index b0f65c15bba..c93983a765f 100644 --- a/.github/workflows/windows-ci.yml +++ b/.github/workflows/windows-ci.yml @@ -46,23 +46,27 @@ jobs: outputs: source: ${{ steps.filter.outputs.source }} steps: - # For pull requests it's not necessary to checkout the code - - uses: dorny/paths-filter@v3 - id: filter - with: - filters: | - source: - - ".github/actions/**" - - ".github/workflows/windows-ci.yml" - - "**.props" - - build.psm1 - - src/** - - test/** - - tools/buildCommon/** - - tools/ci.psm1 - - tools/WindowsCI.psm1 - - "!test/common/markdown/**" - - "!test/perf/**" + - name: checkout + uses: actions/checkout@v4.1.0 + + # For pull requests it's not necessary to checkout the code + - uses: dorny/paths-filter@v3 + id: filter + with: + list-files: json + filters: .github/action-filters.yml + + - name: Capture outputs + run: | + "source: ${{ steps.filter.outputs.source }}" + "github: ${{ steps.filter.outputs.github }}" + "tools: ${{ steps.filter.outputs.tools }}" + "props: ${{ steps.filter.outputs.props }}" + "tests: ${{ steps.filter.outputs.tests }}" + "mainSource: ${{ steps.filter.outputs.mainSource }}" + "buildModule: ${{ steps.filter.outputs.buildModule }}" + shell: pwsh + ci_build: name: Build PowerShell needs: changes From d9edb3d9bee020e24dc72effaa6335eded69ed9e Mon Sep 17 00:00:00 2001 From: PowerShell Team Bot <69177312+pwshBot@users.noreply.github.com> Date: Tue, 11 Feb 2025 16:25:35 -0800 Subject: [PATCH 077/173] [release/v7.5] Update branch for release - Transitive - true - minor (#24994) Co-authored-by: Travis Plunk --- DotnetRuntimeMetadata.json | 2 +- global.json | 2 +- ...oft.PowerShell.Commands.Diagnostics.csproj | 6 +- ...soft.PowerShell.Commands.Management.csproj | 4 +- ...crosoft.PowerShell.Commands.Utility.csproj | 6 +- ...crosoft.PowerShell.CoreCLR.Eventing.csproj | 2 +- .../Microsoft.PowerShell.SDK.csproj | 97 ++++++++-------- .../Microsoft.WSMan.Management.csproj | 4 +- .../System.Management.Automation.csproj | 24 ++-- .../BenchmarkDotNet.Extensions.csproj | 2 +- .../ResultsComparer/ResultsComparer.csproj | 2 +- ...soft.PowerShell.NamedPipeConnection.csproj | 26 ++--- test/tools/TestService/TestService.csproj | 94 ++++++++-------- test/tools/WebListener/WebListener.csproj | 6 +- tools/cgmanifest.json | 106 +++++++++--------- 15 files changed, 193 insertions(+), 190 deletions(-) diff --git a/DotnetRuntimeMetadata.json b/DotnetRuntimeMetadata.json index 644b79dcd7a..a019407c86a 100644 --- a/DotnetRuntimeMetadata.json +++ b/DotnetRuntimeMetadata.json @@ -4,7 +4,7 @@ "quality": "daily", "qualityFallback": "preview", "packageVersionPattern": "9.0.0-preview.6", - "sdkImageVersion": "9.0.102", + "sdkImageVersion": "9.0.200", "nextChannel": "9.0.0-preview.7", "azureFeed": "", "sdkImageOverride": "" diff --git a/global.json b/global.json index ee2876ea570..58b8fbe1952 100644 --- a/global.json +++ b/global.json @@ -1,5 +1,5 @@ { "sdk": { - "version": "9.0.102" + "version": "9.0.200" } } diff --git a/src/Microsoft.PowerShell.Commands.Diagnostics/Microsoft.PowerShell.Commands.Diagnostics.csproj b/src/Microsoft.PowerShell.Commands.Diagnostics/Microsoft.PowerShell.Commands.Diagnostics.csproj index d17d99b190d..7827aa70830 100644 --- a/src/Microsoft.PowerShell.Commands.Diagnostics/Microsoft.PowerShell.Commands.Diagnostics.csproj +++ b/src/Microsoft.PowerShell.Commands.Diagnostics/Microsoft.PowerShell.Commands.Diagnostics.csproj @@ -7,9 +7,11 @@ - + + + - + diff --git a/src/Microsoft.PowerShell.Commands.Management/Microsoft.PowerShell.Commands.Management.csproj b/src/Microsoft.PowerShell.Commands.Management/Microsoft.PowerShell.Commands.Management.csproj index a4cb9ad9dfb..645f15c9ab9 100644 --- a/src/Microsoft.PowerShell.Commands.Management/Microsoft.PowerShell.Commands.Management.csproj +++ b/src/Microsoft.PowerShell.Commands.Management/Microsoft.PowerShell.Commands.Management.csproj @@ -47,8 +47,8 @@ - - + + diff --git a/src/Microsoft.PowerShell.Commands.Utility/Microsoft.PowerShell.Commands.Utility.csproj b/src/Microsoft.PowerShell.Commands.Utility/Microsoft.PowerShell.Commands.Utility.csproj index bc15337da1f..b439f40ee1a 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/Microsoft.PowerShell.Commands.Utility.csproj +++ b/src/Microsoft.PowerShell.Commands.Utility/Microsoft.PowerShell.Commands.Utility.csproj @@ -13,7 +13,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive all
- + @@ -41,8 +41,8 @@ - - + + diff --git a/src/Microsoft.PowerShell.CoreCLR.Eventing/Microsoft.PowerShell.CoreCLR.Eventing.csproj b/src/Microsoft.PowerShell.CoreCLR.Eventing/Microsoft.PowerShell.CoreCLR.Eventing.csproj index bd8754bff4d..b5360a74c89 100644 --- a/src/Microsoft.PowerShell.CoreCLR.Eventing/Microsoft.PowerShell.CoreCLR.Eventing.csproj +++ b/src/Microsoft.PowerShell.CoreCLR.Eventing/Microsoft.PowerShell.CoreCLR.Eventing.csproj @@ -8,7 +8,7 @@ - + diff --git a/src/Microsoft.PowerShell.SDK/Microsoft.PowerShell.SDK.csproj b/src/Microsoft.PowerShell.SDK/Microsoft.PowerShell.SDK.csproj index 75492f49c6c..821d37e94ea 100644 --- a/src/Microsoft.PowerShell.SDK/Microsoft.PowerShell.SDK.csproj +++ b/src/Microsoft.PowerShell.SDK/Microsoft.PowerShell.SDK.csproj @@ -17,55 +17,55 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - + + + + + + - - - - - - - - - - - - - - + + + + + + + + + + + + + + - - + + + diff --git a/src/Microsoft.WSMan.Management/Microsoft.WSMan.Management.csproj b/src/Microsoft.WSMan.Management/Microsoft.WSMan.Management.csproj index c9d448a5091..d4705c002dc 100644 --- a/src/Microsoft.WSMan.Management/Microsoft.WSMan.Management.csproj +++ b/src/Microsoft.WSMan.Management/Microsoft.WSMan.Management.csproj @@ -7,11 +7,11 @@ - + - + diff --git a/src/System.Management.Automation/System.Management.Automation.csproj b/src/System.Management.Automation/System.Management.Automation.csproj index d0e81fddb6d..f93991c084c 100644 --- a/src/System.Management.Automation/System.Management.Automation.csproj +++ b/src/System.Management.Automation/System.Management.Automation.csproj @@ -32,25 +32,25 @@ - - - - - - + + + + + + - + - - - - + + + + - + diff --git a/test/perf/dotnet-tools/BenchmarkDotNet.Extensions/BenchmarkDotNet.Extensions.csproj b/test/perf/dotnet-tools/BenchmarkDotNet.Extensions/BenchmarkDotNet.Extensions.csproj index 427245af6d8..ece797fe296 100644 --- a/test/perf/dotnet-tools/BenchmarkDotNet.Extensions/BenchmarkDotNet.Extensions.csproj +++ b/test/perf/dotnet-tools/BenchmarkDotNet.Extensions/BenchmarkDotNet.Extensions.csproj @@ -13,7 +13,7 @@ - + diff --git a/test/perf/dotnet-tools/ResultsComparer/ResultsComparer.csproj b/test/perf/dotnet-tools/ResultsComparer/ResultsComparer.csproj index f4874cfa6d7..0932ca2dd6b 100644 --- a/test/perf/dotnet-tools/ResultsComparer/ResultsComparer.csproj +++ b/test/perf/dotnet-tools/ResultsComparer/ResultsComparer.csproj @@ -13,7 +13,7 @@ - + diff --git a/test/tools/NamedPipeConnection/src/code/Microsoft.PowerShell.NamedPipeConnection.csproj b/test/tools/NamedPipeConnection/src/code/Microsoft.PowerShell.NamedPipeConnection.csproj index 8bf1139db7d..92ef8c82ce4 100644 --- a/test/tools/NamedPipeConnection/src/code/Microsoft.PowerShell.NamedPipeConnection.csproj +++ b/test/tools/NamedPipeConnection/src/code/Microsoft.PowerShell.NamedPipeConnection.csproj @@ -17,21 +17,21 @@ - + - - - - - - - + + + + + + + - - - - - + + + + + diff --git a/test/tools/TestService/TestService.csproj b/test/tools/TestService/TestService.csproj index 68452edfdb5..f4224411514 100644 --- a/test/tools/TestService/TestService.csproj +++ b/test/tools/TestService/TestService.csproj @@ -15,56 +15,56 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - + + + + + - - - - - - - - + + + + + + + + - + diff --git a/test/tools/WebListener/WebListener.csproj b/test/tools/WebListener/WebListener.csproj index 7117e235557..b0eb19f4e37 100644 --- a/test/tools/WebListener/WebListener.csproj +++ b/test/tools/WebListener/WebListener.csproj @@ -7,9 +7,9 @@ - - + + - + diff --git a/tools/cgmanifest.json b/tools/cgmanifest.json index bb4fd3edb1c..bf50f1488b7 100644 --- a/tools/cgmanifest.json +++ b/tools/cgmanifest.json @@ -1,4 +1,5 @@ { + "$schema": "https://json.schemastore.org/component-detection-manifest.json", "Registrations": [ { "Component": { @@ -115,7 +116,7 @@ "Type": "nuget", "Nuget": { "Name": "Microsoft.Extensions.ObjectPool", - "Version": "8.0.12" + "Version": "8.0.13" } }, "DevelopmentDependency": false @@ -185,7 +186,7 @@ "Type": "nuget", "Nuget": { "Name": "Microsoft.Win32.Registry.AccessControl", - "Version": "9.0.1" + "Version": "9.0.2" } }, "DevelopmentDependency": false @@ -205,7 +206,7 @@ "Type": "nuget", "Nuget": { "Name": "Microsoft.Win32.SystemEvents", - "Version": "9.0.1" + "Version": "9.0.2" } }, "DevelopmentDependency": false @@ -215,7 +216,7 @@ "Type": "nuget", "Nuget": { "Name": "Microsoft.Windows.Compatibility", - "Version": "9.0.1" + "Version": "9.0.2" } }, "DevelopmentDependency": false @@ -235,7 +236,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.android-arm.runtime.native.System.IO.Ports", - "Version": "9.0.1" + "Version": "9.0.2" } }, "DevelopmentDependency": false @@ -245,7 +246,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.android-arm64.runtime.native.System.IO.Ports", - "Version": "9.0.1" + "Version": "9.0.2" } }, "DevelopmentDependency": false @@ -255,7 +256,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.android-x64.runtime.native.System.IO.Ports", - "Version": "9.0.1" + "Version": "9.0.2" } }, "DevelopmentDependency": false @@ -265,7 +266,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.android-x86.runtime.native.System.IO.Ports", - "Version": "9.0.1" + "Version": "9.0.2" } }, "DevelopmentDependency": false @@ -275,7 +276,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.linux-arm.runtime.native.System.IO.Ports", - "Version": "9.0.1" + "Version": "9.0.2" } }, "DevelopmentDependency": false @@ -285,7 +286,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.linux-arm64.runtime.native.System.IO.Ports", - "Version": "9.0.1" + "Version": "9.0.2" } }, "DevelopmentDependency": false @@ -295,7 +296,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.linux-bionic-arm64.runtime.native.System.IO.Ports", - "Version": "9.0.1" + "Version": "9.0.2" } }, "DevelopmentDependency": false @@ -305,7 +306,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.linux-bionic-x64.runtime.native.System.IO.Ports", - "Version": "9.0.1" + "Version": "9.0.2" } }, "DevelopmentDependency": false @@ -315,7 +316,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.linux-musl-arm.runtime.native.System.IO.Ports", - "Version": "9.0.1" + "Version": "9.0.2" } }, "DevelopmentDependency": false @@ -325,7 +326,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.linux-musl-arm64.runtime.native.System.IO.Ports", - "Version": "9.0.1" + "Version": "9.0.2" } }, "DevelopmentDependency": false @@ -335,7 +336,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.linux-musl-x64.runtime.native.System.IO.Ports", - "Version": "9.0.1" + "Version": "9.0.2" } }, "DevelopmentDependency": false @@ -345,7 +346,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.linux-x64.runtime.native.System.IO.Ports", - "Version": "9.0.1" + "Version": "9.0.2" } }, "DevelopmentDependency": false @@ -355,7 +356,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.maccatalyst-arm64.runtime.native.System.IO.Ports", - "Version": "9.0.1" + "Version": "9.0.2" } }, "DevelopmentDependency": false @@ -365,7 +366,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.maccatalyst-x64.runtime.native.System.IO.Ports", - "Version": "9.0.1" + "Version": "9.0.2" } }, "DevelopmentDependency": false @@ -385,7 +386,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.native.System.IO.Ports", - "Version": "9.0.1" + "Version": "9.0.2" } }, "DevelopmentDependency": false @@ -395,7 +396,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.osx-arm64.runtime.native.System.IO.Ports", - "Version": "9.0.1" + "Version": "9.0.2" } }, "DevelopmentDependency": false @@ -405,7 +406,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.osx-x64.runtime.native.System.IO.Ports", - "Version": "9.0.1" + "Version": "9.0.2" } }, "DevelopmentDependency": false @@ -465,7 +466,7 @@ "Type": "nuget", "Nuget": { "Name": "System.CodeDom", - "Version": "9.0.1" + "Version": "9.0.2" } }, "DevelopmentDependency": false @@ -485,7 +486,7 @@ "Type": "nuget", "Nuget": { "Name": "System.ComponentModel.Composition.Registration", - "Version": "9.0.1" + "Version": "9.0.2" } }, "DevelopmentDependency": false @@ -495,7 +496,7 @@ "Type": "nuget", "Nuget": { "Name": "System.ComponentModel.Composition", - "Version": "9.0.1" + "Version": "9.0.2" } }, "DevelopmentDependency": false @@ -505,7 +506,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Configuration.ConfigurationManager", - "Version": "9.0.1" + "Version": "9.0.2" } }, "DevelopmentDependency": false @@ -515,7 +516,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Data.Odbc", - "Version": "9.0.1" + "Version": "9.0.2" } }, "DevelopmentDependency": false @@ -525,7 +526,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Data.OleDb", - "Version": "9.0.1" + "Version": "9.0.2" } }, "DevelopmentDependency": false @@ -545,7 +546,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Diagnostics.DiagnosticSource", - "Version": "9.0.1" + "Version": "9.0.2" } }, "DevelopmentDependency": false @@ -555,7 +556,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Diagnostics.EventLog", - "Version": "9.0.1" + "Version": "9.0.2" } }, "DevelopmentDependency": false @@ -565,7 +566,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Diagnostics.PerformanceCounter", - "Version": "9.0.1" + "Version": "9.0.2" } }, "DevelopmentDependency": false @@ -575,7 +576,7 @@ "Type": "nuget", "Nuget": { "Name": "System.DirectoryServices.AccountManagement", - "Version": "9.0.1" + "Version": "9.0.2" } }, "DevelopmentDependency": false @@ -585,7 +586,7 @@ "Type": "nuget", "Nuget": { "Name": "System.DirectoryServices.Protocols", - "Version": "9.0.1" + "Version": "9.0.2" } }, "DevelopmentDependency": false @@ -595,7 +596,7 @@ "Type": "nuget", "Nuget": { "Name": "System.DirectoryServices", - "Version": "9.0.1" + "Version": "9.0.2" } }, "DevelopmentDependency": false @@ -605,7 +606,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Drawing.Common", - "Version": "9.0.1" + "Version": "9.0.2" } }, "DevelopmentDependency": false @@ -615,7 +616,7 @@ "Type": "nuget", "Nuget": { "Name": "System.IO.Packaging", - "Version": "9.0.1" + "Version": "9.0.2" } }, "DevelopmentDependency": false @@ -625,7 +626,7 @@ "Type": "nuget", "Nuget": { "Name": "System.IO.Ports", - "Version": "9.0.1" + "Version": "9.0.2" } }, "DevelopmentDependency": false @@ -635,7 +636,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Management", - "Version": "9.0.1" + "Version": "9.0.2" } }, "DevelopmentDependency": false @@ -645,7 +646,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Net.Http.WinHttpHandler", - "Version": "9.0.1" + "Version": "9.0.2" } }, "DevelopmentDependency": false @@ -675,7 +676,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Reflection.Context", - "Version": "9.0.1" + "Version": "9.0.2" } }, "DevelopmentDependency": false @@ -705,7 +706,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Runtime.Caching", - "Version": "9.0.1" + "Version": "9.0.2" } }, "DevelopmentDependency": false @@ -725,7 +726,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Security.Cryptography.Pkcs", - "Version": "9.0.1" + "Version": "9.0.2" } }, "DevelopmentDependency": false @@ -735,7 +736,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Security.Cryptography.ProtectedData", - "Version": "9.0.1" + "Version": "9.0.2" } }, "DevelopmentDependency": false @@ -745,7 +746,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Security.Cryptography.Xml", - "Version": "9.0.1" + "Version": "9.0.2" } }, "DevelopmentDependency": false @@ -755,7 +756,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Security.Permissions", - "Version": "9.0.1" + "Version": "9.0.2" } }, "DevelopmentDependency": false @@ -825,7 +826,7 @@ "Type": "nuget", "Nuget": { "Name": "System.ServiceModel.Syndication", - "Version": "9.0.1" + "Version": "9.0.2" } }, "DevelopmentDependency": false @@ -835,7 +836,7 @@ "Type": "nuget", "Nuget": { "Name": "System.ServiceProcess.ServiceController", - "Version": "9.0.1" + "Version": "9.0.2" } }, "DevelopmentDependency": false @@ -845,7 +846,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Speech", - "Version": "9.0.1" + "Version": "9.0.2" } }, "DevelopmentDependency": false @@ -855,7 +856,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Text.Encoding.CodePages", - "Version": "9.0.1" + "Version": "9.0.2" } }, "DevelopmentDependency": false @@ -865,7 +866,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Text.Encodings.Web", - "Version": "9.0.1" + "Version": "9.0.2" } }, "DevelopmentDependency": false @@ -875,7 +876,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Threading.AccessControl", - "Version": "9.0.1" + "Version": "9.0.2" } }, "DevelopmentDependency": false @@ -895,11 +896,10 @@ "Type": "nuget", "Nuget": { "Name": "System.Windows.Extensions", - "Version": "9.0.1" + "Version": "9.0.2" } }, "DevelopmentDependency": false } - ], - "$schema": "https://json.schemastore.org/component-detection-manifest.json" + ] } From 6a8705efc7db1a89671ff961e8ae5466f96e8e76 Mon Sep 17 00:00:00 2001 From: Justin Chung <124807742+jshigetomi@users.noreply.github.com> Date: Mon, 24 Mar 2025 13:19:34 -0500 Subject: [PATCH 078/173] [release/v7.5]Add GitHub Actions workflow to verify PR labels (#25159) Co-authored-by: Travis Plunk --- .github/workflows/labels.yml | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 .github/workflows/labels.yml diff --git a/.github/workflows/labels.yml b/.github/workflows/labels.yml new file mode 100644 index 00000000000..794ef64b213 --- /dev/null +++ b/.github/workflows/labels.yml @@ -0,0 +1,31 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + +name: Verify PR Labels + +on: + pull_request: + types: [opened, reopened, edited, labeled, unlabeled, synchronize] + +permissions: + contents: read + pull-requests: read + +jobs: + verify-labels: + if: github.repository_owner == 'PowerShell' + runs-on: ubuntu-latest + + steps: + - name: Check out the repository + uses: actions/checkout@v2 + + - name: Verify PR has label starting with 'cl-' + id: verify-labels + uses: actions/github-script@v6 + with: + script: | + const labels = context.payload.pull_request.labels.map(label => label.name.toLowerCase()); + if (!labels.some(label => label.startsWith('cl-'))) { + core.setFailed("Every PR must have at least one label starting with 'cl-'."); + } From 8cb9646d1a4097a5520254090b6bdb18f9bd0d50 Mon Sep 17 00:00:00 2001 From: PowerShell Team Bot <69177312+pwshBot@users.noreply.github.com> Date: Mon, 24 Mar 2025 20:47:48 -0700 Subject: [PATCH 079/173] [release/v7.5] Update SDK to `9.0.201` (#25163) --- DotnetRuntimeMetadata.json | 2 +- global.json | 2 +- ...oft.PowerShell.Commands.Diagnostics.csproj | 8 +- ...soft.PowerShell.Commands.Management.csproj | 4 +- ...crosoft.PowerShell.Commands.Utility.csproj | 6 +- ...crosoft.PowerShell.CoreCLR.Eventing.csproj | 2 +- .../Microsoft.PowerShell.SDK.csproj | 98 ++++++++-------- .../Microsoft.WSMan.Management.csproj | 4 +- src/Modules/PSGalleryModules.csproj | 2 +- .../System.Management.Automation.csproj | 24 ++-- .../BenchmarkDotNet.Extensions.csproj | 2 +- .../ResultsComparer/ResultsComparer.csproj | 2 +- ...soft.PowerShell.NamedPipeConnection.csproj | 24 ++-- test/tools/TestService/TestService.csproj | 94 ++++++++-------- test/tools/WebListener/WebListener.csproj | 6 +- tools/cgmanifest.json | 106 +++++++++--------- 16 files changed, 193 insertions(+), 193 deletions(-) diff --git a/DotnetRuntimeMetadata.json b/DotnetRuntimeMetadata.json index a019407c86a..e0869f46def 100644 --- a/DotnetRuntimeMetadata.json +++ b/DotnetRuntimeMetadata.json @@ -4,7 +4,7 @@ "quality": "daily", "qualityFallback": "preview", "packageVersionPattern": "9.0.0-preview.6", - "sdkImageVersion": "9.0.200", + "sdkImageVersion": "9.0.201", "nextChannel": "9.0.0-preview.7", "azureFeed": "", "sdkImageOverride": "" diff --git a/global.json b/global.json index 58b8fbe1952..4667f91bae2 100644 --- a/global.json +++ b/global.json @@ -1,5 +1,5 @@ { "sdk": { - "version": "9.0.200" + "version": "9.0.201" } } diff --git a/src/Microsoft.PowerShell.Commands.Diagnostics/Microsoft.PowerShell.Commands.Diagnostics.csproj b/src/Microsoft.PowerShell.Commands.Diagnostics/Microsoft.PowerShell.Commands.Diagnostics.csproj index 7827aa70830..d8ab11d9740 100644 --- a/src/Microsoft.PowerShell.Commands.Diagnostics/Microsoft.PowerShell.Commands.Diagnostics.csproj +++ b/src/Microsoft.PowerShell.Commands.Diagnostics/Microsoft.PowerShell.Commands.Diagnostics.csproj @@ -7,11 +7,11 @@ - - - + + + - + diff --git a/src/Microsoft.PowerShell.Commands.Management/Microsoft.PowerShell.Commands.Management.csproj b/src/Microsoft.PowerShell.Commands.Management/Microsoft.PowerShell.Commands.Management.csproj index 645f15c9ab9..5494c8fa316 100644 --- a/src/Microsoft.PowerShell.Commands.Management/Microsoft.PowerShell.Commands.Management.csproj +++ b/src/Microsoft.PowerShell.Commands.Management/Microsoft.PowerShell.Commands.Management.csproj @@ -47,8 +47,8 @@ - - + + diff --git a/src/Microsoft.PowerShell.Commands.Utility/Microsoft.PowerShell.Commands.Utility.csproj b/src/Microsoft.PowerShell.Commands.Utility/Microsoft.PowerShell.Commands.Utility.csproj index b439f40ee1a..797849a7e40 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/Microsoft.PowerShell.Commands.Utility.csproj +++ b/src/Microsoft.PowerShell.Commands.Utility/Microsoft.PowerShell.Commands.Utility.csproj @@ -13,7 +13,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive all - + @@ -41,8 +41,8 @@ - - + + diff --git a/src/Microsoft.PowerShell.CoreCLR.Eventing/Microsoft.PowerShell.CoreCLR.Eventing.csproj b/src/Microsoft.PowerShell.CoreCLR.Eventing/Microsoft.PowerShell.CoreCLR.Eventing.csproj index b5360a74c89..21912472c59 100644 --- a/src/Microsoft.PowerShell.CoreCLR.Eventing/Microsoft.PowerShell.CoreCLR.Eventing.csproj +++ b/src/Microsoft.PowerShell.CoreCLR.Eventing/Microsoft.PowerShell.CoreCLR.Eventing.csproj @@ -8,7 +8,7 @@ - + diff --git a/src/Microsoft.PowerShell.SDK/Microsoft.PowerShell.SDK.csproj b/src/Microsoft.PowerShell.SDK/Microsoft.PowerShell.SDK.csproj index 821d37e94ea..549224f457d 100644 --- a/src/Microsoft.PowerShell.SDK/Microsoft.PowerShell.SDK.csproj +++ b/src/Microsoft.PowerShell.SDK/Microsoft.PowerShell.SDK.csproj @@ -17,55 +17,55 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - + + + + + + - - - - - - - - - - - - - - + + + + + + + + + + + + + + - - + + - + diff --git a/src/Microsoft.WSMan.Management/Microsoft.WSMan.Management.csproj b/src/Microsoft.WSMan.Management/Microsoft.WSMan.Management.csproj index d4705c002dc..8c0f4165524 100644 --- a/src/Microsoft.WSMan.Management/Microsoft.WSMan.Management.csproj +++ b/src/Microsoft.WSMan.Management/Microsoft.WSMan.Management.csproj @@ -7,11 +7,11 @@ - + - + diff --git a/src/Modules/PSGalleryModules.csproj b/src/Modules/PSGalleryModules.csproj index 5f9f89a4563..cb799b441fc 100644 --- a/src/Modules/PSGalleryModules.csproj +++ b/src/Modules/PSGalleryModules.csproj @@ -13,7 +13,7 @@ - + diff --git a/src/System.Management.Automation/System.Management.Automation.csproj b/src/System.Management.Automation/System.Management.Automation.csproj index f93991c084c..d0ed69efaaf 100644 --- a/src/System.Management.Automation/System.Management.Automation.csproj +++ b/src/System.Management.Automation/System.Management.Automation.csproj @@ -32,25 +32,25 @@ - - - - - - + + + + + + - + - - - - + + + + - + diff --git a/test/perf/dotnet-tools/BenchmarkDotNet.Extensions/BenchmarkDotNet.Extensions.csproj b/test/perf/dotnet-tools/BenchmarkDotNet.Extensions/BenchmarkDotNet.Extensions.csproj index ece797fe296..8eb7c19141f 100644 --- a/test/perf/dotnet-tools/BenchmarkDotNet.Extensions/BenchmarkDotNet.Extensions.csproj +++ b/test/perf/dotnet-tools/BenchmarkDotNet.Extensions/BenchmarkDotNet.Extensions.csproj @@ -11,7 +11,7 @@ - + diff --git a/test/perf/dotnet-tools/ResultsComparer/ResultsComparer.csproj b/test/perf/dotnet-tools/ResultsComparer/ResultsComparer.csproj index 0932ca2dd6b..a7b60b6eb1b 100644 --- a/test/perf/dotnet-tools/ResultsComparer/ResultsComparer.csproj +++ b/test/perf/dotnet-tools/ResultsComparer/ResultsComparer.csproj @@ -11,7 +11,7 @@ - + diff --git a/test/tools/NamedPipeConnection/src/code/Microsoft.PowerShell.NamedPipeConnection.csproj b/test/tools/NamedPipeConnection/src/code/Microsoft.PowerShell.NamedPipeConnection.csproj index 92ef8c82ce4..d0aeab862f9 100644 --- a/test/tools/NamedPipeConnection/src/code/Microsoft.PowerShell.NamedPipeConnection.csproj +++ b/test/tools/NamedPipeConnection/src/code/Microsoft.PowerShell.NamedPipeConnection.csproj @@ -20,18 +20,18 @@ - - - - - - - + + + + + + + - - - - - + + + + + diff --git a/test/tools/TestService/TestService.csproj b/test/tools/TestService/TestService.csproj index f4224411514..65837bc7e48 100644 --- a/test/tools/TestService/TestService.csproj +++ b/test/tools/TestService/TestService.csproj @@ -15,56 +15,56 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - + + + + + - - - - - - - - + + + + + + + + - + diff --git a/test/tools/WebListener/WebListener.csproj b/test/tools/WebListener/WebListener.csproj index b0eb19f4e37..d2181a374d7 100644 --- a/test/tools/WebListener/WebListener.csproj +++ b/test/tools/WebListener/WebListener.csproj @@ -7,9 +7,9 @@ - - + + - + diff --git a/tools/cgmanifest.json b/tools/cgmanifest.json index bf50f1488b7..d73e68035dd 100644 --- a/tools/cgmanifest.json +++ b/tools/cgmanifest.json @@ -1,5 +1,4 @@ { - "$schema": "https://json.schemastore.org/component-detection-manifest.json", "Registrations": [ { "Component": { @@ -116,7 +115,7 @@ "Type": "nuget", "Nuget": { "Name": "Microsoft.Extensions.ObjectPool", - "Version": "8.0.13" + "Version": "8.0.14" } }, "DevelopmentDependency": false @@ -186,7 +185,7 @@ "Type": "nuget", "Nuget": { "Name": "Microsoft.Win32.Registry.AccessControl", - "Version": "9.0.2" + "Version": "9.0.3" } }, "DevelopmentDependency": false @@ -206,7 +205,7 @@ "Type": "nuget", "Nuget": { "Name": "Microsoft.Win32.SystemEvents", - "Version": "9.0.2" + "Version": "9.0.3" } }, "DevelopmentDependency": false @@ -216,7 +215,7 @@ "Type": "nuget", "Nuget": { "Name": "Microsoft.Windows.Compatibility", - "Version": "9.0.2" + "Version": "9.0.3" } }, "DevelopmentDependency": false @@ -236,7 +235,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.android-arm.runtime.native.System.IO.Ports", - "Version": "9.0.2" + "Version": "9.0.3" } }, "DevelopmentDependency": false @@ -246,7 +245,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.android-arm64.runtime.native.System.IO.Ports", - "Version": "9.0.2" + "Version": "9.0.3" } }, "DevelopmentDependency": false @@ -256,7 +255,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.android-x64.runtime.native.System.IO.Ports", - "Version": "9.0.2" + "Version": "9.0.3" } }, "DevelopmentDependency": false @@ -266,7 +265,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.android-x86.runtime.native.System.IO.Ports", - "Version": "9.0.2" + "Version": "9.0.3" } }, "DevelopmentDependency": false @@ -276,7 +275,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.linux-arm.runtime.native.System.IO.Ports", - "Version": "9.0.2" + "Version": "9.0.3" } }, "DevelopmentDependency": false @@ -286,7 +285,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.linux-arm64.runtime.native.System.IO.Ports", - "Version": "9.0.2" + "Version": "9.0.3" } }, "DevelopmentDependency": false @@ -296,7 +295,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.linux-bionic-arm64.runtime.native.System.IO.Ports", - "Version": "9.0.2" + "Version": "9.0.3" } }, "DevelopmentDependency": false @@ -306,7 +305,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.linux-bionic-x64.runtime.native.System.IO.Ports", - "Version": "9.0.2" + "Version": "9.0.3" } }, "DevelopmentDependency": false @@ -316,7 +315,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.linux-musl-arm.runtime.native.System.IO.Ports", - "Version": "9.0.2" + "Version": "9.0.3" } }, "DevelopmentDependency": false @@ -326,7 +325,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.linux-musl-arm64.runtime.native.System.IO.Ports", - "Version": "9.0.2" + "Version": "9.0.3" } }, "DevelopmentDependency": false @@ -336,7 +335,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.linux-musl-x64.runtime.native.System.IO.Ports", - "Version": "9.0.2" + "Version": "9.0.3" } }, "DevelopmentDependency": false @@ -346,7 +345,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.linux-x64.runtime.native.System.IO.Ports", - "Version": "9.0.2" + "Version": "9.0.3" } }, "DevelopmentDependency": false @@ -356,7 +355,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.maccatalyst-arm64.runtime.native.System.IO.Ports", - "Version": "9.0.2" + "Version": "9.0.3" } }, "DevelopmentDependency": false @@ -366,7 +365,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.maccatalyst-x64.runtime.native.System.IO.Ports", - "Version": "9.0.2" + "Version": "9.0.3" } }, "DevelopmentDependency": false @@ -386,7 +385,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.native.System.IO.Ports", - "Version": "9.0.2" + "Version": "9.0.3" } }, "DevelopmentDependency": false @@ -396,7 +395,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.osx-arm64.runtime.native.System.IO.Ports", - "Version": "9.0.2" + "Version": "9.0.3" } }, "DevelopmentDependency": false @@ -406,7 +405,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.osx-x64.runtime.native.System.IO.Ports", - "Version": "9.0.2" + "Version": "9.0.3" } }, "DevelopmentDependency": false @@ -466,7 +465,7 @@ "Type": "nuget", "Nuget": { "Name": "System.CodeDom", - "Version": "9.0.2" + "Version": "9.0.3" } }, "DevelopmentDependency": false @@ -486,7 +485,7 @@ "Type": "nuget", "Nuget": { "Name": "System.ComponentModel.Composition.Registration", - "Version": "9.0.2" + "Version": "9.0.3" } }, "DevelopmentDependency": false @@ -496,7 +495,7 @@ "Type": "nuget", "Nuget": { "Name": "System.ComponentModel.Composition", - "Version": "9.0.2" + "Version": "9.0.3" } }, "DevelopmentDependency": false @@ -506,7 +505,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Configuration.ConfigurationManager", - "Version": "9.0.2" + "Version": "9.0.3" } }, "DevelopmentDependency": false @@ -516,7 +515,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Data.Odbc", - "Version": "9.0.2" + "Version": "9.0.3" } }, "DevelopmentDependency": false @@ -526,7 +525,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Data.OleDb", - "Version": "9.0.2" + "Version": "9.0.3" } }, "DevelopmentDependency": false @@ -546,7 +545,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Diagnostics.DiagnosticSource", - "Version": "9.0.2" + "Version": "9.0.3" } }, "DevelopmentDependency": false @@ -556,7 +555,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Diagnostics.EventLog", - "Version": "9.0.2" + "Version": "9.0.3" } }, "DevelopmentDependency": false @@ -566,7 +565,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Diagnostics.PerformanceCounter", - "Version": "9.0.2" + "Version": "9.0.3" } }, "DevelopmentDependency": false @@ -576,7 +575,7 @@ "Type": "nuget", "Nuget": { "Name": "System.DirectoryServices.AccountManagement", - "Version": "9.0.2" + "Version": "9.0.3" } }, "DevelopmentDependency": false @@ -586,7 +585,7 @@ "Type": "nuget", "Nuget": { "Name": "System.DirectoryServices.Protocols", - "Version": "9.0.2" + "Version": "9.0.3" } }, "DevelopmentDependency": false @@ -596,7 +595,7 @@ "Type": "nuget", "Nuget": { "Name": "System.DirectoryServices", - "Version": "9.0.2" + "Version": "9.0.3" } }, "DevelopmentDependency": false @@ -606,7 +605,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Drawing.Common", - "Version": "9.0.2" + "Version": "9.0.3" } }, "DevelopmentDependency": false @@ -616,7 +615,7 @@ "Type": "nuget", "Nuget": { "Name": "System.IO.Packaging", - "Version": "9.0.2" + "Version": "9.0.3" } }, "DevelopmentDependency": false @@ -626,7 +625,7 @@ "Type": "nuget", "Nuget": { "Name": "System.IO.Ports", - "Version": "9.0.2" + "Version": "9.0.3" } }, "DevelopmentDependency": false @@ -636,7 +635,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Management", - "Version": "9.0.2" + "Version": "9.0.3" } }, "DevelopmentDependency": false @@ -646,7 +645,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Net.Http.WinHttpHandler", - "Version": "9.0.2" + "Version": "9.0.3" } }, "DevelopmentDependency": false @@ -676,7 +675,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Reflection.Context", - "Version": "9.0.2" + "Version": "9.0.3" } }, "DevelopmentDependency": false @@ -706,7 +705,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Runtime.Caching", - "Version": "9.0.2" + "Version": "9.0.3" } }, "DevelopmentDependency": false @@ -726,7 +725,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Security.Cryptography.Pkcs", - "Version": "9.0.2" + "Version": "9.0.3" } }, "DevelopmentDependency": false @@ -736,7 +735,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Security.Cryptography.ProtectedData", - "Version": "9.0.2" + "Version": "9.0.3" } }, "DevelopmentDependency": false @@ -746,7 +745,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Security.Cryptography.Xml", - "Version": "9.0.2" + "Version": "9.0.3" } }, "DevelopmentDependency": false @@ -756,7 +755,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Security.Permissions", - "Version": "9.0.2" + "Version": "9.0.3" } }, "DevelopmentDependency": false @@ -826,7 +825,7 @@ "Type": "nuget", "Nuget": { "Name": "System.ServiceModel.Syndication", - "Version": "9.0.2" + "Version": "9.0.3" } }, "DevelopmentDependency": false @@ -836,7 +835,7 @@ "Type": "nuget", "Nuget": { "Name": "System.ServiceProcess.ServiceController", - "Version": "9.0.2" + "Version": "9.0.3" } }, "DevelopmentDependency": false @@ -846,7 +845,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Speech", - "Version": "9.0.2" + "Version": "9.0.3" } }, "DevelopmentDependency": false @@ -856,7 +855,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Text.Encoding.CodePages", - "Version": "9.0.2" + "Version": "9.0.3" } }, "DevelopmentDependency": false @@ -866,7 +865,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Text.Encodings.Web", - "Version": "9.0.2" + "Version": "9.0.3" } }, "DevelopmentDependency": false @@ -876,7 +875,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Threading.AccessControl", - "Version": "9.0.2" + "Version": "9.0.3" } }, "DevelopmentDependency": false @@ -896,10 +895,11 @@ "Type": "nuget", "Nuget": { "Name": "System.Windows.Extensions", - "Version": "9.0.2" + "Version": "9.0.3" } }, "DevelopmentDependency": false } - ] + ], + "$schema": "https://json.schemastore.org/component-detection-manifest.json" } From aebf10e25521697198dcd0800b7ff2d710b549ae Mon Sep 17 00:00:00 2001 From: Travis Plunk Date: Tue, 25 Mar 2025 13:33:10 -0700 Subject: [PATCH 080/173] [release/v7.5]Cleanup old release pipelines (#25236) --- tools/releaseBuild/.gitignore | 1 - .../GenericLinuxFiles/PowerShellPackage.ps1 | 145 ---- .../PowerShellPackage.ps1 | 213 ------ .../dockerInstall.psm1 | 115 --- tools/releaseBuild/README.md | 55 -- .../AzArtifactFeed/PSGalleryToAzArtifacts.yml | 33 - tools/releaseBuild/azureDevOps/compliance.yml | 67 -- tools/releaseBuild/azureDevOps/diagram.puml | 107 --- tools/releaseBuild/azureDevOps/diagram.svg | 108 --- .../releaseBuild/azureDevOps/releaseBuild.yml | 379 ---------- .../azureDevOps/releasePipeline.yml | 673 ------------------ .../templates/SetVersionVariables.yml | 63 -- .../templates/checkAzureContainer.yml | 51 -- .../templates/cloneToOfficialPath.yml | 19 - .../azureDevOps/templates/compliance.yml | 124 ---- .../templates/compliance/apiscan.yml | 180 ----- .../templates/compliance/compliance.yml | 83 --- .../templates/compliance/generateNotice.yml | 90 --- .../templates/expand-compliance.yml | 12 - .../templates/global-tool-pkg-sbom.yml | 64 -- .../templates/insert-nuget-config-azfeed.yml | 8 - .../azureDevOps/templates/json.yml | 57 -- .../templates/linux-authenticode-sign.yml | 184 ----- .../azureDevOps/templates/linux-packaging.yml | 489 ------------- .../azureDevOps/templates/linux.yml | 313 -------- .../templates/mac-file-signing.yml | 121 ---- .../templates/mac-package-build.yml | 143 ---- .../templates/mac-package-signing.yml | 135 ---- .../azureDevOps/templates/mac.yml | 68 -- .../azureDevOps/templates/nuget-pkg-sbom.yml | 139 ---- .../azureDevOps/templates/nuget.yml | 290 -------- .../templates/release-BuildJson.yml | 102 --- .../templates/release-CopyGlobalTools.yml | 56 -- .../templates/release-CreateGitHubDraft.yml | 110 --- .../templates/release-GlobalToolTest.yml | 149 ---- .../templates/release-MakeContainerPublic.yml | 20 - .../templates/release-MsixBundle.yml | 81 --- .../release-PublishPackageMsftCom.yml | 57 -- .../templates/release-PublishSymbols.yml | 51 -- .../templates/release-ReleaseToNuGet.yml | 56 -- .../templates/release-SDKTests.yml | 148 ---- .../release-SetReleaseTagAndContainerName.yml | 26 - .../templates/release-UpdateDepsJson.yml | 71 -- .../templates/release-ValidateFxdPackage.yml | 92 --- .../templates/release-ValidatePackageBOM.yml | 49 -- .../release-ValidatePackageNames.yml | 93 --- .../templates/release/approvalJob.yml | 35 - .../azureDevOps/templates/shouldSign.yml | 29 - .../azureDevOps/templates/sign-build-file.yml | 328 --------- .../azureDevOps/templates/signBuildFiles.yml | 189 ----- .../azureDevOps/templates/step/finalize.yml | 5 - .../azureDevOps/templates/testartifacts.yml | 126 ---- .../templates/upload-final-results.yml | 17 - .../azureDevOps/templates/upload.yml | 83 --- .../azureDevOps/templates/vpackReleaseJob.yml | 113 --- .../windows-component-governance.yml | 71 -- .../templates/windows-hosted-build.yml | 84 --- .../templates/windows-package-signing.yml | 132 ---- .../templates/windows-packaging.yml | 369 ---------- .../releaseBuild/azureDevOps/vpackRelease.yml | 72 -- tools/releaseBuild/build.json | 336 --------- tools/releaseBuild/createComplianceFolder.ps1 | 59 -- tools/releaseBuild/generatePackgeSigning.ps1 | 112 --- .../macOS/PowerShellPackageVsts.ps1 | 143 ---- .../macOS/PowerShellPackageVsts.sh | 1 - tools/releaseBuild/macOS/createPowerShell.sh | 8 - tools/releaseBuild/packagesigning.xml | 6 - tools/releaseBuild/setReleaseTag.ps1 | 161 ----- tools/releaseBuild/setReleaseTag.sh | 1 - tools/releaseBuild/signing.xml | 49 -- tools/releaseBuild/updateSigning.ps1 | 46 -- tools/releaseBuild/vstsbuild.ps1 | 120 ---- tools/releaseBuild/vstsbuild.sh | 1 - 73 files changed, 8386 deletions(-) delete mode 100644 tools/releaseBuild/.gitignore delete mode 100644 tools/releaseBuild/Images/GenericLinuxFiles/PowerShellPackage.ps1 delete mode 100644 tools/releaseBuild/Images/microsoft_powershell_windowsservercore/PowerShellPackage.ps1 delete mode 100644 tools/releaseBuild/Images/microsoft_powershell_windowsservercore/dockerInstall.psm1 delete mode 100644 tools/releaseBuild/README.md delete mode 100644 tools/releaseBuild/azureDevOps/AzArtifactFeed/PSGalleryToAzArtifacts.yml delete mode 100644 tools/releaseBuild/azureDevOps/compliance.yml delete mode 100644 tools/releaseBuild/azureDevOps/diagram.puml delete mode 100644 tools/releaseBuild/azureDevOps/diagram.svg delete mode 100644 tools/releaseBuild/azureDevOps/releaseBuild.yml delete mode 100644 tools/releaseBuild/azureDevOps/releasePipeline.yml delete mode 100644 tools/releaseBuild/azureDevOps/templates/SetVersionVariables.yml delete mode 100644 tools/releaseBuild/azureDevOps/templates/checkAzureContainer.yml delete mode 100644 tools/releaseBuild/azureDevOps/templates/cloneToOfficialPath.yml delete mode 100644 tools/releaseBuild/azureDevOps/templates/compliance.yml delete mode 100644 tools/releaseBuild/azureDevOps/templates/compliance/apiscan.yml delete mode 100644 tools/releaseBuild/azureDevOps/templates/compliance/compliance.yml delete mode 100644 tools/releaseBuild/azureDevOps/templates/compliance/generateNotice.yml delete mode 100644 tools/releaseBuild/azureDevOps/templates/expand-compliance.yml delete mode 100644 tools/releaseBuild/azureDevOps/templates/global-tool-pkg-sbom.yml delete mode 100644 tools/releaseBuild/azureDevOps/templates/insert-nuget-config-azfeed.yml delete mode 100644 tools/releaseBuild/azureDevOps/templates/json.yml delete mode 100644 tools/releaseBuild/azureDevOps/templates/linux-authenticode-sign.yml delete mode 100644 tools/releaseBuild/azureDevOps/templates/linux-packaging.yml delete mode 100644 tools/releaseBuild/azureDevOps/templates/linux.yml delete mode 100644 tools/releaseBuild/azureDevOps/templates/mac-file-signing.yml delete mode 100644 tools/releaseBuild/azureDevOps/templates/mac-package-build.yml delete mode 100644 tools/releaseBuild/azureDevOps/templates/mac-package-signing.yml delete mode 100644 tools/releaseBuild/azureDevOps/templates/mac.yml delete mode 100644 tools/releaseBuild/azureDevOps/templates/nuget-pkg-sbom.yml delete mode 100644 tools/releaseBuild/azureDevOps/templates/nuget.yml delete mode 100644 tools/releaseBuild/azureDevOps/templates/release-BuildJson.yml delete mode 100644 tools/releaseBuild/azureDevOps/templates/release-CopyGlobalTools.yml delete mode 100644 tools/releaseBuild/azureDevOps/templates/release-CreateGitHubDraft.yml delete mode 100644 tools/releaseBuild/azureDevOps/templates/release-GlobalToolTest.yml delete mode 100644 tools/releaseBuild/azureDevOps/templates/release-MakeContainerPublic.yml delete mode 100644 tools/releaseBuild/azureDevOps/templates/release-MsixBundle.yml delete mode 100644 tools/releaseBuild/azureDevOps/templates/release-PublishPackageMsftCom.yml delete mode 100644 tools/releaseBuild/azureDevOps/templates/release-PublishSymbols.yml delete mode 100644 tools/releaseBuild/azureDevOps/templates/release-ReleaseToNuGet.yml delete mode 100644 tools/releaseBuild/azureDevOps/templates/release-SDKTests.yml delete mode 100644 tools/releaseBuild/azureDevOps/templates/release-SetReleaseTagAndContainerName.yml delete mode 100644 tools/releaseBuild/azureDevOps/templates/release-UpdateDepsJson.yml delete mode 100644 tools/releaseBuild/azureDevOps/templates/release-ValidateFxdPackage.yml delete mode 100644 tools/releaseBuild/azureDevOps/templates/release-ValidatePackageBOM.yml delete mode 100644 tools/releaseBuild/azureDevOps/templates/release-ValidatePackageNames.yml delete mode 100644 tools/releaseBuild/azureDevOps/templates/release/approvalJob.yml delete mode 100644 tools/releaseBuild/azureDevOps/templates/shouldSign.yml delete mode 100644 tools/releaseBuild/azureDevOps/templates/sign-build-file.yml delete mode 100644 tools/releaseBuild/azureDevOps/templates/signBuildFiles.yml delete mode 100644 tools/releaseBuild/azureDevOps/templates/step/finalize.yml delete mode 100644 tools/releaseBuild/azureDevOps/templates/testartifacts.yml delete mode 100644 tools/releaseBuild/azureDevOps/templates/upload-final-results.yml delete mode 100644 tools/releaseBuild/azureDevOps/templates/upload.yml delete mode 100644 tools/releaseBuild/azureDevOps/templates/vpackReleaseJob.yml delete mode 100644 tools/releaseBuild/azureDevOps/templates/windows-component-governance.yml delete mode 100644 tools/releaseBuild/azureDevOps/templates/windows-hosted-build.yml delete mode 100644 tools/releaseBuild/azureDevOps/templates/windows-package-signing.yml delete mode 100644 tools/releaseBuild/azureDevOps/templates/windows-packaging.yml delete mode 100644 tools/releaseBuild/azureDevOps/vpackRelease.yml delete mode 100644 tools/releaseBuild/build.json delete mode 100644 tools/releaseBuild/createComplianceFolder.ps1 delete mode 100644 tools/releaseBuild/generatePackgeSigning.ps1 delete mode 100644 tools/releaseBuild/macOS/PowerShellPackageVsts.ps1 delete mode 100644 tools/releaseBuild/macOS/PowerShellPackageVsts.sh delete mode 100644 tools/releaseBuild/macOS/createPowerShell.sh delete mode 100644 tools/releaseBuild/packagesigning.xml delete mode 100644 tools/releaseBuild/setReleaseTag.ps1 delete mode 100644 tools/releaseBuild/setReleaseTag.sh delete mode 100644 tools/releaseBuild/signing.xml delete mode 100644 tools/releaseBuild/updateSigning.ps1 delete mode 100644 tools/releaseBuild/vstsbuild.ps1 delete mode 100644 tools/releaseBuild/vstsbuild.sh diff --git a/tools/releaseBuild/.gitignore b/tools/releaseBuild/.gitignore deleted file mode 100644 index 0ff566888a7..00000000000 --- a/tools/releaseBuild/.gitignore +++ /dev/null @@ -1 +0,0 @@ -PSRelease/ diff --git a/tools/releaseBuild/Images/GenericLinuxFiles/PowerShellPackage.ps1 b/tools/releaseBuild/Images/GenericLinuxFiles/PowerShellPackage.ps1 deleted file mode 100644 index 2475dce7d89..00000000000 --- a/tools/releaseBuild/Images/GenericLinuxFiles/PowerShellPackage.ps1 +++ /dev/null @@ -1,145 +0,0 @@ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. - -# PowerShell Script to build and package PowerShell from specified form and branch -# Script is intented to use in Docker containers -# Ensure PowerShell is available in the provided image - -param ( - [string] $location = "/powershell", - - # Destination location of the package on docker host - [string] $destination = '/mnt', - - [ValidatePattern("^v\d+\.\d+\.\d+(-\w+(\.\d{1,2})?)?$")] - [ValidateNotNullOrEmpty()] - [string]$ReleaseTag, - - [switch]$TarX64, - [switch]$TarArm, - [switch]$TarArm64, - [switch]$TarMinSize, - [switch]$FxDependent, - [switch]$Alpine -) - -$releaseTagParam = @{} -if ($ReleaseTag) -{ - $releaseTagParam = @{ 'ReleaseTag' = $ReleaseTag } -} - -#Remove the initial 'v' from the ReleaseTag -$version = $ReleaseTag -replace '^v' -$semVersion = [System.Management.Automation.SemanticVersion] $version - -$metadata = Get-Content "$location/tools/metadata.json" -Raw | ConvertFrom-Json - -$LTS = $metadata.LTSRelease.Package - -Write-Verbose -Verbose -Message "LTS is set to: $LTS" - -function BuildPackages { - param( - [switch] $LTS - ) - - Push-Location - try { - Set-Location $location - Import-Module "$location/build.psm1" - Import-Module "$location/tools/packaging" - - Start-PSBootstrap -Package -NoSudo - - $buildParams = @{ Configuration = 'Release'; PSModuleRestore = $true; Restore = $true } - - if ($FxDependent.IsPresent) { - $projectAssetsZipName = 'linuxFxDependantProjectAssetssymbols.zip' - $buildParams.Add("Runtime", "fxdependent") - } elseif ($Alpine.IsPresent) { - $projectAssetsZipName = 'linuxAlpineProjectAssetssymbols.zip' - $buildParams.Add("Runtime", 'musl-x64') - } else { - # make the artifact name unique - $projectAssetsZipName = "linuxProjectAssets-$((Get-Date).Ticks)-symbols.zip" - } - - Start-PSBuild @buildParams @releaseTagParam - $options = Get-PSOptions - - if ($FxDependent) { - Start-PSPackage -Type 'fxdependent' @releaseTagParam -LTS:$LTS - } elseif ($Alpine) { - Start-PSPackage -Type 'tar-alpine' @releaseTagParam -LTS:$LTS - } else { - Start-PSPackage @releaseTagParam -LTS:$LTS - } - - if ($TarX64) { Start-PSPackage -Type tar @releaseTagParam -LTS:$LTS } - - if ($TarMinSize) { - Write-Verbose -Verbose "---- Min-Size ----" - Write-Verbose -Verbose "options.Output: $($options.Output)" - Write-Verbose -Verbose "options.Top $($options.Top)" - - $binDir = Join-Path -Path $options.Top -ChildPath 'bin' - Write-Verbose -Verbose "Remove $binDir, to get a clean build for min-size package" - Remove-Item -Path $binDir -Recurse -Force - - ## Build 'min-size' and create 'tar.gz' package for it. - $buildParams['ForMinimalSize'] = $true - Start-PSBuild @buildParams @releaseTagParam - Start-PSPackage -Type min-size @releaseTagParam -LTS:$LTS - } - - if ($TarArm) { - ## Build 'linux-arm' and create 'tar.gz' package for it. - ## Note that 'linux-arm' can only be built on Ubuntu environment. - Start-PSBuild -Configuration Release -Restore -Runtime linux-arm -PSModuleRestore @releaseTagParam - Start-PSPackage -Type tar-arm @releaseTagParam -LTS:$LTS - } - - if ($TarArm64) { - Start-PSBuild -Configuration Release -Restore -Runtime linux-arm64 -PSModuleRestore @releaseTagParam - Start-PSPackage -Type tar-arm64 @releaseTagParam -LTS:$LTS - } - } finally { - Pop-Location - } -} - -BuildPackages - -if ($LTS) { - Write-Verbose -Verbose "Packaging LTS" - BuildPackages -LTS -} - -$linuxPackages = Get-ChildItem "$location/powershell*" -Include *.deb,*.rpm,*.tar.gz - -foreach ($linuxPackage in $linuxPackages) -{ - $filePath = $linuxPackage.FullName - Write-Verbose "Copying $filePath to $destination" -Verbose - Copy-Item -Path $filePath -Destination $destination -Force -} - -Write-Verbose "Exporting project.assets files ..." -Verbose - -$projectAssetsCounter = 1 -$projectAssetsFolder = Join-Path -Path $destination -ChildPath 'projectAssets' -$projectAssetsZip = Join-Path -Path $destination -ChildPath $projectAssetsZipName -Get-ChildItem $location\project.assets.json -Recurse | ForEach-Object { - $subfolder = $_.FullName.Replace($location,'') - $subfolder.Replace('project.assets.json','') - $itemDestination = Join-Path -Path $projectAssetsFolder -ChildPath $subfolder - New-Item -Path $itemDestination -ItemType Directory -Force - $file = $_.FullName - Write-Verbose "Copying $file to $itemDestination" -Verbose - Copy-Item -Path $file -Destination "$itemDestination\" -Force - $projectAssetsCounter++ -} - -Compress-Archive -Path $projectAssetsFolder -DestinationPath $projectAssetsZip -Remove-Item -Path $projectAssetsFolder -Recurse -Force -ErrorAction SilentlyContinue diff --git a/tools/releaseBuild/Images/microsoft_powershell_windowsservercore/PowerShellPackage.ps1 b/tools/releaseBuild/Images/microsoft_powershell_windowsservercore/PowerShellPackage.ps1 deleted file mode 100644 index 41ec53fa495..00000000000 --- a/tools/releaseBuild/Images/microsoft_powershell_windowsservercore/PowerShellPackage.ps1 +++ /dev/null @@ -1,213 +0,0 @@ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. -[cmdletbinding(DefaultParameterSetName='default')] -# PowerShell Script to clone, build and package PowerShell from specified fork and branch -param ( - [string] $fork = 'powershell', - - [string] $branch = 'master', - - [string] $location = "$PWD\powershell", - - [string] $destination = "$env:WORKSPACE", - - [ValidateSet("win7-x64", "win7-x86", "win-arm", "win-arm64", "fxdependent", "fxdependent-win-desktop")] - [string] $Runtime = 'win7-x64', - - [switch] $ForMinimalSize, - - [switch] $Wait, - - [ValidatePattern("^v\d+\.\d+\.\d+(-\w+(\.\d{1,2})?)?$")] - [ValidateNotNullOrEmpty()] - [string] $ReleaseTag, - - [Parameter(Mandatory,ParameterSetName='IncludeSymbols')] - [switch] $Symbols, - - [Parameter(Mandatory,ParameterSetName='packageSigned')] - [ValidatePattern("-signed.zip$")] - [string] $BuildZip, - - [Parameter(Mandatory,ParameterSetName='ComponentRegistration')] - [switch] $ComponentRegistration -) - -$releaseTagParam = @{} -if ($ReleaseTag) -{ - $releaseTagParam = @{ 'ReleaseTag' = $ReleaseTag } -} - -if (-not $env:homedrive) -{ - Write-Verbose "fixing empty home paths..." -Verbose - $profileParts = $env:userprofile -split ':' - $env:homedrive = $profileParts[0]+':' - $env:homepath = $profileParts[1] -} - -if (! (Test-Path $destination)) -{ - Write-Verbose "Creating destination $destination" -Verbose - $null = New-Item -Path $destination -ItemType Directory -} - -Write-Verbose "homedrive : ${env:homedrive}" -Write-Verbose "homepath : ${env:homepath}" - -# Don't use CIM_PhysicalMemory, docker containers may cache old values -$memoryMB = (Get-CimInstance win32_computersystem).TotalPhysicalMemory /1MB -$requiredMemoryMB = 2048 -if ($memoryMB -lt $requiredMemoryMB) -{ - throw "Building powershell requires at least $requiredMemoryMB MiB of memory and only $memoryMB MiB is present." -} -Write-Verbose "Running with $memoryMB MB memory." -Verbose - -try -{ - Set-Location $location - - Import-Module "$location\build.psm1" -Force - Import-Module "$location\tools\packaging" -Force - $env:platform = $null - - Write-Verbose "Sync'ing Tags..." -Verbose - Sync-PSTags -AddRemoteIfMissing - - Write-Verbose "Bootstrapping powershell build..." -Verbose - Start-PSBootstrap -Force -Package -ErrorAction Stop - - if ($PSCmdlet.ParameterSetName -eq 'packageSigned') - { - Write-Verbose "Expanding signed build..." -Verbose - if($Runtime -like 'fxdependent*') - { - Expand-PSSignedBuild -BuildZip $BuildZip -SkipPwshExeCheck - } - else - { - Expand-PSSignedBuild -BuildZip $BuildZip - } - - Remove-Item -Path $BuildZip - } - else - { - Write-Verbose "Starting powershell build for RID: $Runtime and ReleaseTag: $ReleaseTag ..." -Verbose - $buildParams = @{ - ForMinimalSize = $ForMinimalSize - } - - if($Symbols) - { - $buildParams['NoPSModuleRestore'] = $true - } - else - { - $buildParams['PSModuleRestore'] = $true - } - - Start-PSBuild -Clean -Runtime $Runtime -Configuration Release @releaseTagParam @buildParams - } - - if ($ComponentRegistration) - { - Write-Verbose "Exporting project.assets files ..." -Verbose - - $projectAssetsCounter = 1 - $projectAssetsFolder = Join-Path -Path $destination -ChildPath 'projectAssets' - $projectAssetsZip = Join-Path -Path $destination -ChildPath 'windowsProjectAssetssymbols.zip' - Get-ChildItem $location\project.assets.json -Recurse | ForEach-Object { - $subfolder = $_.FullName.Replace($location,'') - $subfolder.Replace('project.assets.json','') - $itemDestination = Join-Path -Path $projectAssetsFolder -ChildPath $subfolder - New-Item -Path $itemDestination -ItemType Directory -Force > $null - $file = $_.FullName - Write-Verbose "Copying $file to $itemDestination" -Verbose - Copy-Item -Path $file -Destination "$itemDestination\" -Force - $projectAssetsCounter++ - } - - Compress-Archive -Path $projectAssetsFolder -DestinationPath $projectAssetsZip - Remove-Item -Path $projectAssetsFolder -Recurse -Force -ErrorAction SilentlyContinue - - return - } - - if ($Runtime -like 'fxdependent*') - { - $pspackageParams = @{'Type' = $Runtime} - } - else - { - ## Set the default package type. - $pspackageParams = @{'Type' = 'msi'; 'WindowsRuntime' = $Runtime} - if ($ForMinimalSize) - { - ## Special case for the minimal size self-contained package. - $pspackageParams['Type'] = 'min-size' - } - } - - if (!$Symbols -and $Runtime -notlike 'fxdependent*' -and !$ForMinimalSize) - { - Write-Verbose "Starting powershell packaging(msi)..." -Verbose - Start-PSPackage @pspackageParams @releaseTagParam - - $pspackageParams['Type']='msix' - Write-Verbose "Starting powershell packaging(msix)..." -Verbose - Start-PSPackage @pspackageParams @releaseTagParam - } - - if ($Runtime -like 'fxdependent*' -or $ForMinimalSize) - { - ## Add symbols for just like zip package. - $pspackageParams['IncludeSymbols']=$Symbols - Start-PSPackage @pspackageParams @releaseTagParam - - ## Copy the fxdependent Zip package to destination. - Get-ChildItem $location\PowerShell-*.zip | ForEach-Object { - $file = $_.FullName - Write-Verbose "Copying $file to $destination" -Verbose - Copy-Item -Path $file -Destination "$destination\" -Force - } - } - else - { - if (!$Symbols) { - $pspackageParams['Type'] = 'zip-pdb' - Write-Verbose "Starting powershell symbols packaging(zip)..." -Verbose - Start-PSPackage @pspackageParams @releaseTagParam - } - - $pspackageParams['Type']='zip' - $pspackageParams['IncludeSymbols']=$Symbols - Write-Verbose "Starting powershell packaging(zip)..." -Verbose - Start-PSPackage @pspackageParams @releaseTagParam - - Write-Verbose "Exporting packages ..." -Verbose - - Get-ChildItem $location\*.msi,$location\*.zip,$location\*.wixpdb,$location\*.msix,$location\*.exe | ForEach-Object { - $file = $_.FullName - Write-Verbose "Copying $file to $destination" -Verbose - Copy-Item -Path $file -Destination "$destination\" -Force - } - } -} -finally -{ - Write-Verbose "Beginning build clean-up..." -Verbose - if ($Wait) - { - $path = Join-Path $PSScriptRoot -ChildPath 'delete-to-continue.txt' - $null = New-Item -Path $path -ItemType File - Write-Verbose "Computer name: $env:COMPUTERNAME" -Verbose - Write-Verbose "Delete $path to exit." -Verbose - while(Test-Path -LiteralPath $path) - { - Start-Sleep -Seconds 60 - } - } -} diff --git a/tools/releaseBuild/Images/microsoft_powershell_windowsservercore/dockerInstall.psm1 b/tools/releaseBuild/Images/microsoft_powershell_windowsservercore/dockerInstall.psm1 deleted file mode 100644 index 311fed7e169..00000000000 --- a/tools/releaseBuild/Images/microsoft_powershell_windowsservercore/dockerInstall.psm1 +++ /dev/null @@ -1,115 +0,0 @@ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. -function Install-ChocolateyPackage -{ - param( - [Parameter(Mandatory=$true)] - [string] - $PackageName, - - [Parameter(Mandatory=$false)] - [string] - $Executable, - - [string[]] - $ArgumentList, - - [switch] - $Cleanup, - - [int] - $ExecutionTimeout = 2700, - - [string] - $Version - ) - - if(-not(Get-Command -Name Choco -ErrorAction SilentlyContinue)) - { - Write-Verbose "Installing Chocolatey provider..." -Verbose - Invoke-WebRequest https://chocolatey.org/install.ps1 -UseBasicParsing | Invoke-Expression - } - - Write-Verbose "Installing $PackageName..." -Verbose - $extraCommand = @() - if($Version) - { - $extraCommand += '--version', $version - } - choco install -y $PackageName --no-progress --execution-timeout=$ExecutionTimeout $ArgumentList $extraCommands - - if($executable) - { - Write-Verbose "Verifing $Executable is in path..." -Verbose - $exeSource = $null - $exeSource = Get-ChildItem -Path "$env:ProgramFiles\$Executable" -Recurse -ErrorAction SilentlyContinue | Select-Object -First 1 -ExpandProperty FullName - if(!$exeSource) - { - Write-Verbose "Falling back to x86 program files..." -Verbose - $exeSource = Get-ChildItem -Path "${env:ProgramFiles(x86)}\$Executable" -Recurse -ErrorAction SilentlyContinue | Select-Object -First 1 -ExpandProperty FullName - } - - # Don't search the chocolatey program data until more official locations have been searched - if(!$exeSource) - { - Write-Verbose "Falling back to chocolatey..." -Verbose - $exeSource = Get-ChildItem -Path "$env:ProgramData\chocolatey\$Executable" -Recurse -ErrorAction SilentlyContinue | Select-Object -First 1 -ExpandProperty FullName - } - - # all obvious locations are exhausted, use brute force and search from the root of the filesystem - if(!$exeSource) - { - Write-Verbose "Falling back to the root of the drive..." -Verbose - $exeSource = Get-ChildItem -Path "/$Executable" -Recurse -ErrorAction SilentlyContinue | Select-Object -First 1 -ExpandProperty FullName - } - - if(!$exeSource) - { - throw "$Executable not found" - } - - $exePath = Split-Path -Path $exeSource - Append-Path -path $exePath - } - - if($Cleanup.IsPresent) - { - Remove-Folder -Folder "$env:temp\chocolatey" - } -} - -function Append-Path -{ - param - ( - $path - ) - $machinePathString = [System.Environment]::GetEnvironmentVariable('path',[System.EnvironmentVariableTarget]::Machine) - $machinePath = $machinePathString -split ';' - - if($machinePath -inotcontains $path) - { - $newPath = "$machinePathString;$path" - Write-Verbose "Adding $path to path..." -Verbose - [System.Environment]::SetEnvironmentVariable('path',$newPath,[System.EnvironmentVariableTarget]::Machine) - Write-Verbose "Added $path to path." -Verbose - } - else - { - Write-Verbose "$path already in path." -Verbose - } -} - -function Remove-Folder -{ - param( - [string] - $Folder - ) - - Write-Verbose "Cleaning up $Folder..." -Verbose - $filter = Join-Path -Path $Folder -ChildPath * - [int]$measuredCleanupMB = (Get-ChildItem $filter -Recurse | Measure-Object -Property Length -Sum).Sum / 1MB - Remove-Item -Recurse -Force $filter -ErrorAction SilentlyContinue - Write-Verbose "Cleaned up $measuredCleanupMB MB from $Folder" -Verbose -} diff --git a/tools/releaseBuild/README.md b/tools/releaseBuild/README.md deleted file mode 100644 index 9b78e742b5f..00000000000 --- a/tools/releaseBuild/README.md +++ /dev/null @@ -1,55 +0,0 @@ -# Azure Dev Ops Release Builds - -## Requirements - -Docker must be installed to run any of the release builds. - -## Running Windows Release Builds Locally - -From PowerShell on Windows, run `.\vstsbuild.ps1 -ReleaseTag -Name `. - -For the package builds, run `.\vstsbuild.ps1 -ReleaseTag -Name -BuildPath -SignedFilesPath ` - -Windows Build Names: - -* `win7-x64-symbols` - * Builds the Windows x64 Zip with symbols -* `win7-x86-symbols` - * Builds the Windows x86 Zip with symbols -* `win7-arm-symbols` - * Builds the Windows ARM Zip with symbols -* `win7-arm64-symbols` - * Builds the Windows ARM64 Zip with symbols -* `win7-fxdependent-symbols` - * Builds the Windows FxDependent Zip with symbols -* `win7-x64-package` - * Builds the Windows x64 packages -* `win7-x86-package` - * Builds the Windows x86 packages -* `win7-arm-package` - * Builds the Windows ARM packages -* `win7-arm64-package` - * Builds the Windows ARM64 packages -* `win7-fxdependent-package` - * Builds the Windows FxDependent packages - -## Running Linux Release Builds Locally - -From PowerShell on Linux or macOS, run `.\vstsbuild.ps1 -ReleaseTag -Name `. - -Linux Build Names: - -* `deb` - * Builds the Debian Packages, ARM32 and ARM64. -* `alpine` - * Builds the Alpine Package -* `rpm` - * Builds the RedHat variant Package - -## Azure Dev Ops Build - -The release build is fairly complicated. The definition is at `./azureDevOps/releaseBuild.yml`. - -Here is a diagram of the build: - -[![Release Build diagram](https://raw.githubusercontent.com/PowerShell/PowerShell/master/tools/releaseBuild/azureDevOps/diagram.svg?sanitize=true)](https://raw.githubusercontent.com/PowerShell/PowerShell/master/tools/releaseBuild/azureDevOps/diagram.svg?sanitize=true) diff --git a/tools/releaseBuild/azureDevOps/AzArtifactFeed/PSGalleryToAzArtifacts.yml b/tools/releaseBuild/azureDevOps/AzArtifactFeed/PSGalleryToAzArtifacts.yml deleted file mode 100644 index da26ea6d348..00000000000 --- a/tools/releaseBuild/azureDevOps/AzArtifactFeed/PSGalleryToAzArtifacts.yml +++ /dev/null @@ -1,33 +0,0 @@ -# Sync packages from PSGallery to Azure DevOps Artifacts feed - -resources: -- repo: self - clean: true - -pool: - name: 1es - demands: - - ImageOverride -equals PSMMS2019-Minimal - -steps: - - pwsh: | - $minVer = [version]"2.2.3" - $curVer = Get-Module PowerShellGet -ListAvailable | Select-Object -First 1 | ForEach-Object Version - if (-not $curVer -or $curVer -lt $minVer) { - Install-Module -Name PowerShellGet -MinimumVersion 2.2.3 -Force - } - displayName: Update PSGet and PackageManagement - condition: succeededOrFailed() - - - pwsh: | - Write-Verbose -Verbose "Packages to upload" - if(Test-Path $(Build.ArtifactStagingDirectory)) { Get-ChildItem "$(Build.ArtifactStagingDirectory)/*.nupkg" | ForEach-Object { $_.FullName }} - displayName: List packages to upload - condition: succeededOrFailed() - - - task: NuGetCommand@2 - displayName: 'NuGet push' - inputs: - command: push - publishVstsFeed: 'pscore-release' - publishFeedCredentials: 'AzArtifactsFeed' diff --git a/tools/releaseBuild/azureDevOps/compliance.yml b/tools/releaseBuild/azureDevOps/compliance.yml deleted file mode 100644 index 3624f1e1081..00000000000 --- a/tools/releaseBuild/azureDevOps/compliance.yml +++ /dev/null @@ -1,67 +0,0 @@ -name: Compliance-$(Build.BuildId) - -trigger: none -pr: none - -schedules: - # Chrontab format, see https://en.wikipedia.org/wiki/Cron - # this is in UTC - - cron: '0 13 * * *' - branches: - include: - - master - -resources: - repositories: - - repository: ComplianceRepo - type: github - endpoint: ComplianceGHRepo - name: PowerShell/compliance - ref: master - -parameters: -- name: InternalSDKBlobURL - displayName: URL to the blob havibg internal .NET SDK - type: string - default: ' ' - -variables: - - name: DOTNET_CLI_TELEMETRY_OPTOUT - value: 1 - - name: POWERSHELL_TELEMETRY_OPTOUT - value: 1 - - name: nugetMultiFeedWarnLevel - value: none - - name: NugetSecurityAnalysisWarningLevel - value: none - # Defines the variables AzureFileCopySubscription, StorageAccount, StorageAccountKey, StorageResourceGroup, StorageSubscriptionName - - group: 'Azure Blob variable group' - # Defines the variables CgPat, CgOrganization, and CgProject - - group: 'ComponentGovernance' - - group: 'PoolNames' - - name: __DOTNET_RUNTIME_FEED - value: ${{ parameters.InternalSDKBlobURL }} - - -stages: - - stage: compliance - displayName: 'Compliance' - dependsOn: [] - jobs: - - template: templates/compliance/compliance.yml - parameters: - parentJobs: [] - - stage: APIScan - displayName: 'ApiScan' - dependsOn: [] - jobs: - - template: templates/compliance/apiscan.yml - parameters: - parentJobs: [] - - stage: notice - displayName: Generate Notice File - dependsOn: [] - jobs: - - template: templates/compliance/generateNotice.yml - parameters: - parentJobs: [] diff --git a/tools/releaseBuild/azureDevOps/diagram.puml b/tools/releaseBuild/azureDevOps/diagram.puml deleted file mode 100644 index ade53b11b9c..00000000000 --- a/tools/releaseBuild/azureDevOps/diagram.puml +++ /dev/null @@ -1,107 +0,0 @@ -@startuml - -folder "Linux Builds" as LinuxBuilds { - ' Define the build tasks as business processes - agent "DEB" as BuildDEB - agent "RPM" as BuildRPM - agent "Alpine" as BuildAlpine - agent "Linux-FxDependent" as BuildLinuxFx - -} - -agent "macOS Build" as BuildMac - -agent "Upload build metadata" as BuildMetadata - -folder "Windows Builds" as WinBuilds { - agent "x64" as BuildWinX64 - agent "x86" as BuildWinX86 - agent "arm32" as BuildWinArm32 - agent "arm64" as BuildWinArm64 - agent "FxDependent" as BuildWinFx -} - -agent "ComponentRegistration" as BuildCG - -folder "Linux Package Scanning and Upload" as PkgScanUploadLinux { - agent "DEB" as UploadDEB - agent "RPM" as UploadRPM - agent "Alpine" as UploadAlpine - agent "Linux-FxDependent" as UploadLinuxFx -} - -folder "Package Signing and Upload" as PkgSignUpload { - agent "macOS" as SignMac - - agent "Windows" as SignWin -} - -folder "Build Test Artifacts" as TestArtifacts { - agent "Windows" as WinTest - agent "Linux" as LinuxTest - agent "Linux-ARM" as LinuxArmTest - agent "Linux-ARM64" as LinuxArm64Test -} - -agent "Compliance" as Compliance - - -agent "Create SDK and Global Tool and Upload" as BuildNuGet - - -' Define finishing the build as a goal filled -control "Finish" as Finish -control "Start" as Start - -' map the various Upload task dependencies -BuildDEB -down-> UploadDEB -BuildRPM -down-> UploadRPM -BuildLinuxFx -down-> UploadLinuxFx -BuildAlpine -down-> UploadAlpine - -' map all of the SignMac task dependencies -BuildMac -down-> SignMac - -' map all of the SignWin task dependencies -WinBuilds -down-> SignWin -'BuildWinX64 -down-> SignWin -'BuildWinX86 -down-> SignWin -'BuildWinArm32 -down-> SignWin -'BuildWinArm64 -down-> SignWin -'BuildWinFx -down-> SignWin - -' map all of the Compliance task dependencies -BuildWinX86 -down-> Compliance -BuildWinX64 -down-> Compliance -BuildWinFx -down-> Compliance - -PkgSignUpload -down-> BuildNuGet -LinuxBuilds -down-> BuildNuGet - -' map all leafs to finish -Compliance ~~ Finish -UploadAlpine ~~ Finish -UploadDEB ~~ Finish -UploadRPM ~~ Finish -UploadLinuxFx ~~ Finish -SignMac ~~ Finish -BuildCG ~~ Finish -BuildNuGet ~~ Finish -TestArtifacts ~~ Finish -BuildMetadata ~~ Finish - -Start ~~ BuildDEB -Start ~~ BuildRPM -Start ~~ BuildAlpine -Start ~~ BuildLinuxFx -Start ~~ BuildMac -Start ~~ BuildWinX64 -Start ~~ BuildWinX86 -Start ~~ BuildWinFx -Start ~~ BuildWinArm32 -Start ~~ BuildWinArm64 -Start ~~ BuildCG -Start ~~ TestArtifacts -Start ~~ BuildMetadata - -@enduml diff --git a/tools/releaseBuild/azureDevOps/diagram.svg b/tools/releaseBuild/azureDevOps/diagram.svg deleted file mode 100644 index 024128bf988..00000000000 --- a/tools/releaseBuild/azureDevOps/diagram.svg +++ /dev/null @@ -1,108 +0,0 @@ -Linux BuildsWindows BuildsLinux Package Scanning and UploadPackage Signing and UploadBuild Test ArtifactsDEBRPMAlpineLinux-FxDependentx64x86arm32arm64FxDependentDEBRPMAlpineLinux-FxDependentmacOSWindowsWindowsLinuxLinux-ARMLinux-ARM64macOS BuildUpload build metadataComponentRegistrationComplianceCreate SDK and Global Tool and UploadFinishStart \ No newline at end of file diff --git a/tools/releaseBuild/azureDevOps/releaseBuild.yml b/tools/releaseBuild/azureDevOps/releaseBuild.yml deleted file mode 100644 index 3be90bbefbc..00000000000 --- a/tools/releaseBuild/azureDevOps/releaseBuild.yml +++ /dev/null @@ -1,379 +0,0 @@ -name: UnifiedPackageBuild-$(Build.BuildId) -trigger: - branches: - include: - - master - - release* -pr: - branches: - include: - - master - - release* - -parameters: - - name: ForceAzureBlobDelete - displayName: Delete Azure Blob - type: string - values: - - true - - false - default: false - - name: InternalSDKBlobURL - displayName: URL to the blob having internal .NET SDK - type: string - default: ' ' - -resources: - repositories: - - repository: ComplianceRepo - type: github - endpoint: ComplianceGHRepo - name: PowerShell/compliance - ref: master - -variables: - - name: PS_RELEASE_BUILD - value: 1 - - name: DOTNET_CLI_TELEMETRY_OPTOUT - value: 1 - - name: POWERSHELL_TELEMETRY_OPTOUT - value: 1 - - name: nugetMultiFeedWarnLevel - value: none - - name: NugetSecurityAnalysisWarningLevel - value: none - # Prevents auto-injection of nuget-security-analysis@0 - - name: skipNugetSecurityAnalysis - value: true - - name: branchCounterKey - value: $[format('{0:yyyyMMdd}-{1}', pipeline.startTime,variables['Build.SourceBranch'])] - - name: branchCounter - value: $[counter(variables['branchCounterKey'], 1)] - - name: ForceAzureBlobDelete - value: ${{ parameters.ForceAzureBlobDelete }} - - name: Github_Build_Repository_Uri - value: https://github.com/powershell/powershell - - name: SBOMGenerator_Formats - value: spdx:2.2 - - name: BUILDSECMON_OPT_IN - value: true - - group: PoolNames - - name: __DOTNET_RUNTIME_FEED - value: ${{ parameters.InternalSDKBlobURL }} - -stages: - - stage: prep - jobs: - - template: templates/checkAzureContainer.yml - - - stage: macos - dependsOn: ['prep'] - jobs: - - template: templates/mac.yml - parameters: - buildArchitecture: x64 - - - template: templates/mac.yml - parameters: - buildArchitecture: arm64 - - - stage: linux - dependsOn: ['prep'] - jobs: - - template: templates/linux.yml - parameters: - buildName: deb - - - template: templates/linux.yml - parameters: - buildName: rpm - parentJob: build_deb - - - template: templates/linux.yml - parameters: - buildName: fxdependent - parentJob: build_deb - - - template: templates/linux.yml - parameters: - buildName: alpine - - - stage: windows - dependsOn: ['prep'] - jobs: - - template: templates/windows-hosted-build.yml - parameters: - Architecture: x64 - - - template: templates/windows-hosted-build.yml - parameters: - Architecture: x64 - BuildConfiguration: minSize - - - template: templates/windows-hosted-build.yml - parameters: - Architecture: x86 - - - template: templates/windows-hosted-build.yml - parameters: - Architecture: arm64 - - - template: templates/windows-hosted-build.yml - parameters: - Architecture: fxdependent - - - template: templates/windows-hosted-build.yml - parameters: - Architecture: fxdependentWinDesktop - - - stage: SignFiles - displayName: Sign files - dependsOn: ['windows', 'linux', 'macos'] - jobs: - - template: templates/mac-file-signing.yml - parameters: - buildArchitecture: x64 - - - template: templates/mac-file-signing.yml - parameters: - buildArchitecture: arm64 - - - job: SignFilesWinLinux - pool: - name: $(windowsPool) - demands: - - ImageOverride -equals PSMMS2019-Secure - displayName: Sign files - - variables: - - group: ESRP - - name: runCodesignValidationInjection - value: false - - name: NugetSecurityAnalysisWarningLevel - value: none - - name: repoFolder - value: PowerShell - - name: repoRoot - value: $(Agent.BuildDirectory)\$(repoFolder) - - name: complianceRepoFolder - value: compliance - - strategy: - matrix: - linux-x64: - runtime: linux-x64 - unsignedBuildArtifactContainer: pwshLinuxBuild.tar.gz - unsignedBuildArtifactName: pwshLinuxBuild.tar.gz - signedBuildArtifactName: pwshLinuxBuild.tar.gz - signedArtifactContainer: authenticode-signed - linux-x64-Alpine: - runtime: linux-x64-Alpine - unsignedBuildArtifactContainer: pwshLinuxBuildAlpine.tar.gz - unsignedBuildArtifactName: pwshLinuxBuild.tar.gz - signedBuildArtifactName: pwshLinuxBuildAlpine.tar.gz - signedArtifactContainer: authenticode-signed - linux-x64-Alpine-Fxdependent: - runtime: linux-x64-Alpine-Fxdependent - unsignedBuildArtifactContainer: pwshAlpineFxdBuildAmd64.tar.gz - unsignedBuildArtifactName: pwshAlpineFxdBuildAmd64.tar.gz - signedBuildArtifactName: pwshAlpineFxdBuildAmd64.tar.gz - signedArtifactContainer: authenticode-signed - linux-arm32: - runtime: linux-arm32 - unsignedBuildArtifactContainer: pwshLinuxBuildArm32.tar.gz - unsignedBuildArtifactName: pwshLinuxBuildArm32.tar.gz - signedBuildArtifactName: pwshLinuxBuildArm32.tar.gz - signedArtifactContainer: authenticode-signed - linux-arm64: - runtime: linux-arm64 - unsignedBuildArtifactContainer: pwshLinuxBuildArm64.tar.gz - unsignedBuildArtifactName: pwshLinuxBuildArm64.tar.gz - signedBuildArtifactName: pwshLinuxBuildArm64.tar.gz - signedArtifactContainer: authenticode-signed - linux-fxd: - runtime: linux-fxd - unsignedBuildArtifactContainer: pwshLinuxBuildFxdependent.tar.gz - unsignedBuildArtifactName: pwshLinuxBuild.tar.gz - signedBuildArtifactName: pwshLinuxBuildFxdependent.tar.gz - signedArtifactContainer: authenticode-signed - linux-mariner: - runtime: linux-mariner - unsignedBuildArtifactContainer: pwshMarinerBuildAmd64.tar.gz - unsignedBuildArtifactName: pwshMarinerBuildAmd64.tar.gz - signedBuildArtifactName: pwshMarinerBuildAmd64.tar.gz - signedArtifactContainer: authenticode-signed - linux-arm64-mariner: - runtime: linux-arm64-mariner - unsignedBuildArtifactContainer: pwshMarinerBuildArm64.tar.gz - unsignedBuildArtifactName: pwshMarinerBuildArm64.tar.gz - signedBuildArtifactName: pwshMarinerBuildArm64.tar.gz - signedArtifactContainer: authenticode-signed - linux-minsize: - runtime: linux-minsize - unsignedBuildArtifactContainer: pwshLinuxBuildMinSize.tar.gz - unsignedBuildArtifactName: pwshLinuxBuildMinSize.tar.gz - signedBuildArtifactName: pwshLinuxBuildMinSize.tar.gz - signedArtifactContainer: authenticode-signed - win-x64: - runtime: win-x64 - unsignedBuildArtifactContainer: results - unsignedBuildArtifactName: '**/*-symbols-win-x64.zip' - signedBuildArtifactName: '-symbols-win-x64-signed.zip' - signedArtifactContainer: results - win-x86: - runtime: win-x86 - unsignedBuildArtifactContainer: results - unsignedBuildArtifactName: '**/*-symbols-win-x86.zip' - signedBuildArtifactName: '-symbols-win-x86-signed.zip' - signedArtifactContainer: results - win-arm64: - runtime: win-arm64 - unsignedBuildArtifactContainer: results - unsignedBuildArtifactName: '**/*-symbols-win-arm64.zip' - signedBuildArtifactName: '-symbols-win-arm64-signed.zip' - signedArtifactContainer: results - win-x64-gc: - runtime: win-x64-gc - unsignedBuildArtifactContainer: results - unsignedBuildArtifactName: '**/*-symbols-win-x64-gc.zip' - signedBuildArtifactName: '-symbols-win-x64-gc-signed.zip' - signedArtifactContainer: results - win-fxdependent: - runtime: win-fxdependent - unsignedBuildArtifactContainer: results - unsignedBuildArtifactName: '**/*-symbols-win-fxdependent.zip' - signedBuildArtifactName: '-symbols-win-fxdependent-signed.zip' - signedArtifactContainer: results - win-fxdependentWinDesktop: - runtime: win-fxdependentWinDesktop - unsignedBuildArtifactContainer: results - unsignedBuildArtifactName: '**/*-symbols-win-fxdependentWinDesktop.zip' - signedBuildArtifactName: '-symbols-win-fxdependentWinDesktop-signed.zip' - signedArtifactContainer: results - steps: - - template: templates/sign-build-file.yml - - - stage: mac_packaging - displayName: macOS packaging - dependsOn: ['SignFiles'] - jobs: - - template: templates/mac-package-build.yml - parameters: - buildArchitecture: x64 - - - template: templates/mac-package-build.yml - parameters: - buildArchitecture: arm64 - - - stage: linux_packaging - displayName: Linux Packaging - dependsOn: ['SignFiles'] - jobs: - - template: templates/linux-packaging.yml - parameters: - buildName: deb - - - template: templates/linux-packaging.yml - parameters: - buildName: rpm - uploadDisplayName: Upload and Sign - - - template: templates/linux-packaging.yml - parameters: - buildName: alpine - - - template: templates/linux-packaging.yml - parameters: - buildName: fxdependent - - - stage: win_packaging - displayName: Windows Packaging - dependsOn: ['SignFiles'] - jobs: - - template: templates/windows-packaging.yml - parameters: - Architecture: x64 - parentJob: build_windows_x64_release - - - template: templates/windows-packaging.yml - parameters: - Architecture: x64 - BuildConfiguration: minSize - parentJob: build_windows_x64_minSize - - - template: templates/windows-packaging.yml - parameters: - Architecture: x86 - parentJob: build_windows_x86_release - - - template: templates/windows-packaging.yml - parameters: - Architecture: arm64 - parentJob: build_windows_arm64_release - - - template: templates/windows-packaging.yml - parameters: - Architecture: fxdependent - parentJob: build_windows_fxdependent_release - - - template: templates/windows-packaging.yml - parameters: - Architecture: fxdependentWinDesktop - parentJob: build_windows_fxdependentWinDesktop_release - - - stage: package_signing - displayName: Package Signing - dependsOn: ['mac_packaging', 'linux_packaging', 'win_packaging'] - jobs: - - template: templates/windows-package-signing.yml - - - template: templates/mac-package-signing.yml - parameters: - buildArchitecture: x64 - - - template: templates/mac-package-signing.yml - parameters: - buildArchitecture: arm64 - - - stage: nuget_and_json - displayName: NuGet Packaging and Build Json - dependsOn: ['package_signing'] - jobs: - - template: templates/nuget.yml - - template: templates/json.yml - - # This is done late so that we dont use resources before the big signing and packaging tasks. - - stage: compliance - dependsOn: ['package_signing'] - jobs: - - template: templates/compliance.yml - - - stage: test_and_release_artifacts - displayName: Test and Release Artifacts - dependsOn: ['prep'] - jobs: - - template: templates/testartifacts.yml - - - job: release_json - displayName: Create and Upload release.json - pool: - name: $(windowsPool) - demands: - - ImageOverride -equals PSMMS2019-Secure - steps: - - checkout: self - clean: true - - template: templates/SetVersionVariables.yml - parameters: - ReleaseTagVar: $(ReleaseTagVar) - - - powershell: | - $metadata = Get-Content '$(Build.SourcesDirectory)/tools/metadata.json' -Raw | ConvertFrom-Json - $LTS = $metadata.LTSRelease.Package - @{ ReleaseVersion = "$(Version)"; LTSRelease = $LTS } | ConvertTo-Json | Out-File "$(Build.StagingDirectory)\release.json" - Get-Content "$(Build.StagingDirectory)\release.json" - Write-Host "##vso[artifact.upload containerfolder=metadata;artifactname=metadata]$(Build.StagingDirectory)\release.json" - displayName: Create and upload release.json file to build artifact - retryCountOnTaskFailure: 2 - - - template: /tools/releaseBuild/azureDevOps/templates/step/finalize.yml diff --git a/tools/releaseBuild/azureDevOps/releasePipeline.yml b/tools/releaseBuild/azureDevOps/releasePipeline.yml deleted file mode 100644 index e21f6d590fe..00000000000 --- a/tools/releaseBuild/azureDevOps/releasePipeline.yml +++ /dev/null @@ -1,673 +0,0 @@ -trigger: none - -# needed to disable CI trigger and allow manual trigger -# when the branch is same as pipeline source, the latest build from the source is used. -# all environment used are for manual tasks and approvals. - -parameters: - - name: skipPackagesMsftComPublish - displayName: Skip actual publishing to Packages.microsoft.com, AFTER we upload it. Used to test the publishing script. - default: false - type: boolean - - name: skipNugetPublish - displayName: Skip nuget publishing. Used in testing publishing stage. - default: false - type: boolean - -resources: - pipelines: - - pipeline: releasePipeline - source: 'Coordinated Packages' - trigger: - branches: - - release/* - - repositories: - - repository: Internal-PowerShellTeam-Tools - type: git - trigger: none - name: Internal-PowerShellTeam-Tools - ref: main-mirror - - - repository: ComplianceRepo - type: github - endpoint: ComplianceGHRepo - name: PowerShell/compliance - ref: master - -variables: - - name: runCodesignValidationInjection - value : false - - name: nugetMultiFeedWarnLevel - value: none - - name: NugetSecurityAnalysisWarningLevel - value: none - - name: skipComponentGovernanceDetection - value: true - - name: BUILDSECMON_OPT_IN - value: true - - group: ReleasePipelineSecrets - - group: PipelineExecutionPats - -stages: -- stage: MSIXBundle - displayName: Create MSIX Bundle package - dependsOn: [] - jobs: - - template: templates/release-MsixBundle.yml - -- stage: ValidateSDK - displayName: Validate SDK - dependsOn: [] - jobs: - - template: templates/release-SDKTests.yml - parameters: - jobName: WinSDK - displayName: Windows SDK Test - imageName: windows-latest - - - template: templates/release-SDKTests.yml - parameters: - jobName: LinuxSDK - displayName: Linux SDK Test - imageName: ubuntu-latest - - - template: templates/release-SDKTests.yml - parameters: - jobName: macOSSDK - displayName: macOS SDK Test - imageName: macOS-latest - -- stage: PRCreation - displayName: Create PR in GH Master - dependsOn: [] - jobs: - - deployment: CreatePRInMaster - displayName: Update README.md and metadata.json - pool: server - environment: PSReleaseCreatePR - -- stage: ValidateGlobalTool - displayName: Validate Global Tool - dependsOn: [] - jobs: - - template: templates/release-GlobalToolTest.yml - parameters: - jobName: WinGblTool - displayName: Global Tool Test Windows - imageName: windows-latest - globalToolExeName: 'pwsh.exe' - globalToolPackageName: 'PowerShell.Windows.x64' - - - template: templates/release-GlobalToolTest.yml - parameters: - jobName: LinuxWinGblTool - displayName: Global Tool Test Linux - imageName: ubuntu-latest - globalToolExeName: 'pwsh' - globalToolPackageName: 'PowerShell.Linux.x64' - -- stage: ValidateFxdPackage - displayName: Validate Fxd Package - dependsOn: [] - jobs: - - template: templates/release-ValidateFxdPackage.yml - parameters: - jobName: WinFxdPackage - displayName: Fxd Package Test Win - imageName: windows-latest - packageNamePattern: '**/*win-fxdependent.zip' - - - template: templates/release-ValidateFxdPackage.yml - parameters: - jobName: FxdPackageWindDesktop - displayName: Fxd Package Test WinDesktop - imageName: windows-latest - packageNamePattern: '**/*win-fxdependentWinDesktop.zip' - - - template: templates/release-ValidateFxdPackage.yml - parameters: - jobName: FxdPackageLinux - displayName: Fxd Package Test Linux - imageName: ubuntu-latest - packageNamePattern: '**/*linux-x64-fxdependent.tar.gz' - - - template: templates/release-ValidateFxdPackage.yml - parameters: - jobName: FxdPackageLinuxonARM - displayName: Fxd Package Test Linux ARM64 - imageName: 'PSMMSUbuntu20.04-ARM64-secure' - packageNamePattern: '**/*linux-x64-fxdependent.tar.gz' - use1ES: true - -- stage: StaticPkgValidation - dependsOn: [] - displayName: Static package validation - jobs: - - job: ValidatePkgNames - displayName: Validate Package Names - pool: - name: PowerShell1ES - demands: - - ImageOverride -equals PSMMS2019-Secure - variables: - - group: 'Azure Blob variable group' - steps: - - template: templates/release-ValidatePackageNames.yml - - job: ValidatePkgBOM - displayName: Validate Package BOM - pool: - # testing - vmImage: ubuntu-latest - steps: - - template: templates/release-ValidatePackageBOM.yml - -- stage: StartDocker - dependsOn: [] - displayName: Kick Off Docker Staging build - jobs: - - deployment: PSDockerKickOff - displayName: Start Docker build - pool: server - environment: PSReleaseDockerKickOff - -- stage: ManualValidation - dependsOn: [] - displayName: Manual Validation - jobs: - - template: templates/release/approvalJob.yml - parameters: - displayName: Validate Windows Packages - jobName: ValidateWinPkg - instructions: | - Validate zip and msipackages on Windows Server 2012 R2 - - - template: templates/release/approvalJob.yml - parameters: - displayName: Validate OSX Packages - jobName: ValidateOsxPkg - instructions: | - Validate tar.gz package on osx-arm64 - -- stage: ReleaseAutomation - displayName: Release Automation - dependsOn: [] - jobs: - - job: KickOffRA - displayName: Kickoff Release Automation - timeoutInMinutes: 240 - - pool: - name: PowerShell1ES - demands: - - ImageOverride -equals PSMMS2019-Secure - - steps: - - checkout: Internal-PowerShellTeam-Tools - - task: DownloadPipelineArtifact@2 - inputs: - source: specific - project: PowerShellCore - pipeline: '696' - preferTriggeringPipeline: true - runVersion: latestFromBranch - runBranch: '$(Build.SourceBranch)' - artifact: metadata - path: '$(Pipeline.Workspace)/releasePipeline/metadata' - - - pwsh: | - Get-ChildItem -Path $(Build.SourcesDirectory) - Import-Module $(Build.SourcesDirectory)\ReleaseTools\AzDO -Force - Set-AzDoProjectInfo -ProjectOwner PowerShell-Rel -ProjectName Release-Automation - Set-AzDoAuthToken -Token $(powershellRelExecutionPat) - $packageBuildID = $(resources.pipeline.releasePipeline.runID) - $metadata = Get-Content -Raw -Path '$(Pipeline.Workspace)/releasePipeline/metadata/release.json' | ConvertFrom-Json - $buildInvocationInfo = Start-AzDOBuild -BuildDefinitionId 10 -BuildArguments @{ POWERSHELL_PACKAGE_BUILD_BUILDID = $packageBuildID } -Tag $metadata.ReleaseVersion, 'InProgress' -PassThru - Write-Verbose -Verbose "Kicked off release automation:`n$($buildInvocationInfo | Out-String)" - $status = $buildInvocationInfo | Wait-AzDOBuildStatus -Status Completed -timeoutMinutes 240 - if ($status.result -ne 'Succeeded') { - Write-Verbose "There are errors in release automation tests. Please triage failures." - } - - - template: templates/release/approvalJob.yml - parameters: - displayName: Triage Release Automation Results - jobName: TriageRA - dependsOnJob: KickOffRA - instructions: | - Validate all the test failures and continue when signed off - - - job: MarkRASignOff - displayName: Mark release automation signoff - dependsOn: TriageRA - - pool: - name: PowerShell1ES - demands: - - ImageOverride -equals PSMMS2019-Secure - - steps: - - checkout: Internal-PowerShellTeam-Tools - - task: DownloadPipelineArtifact@2 - inputs: - source: specific - project: PowerShellCore - pipeline: '696' - preferTriggeringPipeline: true - runVersion: latestFromBranch - runBranch: '$(Build.SourceBranch)' - artifact: metadata - path: '$(Pipeline.Workspace)/releasePipeline/metadata' - - - pwsh: | - Import-Module $(Build.SourcesDirectory)\ReleaseTools\AzDO -Force - Set-AzDoProjectInfo -ProjectOwner PowerShell-Rel -ProjectName Release-Automation - Set-AzDoAuthToken -Token $(powershellRelExecutionPat) - $metadata = Get-Content -Raw -Path '$(Pipeline.Workspace)/releasePipeline/metadata/release.json' | ConvertFrom-Json - $azDOBuild = Get-AzDOBuild -buildDefinitionId 10 -MaximumResult 100 | Where-Object { $_.tags -in $metadata.ReleaseVersion } - $azDoBuild | Remove-AzDOBuildTag -tag 'InProgress' -Pass | Add-AzDOBuildTag -tag 'SignedOff' - displayName: Signoff Release-Automation run - -- stage: UpdateChangeLog - displayName: Update the changelog - # do not include stages that are likely to fail in dependency as there is no way to force deploy. - dependsOn: - - MSIXBundle - - ValidateSDK - - PRCreation - - StaticPkgValidation - - StartDocker - - ManualValidation - - ValidateFxdPackage - - ValidateGlobalTool - - jobs: - - template: templates/release/approvalJob.yml - parameters: - displayName: Make sure the changelog is updated - jobName: MergeChangeLog - instructions: | - Update and merge the changelog for the release. - This step is required for creating GitHub draft release. - -- stage: BlobPublic - displayName: Make Blob Public - # do not include stages that are likely to fail in dependency as there is no way to force deploy. - dependsOn: UpdateChangeLog - - # The environment here is used for approval. - jobs: - - deployment: AzureBlobPublic - displayName: Make Azure Blob Public - - pool: - name: PowerShell1ES - demands: - - ImageOverride -equals PSMMS2019-Secure - - variables: - - group: 'Staging_ACR' - environment: PSReleaseAzureBlobPublic - strategy: - runOnce: - deploy: - steps: - - template: templates/release-MakeContainerPublic.yml - - - template: templates/release/approvalJob.yml - parameters: - displayName: Copy Global tool packages to PSInfra storage - jobName: CopyBlobApproval - instructions: | - Approval for Copy global tool packages to PSInfra storage - - - job: PSInfraBlobPublic - displayName: Copy global tools to PSInfra storage - dependsOn: CopyBlobApproval - - pool: - name: PowerShell1ES - demands: - - ImageOverride -equals PSMMS2019-Secure - - variables: - - group: 'PSInfraStorage' - - steps: - - template: templates/release-CopyGlobalTools.yml - parameters: - sourceContainerName: 'tool-private' - destinationContainerName: 'tool' - sourceStorageAccountName: '$(GlobalToolStorageAccount)' - destinationStorageAccountName: '$(PSInfraStorageAccount)' - blobPrefix: '$(Version)' - -- stage: GitHubTasks - displayName: GitHub tasks - dependsOn: BlobPublic - jobs: - - job: GitHubDraft - displayName: Create GitHub Draft release - - pool: - name: PowerShell1ES - demands: - - ImageOverride -equals PSMMS2019-Secure - - variables: - - group: 'Azure Blob variable group' - - group: mscodehub-feed-read-general - - group: mscodehub-feed-read-akv - - group: ReleasePipelineSecrets - steps: - - template: templates/release-CreateGitHubDraft.yml - - - deployment: PushTag - dependsOn: GitHubDraft - displayName: Push Git Tag - pool : server - environment: PSReleasePushTag - - - deployment: MakeDraftPublic - dependsOn: PushTag - displayName: Make GitHub Draft public - pool : server - environment: PSReleaseDraftPublic - -- stage: PublishPackages - displayName: Publish packages - dependsOn: GitHubTasks - jobs: - - job: PublishNuget - - pool: - name: PowerShell1ES - demands: - - ImageOverride -equals PSMMS2019-Secure - - steps: - - template: templates/release-ReleaseToNuGet.yml - parameters: - skipPublish: ${{ parameters.skipNugetPublish }} - - - job: PublishPkgsMsftCom - - timeoutInMinutes: 120 - pool: - name: PowerShell1ES - demands: - - ImageOverride -equals PSMMSUbuntu20.04-Secure - - variables: - - group: mscodehub-feed-read-general - - group: mscodehub-feed-read-akv - - group: 'packages.microsoft.com' - - group: 'mscodehub-code-read-akv' - steps: - - template: templates/release-PublishPackageMsftCom.yml - parameters: - skipPublish: ${{ parameters.skipPackagesMsftComPublish }} - -- stage: PublishSymbols - displayName: Publish symbols - dependsOn: PublishPackages - jobs: - - job: PublishSymbol - - pool: - name: PowerShell1ES - demands: - - ImageOverride -equals PSMMS2019-Secure - - steps: - - template: templates/release-PublishSymbols.yml - -- stage: ChangesToMaster - displayName: Ensure changes are in GH master - dependsOn: PublishPackages - jobs: - - template: templates/release/approvalJob.yml - parameters: - displayName: Make sure changes are in master - jobName: MergeToMaster - instructions: | - Make sure that changes README.md and metadata.json are merged into master on GitHub. - -- stage: ReleaseDocker - displayName: Release Docker - dependsOn: - - GitHubTasks - jobs: - - deployment: ReleaseDocker - displayName: Release Docker - pool: server - environment: PSReleaseDockerRelease - -- stage: ReleaseSnap - displayName: Release Snap - dependsOn: - - PublishPackages - - ChangesToMaster - variables: - # adds newPwshOrgName (exists in new and old org) - - group: PowerShellRelease - jobs: - - job: KickoffSnap - displayName: Kickoff Snap build - - pool: - name: PowerShell1ES - demands: - - ImageOverride -equals PSMMS2019-Secure - - steps: - - checkout: Internal-PowerShellTeam-Tools - - task: DownloadPipelineArtifact@2 - inputs: - source: specific - project: PowerShellCore - pipeline: '696' - preferTriggeringPipeline: true - runVersion: latestFromBranch - runBranch: '$(Build.SourceBranch)' - artifact: metadata - path: '$(Pipeline.Workspace)/releasePipeline/metadata' - - pwsh: | - Import-Module $(Build.SourcesDirectory)\ReleaseTools\AzDO -Force - Set-AzDoProjectInfo -ProjectOwner PowerShell-Rel -ProjectName PowerShell - Set-AzDoAuthToken -Token $(powershellRelExecutionPat) - $metadata = Get-Content -Raw -Path '$(Pipeline.Workspace)/releasePipeline/metadata/release.json' | ConvertFrom-Json - $buildInvocationInfo = Start-AzDOBuild -BuildDefinitionId 49 -Tag $metadata.ReleaseVersion, 'InProgress' -PassThru - Write-Verbose -Verbose "Kicked off snap build: $($buildInvocationInfo.WebUrl)" - $status = $buildInvocationInfo | Wait-AzDOBuildStatus -Status Completed -timeoutMinutes 60 - if ($status.result -ne 'Succeeded') { - throw "There are errors in snap build!!" - } - - - template: templates/release/approvalJob.yml - parameters: - displayName: Approve the release - jobName: SnapEnd - dependsOnJob: KickoffSnap - instructions: | - Once the build is finished, approve the release of all channels. - - - job: MarkSnapSignOff - displayName: Mark release automation signoff - dependsOn: SnapEnd - - pool: - name: PowerShell1ES - demands: - - ImageOverride -equals PSMMS2019-Secure - - steps: - - checkout: Internal-PowerShellTeam-Tools - - task: DownloadPipelineArtifact@2 - inputs: - source: specific - project: PowerShellCore - pipeline: '696' - preferTriggeringPipeline: true - runVersion: latestFromBranch - runBranch: '$(Build.SourceBranch)' - artifact: metadata - path: '$(Pipeline.Workspace)/releasePipeline/metadata' - - pwsh: | - Import-Module $(Build.SourcesDirectory)\ReleaseTools\AzDO -Force - Set-AzDoProjectInfo -ProjectOwner PowerShell-Rel -ProjectName PowerShell - Set-AzDoAuthToken -Token $(powershellRelExecutionPat) - $metadata = Get-Content -Raw -Path '$(Pipeline.Workspace)/releasePipeline/metadata/release.json' | ConvertFrom-Json - $azDOBuild = Get-AzDOBuild -buildDefinitionId 49 -MaximumResult 100 | Where-Object { $_.tags -in $metadata.ReleaseVersion } - $azDoBuild | Remove-AzDOBuildTag -tag 'InProgress' -Pass | Add-AzDOBuildTag -tag 'SignedOff' - displayName: Signoff Release-Automation run - -- stage: ReleaseToMU - displayName: Release to MU - dependsOn: - - PublishPackages - - ChangesToMaster - jobs: - - template: templates/release/approvalJob.yml - parameters: - displayName: Release to MU - instructions: | - Notify the PM team to start the process of releasing to MU. - -- stage: UpdateDotnetDocker - dependsOn: GitHubTasks - displayName: Update DotNet SDK Docker images - jobs: - - template: templates/release/approvalJob.yml - parameters: - displayName: Update .NET SDK docker images - jobName: DotnetDocker - instructions: | - Create PR for updating dotnet-docker images to use latest PowerShell version. - 1. Fork and clone https://github.com/dotnet/dotnet-docker.git - 2. git checkout upstream/nightly -b updatePS - 3. dotnet run --project .\eng\update-dependencies\ -- --product-version powershell= --compute-shas - 4. create PR targeting nightly branch - -- stage: UpdateWinGet - dependsOn: GitHubTasks - displayName: Add manifest entry to winget - jobs: - - template: templates/release/approvalJob.yml - parameters: - displayName: Add manifest entry to winget - jobName: UpdateWinGet - instructions: | - This is typically done by the community 1-2 days after the release. - -- stage: PublishMsix - dependsOn: GitHubTasks - displayName: Publish MSIX to store - jobs: - - template: templates/release/approvalJob.yml - parameters: - displayName: Publish the MSIX Bundle package to store - jobName: PublishMsix - instructions: | - Ask Steve to release MSIX bundle package to Store - -- stage: BuildInfoJson - dependsOn: GitHubTasks - displayName: Upload BuildInfoJson - jobs: - - deployment: UploadJson - displayName: Upload BuildInfoJson - - pool: - name: PowerShell1ES - demands: - - ImageOverride -equals PSMMS2019-Secure - - variables: - - group: 'Azure Blob variable group' - environment: PSReleaseBuildInfoJson - strategy: - runOnce: - deploy: - steps: - - template: templates/release-BuildJson.yml - -- stage: ReleaseVPack - dependsOn: GitHubTasks - displayName: Release VPack - jobs: - - job: KickoffvPack - displayName: Kickoff vPack build - - pool: - name: PowerShell1ES - demands: - - ImageOverride -equals PSMMS2019-Secure - - steps: - - checkout: Internal-PowerShellTeam-Tools - - task: DownloadPipelineArtifact@2 - inputs: - source: specific - project: PowerShellCore - pipeline: '696' - preferTriggeringPipeline: true - runVersion: latestFromBranch - runBranch: '$(Build.SourceBranch)' - artifact: metadata - path: '$(Pipeline.Workspace)/releasePipeline/metadata' - - - pwsh: | - Import-Module $(Build.SourcesDirectory)\ReleaseTools\AzDO -Force - Set-AzDoProjectInfo -ProjectOwner mscodehub -ProjectName PowerShellCore - Set-AzDoAuthToken -Token $(mscodehubBuildExecutionPat) - $metadata = Get-Content -Raw -Path '$(Pipeline.Workspace)/releasePipeline/metadata/release.json' | ConvertFrom-Json - $releaseVersion = $metadata.ReleaseVersion -replace '^v','' - $semanticVersion = [System.Management.Automation.SemanticVersion]$releaseVersion - $isPreview = $semanticVersion.PreReleaseLabel -ne $null - - if (-not $isPreview) { - $buildInvocationInfo = Start-AzDOBuild -BuildDefinitionId 1238 -Branch '$(Build.SourceBranch)' -Tag $metadata.ReleaseVersion, 'InProgress' -PassThru - Write-Verbose -Verbose "Kicked off vPack build: $($buildInvocationInfo.WebUrl)" - $status = $buildInvocationInfo | Wait-AzDOBuildStatus -Status Completed -timeoutMinutes 60 - if ($status.result -ne 'Succeeded') { - throw "There are errors in snap build!!" - } - else { - $buildInvocationInfo | Remove-AzDOBuildTag -tag 'InProgress' -Pass | Add-AzDOBuildTag -tag 'SignedOff' - } - } - else { - Write-Verbose -Verbose "This is a preview release with version: $semanticVersion skipping releasing vPack" - } - -- stage: ReleaseDeps - dependsOn: GitHubTasks - displayName: Update pwsh.deps.json links - jobs: - - template: templates/release-UpdateDepsJson.yml - -- stage: ReleaseClose - displayName: Finish Release - dependsOn: - - ReleaseVPack - - BuildInfoJson - - UpdateDotnetDocker - - ReleaseDocker - - ReleaseSnap - - ChangesToMaster - - ReleaseDeps - jobs: - - template: templates/release/approvalJob.yml - parameters: - displayName: Retain Build - jobName: RetainBuild - instructions: | - Retain the build - - - template: templates/release/approvalJob.yml - parameters: - displayName: Delete release branch - jobName: DeleteBranch - instructions: | - Delete release diff --git a/tools/releaseBuild/azureDevOps/templates/SetVersionVariables.yml b/tools/releaseBuild/azureDevOps/templates/SetVersionVariables.yml deleted file mode 100644 index dd9252a406f..00000000000 --- a/tools/releaseBuild/azureDevOps/templates/SetVersionVariables.yml +++ /dev/null @@ -1,63 +0,0 @@ -parameters: - ReleaseTagVar: v6.2.0 - ReleaseTagVarName: ReleaseTagVar - CreateJson: 'no' - UseJson: 'yes' - -steps: -- ${{ if eq(parameters['UseJson'],'yes') }}: - - task: DownloadBuildArtifacts@0 - inputs: - artifactName: 'BuildInfoJson' - itemPattern: '**/*.json' - downloadPath: '$(System.ArtifactsDirectory)' - displayName: Download Build Info Json - -- powershell: | - $path = "./build.psm1" - - if($env:REPOROOT){ - Write-Verbose "reporoot already set to ${env:REPOROOT}" -Verbose - exit 0 - } - - if(Test-Path -Path $path) - { - Write-Verbose "reporoot detect at: ." -Verbose - $repoRoot = '.' - } - else{ - $path = "./PowerShell/build.psm1" - if(Test-Path -Path $path) - { - Write-Verbose "reporoot detect at: ./PowerShell" -Verbose - $repoRoot = './PowerShell' - } - } - if($repoRoot) { - $vstsCommandString = "vso[task.setvariable variable=repoRoot]$repoRoot" - Write-Host ("sending " + $vstsCommandString) - Write-Host "##$vstsCommandString" - } else { - Write-Verbose -Verbose "repo not found" - } - displayName: 'Set repo Root' - -- powershell: | - $createJson = ("${{ parameters.CreateJson }}" -ne "no") - $releaseTag = & "$env:REPOROOT/tools/releaseBuild/setReleaseTag.ps1" -ReleaseTag ${{ parameters.ReleaseTagVar }} -Variable "${{ parameters.ReleaseTagVarName }}" -CreateJson:$createJson - $version = $releaseTag.Substring(1) - $vstsCommandString = "vso[task.setvariable variable=Version]$version" - Write-Host ("sending " + $vstsCommandString) - Write-Host "##$vstsCommandString" - - $azureVersion = $releaseTag.ToLowerInvariant() -replace '\.', '-' - $vstsCommandString = "vso[task.setvariable variable=AzureVersion]$azureVersion" - Write-Host ("sending " + $vstsCommandString) - Write-Host "##$vstsCommandString" - displayName: 'Set ${{ parameters.ReleaseTagVarName }} and other version Variables' - -- powershell: | - Get-ChildItem -Path env: - displayName: Capture environment - condition: succeededOrFailed() diff --git a/tools/releaseBuild/azureDevOps/templates/checkAzureContainer.yml b/tools/releaseBuild/azureDevOps/templates/checkAzureContainer.yml deleted file mode 100644 index af6451004e4..00000000000 --- a/tools/releaseBuild/azureDevOps/templates/checkAzureContainer.yml +++ /dev/null @@ -1,51 +0,0 @@ -jobs: -- job: DeleteBlob - variables: - - name: runCodesignValidationInjection - value : false - - name: NugetSecurityAnalysisWarningLevel - value: none - - group: Azure Blob variable group - displayName: Delete blob is exists - pool: - name: PowerShell1ES - demands: - - ImageOverride -equals PSMMS2019-Secure - steps: - - checkout: self - clean: true - - - template: SetVersionVariables.yml - parameters: - ReleaseTagVar: $(ReleaseTagVar) - CreateJson: yes - UseJson: no - - - task: AzurePowerShell@4 - displayName: Check if blob exists and delete if specified - inputs: - azureSubscription: '$(AzureFileCopySubscription)' - scriptType: inlineScript - azurePowerShellVersion: latestVersion - inline: | - try { - $container = Get-AzStorageContainer -Container '$(AzureVersion)' -Context (New-AzStorageContext -StorageAccountName '$(StorageAccount)') -ErrorAction Stop - - if ($container -ne $null -and '$(ForceAzureBlobDelete)' -eq 'false') { - throw 'Azure blob container $(AzureVersion) already exists. To overwrite, use ForceAzureBlobDelete parameter' - } - elseif ($container -ne $null -and '$(ForceAzureBlobDelete)' -eq 'true') { - Write-Verbose -Verbose 'Removing container $(AzureVersion) due to ForceAzureBlobDelete parameter' - Remove-AzStorageContainer -Name '$(AzureVersion)' -Context (New-AzStorageContext -StorageAccountName '$(StorageAccount)') -Force - } - } - catch { - if ($_.FullyQualifiedErrorId -eq 'ResourceNotFoundException,Microsoft.WindowsAzure.Commands.Storage.Blob.Cmdlet.GetAzureStorageContainerCommand') { - Write-Verbose -Verbose 'Container "$(AzureVersion)" does not exists.' - } - else { - throw $_ - } - } - - - template: /tools/releaseBuild/azureDevOps/templates/step/finalize.yml diff --git a/tools/releaseBuild/azureDevOps/templates/cloneToOfficialPath.yml b/tools/releaseBuild/azureDevOps/templates/cloneToOfficialPath.yml deleted file mode 100644 index 352458390f9..00000000000 --- a/tools/releaseBuild/azureDevOps/templates/cloneToOfficialPath.yml +++ /dev/null @@ -1,19 +0,0 @@ -parameters: - nativePathRoot: '' - -steps: - - powershell: | - $dirSeparatorChar = [system.io.path]::DirectorySeparatorChar - $nativePath = "${{parameters.nativePathRoot }}${dirSeparatorChar}PowerShell" - Write-Host "##vso[task.setvariable variable=PowerShellRoot]$nativePath" - - if ((Test-Path "$nativePath")) { - Remove-Item -Path "$nativePath" -Force -Recurse -Verbose -ErrorAction ignore - } - else { - Write-Verbose -Verbose -Message "No cleanup required." - } - - git clone --quiet $env:REPOROOT $nativePath - displayName: Clone PowerShell Repo to /PowerShell - errorActionPreference: silentlycontinue diff --git a/tools/releaseBuild/azureDevOps/templates/compliance.yml b/tools/releaseBuild/azureDevOps/templates/compliance.yml deleted file mode 100644 index 0a416389bf4..00000000000 --- a/tools/releaseBuild/azureDevOps/templates/compliance.yml +++ /dev/null @@ -1,124 +0,0 @@ -parameters: - parentJobs: [] - -jobs: -- job: compliance - variables: - - name: runCodesignValidationInjection - value : false - - name: NugetSecurityAnalysisWarningLevel - value: none - - displayName: Compliance - dependsOn: - ${{ parameters.parentJobs }} - pool: - name: PowerShell1ES - demands: - - ImageOverride -equals PSMMS2019-Secure - - steps: - - checkout: self - clean: true - - - template: SetVersionVariables.yml - parameters: - ReleaseTagVar: $(ReleaseTagVar) - - - task: DownloadBuildArtifacts@0 - displayName: 'Download artifacts' - inputs: - buildType: current - downloadType: single - artifactName: results - downloadPath: '$(System.ArtifactsDirectory)' - - - powershell: | - dir "$(System.ArtifactsDirectory)\*" -Recurse - displayName: 'Capture artifacts directory' - continueOnError: true - - - template: expand-compliance.yml - parameters: - architecture: fxdependent - version: $(version) - - - template: expand-compliance.yml - parameters: - architecture: x86 - version: $(version) - - - template: expand-compliance.yml - parameters: - architecture: x64 - version: $(version) - - - task: securedevelopmentteam.vss-secure-development-tools.build-task-antimalware.AntiMalware@3 - displayName: 'Run Defender Scan' - - - task: securedevelopmentteam.vss-secure-development-tools.build-task-binskim.BinSkim@3 - displayName: 'Run BinSkim ' - inputs: - InputType: Basic - AnalyzeTarget: '$(CompliancePath)\*.dll;$(CompliancePath)\*.exe' - AnalyzeSymPath: 'SRV*' - AnalyzeVerbose: true - AnalyzeHashes: true - AnalyzeStatistics: true - continueOnError: true - - # add RoslynAnalyzers - - - task: securedevelopmentteam.vss-secure-development-tools.build-task-autoapplicability.AutoApplicability@1 - displayName: 'Run AutoApplicability' - inputs: - ExternalRelease: true - IsSoftware: true - DataSensitivity: lbi - continueOnError: true - - # add codeMetrics - - - task: securedevelopmentteam.vss-secure-development-tools.build-task-vulnerabilityassessment.VulnerabilityAssessment@0 - displayName: 'Run Vulnerability Assessment' - continueOnError: true - - # FXCop is not applicable - - # PreFASt is not applicable - - - task: securedevelopmentteam.vss-secure-development-tools.build-task-publishsecurityanalysislogs.PublishSecurityAnalysisLogs@2 - displayName: 'Publish Security Analysis Logs to Build Artifacts' - continueOnError: true - - - task: securedevelopmentteam.vss-secure-development-tools.build-task-uploadtotsa.TSAUpload@1 - displayName: 'TSA upload to Codebase: PowerShellCore_201906' - inputs: - tsaVersion: TsaV2 - codeBaseName: 'PowerShellCore_201906' - uploadAPIScan: false - uploadBinSkim: true - uploadCredScan: false - uploadFortifySCA: false - uploadFxCop: false - uploadModernCop: false - uploadPoliCheck: false - uploadPREfast: false - uploadRoslyn: false - uploadTSLint: false - - - task: securedevelopmentteam.vss-secure-development-tools.build-task-report.SdtReport@1 - displayName: 'Create Security Analysis Report' - inputs: - TsvFile: false - APIScan: false - BinSkim: true - CredScan: true - PoliCheck: true - PoliCheckBreakOn: Severity2Above - - - task: ms.vss-governance-buildtask.governance-build-task-component-detection.ComponentGovernanceComponentDetection@0 - displayName: 'Component Detection' - inputs: - sourceScanPath: '$(Build.SourcesDirectory)\tools' - snapshotForceEnabled: true diff --git a/tools/releaseBuild/azureDevOps/templates/compliance/apiscan.yml b/tools/releaseBuild/azureDevOps/templates/compliance/apiscan.yml deleted file mode 100644 index 1b4f9067266..00000000000 --- a/tools/releaseBuild/azureDevOps/templates/compliance/apiscan.yml +++ /dev/null @@ -1,180 +0,0 @@ -jobs: - - job: APIScan - variables: - - name: runCodesignValidationInjection - value : false - - name: NugetSecurityAnalysisWarningLevel - value: none - - name: ReleaseTagVar - value: fromBranch - # Defines the variables APIScanClient, APIScanTenant and APIScanSecret - - group: PS-PS-APIScan - # PAT permissions NOTE: Declare a SymbolServerPAT variable in this group with a 'microsoft' organizanization scoped PAT with 'Symbols' Read permission. - # A PAT in the wrong org will give a single Error 203. No PAT will give a single Error 401, and individual pdbs may be missing even if permissions are correct. - - group: symbols - - name: branchCounterKey - value: $[format('{0:yyyyMMdd}-{1}', pipeline.startTime,variables['Build.SourceBranch'])] - - name: branchCounter - value: $[counter(variables['branchCounterKey'], 1)] - - group: DotNetPrivateBuildAccess - - group: Azure Blob variable group - - group: ReleasePipelineSecrets - - group: mscodehub-feed-read-general - - group: mscodehub-feed-read-akv - - pool: - name: PowerShell1ES - demands: - - ImageOverride -equals PSMMS2019-Secure - - # APIScan can take a long time - timeoutInMinutes: 180 - - steps: - - template: ../SetVersionVariables.yml - parameters: - ReleaseTagVar: $(ReleaseTagVar) - CreateJson: yes - UseJson: no - - - template: ../insert-nuget-config-azfeed.yml - parameters: - repoRoot: '$(Build.SourcesDirectory)' - - - pwsh: | - Import-Module .\build.psm1 -force - Start-PSBootstrap - workingDirectory: '$(Build.SourcesDirectory)' - retryCountOnTaskFailure: 2 - displayName: 'Bootstrap' - env: - __DOTNET_RUNTIME_FEED_KEY: $(RUNTIME_SOURCEFEED_KEY) - - - pwsh: | - Import-Module .\build.psm1 -force - Find-DotNet - dotnet tool install dotnet-symbol --tool-path $(Agent.ToolsDirectory)\tools\dotnet-symbol - $symbolToolPath = Get-ChildItem -Path $(Agent.ToolsDirectory)\tools\dotnet-symbol\dotnet-symbol.exe | Select-Object -First 1 -ExpandProperty FullName - Write-Host "##vso[task.setvariable variable=symbolToolPath]$symbolToolPath" - displayName: Install dotnet-symbol - retryCountOnTaskFailure: 2 - - - pwsh: | - Import-module '$(BUILD.SOURCESDIRECTORY)/build.psm1' - Install-AzCopy - displayName: Install AzCopy - retryCountOnTaskFailure: 2 - - - pwsh: | - Import-module '$(BUILD.SOURCESDIRECTORY)/build.psm1' - $azcopy = Find-AzCopy - Write-Verbose -Verbose "Found AzCopy: $azcopy" - - $winverifySymbolsPath = New-Item -ItemType Directory -Path '$(System.ArtifactsDirectory)/winverify-symbols' -Force - Write-Host "##vso[task.setvariable variable=winverifySymbolsPath]$winverifySymbolsPath" - - & $azcopy cp https://$(StorageAccount).blob.core.windows.net/winverify-private $winverifySymbolsPath --recursive - - Get-ChildItem $winverifySymbolsPath -Recurse | Out-String | Write-Verbose -Verbose - - displayName: Download winverify-private Artifacts - retryCountOnTaskFailure: 2 - env: - AZCOPY_AUTO_LOGIN_TYPE: MSI - - - pwsh: | - Import-Module .\build.psm1 -force - Find-DotNet - Start-PSBuild -Configuration StaticAnalysis -PSModuleRestore -Clean -Runtime fxdependent-win-desktop - - $OutputFolder = Split-Path (Get-PSOutput) - Write-Host "##vso[task.setvariable variable=BinDir]$OutputFolder" - - Write-Verbose -Verbose -Message "Deleting ref folder from output folder" - if (Test-Path $OutputFolder/ref) { - Remove-Item -Recurse -Force $OutputFolder/ref - } - workingDirectory: '$(Build.SourcesDirectory)' - displayName: 'Build PowerShell Source' - - - pwsh: | - Get-ChildItem -Path env: - displayName: Capture Environment - condition: succeededOrFailed() - - # Explicitly download symbols for the drop since the SDL image doesn't have http://SymWeb access and APIScan cannot handle https yet. - - pwsh: | - Import-Module .\build.psm1 -force - Find-DotNet - $pat = '$(SymbolServerPAT)' - if ($pat -like '*PAT*' -or $pat -eq '') - { - throw 'No PAT defined' - } - $url = 'https://microsoft.artifacts.visualstudio.com/defaultcollection/_apis/symbol/symsrv' - $(symbolToolPath) --authenticated-server-path $(SymbolServerPAT) $url --symbols -d "$env:BinDir\*" --recurse-subdirectories - displayName: 'Download Symbols for binaries' - retryCountOnTaskFailure: 2 - workingDirectory: '$(Build.SourcesDirectory)' - - - pwsh: | - Get-ChildItem '$(BinDir)' -File -Recurse | - Foreach-Object { - [pscustomobject]@{ - Path = $_.FullName - Version = $_.VersionInfo.FileVersion - Md5Hash = (Get-FileHash -Algorithm MD5 -Path $_.FullName).Hash - Sha512Hash = (Get-FileHash -Algorithm SHA512 -Path $_.FullName).Hash - } - } | Export-Csv -Path '$(Build.SourcesDirectory)/ReleaseFileHash.csv' - displayName: 'Create release file hash artifact' - - - task: PublishBuildArtifacts@1 - displayName: 'Publish Build File Hash artifact' - inputs: - pathToPublish: '$(Build.SourcesDirectory)/ReleaseFileHash.csv' - artifactName: ReleaseFilesHash - retryCountOnTaskFailure: 2 - - - task: securedevelopmentteam.vss-secure-development-tools.build-task-apiscan.APIScan@2 - displayName: 'Run APIScan' - inputs: - softwareFolder: '$(BinDir)' - softwareName: PowerShell - softwareVersionNum: '$(ReleaseTagVar)' - isLargeApp: false - preserveTempFiles: false - verbosityLevel: standard - # write a status update every 5 minutes. Default is 1 minute - statusUpdateInterval: '00:05:00' - env: - AzureServicesAuthConnectionString: RunAs=App - - - task: securedevelopmentteam.vss-secure-development-tools.build-task-report.SdtReport@2 - continueOnError: true - displayName: 'Guardian Export' - inputs: - GdnExportVstsConsole: true - GdnExportSarifFile: true - GdnExportHtmlFile: true - GdnExportAllTools: false - GdnExportGdnToolApiScan: true - #this didn't do anything GdnExportCustomLogsFolder: '$(Build.ArtifactStagingDirectory)/Guardian' - - - task: TSAUpload@2 - displayName: 'TSA upload' - inputs: - GdnPublishTsaOnboard: false - GdnPublishTsaConfigFile: '$(Build.SourcesDirectory)\tools\guardian\tsaconfig-APIScan.json' - - - pwsh: | - Get-ChildItem -Path env: - displayName: Capture Environment - condition: succeededOrFailed() - - - task: securedevelopmentteam.vss-secure-development-tools.build-task-publishsecurityanalysislogs.PublishSecurityAnalysisLogs@3 - displayName: 'Publish Guardian Artifacts' - inputs: - AllTools: false - APIScan: true - ArtifactName: APIScan diff --git a/tools/releaseBuild/azureDevOps/templates/compliance/compliance.yml b/tools/releaseBuild/azureDevOps/templates/compliance/compliance.yml deleted file mode 100644 index 8db52fc83f0..00000000000 --- a/tools/releaseBuild/azureDevOps/templates/compliance/compliance.yml +++ /dev/null @@ -1,83 +0,0 @@ -parameters: - - name: parentJobs - type: jobList - -jobs: -- job: compliance - variables: - - name: runCodesignValidationInjection - value : false - - name: NugetSecurityAnalysisWarningLevel - value: none - - # Defines the variables APIScanClient, APIScanTenant and APIScanSecret - - group: PS-PS-APIScan - - displayName: Compliance - dependsOn: - ${{ parameters.parentJobs }} - pool: - name: $(windowsPool) - demands: - - ImageOverride -equals PSMMS2019-Secure - - # APIScan can take a long time - timeoutInMinutes: 180 - - steps: - - checkout: self - clean: true - - - task: securedevelopmentteam.vss-secure-development-tools.build-task-credscan.CredScan@3 - displayName: 'Run CredScan' - inputs: - suppressionsFile: tools/credScan/suppress.json - debugMode: false - continueOnError: true - - - task: securedevelopmentteam.vss-secure-development-tools.build-task-policheck.PoliCheck@2 - displayName: 'Run PoliCheck' - inputs: - # targetType F means file or folder and is the only applicable value and the default - targetType: F - # 1 to enable source code comment scanning, which is what we should do for open source - optionsFC: 1 - # recurse - optionsXS: 1 - # run for severity 1, 2, 3 and 4 issues - optionsPE: '1|2|3|4' - # disable history management - optionsHMENABLE: 0 - # Excluclusion access database - optionsRulesDBPath: '$(Build.SourcesDirectory)\tools\terms\PowerShell-Terms-Rules.mdb' - # Terms Exclusion xml file - optionsUEPath: $(Build.SourcesDirectory)\tools\terms\TermsExclusion.xml - continueOnError: true - - - task: securedevelopmentteam.vss-secure-development-tools.build-task-publishsecurityanalysislogs.PublishSecurityAnalysisLogs@3 - displayName: 'Publish Security Analysis Logs to Build Artifacts' - continueOnError: true - - - task: TSAUpload@2 - displayName: 'TSA upload' - inputs: - GdnPublishTsaOnboard: false - GdnPublishTsaConfigFile: '$(Build.SourcesDirectory)\tools\guardian\tsaconfig-others.json' - - - task: securedevelopmentteam.vss-secure-development-tools.build-task-report.SdtReport@1 - displayName: 'Create Security Analysis Report' - inputs: - TsvFile: false - APIScan: false - BinSkim: false - CredScan: true - PoliCheck: true - PoliCheckBreakOn: Severity2Above - - - task: ms.vss-governance-buildtask.governance-build-task-component-detection.ComponentGovernanceComponentDetection@0 - displayName: 'Component Detection' - inputs: - sourceScanPath: '$(Build.SourcesDirectory)\tools' - snapshotForceEnabled: true - - - template: /tools/releaseBuild/azureDevOps/templates/step/finalize.yml diff --git a/tools/releaseBuild/azureDevOps/templates/compliance/generateNotice.yml b/tools/releaseBuild/azureDevOps/templates/compliance/generateNotice.yml deleted file mode 100644 index 3e91b9174d2..00000000000 --- a/tools/releaseBuild/azureDevOps/templates/compliance/generateNotice.yml +++ /dev/null @@ -1,90 +0,0 @@ -parameters: - - name: parentJobs - type: jobList - -jobs: -- job: generateNotice - variables: - - name: runCodesignValidationInjection - value : false - - name: NugetSecurityAnalysisWarningLevel - value: none - - displayName: Generate Notice - dependsOn: - ${{ parameters.parentJobs }} - pool: - name: PowerShell1ES - demands: - - ImageOverride -equals PSMMS2019-Secure - - timeoutInMinutes: 15 - - steps: - - checkout: self - clean: true - - - pwsh: | - [string]$Branch=$env:BUILD_SOURCEBRANCH - $branchOnly = $Branch -replace '^refs/heads/'; - $branchOnly = $branchOnly -replace '[_\-]' - - if ($branchOnly -eq 'master') { - $container = 'tpn' - } else { - $branchOnly = $branchOnly -replace '[\./]', '-' - $container = "tpn-$branchOnly" - } - - $vstsCommandString = "vso[task.setvariable variable=tpnContainer]$container" - Write-Verbose -Message $vstsCommandString -Verbose - Write-Host -Object "##$vstsCommandString" - displayName: Set ContainerName - - - task: ms.vss-governance-buildtask.governance-build-task-component-detection.ComponentGovernanceComponentDetection@0 - displayName: 'Component Detection' - inputs: - sourceScanPath: '$(Build.SourcesDirectory)\tools' - - - pwsh: | - ./tools/clearlyDefined/ClearlyDefined.ps1 -TestAndHarvest - displayName: Verify that packages have license data - - - task: msospo.ospo-extension.8d7f9abb-6896-461d-9e25-4f74ed65ddb2.notice@0 - displayName: 'NOTICE File Generator' - inputs: - outputfile: '$(System.ArtifactsDirectory)\ThirdPartyNotices.txt' - # output format can be html or text - outputformat: text - # this isn't working - # additionaldata: $(Build.SourcesDirectory)\assets\additionalAttributions.txt - - - - pwsh: | - Get-Content -Raw -Path $(Build.SourcesDirectory)\assets\additionalAttributions.txt | Out-File '$(System.ArtifactsDirectory)\ThirdPartyNotices.txt' -Encoding utf8NoBOM -Force -Append - Get-Content -Raw -Path '$(Build.SourcesDirectory)\assets\additionalAttributions.txt' - displayName: Append Additional Attributions - continueOnError: true - - - pwsh: | - Get-Content -Raw -Path '$(System.ArtifactsDirectory)\ThirdPartyNotices.txt' - displayName: Capture Notice - continueOnError: true - - - task: AzureFileCopy@4 - displayName: 'upload Notice' - inputs: - SourcePath: $(System.ArtifactsDirectory)\ThirdPartyNotices.txt - azureSubscription: '$(AzureFileCopySubscription)' - Destination: AzureBlob - storage: '$(StorageAccount)' - ContainerName: $(tpnContainer) - resourceGroup: '$(StorageResourceGroup)' - retryCountOnTaskFailure: 2 - - - task: PublishPipelineArtifact@1 - inputs: - targetPath: $(System.ArtifactsDirectory) - artifactName: notice - displayName: Publish notice artifacts - retryCountOnTaskFailure: 2 diff --git a/tools/releaseBuild/azureDevOps/templates/expand-compliance.yml b/tools/releaseBuild/azureDevOps/templates/expand-compliance.yml deleted file mode 100644 index 4cc25433262..00000000000 --- a/tools/releaseBuild/azureDevOps/templates/expand-compliance.yml +++ /dev/null @@ -1,12 +0,0 @@ -parameters: - architecture: x86 - version: 6.2.0 - -steps: - - powershell: | - Expand-Archive -Path "$(System.ArtifactsDirectory)\results\PowerShell-${{ parameters.version }}-symbols-win-${{ parameters.architecture }}.zip" -Destination "$(Build.StagingDirectory)\symbols\${{ parameters.architecture }}" - displayName: Expand symbols zip - ${{ parameters.architecture }} - - - powershell: | - tools/releaseBuild/createComplianceFolder.ps1 -ArtifactFolder "$(Build.StagingDirectory)\symbols\${{ parameters.architecture }}" -VSTSVariableName 'CompliancePath' - displayName: Expand Compliance file - ${{ parameters.architecture }} diff --git a/tools/releaseBuild/azureDevOps/templates/global-tool-pkg-sbom.yml b/tools/releaseBuild/azureDevOps/templates/global-tool-pkg-sbom.yml deleted file mode 100644 index d7200809cca..00000000000 --- a/tools/releaseBuild/azureDevOps/templates/global-tool-pkg-sbom.yml +++ /dev/null @@ -1,64 +0,0 @@ -parameters: - - name: PackageVersion - - name: LinuxBinPath - - name: WindowsBinPath - - name: WindowsDesktopBinPath - - name: AlpineBinPath - - name: DestinationPath - - name: ListOfPackageTypes - type: object - default: - - Unified - - PowerShell.Linux.Alpine - - PowerShell.Linux.x64 - - PowerShell.Linux.arm32 - - PowerShell.Linux.arm64 - - PowerShell.Windows.x64 - -steps: - -- pwsh: | - Write-Verbose -Verbose 'LinuxBinPath path: ${{ parameters.LinuxBinPath }}' - Write-Verbose -Verbose 'WindowsBinPath path: ${{ parameters.WindowsBinPath }}' - Write-Verbose -Verbose 'WindowsDesktopBinPath path: ${{ parameters.WindowsDesktopBinPath }}' - Write-Verbose -Verbose 'AlpineBinPath path: ${{ parameters.AlpineBinPath }}' - - Import-Module -Name $env:REPOROOT\build.psm1 - Import-Module -Name $env:REPOROOT\tools\packaging - Start-PrepForGlobalToolNupkg -LinuxBinPath '${{ parameters.LinuxBinPath }}' -WindowsBinPath '${{ parameters.WindowsBinPath }}' -WindowsDesktopBinPath '${{ parameters.WindowsDesktopBinPath }}' -AlpineBinPath '${{ parameters.AlpineBinPath }}' - displayName: 'Preparation for Global Tools package creation.' - -# NOTE: The Unified package must always be created first, and so must always be first in ListOfPackageTypes. -- ${{ each value in parameters.ListOfPackageTypes }}: - - pwsh: | - $PackageType = '${{ value }}' - - Write-Verbose -Verbose "PackageType: $PackageType" - Write-Verbose -Verbose 'Destination path: ${{ parameters.PackagePath }}' - - # Create global tool NuSpec source for package. - Import-Module -Name $env:REPOROOT\build.psm1 - Import-Module -Name $env:REPOROOT\tools\packaging - New-GlobalToolNupkgSource -PackageType $PackageType -PackageVersion '${{ parameters.PackageVersion }}' -LinuxBinPath '${{ parameters.LinuxBinPath }}' -WindowsBinPath '${{ parameters.WindowsBinPath }}' -WindowsDesktopBinPath '${{ parameters.WindowsDesktopBinPath }}' -AlpineBinPath '${{ parameters.AlpineBinPath }}' - displayName: 'Create global tool NuSpec source for package.' - - - pwsh: | - Get-ChildItem -Path env: - displayName: 'Capture environment variables after Global Tool package source is created.' - - # NOTE: The above 'New-GlobalToolNupkgSource' task function sets the 'GlobalToolNuSpecSourcePath', 'GlobalToolPkgName', - # and 'GlobalToolCGManifestPath' environment variables. - - template: Sbom.yml@ComplianceRepo - parameters: - BuildDropPath: $(GlobalToolNuSpecSourcePath) - Build_Repository_Uri: 'https://github.com/powershell/powershell' - PackageName: $(GlobalToolPkgName) - PackageVersion: ${{ parameters.PackageVersion }} - sourceScanPath: $(GlobalToolCGManifestPath) - displayName: SBOM for Global Tool package - - - pwsh: | - Import-Module -Name $env:REPOROOT\build.psm1 - Import-Module -Name $env:REPOROOT\tools\packaging - New-GlobalToolNupkgFromSource -PackageNuSpecPath "$env:GlobalToolNuSpecSourcePath" -PackageName "$env:GlobalToolPkgName" -DestinationPath '${{ parameters.DestinationPath }}' -CGManifestPath "$env:GlobalToolCGManifestPath" - displayName: 'Create global tool NuSpec package from NuSpec source.' diff --git a/tools/releaseBuild/azureDevOps/templates/insert-nuget-config-azfeed.yml b/tools/releaseBuild/azureDevOps/templates/insert-nuget-config-azfeed.yml deleted file mode 100644 index 61b9df6c342..00000000000 --- a/tools/releaseBuild/azureDevOps/templates/insert-nuget-config-azfeed.yml +++ /dev/null @@ -1,8 +0,0 @@ -parameters: -- name: "repoRoot" - default: $(REPOROOT) -steps: - - template: /.pipelines/templates/insert-nuget-config-azfeed.yml@self - parameters: - repoRoot: $(REPOROOT) - diff --git a/tools/releaseBuild/azureDevOps/templates/json.yml b/tools/releaseBuild/azureDevOps/templates/json.yml deleted file mode 100644 index 48a50e0bf14..00000000000 --- a/tools/releaseBuild/azureDevOps/templates/json.yml +++ /dev/null @@ -1,57 +0,0 @@ -parameters: - parentJobs: [] - -jobs: -- job: json - variables: - - name: runCodesignValidationInjection - value : false - - name: NugetSecurityAnalysisWarningLevel - value: none - displayName: Create Json for Blob - dependsOn: - ${{ parameters.parentJobs }} - condition: succeeded() - pool: - name: $(windowsPool) - demands: - - ImageOverride -equals PSMMS2019-Secure - - steps: - #- task: @ - # inputs: - # - # displayName: '' - - checkout: self - clean: true - - - template: SetVersionVariables.yml - parameters: - ReleaseTagVar: $(ReleaseTagVar) - CreateJson: yes - - - task: AzureFileCopy@4 - displayName: 'upload daily-build-info JSON file to Azure - ${{ parameters.architecture }}' - inputs: - SourcePath: '$(BuildInfoPath)' - azureSubscription: '$(AzureFileCopySubscription)' - Destination: AzureBlob - storage: '$(StorageAccount)' - ContainerName: 'BuildInfo' - condition: and(succeeded(), eq(variables['IS_DAILY'], 'true')) - - - task: AzureCLI@1 - displayName: 'Make blob public' - inputs: - azureSubscription: '$(AzureFileCopySubscription)' - scriptLocation: inlineScript - inlineScript: 'az storage container set-permission --account-name $(StorageAccount) --name $(azureVersion) --public-access blob' - condition: and(succeeded(), eq(variables['IS_DAILY'], 'true')) - - - task: ms.vss-governance-buildtask.governance-build-task-component-detection.ComponentGovernanceComponentDetection@0 - displayName: 'Component Detection' - inputs: - sourceScanPath: '$(Build.SourcesDirectory)\tools' - snapshotForceEnabled: true - - - template: /tools/releaseBuild/azureDevOps/templates/step/finalize.yml diff --git a/tools/releaseBuild/azureDevOps/templates/linux-authenticode-sign.yml b/tools/releaseBuild/azureDevOps/templates/linux-authenticode-sign.yml deleted file mode 100644 index 719ba1a6c30..00000000000 --- a/tools/releaseBuild/azureDevOps/templates/linux-authenticode-sign.yml +++ /dev/null @@ -1,184 +0,0 @@ -jobs: -- job: sign_linux_builds - displayName: Sign all linux builds - condition: succeeded() - pool: - name: PowerShell1ES - demands: - - ImageOverride -equals PSMMS2019-Secure - dependsOn: ['build_fxdependent', 'build_rpm'] - variables: - - name: runCodesignValidationInjection - value: false - - name: NugetSecurityAnalysisWarningLevel - value: none - - group: ESRP - - steps: - - checkout: self - clean: true - - - task: DownloadPipelineArtifact@2 - inputs: - artifact: pwshLinuxBuild.tar.gz - path: $(Build.ArtifactStagingDirectory)/linuxTars - displayName: Download deb build - - - task: DownloadPipelineArtifact@2 - inputs: - artifact: pwshLinuxBuildMinSize.tar.gz - path: $(Build.ArtifactStagingDirectory)/linuxTars - displayName: Download min-size build - - - task: DownloadPipelineArtifact@2 - inputs: - artifact: pwshLinuxBuildArm32.tar.gz - path: $(Build.ArtifactStagingDirectory)/linuxTars - displayName: Download arm32 build - - - task: DownloadPipelineArtifact@2 - inputs: - artifact: pwshLinuxBuildArm64.tar.gz - path: $(Build.ArtifactStagingDirectory)/linuxTars - displayName: Download arm64 build - - - task: DownloadPipelineArtifact@2 - inputs: - artifact: pwshMarinerBuildAmd64.tar.gz - path: $(Build.ArtifactStagingDirectory)/linuxTars - displayName: Download mariner build - - - task: DownloadPipelineArtifact@2 - inputs: - artifact: pwshMarinerBuildArm64.tar.gz - path: $(Build.ArtifactStagingDirectory)/linuxTars - displayName: Download mariner arm64 build - - - task: DownloadPipelineArtifact@2 - inputs: - artifact: pwshLinuxBuildAlpine.tar.gz - path: $(Build.ArtifactStagingDirectory)/linuxTars/pwshLinuxBuildAlpine.tar.gz - displayName: Download alpine build - - - task: DownloadPipelineArtifact@2 - inputs: - artifact: pwshLinuxBuildAlpine.tar.gz - path: $(Build.ArtifactStagingDirectory)/linuxTars/pwshAlpineFxdBuildAmd64.tar.gz - displayName: Download alpine fxdependent build - - - task: DownloadPipelineArtifact@2 - inputs: - artifact: pwshLinuxBuildFxdependent.tar.gz - path: $(Build.ArtifactStagingDirectory)/linuxTars/pwshLinuxBuildFxdependent.tar.gz - displayName: Download fxdependent build - - - pwsh: | - Get-ChildItem -Path $(Build.ArtifactStagingDirectory)/linuxTars - displayName: Capture downloaded tars - - - pwsh: | - Write-Verbose -Verbose -Message "Expanding $(Build.ArtifactStagingDirectory)/linuxTars/pwshLinuxBuild.tar.gz to $(Build.ArtifactStagingDirectory)/pwshLinuxBuild" - New-Item -Path $(Build.ArtifactStagingDirectory)/pwshLinuxBuild -ItemType Directory - tar -xf $(Build.ArtifactStagingDirectory)/linuxTars/pwshLinuxBuild.tar.gz -C $(Build.ArtifactStagingDirectory)/pwshLinuxBuild - Write-Verbose -Verbose "File permisions after expanding" - Get-ChildItem -Path $(Build.ArtifactStagingDirectory)/pwshLinuxBuild/pwsh | Select-Object -Property 'unixmode', 'size', 'name' - - Write-Verbose -Verbose -Message "Expanding $(Build.ArtifactStagingDirectory)/linuxTars/pwshLinuxBuildMinSize.tar.gz to $(Build.ArtifactStagingDirectory)/pwshLinuxBuildMinSize" - New-Item -Path $(Build.ArtifactStagingDirectory)/pwshLinuxBuildMinSize -ItemType Directory - tar -xf $(Build.ArtifactStagingDirectory)/linuxTars/pwshLinuxBuildMinSize.tar.gz -C $(Build.ArtifactStagingDirectory)/pwshLinuxBuildMinSize - - Write-Verbose -Verbose -Message "Expanding $(Build.ArtifactStagingDirectory)/linuxTars/pwshLinuxBuildArm32.tar.gz to $(Build.ArtifactStagingDirectory)/pwshLinuxBuildArm32" - New-Item -Path $(Build.ArtifactStagingDirectory)/pwshLinuxBuildArm32 -ItemType Directory - tar -xf $(Build.ArtifactStagingDirectory)/linuxTars/pwshLinuxBuildArm32.tar.gz -C $(Build.ArtifactStagingDirectory)/pwshLinuxBuildArm32 - - Write-Verbose -Verbose -Message "Expanding $(Build.ArtifactStagingDirectory)/linuxTars/pwshLinuxBuildArm64.tar.gz to $(Build.ArtifactStagingDirectory)/pwshLinuxBuildArm64" - New-Item -Path $(Build.ArtifactStagingDirectory)/pwshLinuxBuildArm64 -ItemType Directory - tar -xf $(Build.ArtifactStagingDirectory)/linuxTars/pwshLinuxBuildArm64.tar.gz -C $(Build.ArtifactStagingDirectory)/pwshLinuxBuildArm64 - - Write-Verbose -Verbose -Message "Expanding $(Build.ArtifactStagingDirectory)/linuxTars/pwshMarinerBuildAmd64.tar.gz to $(Build.ArtifactStagingDirectory)/pwshMarinerBuildAmd64" - New-Item -Path $(Build.ArtifactStagingDirectory)/pwshMarinerBuildAmd64 -ItemType Directory - tar -xf $(Build.ArtifactStagingDirectory)/linuxTars/pwshMarinerBuildAmd64.tar.gz -C $(Build.ArtifactStagingDirectory)/pwshMarinerBuildAmd64 - - Write-Verbose -Verbose -Message "Expanding $(Build.ArtifactStagingDirectory)/linuxTars/pwshMarinerBuildArm64.tar.gz to $(Build.ArtifactStagingDirectory)/pwshMarinerBuildArm64" - New-Item -Path $(Build.ArtifactStagingDirectory)/pwshMarinerBuildArm64 -ItemType Directory - tar -xf $(Build.ArtifactStagingDirectory)/linuxTars/pwshMarinerBuildArm64.tar.gz -C $(Build.ArtifactStagingDirectory)/pwshMarinerBuildArm64 - - Write-Verbose -Verbose -Message "Expanding $(Build.ArtifactStagingDirectory)/linuxTars/pwshLinuxBuildAlpine.tar.gz/pwshLinuxBuild.tar.gz to $(Build.ArtifactStagingDirectory)/pwshLinuxBuildAlpine" - New-Item -Path $(Build.ArtifactStagingDirectory)/pwshLinuxBuildAlpine -ItemType Directory - tar -xf $(Build.ArtifactStagingDirectory)/linuxTars/pwshLinuxBuildAlpine.tar.gz/pwshLinuxBuild.tar.gz -C $(Build.ArtifactStagingDirectory)/pwshLinuxBuildAlpine - - Write-Verbose -Verbose -Message "Expanding $(Build.ArtifactStagingDirectory)/linuxTars/pwshAlpineFxdBuildAmd64.tar.gz/pwshAlpineFxdBuildAmd64.tar.gz to $(Build.ArtifactStagingDirectory)/pwshLinuxBuildAlpineFxd" - New-Item -Path $(Build.ArtifactStagingDirectory)/pwshLinuxBuildAlpineFxd -ItemType Directory - tar -xf $(Build.ArtifactStagingDirectory)/linuxTars/pwshAlpineFxdBuildAmd64.tar.gz/pwshAlpineFxdBuildAmd64.tar.gz -C $(Build.ArtifactStagingDirectory)/pwshLinuxBuildAlpineFxd - - Write-Verbose -Verbose -Message "Expanding $(Build.ArtifactStagingDirectory)/linuxTars/pwshLinuxBuildFxdependent.tar.gz/pwshLinuxBuild.tar.gz to $(Build.ArtifactStagingDirectory)/pwshLinuxBuildFxdependent" - New-Item -Path $(Build.ArtifactStagingDirectory)/pwshLinuxBuildFxdependent -ItemType Directory - tar -xf $(Build.ArtifactStagingDirectory)/linuxTars/pwshLinuxBuildFxdependent.tar.gz/pwshLinuxBuild.tar.gz -C $(Build.ArtifactStagingDirectory)/pwshLinuxBuildFxdependent - displayName: Expand builds - - - template: SetVersionVariables.yml - parameters: - ReleaseTagVar: $(ReleaseTagVar) - - - template: cloneToOfficialPath.yml - - - template: insert-nuget-config-azfeed.yml - parameters: - repoRoot: $(PowerShellRoot) - - - pwsh: | - Set-Location $env:POWERSHELLROOT - import-module "$env:POWERSHELLROOT/build.psm1" - Sync-PSTags -AddRemoteIfMissing - displayName: SyncTags - condition: and(succeeded(), ne(variables['SkipBuild'], 'true')) - - - checkout: ComplianceRepo - clean: true - - - template: shouldSign.yml - - - template: signBuildFiles.yml - parameters: - binLocation: pwshLinuxBuild - buildPrefixName: 'PowerShell Linux' - - - template: signBuildFiles.yml - parameters: - binLocation: pwshLinuxBuildMinSize - buildPrefixName: 'PowerShell Linux Minimum Size' - - - template: signBuildFiles.yml - parameters: - binLocation: pwshLinuxBuildArm32 - buildPrefixName: 'PowerShell Linux Arm32' - - - template: signBuildFiles.yml - parameters: - binLocation: pwshLinuxBuildArm64 - buildPrefixName: 'PowerShell Linux Arm64' - - - template: signBuildFiles.yml - parameters: - binLocation: pwshMarinerBuildAmd64 - buildPrefixName: 'PowerShell Linux x64 (Mariner) Framework Dependent' - - - template: signBuildFiles.yml - parameters: - binLocation: pwshMarinerBuildArm64 - buildPrefixName: 'PowerShell Linux arm64 (Mariner) Framework Dependent' - - - template: signBuildFiles.yml - parameters: - binLocation: pwshLinuxBuildAlpine - buildPrefixName: 'PowerShell Linux Alpine x64' - - - template: signBuildFiles.yml - parameters: - binLocation: pwshLinuxBuildAlpineFxd - buildPrefixName: 'PowerShell Linux Alpine Fxd x64' - - - template: signBuildFiles.yml - parameters: - binLocation: pwshLinuxBuildFxdependent - buildPrefixName: 'PowerShell Linux Framework Dependent' diff --git a/tools/releaseBuild/azureDevOps/templates/linux-packaging.yml b/tools/releaseBuild/azureDevOps/templates/linux-packaging.yml deleted file mode 100644 index 59db37c64ac..00000000000 --- a/tools/releaseBuild/azureDevOps/templates/linux-packaging.yml +++ /dev/null @@ -1,489 +0,0 @@ -parameters: - buildName: '' - uploadDisplayName: 'Upload' - -jobs: -- job: pkg_${{ parameters.buildName }} - displayName: Package ${{ parameters.buildName }} - condition: succeeded() - pool: - name: PowerShell1ES - demands: - - ImageOverride -equals PSMMSUbuntu20.04-Secure - variables: - - name: runCodesignValidationInjection - value: false - - name: build - value: ${{ parameters.buildName }} - - name: NugetSecurityAnalysisWarningLevel - value: none - - group: ESRP - - group: DotNetPrivateBuildAccess - - steps: - - ${{ if or(eq(variables.build,'deb'), eq(variables.build,'rpm')) }} : - - task: DownloadPipelineArtifact@2 - inputs: - artifact: authenticode-signed - path: $(Build.ArtifactStagingDirectory)/pwshLinuxBuild-signed - pattern: '**/pwshLinuxBuild.tar.gz' - displayName: Download deb build - - - ${{ if eq(variables.build,'deb') }} : - - task: DownloadPipelineArtifact@2 - inputs: - artifact: authenticode-signed - path: $(Build.ArtifactStagingDirectory)/pwshLinuxBuildMinSize-signed - pattern: '**/pwshLinuxBuildMinSize.tar.gz' - displayName: Download min-size build - - - ${{ if eq(variables.build,'deb') }} : - - task: DownloadPipelineArtifact@2 - inputs: - artifact: authenticode-signed - path: $(Build.ArtifactStagingDirectory)/pwshLinuxBuildArm32-signed - pattern: '**/pwshLinuxBuildArm32.tar.gz' - displayName: Download arm32 build - - - ${{ if eq(variables.build,'deb') }} : - - task: DownloadPipelineArtifact@2 - inputs: - artifact: authenticode-signed - path: $(Build.ArtifactStagingDirectory)/pwshLinuxBuildArm64-signed - pattern: '**/pwshLinuxBuildArm64.tar.gz' - displayName: Download arm64 build - - - ${{ if eq(variables.build,'rpm') }} : - - task: DownloadPipelineArtifact@2 - inputs: - artifact: authenticode-signed - path: $(Build.ArtifactStagingDirectory)/pwshMarinerBuildAmd64-signed - pattern: '**/pwshMarinerBuildAmd64.tar.gz' - displayName: Download mariner amd64 build - - - ${{ if eq(variables.build,'rpm') }} : - - task: DownloadPipelineArtifact@2 - inputs: - artifact: authenticode-signed - path: $(Build.ArtifactStagingDirectory)/pwshMarinerBuildArm64-signed - pattern: '**/pwshMarinerBuildArm64.tar.gz' - displayName: Download mariner arm64 build - - - ${{ if eq(variables.build,'alpine') }} : - - task: DownloadPipelineArtifact@2 - inputs: - artifact: authenticode-signed - path: $(Build.ArtifactStagingDirectory)/pwshLinuxBuildAlpine-signed - pattern: '**/pwshLinuxBuildAlpine.tar.gz' - displayName: Download alpine build - - - ${{ if eq(variables.build,'alpine') }} : - - task: DownloadPipelineArtifact@2 - inputs: - artifact: authenticode-signed - path: $(Build.ArtifactStagingDirectory)/pwshAlpineFxdBuildAmd64-signed - pattern: '**/pwshAlpineFxdBuildAmd64.tar.gz' - displayName: Download alpine framework dependent build - - - ${{ if eq(variables.build,'fxdependent') }} : - - task: DownloadPipelineArtifact@2 - inputs: - artifact: authenticode-signed - path: $(Build.ArtifactStagingDirectory)/pwshLinuxBuildFxdependent-signed - pattern: '**/pwshLinuxBuildFxdependent.tar.gz' - displayName: Download fxdependent build - - - ${{ if or(eq(variables.build,'deb'), eq(variables.build,'rpm')) }} : - - task: DownloadPipelineArtifact@2 - inputs: - artifact: pwshLinuxBuild-meta - path: $(Build.ArtifactStagingDirectory)/pwshLinuxBuild-meta - displayName: Download deb build meta - - - ${{ if eq(variables.build,'deb') }} : - - task: DownloadPipelineArtifact@2 - inputs: - artifact: pwshLinuxBuildMinSize-meta - path: $(Build.ArtifactStagingDirectory)/pwshLinuxBuildMinSize-meta - displayName: Download min-size build meta - - - ${{ if eq(variables.build,'deb') }} : - - task: DownloadPipelineArtifact@2 - inputs: - artifact: pwshLinuxBuildArm32-meta - path: $(Build.ArtifactStagingDirectory)/pwshLinuxBuildArm32-meta - displayName: Download arm32 build meta - - - ${{ if eq(variables.build,'deb') }} : - - task: DownloadPipelineArtifact@2 - inputs: - artifact: pwshLinuxBuildArm64-meta - path: $(Build.ArtifactStagingDirectory)/pwshLinuxBuildArm64-meta - displayName: Download arm64 build meta - - - ${{ if eq(variables.build,'rpm') }} : - - task: DownloadPipelineArtifact@2 - inputs: - artifact: pwshMarinerBuildAmd64-meta - path: $(Build.ArtifactStagingDirectory)/pwshMarinerBuildAmd64-meta - displayName: Download mariner x64 build meta - - - ${{ if eq(variables.build,'rpm') }} : - - task: DownloadPipelineArtifact@2 - inputs: - artifact: pwshMarinerBuildArm64-meta - path: $(Build.ArtifactStagingDirectory)/pwshMarinerBuildArm64-meta - displayName: Download mariner arm64 build meta - - - ${{ if eq(variables.build,'alpine') }} : - - task: DownloadPipelineArtifact@2 - inputs: - artifact: pwshLinuxBuildAlpine-meta - path: $(Build.ArtifactStagingDirectory)/pwshLinuxBuild-meta - displayName: Download alpine build meta - - - ${{ if eq(variables.build,'alpine') }} : - - task: DownloadPipelineArtifact@2 - inputs: - artifact: pwshAlpineFxdBuildAmd64-meta - path: $(Build.ArtifactStagingDirectory)/pwshAlpineFxdBuildAmd64-meta - displayName: Download alpine build meta - - - ${{ if eq(variables.build,'fxdependent') }} : - - task: DownloadPipelineArtifact@2 - inputs: - artifact: pwshLinuxBuildFxdependent-meta - path: $(Build.ArtifactStagingDirectory)/pwshLinuxBuild-meta - displayName: Download fxdependent build meta - - - pwsh: | - Get-ChildItem '$(Build.ArtifactStagingDirectory)' | Select-Object -Property 'unixmode', 'size', 'name' - displayName: Capture downloads - - - pwsh: | - if ('$(build)' -eq 'deb' -or '$(build)' -eq 'rpm') { - Write-Verbose -Verbose "Expanding $(Build.ArtifactStagingDirectory)/pwshLinuxBuild-signed/pwshLinuxBuild.tar.gz to $(Build.ArtifactStagingDirectory)/pwshLinuxBuild" - New-Item -Path $(Build.ArtifactStagingDirectory)/pwshLinuxBuild -ItemType Directory - tar -xf $(Build.ArtifactStagingDirectory)/pwshLinuxBuild-signed/pwshLinuxBuild.tar.gz -C $(Build.ArtifactStagingDirectory)/pwshLinuxBuild - } - - if ('$(build)' -eq 'deb') { - Write-Verbose -Verbose "Expanding $(Build.ArtifactStagingDirectory)/pwshLinuxBuildMinSize-signed/pwshLinuxBuildMinSize.tar.gz to $(Build.ArtifactStagingDirectory)/pwshLinuxBuildMinSize" - New-Item -Path $(Build.ArtifactStagingDirectory)/pwshLinuxBuildMinSize -ItemType Directory - tar -xf $(Build.ArtifactStagingDirectory)/pwshLinuxBuildMinSize-signed/pwshLinuxBuildMinSize.tar.gz -C $(Build.ArtifactStagingDirectory)/pwshLinuxBuildMinSize - - Write-Verbose -Verbose "Expanding $(Build.ArtifactStagingDirectory)/pwshLinuxBuildArm32-signed/pwshLinuxBuildArm32.tar.gz to $(Build.ArtifactStagingDirectory)/pwshLinuxBuildArm32" - New-Item -Path $(Build.ArtifactStagingDirectory)/pwshLinuxBuildArm32 -ItemType Directory - tar -xf $(Build.ArtifactStagingDirectory)/pwshLinuxBuildArm32-signed/pwshLinuxBuildArm32.tar.gz -C $(Build.ArtifactStagingDirectory)/pwshLinuxBuildArm32 - - Write-Verbose -Verbose "Expanding $(Build.ArtifactStagingDirectory)/pwshLinuxBuildArm64-signed/pwshLinuxBuildArm64.tar.gz to $(Build.ArtifactStagingDirectory)/pwshLinuxBuildArm64" - New-Item -Path $(Build.ArtifactStagingDirectory)/pwshLinuxBuildArm64 -ItemType Directory - tar -xf $(Build.ArtifactStagingDirectory)/pwshLinuxBuildArm64-signed/pwshLinuxBuildArm64.tar.gz -C $(Build.ArtifactStagingDirectory)/pwshLinuxBuildArm64 - } - - if ('$(build)' -eq 'rpm') { - # for mariner x64 - Write-Verbose -Verbose "Expanding $(Build.ArtifactStagingDirectory)/pwshMarinerBuildAmd64-signed/pwshMarinerBuildAmd64.tar.gz to $(Build.ArtifactStagingDirectory)/pwshMarinerBuildAmd64" - New-Item -Path $(Build.ArtifactStagingDirectory)/pwshMarinerBuildAmd64 -ItemType Directory - tar -xf $(Build.ArtifactStagingDirectory)/pwshMarinerBuildAmd64-signed/pwshMarinerBuildAmd64.tar.gz -C $(Build.ArtifactStagingDirectory)/pwshMarinerBuildAmd64 - - # for mariner arm64 - Write-Verbose -Verbose "Expanding $(Build.ArtifactStagingDirectory)/pwshMarinerBuildArm64-signed/pwshMarinerBuildArm64.tar.gz to $(Build.ArtifactStagingDirectory)/pwshMarinerBuildArm64" - New-Item -Path $(Build.ArtifactStagingDirectory)/pwshMarinerBuildArm64 -ItemType Directory - tar -xf $(Build.ArtifactStagingDirectory)/pwshMarinerBuildArm64-signed/pwshMarinerBuildArm64.tar.gz -C $(Build.ArtifactStagingDirectory)/pwshMarinerBuildArm64 - } - - if ('$(build)' -eq 'alpine') { - Write-Verbose -Verbose "Expanding $(Build.ArtifactStagingDirectory)/pwshLinuxBuildAlpine-signed/pwshLinuxBuildAlpine.tar.gz to $(Build.ArtifactStagingDirectory)/pwshLinuxBuild" - New-Item -Path $(Build.ArtifactStagingDirectory)/pwshLinuxBuild -ItemType Directory - tar -xf $(Build.ArtifactStagingDirectory)/pwshLinuxBuildAlpine-signed/pwshLinuxBuildAlpine.tar.gz -C $(Build.ArtifactStagingDirectory)/pwshLinuxBuild - - Write-Verbose -Verbose "Expanding $(Build.ArtifactStagingDirectory)/pwshAlpineFxdBuildAmd64-signed/pwshAlpineFxdBuildAmd64.tar.gz to $(Build.ArtifactStagingDirectory)/pwshAlpineFxdBuildAmd64" - New-Item -Path $(Build.ArtifactStagingDirectory)/pwshAlpineFxdBuildAmd64 -ItemType Directory - tar -xf $(Build.ArtifactStagingDirectory)/pwshAlpineFxdBuildAmd64-signed/pwshAlpineFxdBuildAmd64.tar.gz -C $(Build.ArtifactStagingDirectory)/pwshAlpineFxdBuildAmd64 - } - - if ('$(build)' -eq 'fxdependent') { - Write-Verbose -Verbose "Expanding $(Build.ArtifactStagingDirectory)/pwshLinuxBuildFxdependent-signed/pwshLinuxBuildFxdependent.tar.gz to $(Build.ArtifactStagingDirectory)/pwshLinuxBuild" - New-Item -Path $(Build.ArtifactStagingDirectory)/pwshLinuxBuild -ItemType Directory - tar -xf $(Build.ArtifactStagingDirectory)/pwshLinuxBuildFxdependent-signed/pwshLinuxBuildFxdependent.tar.gz -C $(Build.ArtifactStagingDirectory)/pwshLinuxBuild - } - displayName: Expand all signed tar.gz - - - pwsh: | - Get-ChildItem '$(Build.ArtifactStagingDirectory)' | Select-Object -Property 'unixmode', 'size', 'name' - displayName: Capture expanded - - - checkout: self - clean: true - - - checkout: ComplianceRepo - clean: true - - - template: SetVersionVariables.yml - parameters: - ReleaseTagVar: $(ReleaseTagVar) - - - pwsh: | - # create folder - sudo mkdir /PowerShell - - # make the current user the owner - sudo chown $env:USER /PowerShell - displayName: 'Create /PowerShell' - - - template: cloneToOfficialPath.yml - - - template: insert-nuget-config-azfeed.yml - parameters: - repoRoot: $(PowerShellRoot) - - - powershell: | - import-module "$env:POWERSHELLROOT/build.psm1" - Sync-PSTags -AddRemoteIfMissing - displayName: SyncTags - condition: and(succeeded(), ne(variables['SkipBuild'], 'true')) - workingDirectory: $(PowerShellRoot) - - - powershell: | - Import-Module "$env:POWERSHELLROOT/build.psm1" - - Start-PSBootstrap -Package - displayName: 'Bootstrap' - condition: and(succeeded(), ne(variables['SkipBuild'], 'true')) - workingDirectory: $(PowerShellRoot) - env: - __DOTNET_RUNTIME_FEED_KEY: $(RUNTIME_SOURCEFEED_KEY) - - - powershell: | - try { - Import-Module "$env:POWERSHELLROOT/build.psm1" - Import-Module "$env:POWERSHELLROOT/tools/packaging" - - $metadata = Get-Content "$env:POWERSHELLROOT/tools/metadata.json" -Raw | ConvertFrom-Json - - # LTSRelease.Package indicates that the release should be packaged as an LTS - $LTS = $metadata.LTSRelease.Package - Write-Verbose -Verbose -Message "LTS is set to: $LTS" - - Invoke-AzDevOpsLinuxPackageCreation -ReleaseTag '$(ReleaseTagVar)' -BuildType '$(build)' - - if ($LTS) { - Write-Verbose -Verbose "Packaging LTS" - Invoke-AzDevOpsLinuxPackageCreation -LTS -ReleaseTag '$(ReleaseTagVar)' -BuildType '$(build)' - } - } catch { - Get-Error - throw - } - displayName: 'Package' - condition: and(succeeded(), ne(variables['SkipBuild'], 'true')) - workingDirectory: $(PowerShellRoot) - - - powershell: | - $linuxPackages = Get-ChildItem "$env:POWERSHELLROOT/powershell*" -Include *.deb,*.rpm,*.tar.gz - - $bucket = 'release' - foreach ($linuxPackage in $linuxPackages) - { - $filePath = $linuxPackage.FullName - Write-Verbose "Publishing $filePath to $bucket" -Verbose - Write-Host "##vso[artifact.upload containerfolder=$bucket;artifactname=$bucket]$filePath" - } - displayName: Publish artifacts - condition: and(succeeded(), ne(variables['SkipBuild'], 'true')) - workingDirectory: $(PowerShellRoot) - retryCountOnTaskFailure: 2 - - - - template: /tools/releaseBuild/azureDevOps/templates/step/finalize.yml - -- job: upload_${{ parameters.buildName }} - displayName: ${{ parameters.uploadDisplayName }} ${{ parameters.buildName }} - dependsOn: pkg_${{ parameters.buildName }} - condition: succeeded() - pool: - name: PowerShell1ES - demands: - - ImageOverride -equals PSMMS2019-Secure - variables: - - name: buildName - value: ${{ parameters.buildName }} - - group: ESRP - - name: runCodesignValidationInjection - value: false - - name: NugetSecurityAnalysisWarningLevel - value: none - - name: skipComponentGovernanceDetection - value: true - - steps: - - checkout: self - clean: true - - - checkout: ComplianceRepo - clean: true - - - template: SetVersionVariables.yml - parameters: - ReleaseTagVar: $(ReleaseTagVar) - - template: shouldSign.yml - - - task: DownloadBuildArtifacts@0 - displayName: 'Download Deb Artifacts' - inputs: - downloadType: specific - itemPattern: '**/*.deb' - downloadPath: '$(System.ArtifactsDirectory)\finished' - condition: and(eq(variables['buildName'], 'DEB'), succeeded()) - - - task: DownloadBuildArtifacts@0 - displayName: 'Download tar.gz Artifacts copy' - inputs: - downloadType: specific - itemPattern: '**/*.tar.gz' - downloadPath: '$(System.ArtifactsDirectory)\finished' - - - powershell: | - Write-Host 'We handle the min-size package only when uploading for deb build.' - Write-Host '- For deb build, the min-size package is moved to a separate folder "finished\minSize",' - Write-Host ' so that the min-size package can be uploaded to a different Az Blob container.' - Write-Host '- For other builds, the min-size package is removed after being downloaded, so that it' - Write-Host ' does not get accidentally uploaded to the wrong Az Blob container.' - - $minSizePkg = '$(System.ArtifactsDirectory)\finished\release\*-gc.tar.gz' - if (Test-Path -Path $minSizePkg) - { - if ('$(buildName)' -eq 'DEB') - { - $minSizeDir = '$(System.ArtifactsDirectory)\finished\minSize' - New-Item -Path $minSizeDir -Type Directory -Force > $null - Move-Item -Path $minSizePkg -Destination $minSizeDir - - Write-Host "`nCapture the min-size package moved to the target folder." - Get-ChildItem -Path $minSizeDir - } - else - { - Write-Host '$(buildName): Remove the min-size package.' - Remove-Item -Path $minSizePkg -Force - } - } - else - { - Write-Host 'min-size package not found, so skip this step.' - } - displayName: 'Move minSize package to separate folder' - - - task: DownloadBuildArtifacts@0 - displayName: 'Download rpm Artifacts copy' - inputs: - downloadType: specific - itemPattern: '**/*.rpm' - downloadPath: '$(System.ArtifactsDirectory)\rpm' - condition: and(eq(variables['buildName'], 'RPM'), succeeded()) - - - template: EsrpScan.yml@ComplianceRepo - parameters: - scanPath: $(System.ArtifactsDirectory) - pattern: | - **\*.rpm - **\*.deb - **\*.tar.gz - - - ${{ if eq(variables['buildName'], 'RPM') }}: - - template: EsrpSign.yml@ComplianceRepo - parameters: - buildOutputPath: $(System.ArtifactsDirectory)\rpm - signOutputPath: $(Build.StagingDirectory)\signedPackages - certificateId: "CP-450779-Pgp" - pattern: | - **\*.rh.*.rpm - useMinimatch: true - shouldSign: $(SHOULD_SIGN) - displayName: Sign RedHat RPM - OutputMode: AlwaysCopy - - - ${{ if eq(variables['buildName'], 'RPM') }}: - - template: EsrpSign.yml@ComplianceRepo - parameters: - # Sign in-place, previous task copied the files to this folder - buildOutputPath: $(Build.StagingDirectory)\signedPackages - signOutputPath: $(Build.StagingDirectory)\signedPackages - certificateId: "CP-459159-Pgp" - pattern: | - **\*.cm.*.rpm - **\*.cm?.*.rpm - useMinimatch: true - shouldSign: $(SHOULD_SIGN) - displayName: Sign Mariner RPM - OutputMode: NeverCopy - - # requires windows - - ${{ if ne(variables['buildName'], 'RPM') }}: - - task: AzureFileCopy@4 - displayName: 'Upload to Azure - DEB and tar.gz' - inputs: - SourcePath: '$(System.ArtifactsDirectory)\finished\release\*' - azureSubscription: '$(AzureFileCopySubscription)' - Destination: AzureBlob - storage: '$(StorageAccount)' - ContainerName: '$(AzureVersion)' - retryCountOnTaskFailure: 2 - - - template: upload-final-results.yml - parameters: - artifactPath: $(System.ArtifactsDirectory)\finished\release - - # requires windows - - task: AzureFileCopy@4 - displayName: 'Upload to Azure - min-size package for Guest Config' - inputs: - SourcePath: '$(System.ArtifactsDirectory)\finished\minSize\*' - azureSubscription: '$(AzureFileCopySubscription)' - Destination: AzureBlob - storage: '$(StorageAccount)' - ContainerName: '$(AzureVersion)-gc' - condition: and(eq(variables['buildName'], 'DEB'), succeeded()) - retryCountOnTaskFailure: 2 - - - template: upload-final-results.yml - parameters: - artifactPath: $(System.ArtifactsDirectory)\finished\minSize - condition: and(eq(variables['buildName'], 'DEB'), succeeded()) - - # requires windows - - task: AzureFileCopy@4 - displayName: 'Upload to Azure - RPM - Unsigned' - inputs: - SourcePath: '$(System.ArtifactsDirectory)\rpm\release\*' - azureSubscription: '$(AzureFileCopySubscription)' - Destination: AzureBlob - storage: '$(StorageAccount)' - ContainerName: '$(AzureVersion)' - condition: and(and(succeeded(), ne(variables['SHOULD_SIGN'], 'true')),eq(variables['buildName'], 'RPM')) - retryCountOnTaskFailure: 2 - - # requires windows - - task: AzureFileCopy@4 - displayName: 'Upload to Azure - RPM - Signed' - inputs: - SourcePath: '$(Build.StagingDirectory)\signedPackages\release\*' - azureSubscription: '$(AzureFileCopySubscription)' - Destination: AzureBlob - storage: '$(StorageAccount)' - ContainerName: '$(AzureVersion)' - condition: and(and(succeeded(), eq(variables['SHOULD_SIGN'], 'true')),eq(variables['buildName'], 'RPM')) - retryCountOnTaskFailure: 2 - - - template: upload-final-results.yml - parameters: - artifactPath: $(System.ArtifactsDirectory)\rpm\release - condition: and(and(succeeded(), ne(variables['SHOULD_SIGN'], 'true')),eq(variables['buildName'], 'RPM')) - - - template: upload-final-results.yml - parameters: - artifactPath: '$(Build.StagingDirectory)\signedPackages\release' - condition: and(and(succeeded(), eq(variables['SHOULD_SIGN'], 'true')),eq(variables['buildName'], 'RPM')) - - - template: /tools/releaseBuild/azureDevOps/templates/step/finalize.yml diff --git a/tools/releaseBuild/azureDevOps/templates/linux.yml b/tools/releaseBuild/azureDevOps/templates/linux.yml deleted file mode 100644 index bb343bed54e..00000000000 --- a/tools/releaseBuild/azureDevOps/templates/linux.yml +++ /dev/null @@ -1,313 +0,0 @@ -parameters: - buildName: '' - uploadDisplayName: 'Upload' - parentJob: '' - -jobs: -- job: build_${{ parameters.buildName }} - displayName: Build ${{ parameters.buildName }} - condition: succeeded() - pool: - name: PowerShell1ES - demands: - - ImageOverride -equals PSMMSUbuntu20.04-Secure - dependsOn: ${{ parameters.parentJob }} - variables: - - name: runCodesignValidationInjection - value: false - - name: build - value: ${{ parameters.buildName }} - - name: NugetSecurityAnalysisWarningLevel - value: none - - group: ESRP - - group: DotNetPrivateBuildAccess - - steps: - - checkout: self - clean: true - - - checkout: ComplianceRepo - clean: true - - - template: SetVersionVariables.yml - parameters: - ReleaseTagVar: $(ReleaseTagVar) - - - pwsh: | - # create folder - sudo mkdir /PowerShell - - # make the current user the owner - sudo chown $env:USER /PowerShell - displayName: 'Create /PowerShell' - - - template: cloneToOfficialPath.yml - - - template: insert-nuget-config-azfeed.yml - parameters: - repoRoot: $(PowerShellRoot) - - - powershell: | - import-module "$env:POWERSHELLROOT/build.psm1" - Sync-PSTags -AddRemoteIfMissing - displayName: SyncTags - condition: and(succeeded(), ne(variables['SkipBuild'], 'true')) - workingDirectory: $(PowerShellRoot) - - - powershell: | - Import-Module "$env:POWERSHELLROOT/build.psm1" - - Start-PSBootstrap -Package - displayName: 'Bootstrap' - condition: and(succeeded(), ne(variables['SkipBuild'], 'true')) - workingDirectory: $(PowerShellRoot) - env: - __DOTNET_RUNTIME_FEED_KEY: $(RUNTIME_SOURCEFEED_KEY) - - - pwsh: | - try { - Import-Module "$env:POWERSHELLROOT/build.psm1" - Import-Module "$env:POWERSHELLROOT/tools/packaging" - - Invoke-AzDevOpsLinuxPackageBuild -ReleaseTag '$(ReleaseTagVar)' -BuildType '$(build)' - - Write-Verbose -Verbose "File permisions after building" - Get-ChildItem -Path $(System.ArtifactsDirectory)/pwshLinuxBuild/pwsh | Select-Object -Property 'unixmode', 'size', 'name' - - } catch { - Get-Error - throw - } - displayName: 'Build' - condition: and(succeeded(), ne(variables['SkipBuild'], 'true')) - workingDirectory: $(PowerShellRoot) - - - template: Sbom.yml@ComplianceRepo - parameters: - BuildDropPath: '$(System.ArtifactsDirectory)/pwshLinuxBuild' - Build_Repository_Uri: $(Github_Build_Repository_Uri) - displayName: ${{ parameters.buildName }} SBOM - PackageName: PowerShell Linux - PackageVersion: $(Version) - sourceScanPath: '$(PowerShellRoot)/tools' - - - ${{ if eq(variables.build,'rpm') }} : - - template: Sbom.yml@ComplianceRepo - parameters: - BuildDropPath: '$(System.ArtifactsDirectory)/pwshMarinerBuildAmd64' - Build_Repository_Uri: $(Github_Build_Repository_Uri) - displayName: Mariner x64 SBOM - PackageName: PowerShell Linux Framework Dependent - PackageVersion: $(Version) - sourceScanPath: '$(PowerShellRoot)/tools' - - - ${{ if eq(variables.build,'rpm') }} : - - template: Sbom.yml@ComplianceRepo - parameters: - BuildDropPath: '$(System.ArtifactsDirectory)/pwshMarinerBuildArm64' - Build_Repository_Uri: $(Github_Build_Repository_Uri) - displayName: Mariner arm64 SBOM - PackageName: PowerShell Linux Framework Dependent - PackageVersion: $(Version) - sourceScanPath: '$(PowerShellRoot)/tools' - - - ${{ if eq(variables.build,'deb') }} : - - template: Sbom.yml@ComplianceRepo - parameters: - BuildDropPath: '$(System.ArtifactsDirectory)/pwshLinuxBuildMinSize' - Build_Repository_Uri: $(Github_Build_Repository_Uri) - displayName: MinSize SBOM - PackageName: PowerShell Linux Minimum Size - PackageVersion: $(Version) - sourceScanPath: '$(PowerShellRoot)/tools' - - - ${{ if eq(variables.build,'deb') }} : - - template: Sbom.yml@ComplianceRepo - parameters: - BuildDropPath: '$(System.ArtifactsDirectory)/pwshLinuxBuildArm32' - Build_Repository_Uri: $(Github_Build_Repository_Uri) - displayName: Arm32 SBOM - PackageName: PowerShell Linux Arm32 - PackageVersion: $(Version) - sourceScanPath: '$(PowerShellRoot)/tools' - - - ${{ if eq(variables.build,'deb') }} : - - template: Sbom.yml@ComplianceRepo - parameters: - BuildDropPath: '$(System.ArtifactsDirectory)/pwshLinuxBuildArm64' - Build_Repository_Uri: $(Github_Build_Repository_Uri) - displayName: Arm64 SBOM - PackageName: PowerShell Linux Arm64 - PackageVersion: $(Version) - sourceScanPath: '$(PowerShellRoot)/tools' - - - ${{ if eq(variables.build,'alpine') }} : - - template: Sbom.yml@ComplianceRepo - parameters: - BuildDropPath: '$(System.ArtifactsDirectory)/pwshAlpineFxdBuildAmd64' - Build_Repository_Uri: $(Github_Build_Repository_Uri) - displayName: Alpine FXD SBOM - PackageName: PowerShell Alpine Framework Dependent AMD64 - PackageVersion: $(Version) - sourceScanPath: '$(PowerShellRoot)/tools' - - - pwsh: | - Set-Location '$(System.ArtifactsDirectory)/pwshLinuxBuild' - Write-Verbose -Verbose "File permisions before compressing" - Get-ChildItem -Path $(Build.ArtifactStagingDirectory)/pwshLinuxBuild/pwsh | Select-Object -Property 'unixmode', 'size', 'name' - tar -czvf $(System.ArtifactsDirectory)/pwshLinuxBuild.tar.gz * - displayName: Compress pwshLinuxBuild - - - ${{ if eq(variables.build,'deb') }} : - - pwsh: | - Set-Location '$(System.ArtifactsDirectory)/pwshLinuxBuildMinSize' - tar -czvf $(System.ArtifactsDirectory)/pwshLinuxBuildMinSize.tar.gz * - Set-Location '$(System.ArtifactsDirectory)/pwshLinuxBuildArm32' - tar -czvf $(System.ArtifactsDirectory)/pwshLinuxBuildArm32.tar.gz * - Set-Location '$(System.ArtifactsDirectory)/pwshLinuxBuildArm64' - tar -czvf $(System.ArtifactsDirectory)/pwshLinuxBuildArm64.tar.gz * - displayName: Compress deb - - - ${{ if eq(variables.build,'rpm') }} : - - pwsh: | - Set-Location '$(System.ArtifactsDirectory)/pwshMarinerBuildAmd64' - tar -czvf $(System.ArtifactsDirectory)/pwshMarinerBuildAmd64.tar.gz * - displayName: Compress pwshMarinerBuildAmd64 - - - ${{ if eq(variables.build,'alpine') }} : - - pwsh: | - Set-Location '$(System.ArtifactsDirectory)/pwshAlpineFxdBuildAmd64' - tar -czvf $(System.ArtifactsDirectory)/pwshAlpineFxdBuildAmd64.tar.gz * - displayName: Compress pwshAlpineFxdBuildAmd64 - - - ${{ if eq(variables.build,'rpm') }} : - - pwsh: | - Set-Location '$(System.ArtifactsDirectory)/pwshMarinerBuildArm64' - tar -czvf $(System.ArtifactsDirectory)/pwshMarinerBuildArm64.tar.gz * - displayName: Compress pwshMarinerBuildArm64 - - - ${{ if eq(variables.build,'deb') }} : - - task: PublishPipelineArtifact@1 - inputs: - path: '$(System.ArtifactsDirectory)/pwshLinuxBuild.tar.gz' - artifactName: pwshLinuxBuild.tar.gz - retryCountOnTaskFailure: 2 - - - ${{ if eq(variables.build,'deb') }} : - - task: PublishPipelineArtifact@1 - inputs: - path: '$(System.ArtifactsDirectory)/pwshLinuxBuild-meta' - artifactName: pwshLinuxBuild-meta - retryCountOnTaskFailure: 2 - - - ${{ if eq(variables.build,'deb') }} : - - task: PublishPipelineArtifact@1 - inputs: - path: '$(System.ArtifactsDirectory)/pwshLinuxBuildMinSize.tar.gz' - artifactName: pwshLinuxBuildMinSize.tar.gz - retryCountOnTaskFailure: 2 - - - ${{ if eq(variables.build,'deb') }} : - - task: PublishPipelineArtifact@1 - inputs: - path: '$(System.ArtifactsDirectory)/pwshLinuxBuildMinSize-meta' - artifactName: pwshLinuxBuildMinSize-meta - retryCountOnTaskFailure: 2 - - - ${{ if eq(variables.build,'deb') }} : - - task: PublishPipelineArtifact@1 - inputs: - path: '$(System.ArtifactsDirectory)/pwshLinuxBuildArm32.tar.gz' - artifactName: pwshLinuxBuildArm32.tar.gz - retryCountOnTaskFailure: 2 - - - ${{ if eq(variables.build,'deb') }} : - - task: PublishPipelineArtifact@1 - inputs: - path: '$(System.ArtifactsDirectory)/pwshLinuxBuildArm32-meta' - artifactName: pwshLinuxBuildArm32-meta - retryCountOnTaskFailure: 2 - - - ${{ if eq(variables.build,'deb') }} : - - task: PublishPipelineArtifact@1 - inputs: - path: '$(System.ArtifactsDirectory)/pwshLinuxBuildArm64.tar.gz' - artifactName: pwshLinuxBuildArm64.tar.gz - retryCountOnTaskFailure: 2 - - - ${{ if eq(variables.build,'deb') }} : - - task: PublishPipelineArtifact@1 - inputs: - path: '$(System.ArtifactsDirectory)/pwshLinuxBuildArm64-meta' - artifactName: pwshLinuxBuildArm64-meta - retryCountOnTaskFailure: 2 - - - ${{ if eq(variables.build,'rpm') }} : - - task: PublishPipelineArtifact@1 - inputs: - path: '$(System.ArtifactsDirectory)/pwshMarinerBuildAmd64.tar.gz' - artifactName: pwshMarinerBuildAmd64.tar.gz - retryCountOnTaskFailure: 2 - - - ${{ if eq(variables.build,'rpm') }} : - - task: PublishPipelineArtifact@1 - inputs: - path: '$(System.ArtifactsDirectory)/pwshMarinerBuildAmd64-meta' - artifactName: pwshMarinerBuildAmd64-meta - retryCountOnTaskFailure: 2 - - - ${{ if eq(variables.build,'rpm') }} : - - task: PublishPipelineArtifact@1 - inputs: - path: '$(System.ArtifactsDirectory)/pwshMarinerBuildArm64.tar.gz' - artifactName: pwshMarinerBuildArm64.tar.gz - retryCountOnTaskFailure: 2 - - - ${{ if eq(variables.build,'rpm') }} : - - task: PublishPipelineArtifact@1 - inputs: - path: '$(System.ArtifactsDirectory)/pwshMarinerBuildArm64-meta' - artifactName: pwshMarinerBuildArm64-meta - retryCountOnTaskFailure: 2 - - - ${{ if eq(variables.build,'alpine') }} : - - task: PublishPipelineArtifact@1 - inputs: - path: '$(System.ArtifactsDirectory)/pwshLinuxBuild.tar.gz' - artifactName: pwshLinuxBuildAlpine.tar.gz - retryCountOnTaskFailure: 2 - - - ${{ if eq(variables.build,'alpine') }} : - - task: PublishPipelineArtifact@1 - inputs: - path: '$(System.ArtifactsDirectory)/pwshLinuxBuild-meta' - artifactName: pwshLinuxBuildAlpine-meta - retryCountOnTaskFailure: 2 - - - ${{ if eq(variables.build,'alpine') }} : - - task: PublishPipelineArtifact@1 - inputs: - path: '$(System.ArtifactsDirectory)/pwshAlpineFxdBuildAmd64.tar.gz' - artifactName: pwshAlpineFxdBuildAmd64.tar.gz - retryCountOnTaskFailure: 2 - - - ${{ if eq(variables.build,'alpine') }} : - - task: PublishPipelineArtifact@1 - inputs: - path: '$(System.ArtifactsDirectory)/pwshAlpineFxdBuildAmd64-meta' - artifactName: pwshAlpineFxdBuildAmd64-meta - retryCountOnTaskFailure: 2 - - - ${{ if eq(variables.build,'fxdependent') }} : - - task: PublishPipelineArtifact@1 - inputs: - path: '$(System.ArtifactsDirectory)/pwshLinuxBuild.tar.gz' - artifactName: pwshLinuxBuildFxdependent.tar.gz - retryCountOnTaskFailure: 2 - - - ${{ if eq(variables.build,'fxdependent') }} : - - task: PublishPipelineArtifact@1 - inputs: - path: '$(System.ArtifactsDirectory)/pwshLinuxBuild-meta' - artifactName: pwshLinuxBuildFxdependent-meta - retryCountOnTaskFailure: 2 diff --git a/tools/releaseBuild/azureDevOps/templates/mac-file-signing.yml b/tools/releaseBuild/azureDevOps/templates/mac-file-signing.yml deleted file mode 100644 index 8159c2bc7d9..00000000000 --- a/tools/releaseBuild/azureDevOps/templates/mac-file-signing.yml +++ /dev/null @@ -1,121 +0,0 @@ -parameters: - buildArchitecture: 'x64' - -jobs: - - job: MacFileSigningJob_${{ parameters.buildArchitecture }} - displayName: macOS File signing ${{ parameters.buildArchitecture }} - condition: succeeded() - pool: - name: PowerShell1ES - demands: - - ImageOverride -equals PSMMS2019-Secure - - variables: - - group: ESRP - - name: runCodesignValidationInjection - value: false - - name: NugetSecurityAnalysisWarningLevel - value: none - - name: repoFolder - value: PowerShell - - name: repoRoot - value: $(Agent.BuildDirectory)\$(repoFolder) - - name: complianceRepoFolder - value: compliance - - steps: - - checkout: self - clean: true - path: $(repoFolder) - - - checkout: ComplianceRepo - clean: true - path: $(complianceRepoFolder) - - - template: SetVersionVariables.yml - parameters: - ReleaseTagVar: $(ReleaseTagVar) - - - template: shouldSign.yml - - - task: DownloadBuildArtifacts@0 - inputs: - artifactName: 'macosBinResults' - itemPattern: '**/*.zip' - downloadPath: '$(System.ArtifactsDirectory)\Symbols' - - - pwsh: | - Get-ChildItem "$(System.ArtifactsDirectory)\*" -Recurse - displayName: 'Capture Downloaded Artifacts' - # Diagnostics is not critical it passes every time it runs - continueOnError: true - - - pwsh: | - $zipPath = Get-Item '$(System.ArtifactsDirectory)\Symbols\macosBinResults\*symbol*${{ parameters.buildArchitecture }}*.zip' - Write-Verbose -Verbose "Zip Path: $zipPath" - - $expandedFolder = $zipPath.BaseName - Write-Host "sending.. vso[task.setvariable variable=SymbolsFolder]$expandedFolder" - Write-Host "##vso[task.setvariable variable=SymbolsFolder]$expandedFolder" - - Expand-Archive -Path $zipPath -Destination "$(System.ArtifactsDirectory)\$expandedFolder" -Force - displayName: Expand symbols zip - - - pwsh: | - Get-ChildItem "$(System.ArtifactsDirectory)\*" -Recurse - displayName: 'Capture artifacts dir Binaries' - - - pwsh: | - Get-ChildItem "$(System.ArtifactsDirectory)\$(SymbolsFolder)" -Recurse -Include pwsh, *.dylib - displayName: 'Capture Expanded Binaries' - # Diagnostics is not critical it passes every time it runs - continueOnError: true - - - pwsh: | - $null = new-item -type directory -path "$(Build.StagingDirectory)\macos" - $zipFile = "$(Build.StagingDirectory)\macos\powershell-files-$(Version)-osx-${{ parameters.buildArchitecture }}.zip" - Get-ChildItem "$(System.ArtifactsDirectory)\$(SymbolsFolder)" -Recurse -Include pwsh, *.dylib | - Compress-Archive -Destination $zipFile - Write-Host $zipFile - displayName: 'Compress macOS binary files' - - - template: EsrpSign.yml@ComplianceRepo - parameters: - buildOutputPath: $(Build.StagingDirectory)\macos - signOutputPath: $(Build.StagingDirectory)\signedMacOSPackages - certificateId: "CP-401337-Apple" - pattern: | - **\*.zip - useMinimatch: true - shouldSign: $(SHOULD_SIGN) - displayName: Sign macOS Binaries - - - pwsh: | - $destination = "$(System.ArtifactsDirectory)\azureMacOs_${{ parameters.buildArchitecture }}" - New-Item -Path $destination -Type Directory - $zipPath = Get-ChildItem "$(Build.StagingDirectory)\signedMacOSPackages\powershell-*.zip" -Recurse | select-object -expandproperty fullname - foreach ($z in $zipPath) { Expand-Archive -Path $z -DestinationPath $destination } - displayName: 'Extract and copy macOS artifacts for upload' - condition: and(succeeded(), eq(variables['SHOULD_SIGN'], 'true')) - - - template: upload-final-results.yml - parameters: - artifactPath: $(System.ArtifactsDirectory)\azureMacOs_${{ parameters.buildArchitecture }} - artifactFilter: "*" - artifactName: signedMacOsBins_${{ parameters.buildArchitecture }} - condition: and(succeeded(), eq(variables['SHOULD_SIGN'], 'true')) - - - ${{ if eq(variables['SHOULD_SIGN'], 'true') }}: - - template: EsrpScan.yml@ComplianceRepo - parameters: - scanPath: $(System.ArtifactsDirectory)\azureMacOs_${{ parameters.buildArchitecture }} - pattern: | - **\* - - - task: ms.vss-governance-buildtask.governance-build-task-component-detection.ComponentGovernanceComponentDetection@0 - displayName: 'Component Detection' - inputs: - sourceScanPath: '$(repoRoot)\tools' - snapshotForceEnabled: true - - - template: /tools/releaseBuild/azureDevOps/templates/step/finalize.yml diff --git a/tools/releaseBuild/azureDevOps/templates/mac-package-build.yml b/tools/releaseBuild/azureDevOps/templates/mac-package-build.yml deleted file mode 100644 index c853a21ef37..00000000000 --- a/tools/releaseBuild/azureDevOps/templates/mac-package-build.yml +++ /dev/null @@ -1,143 +0,0 @@ -parameters: - parentJob: '' - buildArchitecture: x64 - -jobs: -- job: package_macOS_${{ parameters.buildArchitecture }} - displayName: Package macOS ${{ parameters.buildArchitecture }} - condition: succeeded() - pool: - vmImage: macos-latest - variables: - # Turn off Homebrew analytics - - name: HOMEBREW_NO_ANALYTICS - value: 1 - - name: runCodesignValidationInjection - value: false - - name: NugetSecurityAnalysisWarningLevel - value: none - - group: DotNetPrivateBuildAccess - steps: - - checkout: self - clean: true - - - pwsh: | - # create folder - sudo mkdir "$(Agent.TempDirectory)/PowerShell" - - # make the current user the owner - sudo chown $env:USER "$(Agent.TempDirectory)/PowerShell" - displayName: 'Create $(Agent.TempDirectory)/PowerShell' - - - template: SetVersionVariables.yml - parameters: - ReleaseTagVar: $(ReleaseTagVar) - - - template: shouldSign.yml - - - template: cloneToOfficialPath.yml - parameters: - nativePathRoot: '$(Agent.TempDirectory)' - - - task: DownloadBuildArtifacts@0 - displayName: Download macosBinResults - inputs: - artifactName: 'macosBinResults' - itemPattern: '**/*${{ parameters.buildArchitecture }}.zip' - downloadPath: '$(System.ArtifactsDirectory)/Symbols' - - - task: DownloadBuildArtifacts@0 - displayName: Download signedMacOsBins - inputs: - artifactName: 'signedMacOsBins_${{ parameters.buildArchitecture }}' - itemPattern: '**/*' - downloadPath: '$(System.ArtifactsDirectory)/macOsBins' - condition: and(succeeded(), eq(variables['SHOULD_SIGN'], 'true')) - - - pwsh: | - Get-ChildItem "$(System.ArtifactsDirectory)\*" -Recurse - displayName: 'Capture Downloaded Artifacts' - # Diagnostics is not critical it passes every time it runs - continueOnError: true - - - pwsh: | - $zipPath = Get-Item '$(System.ArtifactsDirectory)\Symbols\macosBinResults\*symbol*${{ parameters.buildArchitecture }}.zip' - Write-Verbose -Verbose "Zip Path: $zipPath" - - $expandedFolder = $zipPath.BaseName - Write-Host "sending.. vso[task.setvariable variable=SymbolsFolder]$expandedFolder" - Write-Host "##vso[task.setvariable variable=SymbolsFolder]$expandedFolder" - - Expand-Archive -Path $zipPath -Destination "$(System.ArtifactsDirectory)\$expandedFolder" -Force - displayName: Expand symbols zip - - - pwsh: | - Import-Module $(PowerShellRoot)/build.psm1 -Force - Import-Module $(PowerShellRoot)/tools/packaging -Force - $signedFilesPath = '$(System.ArtifactsDirectory)/macOsBins/signedMacOsBins_${{ parameters.buildArchitecture }}/' - $BuildPath = '$(System.ArtifactsDirectory)\$(SymbolsFolder)' - - Update-PSSignedBuildFolder -BuildPath $BuildPath -SignedFilesPath $SignedFilesPath - displayName: Merge signed files with Build - condition: and(succeeded(), eq(variables['SHOULD_SIGN'], 'true')) - - - template: Sbom.yml@ComplianceRepo - parameters: - BuildDropPath: '$(System.ArtifactsDirectory)/$(SymbolsFolder)' - Build_Repository_Uri: $(Github_Build_Repository_Uri) - PackageName: PowerShell macOS ${{ parameters.buildArchitecture }} - PackageVersion: $(Version) - sourceScanPath: '$(PowerShellRoot)/tools' - - - pwsh: | - Import-Module $(PowerShellRoot)/build.psm1 -Force - Import-Module $(PowerShellRoot)/tools/packaging -Force - - $destFolder = '$(System.ArtifactsDirectory)\signedZip' - $BuildPath = '$(System.ArtifactsDirectory)\$(SymbolsFolder)' - - $null = New-Item -ItemType Directory -Path $destFolder -Force - - $BuildPackagePath = New-PSBuildZip -BuildPath $BuildPath -DestinationFolder $destFolder - - Write-Verbose -Verbose "New-PSSignedBuildZip returned `$BuildPackagePath as: $BuildPackagePath" - Write-Host "##vso[artifact.upload containerfolder=results;artifactname=results]$BuildPackagePath" - - $vstsCommandString = "vso[task.setvariable variable=BuildPackagePath]$BuildPackagePath" - Write-Host ("sending " + $vstsCommandString) - Write-Host "##$vstsCommandString" - displayName: Compress signed files - retryCountOnTaskFailure: 2 - - - - pwsh: | - try { - tools/releaseBuild/macOS/PowerShellPackageVsts.ps1 -location $(PowerShellRoot) -BootStrap - } catch { - Get-Error - throw - } - displayName: 'Bootstrap VM' - env: - __DOTNET_RUNTIME_FEED_KEY: $(RUNTIME_SOURCEFEED_KEY) - - - pwsh: | - # Add -SkipReleaseChecks as a mitigation to unblock release. - # macos-10.15 does not allow creating a folder under root. Hence, moving the folder. - try { - $(Build.SourcesDirectory)/tools/releaseBuild/macOS/PowerShellPackageVsts.ps1 -ReleaseTag $(ReleaseTagVar) -Destination $(System.ArtifactsDirectory) -location $(PowerShellRoot) -ArtifactName macosPkgResults -BuildZip $(BuildPackagePath) -ExtraPackage "tar" -Runtime 'osx-${{ parameters.buildArchitecture }}' -SkipReleaseChecks - } catch { - Get-Error - throw - } - displayName: 'Package' - env: - __DOTNET_RUNTIME_FEED_KEY: $(RUNTIME_SOURCEFEED_KEY) - - - task: ms.vss-governance-buildtask.governance-build-task-component-detection.ComponentGovernanceComponentDetection@0 - displayName: 'Component Detection' - inputs: - sourceScanPath: '$(PowerShellRoot)/tools' - snapshotForceEnabled: true - - - template: /tools/releaseBuild/azureDevOps/templates/step/finalize.yml diff --git a/tools/releaseBuild/azureDevOps/templates/mac-package-signing.yml b/tools/releaseBuild/azureDevOps/templates/mac-package-signing.yml deleted file mode 100644 index d4901580b0b..00000000000 --- a/tools/releaseBuild/azureDevOps/templates/mac-package-signing.yml +++ /dev/null @@ -1,135 +0,0 @@ -parameters: - buildArchitecture: x64 - -jobs: -- job: MacPackageSigningJob_${{ parameters.buildArchitecture }} - displayName: macOS Package signing ${{ parameters.buildArchitecture }} - condition: succeeded() - pool: - name: PowerShell1ES - demands: - - ImageOverride -equals PSMMS2019-Secure - variables: - - group: ESRP - - name: runCodesignValidationInjection - value: false - - name: NugetSecurityAnalysisWarningLevel - value: none - - name: repoFolder - value: PowerShell - - name: repoRoot - value: $(Agent.BuildDirectory)\$(repoFolder) - - name: complianceRepoFolder - value: compliance - - steps: - - checkout: self - clean: true - path: $(repoFolder) - - - checkout: ComplianceRepo - clean: true - path: $(complianceRepoFolder) - - - template: shouldSign.yml - - - template: SetVersionVariables.yml - parameters: - ReleaseTagVar: $(ReleaseTagVar) - - - task: DownloadBuildArtifacts@0 - inputs: - artifactName: 'macosPkgResults' - itemPattern: '**/*' - downloadPath: '$(System.ArtifactsDirectory)' - - - pwsh: | - dir "$(System.ArtifactsDirectory)\*" -Recurse - displayName: 'Capture Downloaded Artifacts' - # Diagnostics is not critical it passes every time it runs - continueOnError: true - - - pwsh: | - $null = new-item -type directory -path "$(Build.StagingDirectory)\macos" - $zipFile = "$(Build.StagingDirectory)\macos\powershell-$(Version)-osx-${{ parameters.buildArchitecture }}.zip" - Compress-Archive -Path "$(System.ArtifactsDirectory)\macosPkgResults\powershell-$(Version)-osx-${{ parameters.buildArchitecture }}.pkg" -Destination $zipFile - Write-Host $zipFile - - $ltsPkgPath = "$(System.ArtifactsDirectory)\macosPkgResults\powershell-lts-$(Version)-osx-${{ parameters.buildArchitecture }}.pkg" - - if(Test-Path $ltsPkgPath) - { - $ltsZipFile = "$(Build.StagingDirectory)\macos\powershell-lts-$(Version)-osx-${{ parameters.buildArchitecture }}.zip" - Compress-Archive -Path $ltsPkgPath -Destination $ltsZipFile - Write-Host $ltsZipFile - } - displayName: 'Compress macOS Package' - - - template: EsrpSign.yml@ComplianceRepo - parameters: - buildOutputPath: $(Build.StagingDirectory)\macos - signOutputPath: $(Build.StagingDirectory)\signedMacOSPackages - certificateId: "CP-401337-Apple" - pattern: | - **\*.zip - useMinimatch: true - shouldSign: $(SHOULD_SIGN) - displayName: Sign pkg - - - template: upload-final-results.yml - parameters: - artifactPath: $(System.ArtifactsDirectory)\macosPkgResults - artifactFilter: "*${{ parameters.buildArchitecture }}.tar.gz" - - - pwsh: | - $destination = "$(System.ArtifactsDirectory)\azureMacOs" - New-Item -Path $destination -Type Directory - $zipPath = dir "$(Build.StagingDirectory)\signedMacOSPackages\powershell-*.zip" -Recurse | select-object -expandproperty fullname - foreach ($z in $zipPath) { Expand-Archive -Path $z -DestinationPath $destination } - $targzPath = dir "$(System.ArtifactsDirectory)\*osx*.tar.gz" -Recurse | select-object -expandproperty fullname - Copy-Item -Path $targzPath -Destination $destination - displayName: 'Extract and copy macOS artifacts for upload' - condition: and(succeeded(), eq(variables['SHOULD_SIGN'], 'true')) - - - template: upload-final-results.yml - parameters: - artifactPath: $(System.ArtifactsDirectory)\azureMacOs - artifactFilter: "*.pkg" - condition: and(succeeded(), eq(variables['SHOULD_SIGN'], 'true')) - - - pwsh: | - $null = new-item -type directory -path "$(Build.StagingDirectory)\macos-unsigned" - Copy-Item -Path "$(System.ArtifactsDirectory)\macosPkgResults\powershell-$(Version)-osx-x64.pkg" -Destination "$(Build.StagingDirectory)\macos-unsigned" - Copy-Item -Path "$(System.ArtifactsDirectory)\macosPkgResults\powershell-$(Version)-osx-x64.tar.gz" -Destination "$(Build.StagingDirectory)\macos-unsigned" - displayName: 'Create unsigned folder to upload' - condition: and(succeeded(), ne(variables['SHOULD_SIGN'], 'true')) - - - task: AzureFileCopy@4 - displayName: 'AzureBlob File Copy - unsigned' - inputs: - SourcePath: '$(Build.StagingDirectory)\macos-unsigned\*' - azureSubscription: '$(AzureFileCopySubscription)' - Destination: AzureBlob - storage: '$(StorageAccount)' - ContainerName: '$(AzureVersion)' - condition: and(succeeded(), ne(variables['SHOULD_SIGN'], 'true')) - retryCountOnTaskFailure: 2 - - - task: AzureFileCopy@4 - displayName: 'AzureBlob File Copy - signed' - inputs: - SourcePath: '$(System.ArtifactsDirectory)\azureMacOs\*' - azureSubscription: '$(AzureFileCopySubscription)' - Destination: AzureBlob - storage: '$(StorageAccount)' - ContainerName: '$(AzureVersion)' - condition: and(succeeded(), eq(variables['SHOULD_SIGN'], 'true')) - retryCountOnTaskFailure: 2 - - - task: ms.vss-governance-buildtask.governance-build-task-component-detection.ComponentGovernanceComponentDetection@0 - displayName: 'Component Detection' - inputs: - sourceScanPath: '$(repoRoot)/tools' - snapshotForceEnabled: true - - - template: /tools/releaseBuild/azureDevOps/templates/step/finalize.yml diff --git a/tools/releaseBuild/azureDevOps/templates/mac.yml b/tools/releaseBuild/azureDevOps/templates/mac.yml deleted file mode 100644 index d173e900434..00000000000 --- a/tools/releaseBuild/azureDevOps/templates/mac.yml +++ /dev/null @@ -1,68 +0,0 @@ -parameters: - buildArchitecture: 'x64' - -jobs: -- job: build_macOS_${{ parameters.buildArchitecture }} - displayName: Build macOS ${{ parameters.buildArchitecture }} - condition: succeeded() - pool: - vmImage: macos-latest - variables: - # Turn off Homebrew analytics - - name: HOMEBREW_NO_ANALYTICS - value: 1 - - name: runCodesignValidationInjection - value: false - - name: NugetSecurityAnalysisWarningLevel - value: none - - group: DotNetPrivateBuildAccess - steps: - #- task: @ - # inputs: - # - # displayName: '' - - checkout: self - clean: true - - template: SetVersionVariables.yml - parameters: - ReleaseTagVar: $(ReleaseTagVar) - - - pwsh: | - # create folder - sudo mkdir "$(Agent.TempDirectory)/PowerShell" - - # make the current user the owner - sudo chown $env:USER "$(Agent.TempDirectory)/PowerShell" - displayName: 'Create $(Agent.TempDirectory)/PowerShell' - - - template: cloneToOfficialPath.yml - parameters: - nativePathRoot: '$(Agent.TempDirectory)' - - - pwsh: | - tools/releaseBuild/macOS/PowerShellPackageVsts.ps1 -location $(PowerShellRoot) -BootStrap - displayName: 'Bootstrap VM' - env: - __DOTNET_RUNTIME_FEED_KEY: $(RUNTIME_SOURCEFEED_KEY) - - - template: /tools/releaseBuild/azureDevOps/templates/insert-nuget-config-azfeed.yml - parameters: - repoRoot: $(PowerShellRoot) - - - pwsh: | - $env:AzDevOpsFeedPAT2 = '$(powershellPackageReadPat)' - # Add -SkipReleaseChecks as a mitigation to unblock release. - # macos-10.15 does not allow creating a folder under root. Hence, moving the folder. - $(Build.SourcesDirectory)/tools/releaseBuild/macOS/PowerShellPackageVsts.ps1 -ReleaseTag $(ReleaseTagVar) -Destination $(System.ArtifactsDirectory) -Symbols -location $(PowerShellRoot) -Build -ArtifactName macosBinResults -Runtime 'osx-${{ parameters.buildArchitecture }}' -SkipReleaseChecks - $env:AzDevOpsFeedPAT2 = $null - displayName: 'Build' - env: - __DOTNET_RUNTIME_FEED_KEY: $(RUNTIME_SOURCEFEED_KEY) - - - task: ms.vss-governance-buildtask.governance-build-task-component-detection.ComponentGovernanceComponentDetection@0 - displayName: 'Component Detection' - inputs: - sourceScanPath: '$(Build.SourcesDirectory)/tools' - snapshotForceEnabled: true - - - template: /tools/releaseBuild/azureDevOps/templates/step/finalize.yml diff --git a/tools/releaseBuild/azureDevOps/templates/nuget-pkg-sbom.yml b/tools/releaseBuild/azureDevOps/templates/nuget-pkg-sbom.yml deleted file mode 100644 index 0a0e3b96cc1..00000000000 --- a/tools/releaseBuild/azureDevOps/templates/nuget-pkg-sbom.yml +++ /dev/null @@ -1,139 +0,0 @@ -parameters: - - name: PackageVersion - - name: PackagePath - - name: WinFxdPath - - name: LinuxFxdPath - - name: ListOfFiles - type: object - default: - - Microsoft.Management.Infrastructure.CimCmdlets.dll - - Microsoft.PowerShell.Commands.Diagnostics.dll - - Microsoft.PowerShell.Commands.Management.dll - - Microsoft.PowerShell.Commands.Utility.dll - - Microsoft.PowerShell.ConsoleHost.dll - - Microsoft.PowerShell.CoreCLR.Eventing.dll - - Microsoft.PowerShell.Security.dll - - Microsoft.PowerShell.SDK.dll - - Microsoft.WSMan.Management.dll - - Microsoft.WSMan.Runtime.dll - - System.Management.Automation.dll - -steps: - -- template: /.pipelines/templates/insert-nuget-config-azfeed.yml@self - parameters: - repoRoot: $(REPOROOT) - -- pwsh: | - Import-Module "$env:REPOROOT/build.psm1" -Force - Start-PSBootstrap - - $sharedModules = @('Microsoft.PowerShell.Commands.Management', - 'Microsoft.PowerShell.Commands.Utility', - 'Microsoft.PowerShell.ConsoleHost', - 'Microsoft.PowerShell.Security', - 'System.Management.Automation' - ) - - $winOnlyModules = @('Microsoft.Management.Infrastructure.CimCmdlets', - 'Microsoft.PowerShell.Commands.Diagnostics', - 'Microsoft.PowerShell.CoreCLR.Eventing', - 'Microsoft.WSMan.Management', - 'Microsoft.WSMan.Runtime' - ) - - $refAssemblyFolder = Join-Path '$(System.ArtifactsDirectory)' 'RefAssembly' - $null = New-Item -Path $refAssemblyFolder -Force -Verbose -Type Directory - - Start-PSBuild -Clean -Runtime linux-x64 -Configuration Release - - $sharedModules | Foreach-Object { - $refFile = Get-ChildItem -Path "$env:REPOROOT\src\$_\obj\Release\net9.0\refint\$_.dll" - Write-Verbose -Verbose "RefAssembly: $refFile" - Copy-Item -Path $refFile -Destination "$refAssemblyFolder\$_.dll" -Verbose - $refDoc = "$env:REPOROOT\src\$_\bin\Release\net9.0\$_.xml" - if (-not (Test-Path $refDoc)) { - Write-Warning "$refDoc not found" - Get-ChildItem -Path "$env:REPOROOT\src\$_\bin\Release\net9.0\" | Out-String | Write-Verbose -Verbose - } - else { - Copy-Item -Path $refDoc -Destination "$refAssemblyFolder\$_.xml" -Verbose - } - } - - Start-PSBuild -Clean -Runtime win7-x64 -Configuration Release - - $winOnlyModules | Foreach-Object { - $refFile = Get-ChildItem -Path "$env:REPOROOT\src\$_\obj\Release\net9.0\refint\*.dll" - Write-Verbose -Verbose 'RefAssembly: $refFile' - Copy-Item -Path $refFile -Destination "$refAssemblyFolder\$_.dll" -Verbose - $refDoc = "$env:REPOROOT\src\$_\bin\Release\net9.0\$_.xml" - if (-not (Test-Path $refDoc)) { - Write-Warning "$refDoc not found" - Get-ChildItem -Path "$env:REPOROOT\src\$_\bin\Release\net9.0" | Out-String | Write-Verbose -Verbose - } - else { - Copy-Item -Path $refDoc -Destination "$refAssemblyFolder\$_.xml" -Verbose - } - } - - Get-ChildItem $refAssemblyFolder -Recurse | Out-String | Write-Verbose -Verbose - - # Set RefAssemblyPath path variable - $vstsCommandString = "vso[task.setvariable variable=RefAssemblyPath]${refAssemblyFolder}" - Write-Host "sending " + $vstsCommandString - Write-Host "##$vstsCommandString" - - displayName: Build reference assemblies - env: - __DOTNET_RUNTIME_FEED: $(RUNTIME_SOURCEFEED) - __DOTNET_RUNTIME_FEED_KEY: $(RUNTIME_SOURCEFEED_KEY) - -- ${{ each value in parameters.ListOfFiles }}: - - pwsh: | - $FileName = '${{ value }}' - $FileBaseName = [System.IO.Path]::GetFileNameWithoutExtension($FileName) - $FilePackagePath = Join-Path -Path '${{ parameters.PackagePath }}' -ChildPath $FileBaseName - $CGManifestPath = Join-Path -Path '${{ parameters.PackagePath }}' -ChildPath 'CGManifest' - Write-Verbose -Verbose "FileName to package: $FileName" - Write-Verbose -Verbose "FilePackage path: $FilePackagePath" - Write-Verbose -Verbose "CGManifest path: $CGManifestPath" - # Set SBOM package name - $vstsCommandString = "vso[task.setvariable variable=SbomFilePackageName]${FileBaseName}" - Write-Host "sending " + $vstsCommandString - Write-Host "##$vstsCommandString" - # Set SBOM package path variable - $vstsCommandString = "vso[task.setvariable variable=SbomFilePackagePath]${FilePackagePath}" - Write-Host "sending " + $vstsCommandString - Write-Host "##$vstsCommandString" - # Set CGManifest path variable - $vstsCommandString = "vso[task.setvariable variable=CGManifestPath]${CGManifestPath}" - Write-Host "sending " + $vstsCommandString - Write-Host "##$vstsCommandString" - # Create Nuget package sources - Import-Module -Name $env:REPOROOT\build.psm1 - Import-Module -Name $env:REPOROOT\tools\packaging - Find-DotNet - New-ILNugetPackageSource -File $FileName -PackagePath '${{ parameters.PackagePath }}' -PackageVersion '${{ parameters.PackageVersion }}' -WinFxdBinPath '${{ parameters.WinFxdPath }}' -LinuxFxdBinPath '${{ parameters.LinuxFxdPath }}' -CGManifestPath $CGManifestPath -RefAssemblyPath $(RefAssemblyPath) - displayName: 'Create NuGet Package source for single file' - - - template: Sbom.yml@ComplianceRepo - parameters: - BuildDropPath: $(SbomFilePackagePath) - Build_Repository_Uri: 'https://github.com/powershell/powershell' - PackageName: $(SbomFilePackageName) - PackageVersion: ${{ parameters.PackageVersion }} - sourceScanPath: $(CGManifestPath) - displayName: SBOM for NuGetPkg - - - pwsh: | - $FileName = '${{ value }}' - $FileBaseName = [System.IO.Path]::GetFileNameWithoutExtension($FileName) - $FilePackagePath = Join-Path -Path '${{ parameters.PackagePath }}' -ChildPath $FileBaseName - Write-Verbose -Verbose "FileName to package: $FileName" - Write-Verbose -Verbose "FilePackage path: $FilePackagePath" - Import-Module -Name $env:REPOROOT\build.psm1 - Import-Module -Name $env:REPOROOT\tools\packaging - Find-DotNet - New-ILNugetPackageFromSource -FileName $FileName -PackageVersion '${{ parameters.PackageVersion }}' -PackagePath '${{ parameters.PackagePath }}' - displayName: 'Create NuGet Package for single file' diff --git a/tools/releaseBuild/azureDevOps/templates/nuget.yml b/tools/releaseBuild/azureDevOps/templates/nuget.yml deleted file mode 100644 index 22f791bf0eb..00000000000 --- a/tools/releaseBuild/azureDevOps/templates/nuget.yml +++ /dev/null @@ -1,290 +0,0 @@ -parameters: - parentJobs: [] - -jobs: -- job: build_nuget - dependsOn: - ${{ parameters.parentJobs }} - displayName: Build NuGet packages - condition: succeeded() - pool: - name: $(windowsPool) - demands: - - ImageOverride -equals PSMMS2019-Secure - - timeoutInMinutes: 90 - - variables: - - name: runCodesignValidationInjection - value: false - - name: NugetSecurityAnalysisWarningLevel - value: none - - name: build - value: ${{ parameters.buildName }} - - group: ESRP - - name: GenAPIToolPath - value: '$(System.ArtifactsDirectory)/GenAPI' - - name: PackagePath - value: '$(System.ArtifactsDirectory)/UnifiedPackagePath' - - name: winFxdPath - value: '$(System.ArtifactsDirectory)/winFxd' - - name: winFxdWinDesktopPath - value: '$(System.ArtifactsDirectory)/winFxdWinDesktop' - - name: linuxFxdPath - value: '$(System.ArtifactsDirectory)/linuxFxd' - - name: alpineFxdPath - value: '$(System.ArtifactsDirectory)/alpineFxd' - - group: DotNetPrivateBuildAccess - - steps: - - checkout: self - clean: true - - - checkout: ComplianceRepo - clean: true - - - template: SetVersionVariables.yml - parameters: - ReleaseTagVar: $(ReleaseTagVar) - - - powershell: | - $content = Get-Content "$env:REPOROOT/global.json" -Raw | ConvertFrom-Json - $vstsCommandString = "vso[task.setvariable variable=SDKVersion]$($content.sdk.version)" - Write-Host "sending " + $vstsCommandString - Write-Host "##$vstsCommandString" - displayName: 'Find SDK version from global.json' - - - pwsh: | - Import-Module "$env:REPOROOT/build.psm1" -Force - # We just need .NET but we fixed this in an urgent situation. - Start-PSBootStrap -Verbose - displayName: Bootstrap - env: - __DOTNET_RUNTIME_FEED_KEY: $(RUNTIME_SOURCEFEED_KEY) - - - task: DownloadBuildArtifacts@0 - displayName: 'Download PowerShell build artifacts - finalResults' - inputs: - buildType: current - downloadType: single - artifactName: finalResults - downloadPath: '$(System.ArtifactsDirectory)' - - - task: DownloadBuildArtifacts@0 - displayName: 'Download PowerShell build artifacts - macosPkgResults' - inputs: - buildType: current - downloadType: single - artifactName: macosPkgResults - downloadPath: '$(System.ArtifactsDirectory)' - - - powershell: 'Get-ChildItem $(System.ArtifactsDirectory) -recurse' - displayName: 'Capture downloaded artifacts' - - - powershell: | - $packagePath = (Join-Path $(System.ArtifactsDirectory) packages) - New-Item $packagePath -ItemType Directory -Force > $null - $packages = Get-ChildItem $(System.ArtifactsDirectory) -Include *.zip, *.tar.gz -Recurse - $packages | ForEach-Object { Copy-Item $_.FullName -Destination $packagePath -Verbose } - Get-ChildItem $packagePath -Recurse - displayName: 'Conflate packages to same folder' - - - task: ExtractFiles@1 - displayName: 'Extract files win-fxdependent' - inputs: - archiveFilePatterns: '$(System.ArtifactsDirectory)/packages/PowerShell-*-win-fxdependent.zip' - destinationFolder: '$(winFxdPath)' - - - task: ExtractFiles@1 - displayName: 'Extract files win-fxdependentWinDesktop' - inputs: - archiveFilePatterns: '$(System.ArtifactsDirectory)/packages/PowerShell-*-win-fxdependentWinDesktop.zip' - destinationFolder: '$(winFxdWinDesktopPath)' - - - task: ExtractFiles@1 - displayName: 'Extract files linux-fxdependent' - inputs: - archiveFilePatterns: '$(System.ArtifactsDirectory)/packages/powershell-*-linux-x64-fxdependent.tar.gz' - destinationFolder: '$(linuxFxdPath)' - - - task: ExtractFiles@1 - displayName: 'Extract files alpine-fxdependent' - inputs: - archiveFilePatterns: '$(System.ArtifactsDirectory)/packages/powershell-*-linux-x64-musl-noopt-fxdependent.tar.gz' - destinationFolder: '$(alpineFxdPath)' - - - template: SetVersionVariables.yml - parameters: - ReleaseTagVar: $(ReleaseTagVar) - - - template: shouldSign.yml - - - task: NuGetToolInstaller@1 - displayName: 'Install NuGet.exe' - - # Create nuget packages along with SBOM manifests. - - template: nuget-pkg-sbom.yml - parameters: - PackageVersion: $(Version) - PackagePath: $(PackagePath) - WinFxdPath: $(winFxdPath) - LinuxFxdPath: $(linuxFxdPath) - - - pwsh: | - Get-ChildItem $(linuxFxdPath) - Get-ChildItem $(winFxdPath) - Get-ChildItem $(winFxdWinDesktopPath) - Get-ChildItem $(alpineFxdPath) - displayName: Capture fxd folders - - # Create Global Tool packages along with SBOM manifests - - template: global-tool-pkg-sbom.yml - parameters: - PackageVersion: $(Version) - LinuxBinPath: $(linuxFxdPath) - WindowsBinPath: $(winFxdPath) - WindowsDesktopBinPath: $(winFxdWinDesktopPath) - AlpineBinPath: $(alpineFxdPath) - DestinationPath: $(PackagePath)\globaltool - - - pwsh: | - Get-ChildItem "$(PackagePath)" -Recurse - displayName: Capture generated packages - - - template: EsrpSign.yml@ComplianceRepo - parameters: - buildOutputPath: $(PackagePath) - signOutputPath: $(System.ArtifactsDirectory)\signed - certificateId: "CP-401405" - pattern: | - **\*.nupkg - useMinimatch: true - shouldSign: $(SHOULD_SIGN) - displayName: Sign NuPkg - - - pwsh: | - if (-not (Test-Path '$(System.ArtifactsDirectory)\signed\')) { $null = New-Item -ItemType Directory -Path '$(System.ArtifactsDirectory)\signed\' } - Copy-Item -Path '$(PackagePath)\*.nupkg' -Destination '$(System.ArtifactsDirectory)\signed\' -Verbose -Force - Copy-Item -Path '$(PackagePath)\globaltool\*.nupkg' -Destination '$(System.ArtifactsDirectory)\signed\' -Verbose -Force - displayName: Fake copy when not signing - condition: eq(variables['SHOULD_SIGN'], 'false') - - - pwsh: | - Import-Module "${env:REPOROOT}\build.psm1" -Force - Get-ChildItem -Recurse "$(System.ArtifactsDirectory)\signed\*.nupkg" -Verbose | ForEach-Object { Start-NativeExecution -sb { nuget.exe verify -All $_.FullName } } - displayName: Verify all packages are signed - condition: eq(variables['SHOULD_SIGN'], 'true') - - - task: securedevelopmentteam.vss-secure-development-tools.build-task-antimalware.AntiMalware@3 - displayName: 'Run MpCmdRun.exe' - inputs: - FileDirPath: '$(PackagePath)' - TreatStaleSignatureAs: Warning - - - task: securedevelopmentteam.vss-secure-development-tools.build-task-publishsecurityanalysislogs.PublishSecurityAnalysisLogs@2 - displayName: 'Publish Security Analysis Logs' - - - template: upload-final-results.yml - parameters: - artifactPath: '$(System.ArtifactsDirectory)\signed' - - - pwsh: | - if (-not (Test-Path "$(System.ArtifactsDirectory)\signed\globaltool")) - { - $null = New-Item -Path "$(System.ArtifactsDirectory)\signed\globaltool" -ItemType Directory -Force - } - - Move-Item -Path "$(System.ArtifactsDirectory)\signed\PowerShell.*" -Destination "$(System.ArtifactsDirectory)\signed\globaltool" -Force - Get-ChildItem "$(System.ArtifactsDirectory)\signed\globaltool" -Recurse - displayName: Move global tool packages to subfolder and capture - - - pwsh: | - $packagePath = (Join-Path $(System.ArtifactsDirectory) checksum) - New-Item $packagePath -ItemType Directory -Force > $null - $srcPaths = @("$(System.ArtifactsDirectory)\finalResults", "$(System.ArtifactsDirectory)\macosPkgResults", "$(System.ArtifactsDirectory)\signed") - - $packages = Get-ChildItem -Path $srcPaths -Include *.zip, *.tar.gz, *.msi*, *.pkg, *.deb, *.rpm -Exclude "PowerShell-Symbols*" -Recurse - $packages | ForEach-Object { Copy-Item $_.FullName -Destination $packagePath -Verbose } - - $packagePathList = Get-ChildItem $packagePath -Recurse | Select-Object -ExpandProperty FullName | Out-String - Write-Verbose -Verbose $packagePathList - - $checksums = Get-ChildItem -Path $packagePath -Exclude "SHA512SUMS" | - ForEach-Object { - Write-Verbose -Verbose "Generating checksum file for $($_.FullName)" - $packageName = $_.Name - $hash = (Get-FileHash -Path $_.FullName -Algorithm SHA512).Hash.ToLower() - - # the '*' before the packagename signifies it is a binary - "$hash *$packageName" - } - - $checksums | Out-File -FilePath "$packagePath\SHA512SUMS" -Force - - - $fileContent = Get-Content -Path "$packagePath\SHA512SUMS" -Raw | Out-String - Write-Verbose -Verbose -Message $fileContent - - Copy-Item -Path "$packagePath\SHA512SUMS" -Destination '$(System.ArtifactsDirectory)\signed\' -verbose - displayName: Generate checksum file for packages - - - pwsh: | - $packagePath = (Join-Path $(System.ArtifactsDirectory) checksum_gbltool) - New-Item $packagePath -ItemType Directory -Force > $null - $srcPaths = @("$(System.ArtifactsDirectory)\signed\globaltool") - $packages = Get-ChildItem -Path $srcPaths -Include *.nupkg -Recurse - $packages | ForEach-Object { Copy-Item $_.FullName -Destination $packagePath -Verbose } - - $packagePathList = Get-ChildItem $packagePath -Recurse | Select-Object -ExpandProperty FullName | Out-String - Write-Verbose -Verbose $packagePathList - - $checksums = Get-ChildItem -Path $packagePath -Exclude "SHA512SUMS" | - ForEach-Object { - Write-Verbose -Verbose "Generating checksum file for $($_.FullName)" - $packageName = $_.Name - $hash = (Get-FileHash -Path $_.FullName -Algorithm SHA512).Hash.ToLower() - - # the '*' before the packagename signifies it is a binary - "$hash *$packageName" - } - - $checksums | Out-File -FilePath "$packagePath\SHA512SUMS" -Force - - $fileContent = Get-Content -Path "$packagePath\SHA512SUMS" -Raw | Out-String - Write-Verbose -Verbose -Message $fileContent - - Copy-Item -Path "$packagePath\SHA512SUMS" -Destination '$(System.ArtifactsDirectory)\signed\globaltool\' -verbose - displayName: Generate checksum for global tools - - - template: upload-final-results.yml - parameters: - artifactPath: '$(System.ArtifactsDirectory)\checksum' - artifactFilter: SHA512SUMS - - - task: AzureFileCopy@4 - displayName: 'Upload NuGet packages to Azure' - inputs: - SourcePath: '$(System.ArtifactsDirectory)\signed\*' - azureSubscription: '$(AzureFileCopySubscription)' - Destination: AzureBlob - storage: '$(StorageAccount)' - ContainerName: '$(AzureVersion)-nuget' - condition: and(succeeded(), eq(variables['SHOULD_SIGN'], 'true')) - retryCountOnTaskFailure: 2 - - - task: AzureFileCopy@4 - displayName: 'Upload global tool packages to Azure' - inputs: - sourcePath: '$(System.ArtifactsDirectory)\signed\globaltool\*' - azureSubscription: '$(GlobalToolSubscription)' - Destination: AzureBlob - storage: '$(GlobalToolStorageAccount)' - ContainerName: 'tool-private' - blobPrefix: '$(Version)' - condition: and(succeeded(), eq(variables['SHOULD_SIGN'], 'true')) - retryCountOnTaskFailure: 2 - - - task: ms.vss-governance-buildtask.governance-build-task-component-detection.ComponentGovernanceComponentDetection@0 - displayName: 'Component Detection' - inputs: - sourceScanPath: '$(PackagePath)' diff --git a/tools/releaseBuild/azureDevOps/templates/release-BuildJson.yml b/tools/releaseBuild/azureDevOps/templates/release-BuildJson.yml deleted file mode 100644 index d183601a06c..00000000000 --- a/tools/releaseBuild/azureDevOps/templates/release-BuildJson.yml +++ /dev/null @@ -1,102 +0,0 @@ -steps: -- checkout: self - clean: true - -- task: DownloadPipelineArtifact@2 - inputs: - source: specific - project: PowerShellCore - pipeline: '696' - preferTriggeringPipeline: true - runVersion: latestFromBranch - runBranch: '$(Build.SourceBranch)' - artifact: BuildInfoJson - path: '$(Pipeline.Workspace)/releasePipeline/BuildInfoJson' - -- pwsh: | - Import-Module '$(Build.SourcesDirectory)/tools/ci.psm1' - $jsonFile = Get-Item "$ENV:PIPELINE_WORKSPACE/releasePipeline/BuildInfoJson/*.json" - $fileName = Split-Path $jsonFile -Leaf - - $dateTime = [datetime]::UtcNow - $dateTime = [datetime]::new($dateTime.Ticks - ($dateTime.Ticks % [timespan]::TicksPerSecond), $dateTime.Kind) - - $metadata = Get-Content ./tools/metadata.json | ConvertFrom-Json - $stableRelease = $metadata.StableRelease.Latest - $ltsRelease = $metadata.LTSRelease.Latest - - Write-Verbose -Verbose "Writing $jsonFile contents:" - $buildInfoJsonContent = Get-Content $jsonFile -Encoding UTF8NoBom -Raw - Write-Verbose -Verbose $buildInfoJsonContent - - $buildInfo = $buildInfoJsonContent | ConvertFrom-Json - $buildInfo.ReleaseDate = $dateTime - - $targetFile = "$ENV:PIPELINE_WORKSPACE/$fileName" - ConvertTo-Json -InputObject $buildInfo | Out-File $targetFile -Encoding ascii - - if ($stableRelease -or $fileName -eq "preview.json") { - Set-BuildVariable -Name CopyMainBuildInfo -Value YES - } else { - Set-BuildVariable -Name CopyMainBuildInfo -Value NO - } - - Set-BuildVariable -Name BuildInfoJsonFile -Value $targetFile - - ## Create 'lts.json' if it's the latest stable and also a LTS release. - - if ($fileName -eq "stable.json") { - if ($ltsRelease) { - $ltsFile = "$ENV:PIPELINE_WORKSPACE/lts.json" - Copy-Item -Path $targetFile -Destination $ltsFile -Force - Set-BuildVariable -Name LtsBuildInfoJsonFile -Value $ltsFile - Set-BuildVariable -Name CopyLTSBuildInfo -Value YES - } else { - Set-BuildVariable -Name CopyLTSBuildInfo -Value NO - } - - $releaseTag = $buildInfo.ReleaseTag - $version = $releaseTag -replace '^v' - $semVersion = [System.Management.Automation.SemanticVersion] $version - - $versionFile = "$ENV:PIPELINE_WORKSPACE/$($semVersion.Major)-$($semVersion.Minor).json" - Copy-Item -Path $targetFile -Destination $versionFile -Force - Set-BuildVariable -Name VersionBuildInfoJsonFile -Value $versionFile - Set-BuildVariable -Name CopyVersionBuildInfo -Value YES - } else { - Set-BuildVariable -Name CopyVersionBuildInfo -Value NO - } - displayName: Download and Capture NuPkgs - -- task: AzureFileCopy@4 - displayName: 'AzureBlob build info JSON file Copy' - inputs: - SourcePath: '$(BuildInfoJsonFile)' - azureSubscription: '$(AzureFileCopySubscription)' - Destination: AzureBlob - storage: '$(StorageAccount)' - ContainerName: BuildInfo - condition: and(succeeded(), eq(variables['CopyMainBuildInfo'], 'YES')) - retryCountOnTaskFailure: 2 - -- task: AzureFileCopy@4 - displayName: 'AzureBlob build info ''lts.json'' Copy when needed' - inputs: - SourcePath: '$(LtsBuildInfoJsonFile)' - azureSubscription: '$(AzureFileCopySubscription)' - Destination: AzureBlob - storage: '$(StorageAccount)' - ContainerName: BuildInfo - condition: and(succeeded(), eq(variables['CopyLTSBuildInfo'], 'YES')) - retryCountOnTaskFailure: 2 - -- task: AzureFileCopy@4 - displayName: 'AzureBlob build info ''Major-Minor.json'' Copy when needed' - inputs: - SourcePath: '$(VersionBuildInfoJsonFile)' - azureSubscription: '$(AzureFileCopySubscription)' - Destination: AzureBlob - storage: '$(StorageAccount)' - ContainerName: BuildInfo - condition: and(succeeded(), eq(variables['CopyVersionBuildInfo'], 'YES')) - retryCountOnTaskFailure: 2 diff --git a/tools/releaseBuild/azureDevOps/templates/release-CopyGlobalTools.yml b/tools/releaseBuild/azureDevOps/templates/release-CopyGlobalTools.yml deleted file mode 100644 index 7c9306496ed..00000000000 --- a/tools/releaseBuild/azureDevOps/templates/release-CopyGlobalTools.yml +++ /dev/null @@ -1,56 +0,0 @@ -parameters: -- name: sourceContainerName - type: string - default: 'source-container' - -- name: destinationContainerName - type: string - default: 'destination-container' - -- name: sourceStorageAccountName - type: string - default: 'source-storage-account' - -- name: destinationStorageAccountName - type: string - default: 'destination-storage-account' - -- name: blobPrefix - type: string - default: '$(Version)' - -steps: -- template: release-SetReleaseTagAndContainerName.yml - -- pwsh: | - Import-module '$(BUILD.SOURCESDIRECTORY)/build.psm1' - Install-AzCopy - displayName: Install AzCopy - retryCountOnTaskFailure: 2 - -- pwsh: | - Import-module '$(BUILD.SOURCESDIRECTORY)/build.psm1' - $azcopy = Find-AzCopy - Write-Verbose -Verbose "Found AzCopy: $azcopy" - - $sourceContainerName = "${{ parameters.sourceContainerName }}" - $destinationContainerName = "${{ parameters.destinationContainerName }}" - $sourceStorageAccountName = "${{ parameters.sourceStorageAccountName }}" - $destinationStorageAccountName = "${{ parameters.destinationStorageAccountName }}" - $blobPrefix = "${{ parameters.blobPrefix }}" - - $sourceBlobUrl = "https://${sourceStorageAccountName}.blob.core.windows.net/${sourceContainerName}/${blobPrefix}" - Write-Verbose -Verbose "Source blob url: $sourceBlobUrl" - $destinationBlobUrl = "https://${destinationStorageAccountName}.blob.core.windows.net/${destinationContainerName}" - Write-Verbose -Verbose "Destination blob url: $destinationBlobUrl" - - & $azcopy cp $sourceBlobUrl $destinationBlobUrl --recursive - - $packagesPath = Get-ChildItem -Path $(System.ArtifactsDirectory)\*.deb -Recurse -File | Select-Object -First 1 -ExpandProperty DirectoryName - Write-Host "sending -- vso[task.setvariable variable=PackagesRoot]$packagesPath" - Write-Host "##vso[task.setvariable variable=PackagesRoot]$packagesPath" - - displayName: Copy blobs - retryCountOnTaskFailure: 2 - env: - AZCOPY_AUTO_LOGIN_TYPE: MSI diff --git a/tools/releaseBuild/azureDevOps/templates/release-CreateGitHubDraft.yml b/tools/releaseBuild/azureDevOps/templates/release-CreateGitHubDraft.yml deleted file mode 100644 index 64c4d1b6a24..00000000000 --- a/tools/releaseBuild/azureDevOps/templates/release-CreateGitHubDraft.yml +++ /dev/null @@ -1,110 +0,0 @@ -steps: -- checkout: self - clean: true - -- download: none - -- template: release-SetReleaseTagAndContainerName.yml - -- pwsh: | - Import-module '$(BUILD.SOURCESDIRECTORY)/PowerShell/build.psm1' - Install-AzCopy - displayName: Install AzCopy - retryCountOnTaskFailure: 2 - -- pwsh: | - Import-module '$(BUILD.SOURCESDIRECTORY)/PowerShell/build.psm1' - $azcopy = Find-AzCopy - Write-Verbose -Verbose "Found AzCopy: $azcopy" - - & $azcopy cp https://$(StorageAccount).blob.core.windows.net/$(AzureVersion) $(System.ArtifactsDirectory) --recursive - - $packagesPath = Get-ChildItem -Path $(System.ArtifactsDirectory)\*.deb -Recurse -File | Select-Object -First 1 -ExpandProperty DirectoryName - Write-Host "sending -- vso[task.setvariable variable=PackagesRoot]$packagesPath" - Write-Host "##vso[task.setvariable variable=PackagesRoot]$packagesPath" - - displayName: Download Azure Artifacts - retryCountOnTaskFailure: 2 - env: - AZCOPY_AUTO_LOGIN_TYPE: MSI - -- pwsh: | - Get-ChildItem $(System.ArtifactsDirectory)\* -recurse | Select-Object -ExpandProperty FullName - displayName: Capture downloaded artifacts - -- pwsh: | - git clone https://$(AzureDevOpsPat)@mscodehub.visualstudio.com/PowerShellCore/_git/Internal-PowerShellTeam-Tools '$(Pipeline.Workspace)/tools' - displayName: Clone Internal-Tools repository - -- pwsh: | - $Path = "$(PackagesRoot)" - $OutputPath = Join-Path $Path ‘hashes.sha256’ - $srcPaths = @($Path) - $packages = Get-ChildItem -Path $srcPaths -Include * -Recurse -File - $checksums = $packages | - ForEach-Object { - Write-Verbose -Verbose "Generating checksum file for $($_.FullName)" - $packageName = $_.Name - $hash = (Get-FileHash -Path $_.FullName -Algorithm SHA256).Hash.ToLower() - # the '*' before the packagename signifies it is a binary - "$hash *$packageName" - } - $checksums | Out-File -FilePath $OutputPath -Force - $fileContent = Get-Content -Path $OutputPath -Raw | Out-String - Write-Verbose -Verbose -Message $fileContent - displayName: Add sha256 hashes - -- checkout: ComplianceRepo - -- pwsh: | - $releaseVersion = '$(ReleaseTag)' -replace '^v','' - $vstsCommandString = "vso[task.setvariable variable=ReleaseVersion]$releaseVersion" - Write-Host "sending " + $vstsCommandString - Write-Host "##$vstsCommandString" - displayName: 'Set release version' - -- template: Sbom.yml@ComplianceRepo - parameters: - BuildDropPath: '$(PackagesRoot)' - Build_Repository_Uri: 'https://github.com/powershell/powershell.git' - displayName: PowerShell Hashes SBOM - packageName: PowerShell Artifact Hashes - packageVersion: $(ReleaseVersion) - sourceScanPath: '$(PackagesRoot)' - -- pwsh: | - Import-module '$(Pipeline.Workspace)/tools/Scripts/GitHubRelease.psm1' - $releaseVersion = '$(ReleaseTag)' -replace '^v','' - $semanticVersion = [System.Management.Automation.SemanticVersion]$releaseVersion - - $isPreview = $semanticVersion.PreReleaseLabel -ne $null - - $fileName = if ($isPreview) { - "preview.md" - } - else { - $semanticVersion.Major.ToString() + "." + $semanticVersion.Minor.ToString() + ".md" - } - - $filePath = "$env:BUILD_SOURCESDIRECTORY/PowerShell/CHANGELOG/$fileName" - Write-Verbose -Verbose "Selected Log file: $filePath" - - if (-not (Test-Path $filePath)) { - throw "$filePath not found" - } - - $changelog = Get-Content -Path $filePath - - $startPattern = "^## \[" + ([regex]::Escape($releaseVersion)) + "\]" - $endPattern = "^## \[{0}\.{1}\.{2}*" -f $semanticVersion.Major, $semanticVersion.Minor, $semanticVersion.Patch - - $clContent = $changelog | ForEach-Object { - if ($_ -match $startPattern) { $outputLine = $true } - elseif ($_ -match $endPattern) { $outputLine = $false } - if ($outputLine) { $_} - } | Out-String - - Write-Verbose -Verbose "Selected content: `n$clContent" - - Publish-ReleaseDraft -Tag '$(ReleaseTag)' -Name '$(ReleaseTag) Release of PowerShell' -Description $clContent -User PowerShell -Repository PowerShell -PackageFolder $(PackagesRoot) -Token $(GitHubReleasePat) - displayName: Publish Release Draft diff --git a/tools/releaseBuild/azureDevOps/templates/release-GlobalToolTest.yml b/tools/releaseBuild/azureDevOps/templates/release-GlobalToolTest.yml deleted file mode 100644 index 8591791de0e..00000000000 --- a/tools/releaseBuild/azureDevOps/templates/release-GlobalToolTest.yml +++ /dev/null @@ -1,149 +0,0 @@ -parameters: - jobName: "" - displayName: "" - imageName: "" - globalToolExeName: 'pwsh.exe' - globalToolPackageName: 'PowerShell.Windows.x64' - - -jobs: -- job: ${{ parameters.jobName }} - displayName: ${{ parameters.displayName }} - pool: - # test - vmImage: ${{ parameters.imageName }} - variables: - - group: DotNetPrivateBuildAccess - - steps: - - checkout: self - clean: true - - - task: DownloadPipelineArtifact@2 - inputs: - source: specific - project: PowerShellCore - pipeline: '696' - preferTriggeringPipeline: true - runVersion: latestFromBranch - runBranch: '$(Build.SourceBranch)' - artifact: finalResults - patterns: '**/*.nupkg' - path: '$(Pipeline.Workspace)/releasePipeline/finalResults' - - - pwsh: | - $dotnetMetadataPath = "$(Build.SourcesDirectory)/DotnetRuntimeMetadata.json" - $dotnetMetadataJson = Get-Content $dotnetMetadataPath -Raw | ConvertFrom-Json - - # Channel is like: $Channel = "5.0.1xx-preview2" - $Channel = $dotnetMetadataJson.sdk.channel - - $sdkVersion = (Get-Content "$(Build.SourcesDirectory)/global.json" -Raw | ConvertFrom-Json).sdk.version - Import-Module "$(Build.SourcesDirectory)/build.psm1" -Force - - Find-Dotnet - - if(-not (Get-PackageSource -Name 'dotnet' -ErrorAction SilentlyContinue)) - { - $nugetFeed = ([xml](Get-Content $(Build.SourcesDirectory)/nuget.config -Raw)).Configuration.packagesources.add | Where-Object { $_.Key -eq 'dotnet' } | Select-Object -ExpandProperty Value - if ($nugetFeed) { - Register-PackageSource -Name 'dotnet' -Location $nugetFeed -ProviderName NuGet - Write-Verbose -Message "Register new package source 'dotnet'" -verbose - } - } - - ## Install latest version from the channel - - #Install-Dotnet -Channel "$Channel" -Version $sdkVersion - Start-PSBootstrap - - Write-Verbose -Message "Installing .NET SDK completed." -Verbose - - displayName: Install .NET - env: - __DOTNET_RUNTIME_FEED_KEY: $(RUNTIME_SOURCEFEED_KEY) - - - pwsh: | - $branch = $ENV:BUILD_SOURCEBRANCH - $version = $branch -replace '^.*(release[-/])v' - $vstsCommandString = "vso[task.setvariable variable=PowerShellVersion]$version" - Write-Verbose -Message "Version is $version" -Verbose - Write-Host -Object "##$vstsCommandString" - displayName: Set PowerShell Version - - - pwsh: | - $env:DOTNET_SKIP_FIRST_TIME_EXPERIENCE=1 - Import-Module "$(Build.SourcesDirectory)/build.psm1" -Force - Start-PSBootstrap - - $toolPath = New-Item -ItemType Directory "$(System.DefaultWorkingDirectory)/toolPath" | Select-Object -ExpandProperty FullName - - dotnet tool install --add-source "$ENV:PIPELINE_WORKSPACE/releasePipeline/finalResults" --tool-path $toolPath --version '$(PowerShellVersion)' '${{ parameters.globalToolPackageName }}' - - Get-ChildItem -Path $toolPath - - displayName: Install global tool - env: - __DOTNET_RUNTIME_FEED_KEY: $(RUNTIME_SOURCEFEED_KEY) - - - pwsh: | - $toolPath = "$(System.DefaultWorkingDirectory)/toolPath/${{ parameters.globalToolExeName }}" - - if (-not (Test-Path $toolPath)) - { - throw "Tool is not installed at $toolPath" - } - else - { - Write-Verbose -Verbose "Tool found at: $toolPath" - } - displayName: Validate tool is installed - - - pwsh: | - Import-Module "$(Build.SourcesDirectory)/build.psm1" -Force - Start-PSBootstrap - - $exeName = if ($IsWindows) { "pwsh.exe" } else { "pwsh" } - - $toolPath = "$(System.DefaultWorkingDirectory)/toolPath/${{ parameters.globalToolExeName }}" - - $source = (get-command -Type Application -Name dotnet | Select-Object -First 1 -ExpandProperty source) - $target = (Get-ChildItem $source).target - - # If we find a symbolic link for dotnet, then we need to split the filename off the target. - if ($target) { - Write-Verbose -Verbose "Splitting target: $target" - $target = Split-Path $target - } - - Write-Verbose -Verbose "target is set as $target" - - $env:DOTNET_ROOT = (resolve-path -Path (Join-Path (split-path $source) $target)).ProviderPath - - Write-Verbose -Verbose "DOTNET_ROOT: $env:DOTNET_ROOT" - Get-ChildItem $env:DOTNET_ROOT - - $versionFound = & $toolPath -c '$PSVersionTable.PSVersion.ToString()' - - if ( '$(PowerShellVersion)' -ne $versionFound) - { - throw "Expected version of global tool not found. Installed version is $versionFound" - } - else - { - write-verbose -verbose "Found expected version: $versionFound" - } - - $dateYear = & $toolPath -c '(Get-Date).Year' - - if ( $dateYear -ne [DateTime]::Now.Year) - { - throw "Get-Date returned incorrect year: $dateYear" - } - else - { - write-verbose -verbose "Got expected year: $dateYear" - } - displayName: Basic validation - env: - __DOTNET_RUNTIME_FEED_KEY: $(RUNTIME_SOURCEFEED_KEY) diff --git a/tools/releaseBuild/azureDevOps/templates/release-MakeContainerPublic.yml b/tools/releaseBuild/azureDevOps/templates/release-MakeContainerPublic.yml deleted file mode 100644 index 65d5ea50191..00000000000 --- a/tools/releaseBuild/azureDevOps/templates/release-MakeContainerPublic.yml +++ /dev/null @@ -1,20 +0,0 @@ -steps: -- download: none - -- template: release-SetReleaseTagAndContainerName.yml - -- pwsh: | - az login --service-principal -u $(az_url) -p $(az_key) --tenant $(az_name) - displayName: az login - -- pwsh: | - az storage container set-permission --account-name $(StorageAccount) --name $(azureVersion) --public-access blob - displayName: Make container public - -- pwsh: | - az storage container set-permission --account-name $(StorageAccount) --name $(azureVersion)-gc --public-access blob - displayName: Make guest configuration miminal package container public - -- pwsh: | - az logout - displayName: az logout diff --git a/tools/releaseBuild/azureDevOps/templates/release-MsixBundle.yml b/tools/releaseBuild/azureDevOps/templates/release-MsixBundle.yml deleted file mode 100644 index a9591b2d251..00000000000 --- a/tools/releaseBuild/azureDevOps/templates/release-MsixBundle.yml +++ /dev/null @@ -1,81 +0,0 @@ -jobs: -- job: CreateMSIXBundle - displayName: Create .msixbundle file - - pool: - name: PowerShell1ES - demands: - - ImageOverride -equals PSMMS2019-Secure - - variables: - - group: msixTools - - group: 'Azure Blob variable group' - - steps: - - template: release-SetReleaseTagAndContainerName.yml - - - task: DownloadPipelineArtifact@2 - retryCountOnTaskFailure: 2 - inputs: - source: specific - project: PowerShellCore - pipeline: '696' - preferTriggeringPipeline: true - runVersion: latestFromBranch - runBranch: '$(Build.SourceBranch)' - artifact: finalResults - patterns: '**/*.msix' - path: '$(Pipeline.Workspace)\releasePipeline\msix' - - - pwsh: | - $cmd = Get-Command makeappx.exe -ErrorAction Ignore - if ($cmd) { - Write-Verbose -Verbose 'makeappx available in PATH' - $exePath = $cmd.Source - } else { - $toolsDir = '$(Pipeline.Workspace)\releasePipeline\tools' - New-Item $toolsDir -Type Directory -Force > $null - Invoke-RestMethod -Uri '$(makeappUrl)' -OutFile "$toolsDir\makeappx.zip" - Expand-Archive "$toolsDir\makeappx.zip" -DestinationPath "$toolsDir\makeappx" -Force - $exePath = "$toolsDir\makeappx\makeappx.exe" - - Write-Verbose -Verbose 'makeappx was installed:' - Get-ChildItem -Path $toolsDir -Recurse - } - - $vstsCommandString = "vso[task.setvariable variable=MakeAppxPath]$exePath" - Write-Host "sending " + $vstsCommandString - Write-Host "##$vstsCommandString" - displayName: Install makeappx tool - retryCountOnTaskFailure: 1 - - - pwsh: | - $sourceDir = '$(Pipeline.Workspace)\releasePipeline\msix' - $file = Get-ChildItem $sourceDir | Select-Object -First 1 - $prefix = ($file.BaseName -split "-win")[0] - $pkgName = "$prefix.msixbundle" - Write-Verbose -Verbose "Creating $pkgName" - - $makeappx = '$(MakeAppxPath)' - $outputDir = "$sourceDir\output" - New-Item $outputDir -Type Directory -Force > $null - & $makeappx bundle /d $sourceDir /p "$outputDir\$pkgName" - - Get-ChildItem -Path $sourceDir -Recurse - $vstsCommandString = "vso[task.setvariable variable=BundleDir]$outputDir" - Write-Host "sending " + $vstsCommandString - Write-Host "##$vstsCommandString" - displayName: Create MsixBundle - retryCountOnTaskFailure: 1 - - - task: AzureFileCopy@4 - displayName: 'Upload MSIX Bundle package to Az Blob' - retryCountOnTaskFailure: 2 - inputs: - SourcePath: '$(BundleDir)/*.msixbundle' - azureSubscription: '$(AzureFileCopySubscription)' - Destination: AzureBlob - storage: '$(StorageAccount)' - ContainerName: '$(AzureVersion)-private' - resourceGroup: '$(StorageResourceGroup)' - condition: succeeded() diff --git a/tools/releaseBuild/azureDevOps/templates/release-PublishPackageMsftCom.yml b/tools/releaseBuild/azureDevOps/templates/release-PublishPackageMsftCom.yml deleted file mode 100644 index 861cf48c35a..00000000000 --- a/tools/releaseBuild/azureDevOps/templates/release-PublishPackageMsftCom.yml +++ /dev/null @@ -1,57 +0,0 @@ -parameters: - - name: skipPublish - default: false - type: boolean - -steps: -- template: release-SetReleaseTagAndContainerName.yml - -- pwsh: | - $packageVersion = '$(ReleaseTag)'.ToLowerInvariant() -replace '^v','' - $vstsCommandString = "vso[task.setvariable variable=packageVersion]$packageVersion" - Write-Host "sending " + $vstsCommandString - Write-Host "##$vstsCommandString" - displayName: Set Package version - -- pwsh: | - $branch = 'main-mirror' - $gitArgs = "clone", - "--verbose", - "--branch", - "$branch", - "https://$(mscodehubCodeReadPat)@mscodehub.visualstudio.com/PowerShellCore/_git/Internal-PowerShellTeam-Tools", - '$(Pipeline.Workspace)/tools' - $gitArgs | Write-Verbose -Verbose - git $gitArgs - displayName: Clone Internal-PowerShellTeam-Tools from MSCodeHub - -- task: PipAuthenticate@1 - inputs: - artifactFeeds: 'pmc' - pythonDownloadServiceConnections: pmcDownload - -- pwsh: | - pip install pmc-cli - - $newPath = (resolve-path '~/.local/bin').providerpath - $vstsCommandString = "vso[task.setvariable variable=PATH]${env:PATH}:$newPath" - Write-Host "sending " + $vstsCommandString - Write-Host "##$vstsCommandString" - displayName: Install pmc cli - -- pwsh: | - $metadata = Get-Content -Path "$(Build.SourcesDirectory)/tools/metadata.json" -Raw | ConvertFrom-Json - $params = @{ - ReleaseTag = "$(ReleaseTag)" - AadClientId = "$(PmcCliClientID)" - BlobFolderName = "$(AzureVersion)" - LTS = $metadata.LTSRelease.Latest - ForProduction = $true - SkipPublish = $${{ parameters.skipPublish }} - MappingFilePath = '$(System.DefaultWorkingDirectory)/tools/packages.microsoft.com/mapping.json' - } - - $params | Out-String -width 9999 -Stream | write-Verbose -Verbose - - & '$(Pipeline.Workspace)/tools/packages.microsoft.com-v4/releaseLinuxPackages.ps1' @params - displayName: Run release script diff --git a/tools/releaseBuild/azureDevOps/templates/release-PublishSymbols.yml b/tools/releaseBuild/azureDevOps/templates/release-PublishSymbols.yml deleted file mode 100644 index db2cc86e259..00000000000 --- a/tools/releaseBuild/azureDevOps/templates/release-PublishSymbols.yml +++ /dev/null @@ -1,51 +0,0 @@ -steps: -- task: DownloadPipelineArtifact@2 - inputs: - source: specific - project: PowerShellCore - pipeline: '696' - preferTriggeringPipeline: true - runVersion: latestFromBranch - runBranch: '$(Build.SourceBranch)' - artifact: results - path: '$(Pipeline.Workspace)\results' - itemPattern: | - **/* - !**/*signed.zip - -- pwsh: | - Write-Verbose -Verbose "Enumerating $(Pipeline.Workspace)\results" - $downloadedArtifacts = Get-ChildItem -Recurse "$(Pipeline.Workspace)\results" - $downloadedArtifacts - $expandedRoot = New-Item -Path "$(Pipeline.Workspace)/expanded" -ItemType Directory -Verbose - $symbolsRoot = New-Item -Path "$(Pipeline.Workspace)/symbols" -ItemType Directory -Verbose - - $downloadedArtifacts | ForEach-Object { - $destFolder = New-Item -Path "$expandedRoot/$($_.BaseName)/" -ItemType Directory -Verbose - Expand-Archive -Path $_.FullName -DestinationPath $destFolder -Force - - $symbolsZipFile = Join-Path -Path $destFolder -ChildPath "symbols.zip" - $symbolZipFileContents = New-Item -Path "$destFolder/Symbols-$($_.BaseName)" -ItemType Directory -Verbose - Expand-Archive -Path $symbolsZipFile -DestinationPath $symbolZipFileContents -Force - - $symbolsToPublish = New-Item -Path "$symbolsRoot/$($_.BaseName)" -ItemType Directory -Verbose - - Get-ChildItem -Path $symbolZipFileContents -Recurse -Filter '*.pdb' | ForEach-Object { - Copy-Item -Path $_.FullName -Destination $symbolsToPublish -Verbose - } - } - - Write-Verbose -Verbose "Enumerating $symbolsRoot" - Get-ChildItem -Path $symbolsRoot -Recurse - $vstsCommandString = "vso[task.setvariable variable=SymbolsPath]$symbolsRoot" - Write-Verbose -Message "$vstsCommandString" -Verbose - Write-Host -Object "##$vstsCommandString" - displayName: Expand and capture symbols folders -- task: PublishSymbols@2 - inputs: - symbolsFolder: '$(SymbolsPath)' - searchPattern: '**/*.pdb' - indexSources: false - publishSymbols: true - symbolServerType: teamServices - detailedLog: true diff --git a/tools/releaseBuild/azureDevOps/templates/release-ReleaseToNuGet.yml b/tools/releaseBuild/azureDevOps/templates/release-ReleaseToNuGet.yml deleted file mode 100644 index 33a72f56bbb..00000000000 --- a/tools/releaseBuild/azureDevOps/templates/release-ReleaseToNuGet.yml +++ /dev/null @@ -1,56 +0,0 @@ -parameters: - - name: skipPublish - default: false - type: boolean - -steps: -- task: DownloadPipelineArtifact@2 - condition: and(eq('${{ parameters.skipPublish }}', 'false'), succeeded()) - inputs: - source: specific - project: PowerShellCore - pipeline: '696' - preferTriggeringPipeline: true - runVersion: latestFromBranch - runBranch: '$(Build.SourceBranch)' - artifact: finalResults - patterns: '**/*.nupkg' - path: '$(Pipeline.Workspace)/releasePipeline/finalResults' - -- task: DownloadPipelineArtifact@2 - condition: and(eq('${{ parameters.skipPublish }}', 'false'), succeeded()) - inputs: - source: specific - project: PowerShellCore - pipeline: '696' - preferTriggeringPipeline: true - runVersion: latestFromBranch - runBranch: '$(Build.SourceBranch)' - artifact: metadata - path: '$(Pipeline.Workspace)/releasePipeline/metadata' - -- pwsh: | - #Exclude all global tool packages. Their names start with 'PowerShell.' - $null = New-Item -ItemType Directory -Path "$(Pipeline.Workspace)/release" - Copy-Item "$ENV:PIPELINE_WORKSPACE/releasePipeline/finalResults/*.nupkg" -Destination "$(Pipeline.Workspace)/release" -Exclude "PowerShell.*.nupkg" -Force -Verbose - - $releaseVersion = Get-Content "$ENV:PIPELINE_WORKSPACE/releasePipeline/metadata/release.json" | ConvertFrom-Json | Select-Object -ExpandProperty 'ReleaseVersion' - $globalToolPath = "$ENV:PIPELINE_WORKSPACE/releasePipeline/finalResults/PowerShell.$releaseVersion.nupkg" - - if ($releaseVersion -notlike '*-*') { - # Copy the global tool package for stable releases - Copy-Item $globalToolPath -Destination "$(Pipeline.Workspace)/release" - } - - Get-ChildItem "$(Pipeline.Workspace)/release" -recurse - displayName: Download and capture nupkgs - condition: and(eq('${{ parameters.skipPublish }}', 'false'), succeeded()) - -- task: NuGetCommand@2 - displayName: 'NuGet push' - condition: and(eq('${{ parameters.skipPublish }}', 'false'), succeeded()) - inputs: - command: push - packagesToPush: '$(Pipeline.Workspace)/release/*.nupkg' - nuGetFeedType: external - publishFeedCredentials: PowerShellNuGetOrgPush diff --git a/tools/releaseBuild/azureDevOps/templates/release-SDKTests.yml b/tools/releaseBuild/azureDevOps/templates/release-SDKTests.yml deleted file mode 100644 index 93fb0bf07cb..00000000000 --- a/tools/releaseBuild/azureDevOps/templates/release-SDKTests.yml +++ /dev/null @@ -1,148 +0,0 @@ -parameters: - jobName: "" - displayName: "" - imageName: "" - -jobs: -- job: ${{ parameters.jobName }} - displayName: ${{ parameters.displayName }} - pool: - # testing - vmImage: ${{ parameters.imageName }} - variables: - - group: mscodehub-feed-read-general - - group: mscodehub-feed-read-akv - - group: DotNetPrivateBuildAccess - steps: - - checkout: self - clean: true - - - task: DownloadPipelineArtifact@2 - inputs: - source: specific - project: PowerShellCore - pipeline: '696' - preferTriggeringPipeline: true - runVersion: latestFromBranch - runBranch: '$(Build.SourceBranch)' - artifact: finalResults - patterns: '**/*.nupkg' - path: '$(Pipeline.Workspace)/releasePipeline/finalResults' - - - task: DownloadPipelineArtifact@2 - inputs: - source: specific - project: PowerShellCore - pipeline: '696' - preferTriggeringPipeline: true - runVersion: latestFromBranch - runBranch: '$(Build.SourceBranch)' - artifact: metadata - path: '$(Pipeline.Workspace)/releasePipeline/metadata' - - - template: /.pipelines/templates/insert-nuget-config-azfeed.yml@self - parameters: - repoRoot: $(Build.SourcesDirectory) - - - pwsh: | - Import-Module "$(Build.SourcesDirectory)/build.psm1" -Force - - Write-Verbose -Verbose "Capture hosting folder files" - Get-ChildItem '$(Build.SourcesDirectory)/test/hosting' - - # The above cmdlet creates a lower-case nuget.config. There also exists a NuGet.config which we needed to replace. - # Hence the following workaround - - if (-not $IsWindows) { - Move-Item -Path '$(Build.SourcesDirectory)/test/hosting/nuget.config' -Destination '$(Build.SourcesDirectory)/test/hosting/NuGet.Config' -Force -ErrorAction Continue - Write-Verbose -Verbose "Capture hosting folder files after Move-Item" - Get-ChildItem '$(Build.SourcesDirectory)/test/hosting' - } - - if(-not (Test-Path "$(Build.SourcesDirectory)/test/hosting/NuGet.Config")) - { - throw "NuGet.Config is not created" - } - else - { - Write-Verbose -Verbose "Capture NuGet.Config contents" - Get-Content "$(Build.SourcesDirectory)/test/hosting/NuGet.Config" -Raw - } - displayName: Insert internal nuget feed - - - pwsh: | - $dotnetMetadataPath = "$(Build.SourcesDirectory)/DotnetRuntimeMetadata.json" - $dotnetMetadataJson = Get-Content $dotnetMetadataPath -Raw | ConvertFrom-Json - - # Channel is like: $Channel = "5.0.1xx-preview2" - $Channel = $dotnetMetadataJson.sdk.channel - - $sdkVersion = (Get-Content "$(Build.SourcesDirectory)/global.json" -Raw | ConvertFrom-Json).sdk.version - Import-Module "$(Build.SourcesDirectory)/build.psm1" -Force - - Find-Dotnet - - if(-not (Get-PackageSource -Name 'dotnet' -ErrorAction SilentlyContinue)) - { - $nugetFeed = ([xml](Get-Content $(Build.SourcesDirectory)/nuget.config -Raw)).Configuration.packagesources.add | Where-Object { $_.Key -eq 'dotnet' } | Select-Object -ExpandProperty Value - - if ($nugetFeed) { - Register-PackageSource -Name 'dotnet' -Location $nugetFeed -ProviderName NuGet - Write-Verbose -Message "Register new package source 'dotnet'" -verbose - } - } - - ## Install latest version from the channel - #Install-Dotnet -Channel "$Channel" -Version $sdkVersion - - Start-PSBootstrap - - Write-Verbose -Message "Installing .NET SDK completed." -Verbose - - displayName: Install .NET - env: - __DOTNET_RUNTIME_FEED_KEY: $(RUNTIME_SOURCEFEED_KEY) - - - pwsh: | - $env:DOTNET_SKIP_FIRST_TIME_EXPERIENCE=1 - Import-Module "$(Build.SourcesDirectory)/build.psm1" -Force - Start-PSBootstrap - - $localLocation = "$(Pipeline.Workspace)/releasePipeline/finalResults" - $xmlElement = @" - - - - "@ - - $releaseVersion = Get-Content "$(Pipeline.Workspace)/releasePipeline/metadata/release.json" | ConvertFrom-Json | Select-Object -ExpandProperty 'ReleaseVersion' - - Set-Location -Path $(Build.SourcesDirectory)/test/hosting - - Get-ChildItem - - ## register the packages download directory in the nuget file - $nugetConfigContent = Get-Content ./NuGet.Config -Raw - $updateNugetContent = $nugetConfigContent.Replace("", $xmlElement) - - $updateNugetContent | Out-File ./NuGet.Config -Encoding ascii - - Get-Content ./NuGet.Config - - # Add workaround to unblock xUnit testing see issue: https://github.com/dotnet/sdk/issues/26462 - $dotnetPath = if ($IsWindows) { "$env:LocalAppData\Microsoft\dotnet" } else { "$env:HOME/.dotnet" } - $env:DOTNET_ROOT = $dotnetPath - - dotnet --info - dotnet restore - dotnet test /property:RELEASE_VERSION=$releaseVersion --test-adapter-path:. "--logger:xunit;LogFilePath=$(System.DefaultWorkingDirectory)/test-hosting.xml" - - displayName: Restore and execute tests - env: - __DOTNET_RUNTIME_FEED_KEY: $(RUNTIME_SOURCEFEED_KEY) - - - task: PublishTestResults@2 - displayName: 'Publish Test Results **\test-hosting.xml' - inputs: - testResultsFormat: XUnit - testResultsFiles: '**\test-hosting.xml' diff --git a/tools/releaseBuild/azureDevOps/templates/release-SetReleaseTagAndContainerName.yml b/tools/releaseBuild/azureDevOps/templates/release-SetReleaseTagAndContainerName.yml deleted file mode 100644 index 7e88624b45c..00000000000 --- a/tools/releaseBuild/azureDevOps/templates/release-SetReleaseTagAndContainerName.yml +++ /dev/null @@ -1,26 +0,0 @@ -steps: -- pwsh: | - $variable = 'releaseTag' - $branch = $ENV:BUILD_SOURCEBRANCH - if($branch -notmatch '^.*((release/|rebuild/.*rebuild))') - { - throw "Branch name is not in release format: '$branch'" - } - - $releaseTag = $Branch -replace '^.*((release|rebuild)/)' - $vstsCommandString = "vso[task.setvariable variable=$Variable]$releaseTag" - Write-Verbose -Message "setting $Variable to $releaseTag" -Verbose - Write-Host -Object "##$vstsCommandString" - displayName: Set Release Tag - -- pwsh: | - $azureVersion = '$(ReleaseTag)'.ToLowerInvariant() -replace '\.', '-' - $vstsCommandString = "vso[task.setvariable variable=AzureVersion]$azureVersion" - Write-Host "sending " + $vstsCommandString - Write-Host "##$vstsCommandString" - - $version = '$(ReleaseTag)'.ToLowerInvariant().Substring(1) - $vstsCommandString = "vso[task.setvariable variable=Version]$version" - Write-Host ("sending " + $vstsCommandString) - Write-Host "##$vstsCommandString" - displayName: Set container name diff --git a/tools/releaseBuild/azureDevOps/templates/release-UpdateDepsJson.yml b/tools/releaseBuild/azureDevOps/templates/release-UpdateDepsJson.yml deleted file mode 100644 index fa42064602e..00000000000 --- a/tools/releaseBuild/azureDevOps/templates/release-UpdateDepsJson.yml +++ /dev/null @@ -1,71 +0,0 @@ -jobs: -- job: UpdateDepsFiles - displayName: Update deps files - - pool: - name: PowerShell1ES - demands: - - ImageOverride -equals PSMMS2019-Secure - - variables: - - group: 'Azure Blob variable group' - steps: - - checkout: self - clean: true - - - task: DownloadPipelineArtifact@2 - inputs: - source: specific - project: PowerShellCore - pipeline: '696' - preferTriggeringPipeline: true - runVersion: latestFromBranch - runBranch: '$(Build.SourceBranch)' - artifact: finalResults - patterns: '**/PowerShell*-win-x64.zip' - path: '$(Pipeline.Workspace)/releasePipeline/finalResults' - - - task: DownloadPipelineArtifact@2 - inputs: - source: specific - project: PowerShellCore - pipeline: '696' - preferTriggeringPipeline: true - runVersion: latestFromBranch - runBranch: '$(Build.SourceBranch)' - artifact: BuildInfoJson - path: '$(Pipeline.Workspace)/releasePipeline/BuildInfoJson' - - - pwsh: | - $fileName = (Get-Item "$ENV:PIPELINE_WORKSPACE/releasePipeline/BuildInfoJson/*.json").BaseName - if ($fileName -notin 'stable','preview') - { - throw "Unexpected fileName: $fileName" - } - - $vstsCommand = "vso[task.setvariable variable=BlobPrefix]$fileName" - Write-Verbose -Verbose $vstsCommand - Write-Host "##$vstsCommand" - displayName: Determine container name - - - pwsh: | - $zipFile = Get-Item "$ENV:PIPELINE_WORKSPACE/releasePipeline/finalResults/PowerShell*-win-x64.zip" -Exclude *-symbols-* - Write-Verbose -Verbose "zipFile: $zipFile" - Expand-Archive -Path $zipFile -Destination "$ENV:PIPELINE_WORKSPACE/expanded" - - $pwshDepsFile = Get-Item "$ENV:PIPELINE_WORKSPACE/expanded/pwsh.deps.json" - $vstsCommand = "vso[task.setvariable variable=FileToUpload]$pwshDepsFile" - Write-Verbose -Verbose $vstsCommand - Write-Host "##$vstsCommand" - displayName: Determine file to upload - - - task: AzureFileCopy@4 - displayName: 'AzureBlob pwsh.deps.json file Copy' - inputs: - SourcePath: '$(FileToUpload)' - azureSubscription: '$(AzureFileCopySubscription)' - Destination: AzureBlob - storage: '$(StorageAccount)' - ContainerName: ps-deps-json - blobPrefix: '$(BlobPrefix)' - retryCountOnTaskFailure: 2 diff --git a/tools/releaseBuild/azureDevOps/templates/release-ValidateFxdPackage.yml b/tools/releaseBuild/azureDevOps/templates/release-ValidateFxdPackage.yml deleted file mode 100644 index 7f2c816a20f..00000000000 --- a/tools/releaseBuild/azureDevOps/templates/release-ValidateFxdPackage.yml +++ /dev/null @@ -1,92 +0,0 @@ -parameters: - jobName: "" - displayName: "" - imageName: "" - packageNamePattern: "" - use1ES: false - -jobs: -- job: ${{ parameters.jobName }} - displayName: ${{ parameters.displayName }} - variables: - - group: DotNetPrivateBuildAccess - pool: - ${{ if eq(parameters.use1ES, 'false') }}: - vmImage: ${{ parameters.imageName }} - ${{ else }}: - name: 'PS-MSCodeHub-ARM' # add ImageOverride to select image - steps: - - checkout: self - clean: true - - - task: DownloadPipelineArtifact@2 - inputs: - source: specific - project: PowerShellCore - pipeline: '696' - preferTriggeringPipeline: true - runVersion: latestFromBranch - runBranch: '$(Build.SourceBranch)' - artifact: finalResults - patterns: '${{ parameters.packageNamePattern }}' - path: '$(Pipeline.Workspace)/releasePipeline/finalResults' - - - pwsh: | - $env:DOTNET_SKIP_FIRST_TIME_EXPERIENCE=1 - Import-Module "$(Build.SourcesDirectory)/build.psm1" -Force - Start-PSBootstrap - Write-Verbose -Message "Installing .NET SDK completed." -Verbose - displayName: Install .NET - env: - __DOTNET_RUNTIME_FEED_KEY: $(RUNTIME_SOURCEFEED_KEY) - - - pwsh: | - Get-ChildItem -Path '$(Pipeline.Workspace)/releasePipeline/finalResults' -Recurse - displayName: Capture downloaded package - - - pwsh: | - $destPath = New-Item '$(Pipeline.Workspace)/releasePipeline/finalResults/fxd' -ItemType Directory - $packageNameFilter = '${{ parameters.packageNamePattern }}' - - if ($packageNameFilter.EndsWith('tar.gz')) { - $package = @(Get-ChildItem -Path '$(Pipeline.Workspace)/releasePipeline/finalResults/*.tar.gz') - Write-Verbose -Verbose "Package: $package" - if ($package.Count -ne 1) { - throw 'Only 1 package was expected.' - } - tar -xvf $package.FullName -C $destPath - } - else { - $package = @(Get-ChildItem -Path '$(Pipeline.Workspace)/releasePipeline/finalResults/*.zip') - Write-Verbose -Verbose "Package: $package" - if ($package.Count -ne 1) { - throw 'Only 1 package was expected.' - } - Expand-Archive -Path $package.FullName -Destination "$destPath" -Verbose - } - displayName: Expand fxd package - - - pwsh: | - $env:DOTNET_SKIP_FIRST_TIME_EXPERIENCE=1 - Import-Module "$(Build.SourcesDirectory)/build.psm1" -Force - Find-Dotnet -SetDotnetRoot - Write-Verbose -Verbose "DOTNET_ROOT: $env:DOTNET_ROOT" - Write-Verbose -Verbose "Check dotnet install" - dotnet --info - Write-Verbose -Verbose "Start test" - $packageNameFilter = '${{ parameters.packageNamePattern }}' - $pwshExeName = if ($packageNameFilter.EndsWith('tar.gz')) { 'pwsh' } else { 'pwsh.exe' } - $pwshPath = Join-Path '$(Pipeline.Workspace)/releasePipeline/finalResults/fxd' $pwshExeName - - if ($IsLinux) { - chmod u+x $pwshPath - } - - $pwshDllPath = Join-Path '$(Pipeline.Workspace)/releasePipeline/finalResults/fxd' 'pwsh.dll' - - $actualOutput = & dotnet $pwshDllPath -c 'Start-ThreadJob -ScriptBlock { "1" } | Wait-Job | Receive-Job' - Write-Verbose -Verbose "Actual output: $actualOutput" - if ($actualOutput -ne 1) { - throw "Actual output is not as expected" - } - displayName: Test package diff --git a/tools/releaseBuild/azureDevOps/templates/release-ValidatePackageBOM.yml b/tools/releaseBuild/azureDevOps/templates/release-ValidatePackageBOM.yml deleted file mode 100644 index 3fd560cbd00..00000000000 --- a/tools/releaseBuild/azureDevOps/templates/release-ValidatePackageBOM.yml +++ /dev/null @@ -1,49 +0,0 @@ -steps: -- checkout: self - clean: true - -- pwsh: | - Get-ChildItem ENV: - displayName: Capture environment - -- template: release-SetReleaseTagAndContainerName.yml - -- pwsh: | - $name = "{0}_{1:x}" -f '$(releaseTag)', (Get-Date).Ticks - Write-Host $name - Write-Host "##vso[build.updatebuildnumber]$name" - displayName: Set Release Name - -- task: DownloadPipelineArtifact@2 - inputs: - source: specific - project: PowerShellCore - pipeline: '696' - preferTriggeringPipeline: true - runVersion: latestFromBranch - runBranch: '$(Build.SourceBranch)' - artifact: finalResults - path: $(System.ArtifactsDirectory) - - -- pwsh: | - Get-ChildItem $(System.ArtifactsDirectory)\* -recurse | Select-Object -ExpandProperty Name - displayName: Capture Artifact Listing - -- pwsh: | - Install-module Pester -Scope CurrentUser -Force -MaximumVersion 4.99 - displayName: Install Pester - condition: succeededOrFailed() - -- pwsh: | - Import-module './build.psm1' - Import-module './tools/packaging' - $env:PACKAGE_FOLDER = '$(System.ArtifactsDirectory)' - $path = Join-Path -Path $pwd -ChildPath './packageReleaseTests.xml' - $results = invoke-pester -Script './tools/packaging/releaseTests' -OutputFile $path -OutputFormat NUnitXml -PassThru - Write-Host "##vso[results.publish type=NUnit;mergeResults=true;runTitle=Package Release Tests;publishRunAttachments=true;resultFiles=$path;]" - if($results.TotalCount -eq 0 -or $results.FailedCount -gt 0) - { - throw "Package Release Tests failed" - } - displayName: Run packaging release tests diff --git a/tools/releaseBuild/azureDevOps/templates/release-ValidatePackageNames.yml b/tools/releaseBuild/azureDevOps/templates/release-ValidatePackageNames.yml deleted file mode 100644 index 8e41fbc4a55..00000000000 --- a/tools/releaseBuild/azureDevOps/templates/release-ValidatePackageNames.yml +++ /dev/null @@ -1,93 +0,0 @@ -steps: -- pwsh: | - Get-ChildItem ENV: - displayName: Capture environment - -- template: release-SetReleaseTagAndContainerName.yml - -- pwsh: | - $name = "{0}_{1:x}" -f '$(releaseTag)', (Get-Date).Ticks - Write-Host $name - Write-Host "##vso[build.updatebuildnumber]$name" - displayName: Set Release Name - -- pwsh: | - Import-module '$(BUILD.SOURCESDIRECTORY)/build.psm1' - $azcopy = Find-AzCopy - Write-Verbose -Verbose "Found AzCopy: $azcopy" - - & $azcopy cp https://$(StorageAccount).blob.core.windows.net/$(AzureVersion)/* $(System.ArtifactsDirectory) --recursive - - displayName: Download Azure Artifacts - env: - AZCOPY_AUTO_LOGIN_TYPE: MSI - -- pwsh: | - Get-ChildItem $(System.ArtifactsDirectory)\* -recurse | Select-Object -ExpandProperty Name - displayName: Capture Artifact Listing - -- pwsh: | - $message = @() - Get-ChildItem $(System.ArtifactsDirectory)\* -recurse -filter *.rpm | ForEach-Object { - if($_.Name -notmatch 'powershell\-(preview-|lts-)?\d+\.\d+\.\d+(_[a-z]*\.\d+)?-1.(rh|cm).(x86_64|aarch64)\.rpm') - { - $messageInstance = "$($_.Name) is not a valid package name" - $message += $messageInstance - Write-Warning $messageInstance - } - } - if($message.count -gt 0){throw ($message | out-string)} - displayName: Validate RPM package names - -- pwsh: | - $message = @() - Get-ChildItem $(System.ArtifactsDirectory)\* -recurse -filter *.tar.gz | ForEach-Object { - if($_.Name -notmatch 'powershell-(lts-)?\d+\.\d+\.\d+\-([a-z]*.\d+\-)?(linux|osx|linux-musl)+\-(x64\-fxdependent|x64|arm32|arm64|x64\-musl-noopt\-fxdependent)\.(tar\.gz)') - { - $messageInstance = "$($_.Name) is not a valid package name" - $message += $messageInstance - Write-Warning $messageInstance - } - } - if($message.count -gt 0){throw ($message | out-string)} - displayName: Validate Tar.Gz Package Names - -- pwsh: | - $message = @() - Get-ChildItem $(System.ArtifactsDirectory)\* -recurse -filter *.pkg | ForEach-Object { - if($_.Name -notmatch 'powershell-(lts-)?\d+\.\d+\.\d+\-([a-z]*.\d+\-)?osx(\.10\.12)?\-(x64|arm64)\.pkg') - { - $messageInstance = "$($_.Name) is not a valid package name" - $message += $messageInstance - Write-Warning $messageInstance - } - } - if($message.count -gt 0){throw ($message | out-string)} - displayName: Validate PKG Package Names - -- pwsh: | - $message = @() - Get-ChildItem $(System.ArtifactsDirectory)\* -recurse -include *.zip, *.msi | ForEach-Object { - if($_.Name -notmatch 'PowerShell-\d+\.\d+\.\d+\-([a-z]*.\d+\-)?win\-(fxdependent|x64|arm64|x86|fxdependentWinDesktop)\.(msi|zip){1}') - { - $messageInstance = "$($_.Name) is not a valid package name" - $message += $messageInstance - Write-Warning $messageInstance - } - } - - if($message.count -gt 0){throw ($message | out-string)} - displayName: Validate Zip and MSI Package Names - -- pwsh: | - $message = @() - Get-ChildItem $(System.ArtifactsDirectory)\* -recurse -filter *.deb | ForEach-Object { - if($_.Name -notmatch 'powershell(-preview|-lts)?_\d+\.\d+\.\d+([\-~][a-z]*.\d+)?-\d\.deb_amd64\.deb') - { - $messageInstance = "$($_.Name) is not a valid package name" - $message += $messageInstance - Write-Warning $messageInstance - } - } - if($message.count -gt 0){throw ($message | out-string)} - displayName: Validate Deb Package Names diff --git a/tools/releaseBuild/azureDevOps/templates/release/approvalJob.yml b/tools/releaseBuild/azureDevOps/templates/release/approvalJob.yml deleted file mode 100644 index b34cc4c75b6..00000000000 --- a/tools/releaseBuild/azureDevOps/templates/release/approvalJob.yml +++ /dev/null @@ -1,35 +0,0 @@ -parameters: - - name: displayName - type: string - - name: instructions - type: string - - name: jobName - type: string - default: approval - - name: timeoutInMinutes - type: number - # 2 days - default: 2880 - - name: onTimeout - type: string - default: 'reject' - values: - - resume - - reject - - name: dependsOnJob - type: string - default: '' - -jobs: - - job: ${{ parameters.jobName }} - dependsOn: ${{ parameters.dependsOnJob }} - displayName: ${{ parameters.displayName }} - pool: server - timeoutInMinutes: 4320 # job times out in 3 days - steps: - - task: ManualValidation@0 - displayName: ${{ parameters.displayName }} - timeoutInMinutes: ${{ parameters.timeoutInMinutes }} - inputs: - instructions: ${{ parameters.instructions }} - onTimeout: ${{ parameters.onTimeout }} diff --git a/tools/releaseBuild/azureDevOps/templates/shouldSign.yml b/tools/releaseBuild/azureDevOps/templates/shouldSign.yml deleted file mode 100644 index e3c38cb29d5..00000000000 --- a/tools/releaseBuild/azureDevOps/templates/shouldSign.yml +++ /dev/null @@ -1,29 +0,0 @@ -steps: -- powershell: | - $shouldSign = $true - $authenticodeCert = 'CP-230012' - $msixCert = 'CP-230012' - - if($env:IS_DAILY -eq 'true') - { - $authenticodeCert = 'CP-460906' - } - - if($env:SKIP_SIGNING -eq 'Yes') - { - $shouldSign = $false - } - - $vstsCommandString = "vso[task.setvariable variable=SHOULD_SIGN]$($shouldSign.ToString().ToLowerInvariant())" - Write-Host "sending " + $vstsCommandString - Write-Host "##$vstsCommandString" - - $vstsCommandString = "vso[task.setvariable variable=MSIX_CERT]$($msixCert)" - Write-Host "sending " + $vstsCommandString - Write-Host "##$vstsCommandString" - - $vstsCommandString = "vso[task.setvariable variable=AUTHENTICODE_CERT]$($authenticodeCert)" - Write-Host "sending " + $vstsCommandString - Write-Host "##$vstsCommandString" - - displayName: 'Set SHOULD_SIGN Variable' diff --git a/tools/releaseBuild/azureDevOps/templates/sign-build-file.yml b/tools/releaseBuild/azureDevOps/templates/sign-build-file.yml deleted file mode 100644 index a584e15e27c..00000000000 --- a/tools/releaseBuild/azureDevOps/templates/sign-build-file.yml +++ /dev/null @@ -1,328 +0,0 @@ -steps: -- pwsh: | - $platform = '$(runtime)' -match '^linux' ? 'linux' : 'windows' - $vstsCommandString = "vso[task.setvariable variable=ArtifactPlatform]$platform" - Write-Host ("sending " + $vstsCommandString) - Write-Host "##$vstsCommandString" - displayName: Set artifact platform - -- task: DownloadPipelineArtifact@2 - inputs: - artifactName: '$(unsignedBuildArtifactContainer)' - itemPattern: '$(unsignedBuildArtifactName)' - -- pwsh: | - Get-ChildItem "$(Pipeline.Workspace)\*" -Recurse - displayName: 'Capture Downloaded Artifacts' - # Diagnostics is not critical it passes every time it runs - continueOnError: true - -- checkout: self - clean: true - path: $(repoFolder) - -- template: SetVersionVariables.yml - parameters: - ReleaseTagVar: $(ReleaseTagVar) - -- template: cloneToOfficialPath.yml - -- pwsh: | - $zipFileFilter = '$(unsignedBuildArtifactName)' - $zipFileFilter = $zipFileFilter.Replace('**/', '') - - Write-Verbose -Verbose -Message "zipFileFilter = $zipFileFilter" - - Write-Verbose -Verbose -Message "Looking for $(Pipeline.Workspace)\$(unsignedBuildArtifactName)" - - $zipFilePath = Get-ChildItem -Path '$(Pipeline.Workspace)\$(unsignedBuildArtifactName)' -recurse - - if (-not (Test-Path $zipFilePath)) - { - throw "zip file not found: $zipfilePath" - } - - if ($zipFilePath.Count -ne 1) { - Write-Verbose "zip filename" -verbose - $zipFilePath | Out-String | Write-Verbose -Verbose - throw 'multiple zip files found when 1 was expected' - } - - $expandedFolderName = [System.io.path]::GetFileNameWithoutExtension($zipfilePath) - $expandedFolderPath = Join-Path '$(Pipeline.Workspace)' 'expanded' $expandedFolderName - - Write-Verbose -Verbose -Message "Expaning $zipFilePath to $expandedFolderPath" - - New-Item -Path $expandedFolderPath -ItemType Directory - Expand-Archive -Path $zipFilePath -DestinationPath $expandedFolderPath - - if (-not (Test-Path $expandedFolderPath\pwsh.exe) ) { - throw 'zip did not expand as expected' - } - else { - $vstsCommandString = "vso[task.setvariable variable=BinPath]$expandedFolderPath" - Write-Host ("sending " + $vstsCommandString) - Write-Host "##$vstsCommandString" - } - - displayName: Expand zip packages - condition: eq(variables['ArtifactPlatform'], 'windows') - -- pwsh: | - $tarPackageName = '$(unsignedBuildArtifactName)' - - Write-Verbose -Verbose -Message "tarPackageName = $tarPackageName" - - $tarPackagePath = Join-Path '$(Pipeline.Workspace)' $tarPackageName - - Write-Verbose -Verbose -Message "Looking for: $tarPackagePath" - - $expandedPathFolderName = $tarPackageName -replace '.tar.gz', '' - $expandedFolderPath = Join-Path '$(Pipeline.Workspace)' 'expanded' $expandedPathFolderName - - if (-not (Test-Path $tarPackagePath)) - { - throw "tar file not found: $tarPackagePath" - } - - Write-Verbose -Verbose -Message "Expanding $tarPackagePath to $expandedFolderPath" - - New-Item -Path $expandedFolderPath -ItemType Directory - tar -xf $tarPackagePath -C $expandedFolderPath - - if (-not (Test-Path $expandedFolderPath/pwsh) ) { - throw 'tar.gz did not expand as expected' - } - else { - $vstsCommandString = "vso[task.setvariable variable=BinPath]$expandedFolderPath" - Write-Host ("sending " + $vstsCommandString) - Write-Host "##$vstsCommandString" - } - - Write-Verbose -Verbose "File permisions after expanding" - Get-ChildItem -Path "$expandedFolderPath/pwsh" | Select-Object -Property 'unixmode', 'size', 'name' - displayName: Expand tar.gz packages - condition: eq(variables['ArtifactPlatform'], 'linux') - -- template: insert-nuget-config-azfeed.yml - parameters: - repoRoot: $(PowerShellRoot) - -- pwsh: | - Set-Location $env:POWERSHELLROOT - import-module "$env:POWERSHELLROOT/build.psm1" - Sync-PSTags -AddRemoteIfMissing - displayName: SyncTags - condition: and(succeeded(), ne(variables['SkipBuild'], 'true')) - -- checkout: ComplianceRepo - clean: true - path: $(complianceRepoFolder) - -- template: shouldSign.yml - -- pwsh: | - $fullSymbolsFolder = '$(BinPath)' - Write-Verbose -Verbose "fullSymbolsFolder == $fullSymbolsFolder" - - Get-ChildItem -Recurse $fullSymbolsFolder | out-string | Write-Verbose -Verbose - - $filesToSignDirectory = "$(System.ArtifactsDirectory)\toBeSigned" - - if ((Test-Path -Path $filesToSignDirectory)) { - Remove-Item -Path $filesToSignDirectory -Recurse -Force - } - - $null = New-Item -ItemType Directory -Path $filesToSignDirectory -Force - - $signedFilesDirectory = "$(System.ArtifactsDirectory)\signed" - - if ((Test-Path -Path $signedFilesDirectory)) { - Remove-Item -Path $signedFilesDirectory -Recurse -Force - } - - $null = New-Item -ItemType Directory -Path $signedFilesDirectory -Force - - $itemsToCopyWithRecurse = @( - "$($fullSymbolsFolder)\*.ps1" - "$($fullSymbolsFolder)\Microsoft.PowerShell*.dll" - ) - - $itemsToCopy = @{ - "$($fullSymbolsFolder)\*.ps1" = "" - "$($fullSymbolsFolder)\Modules\Microsoft.PowerShell.Host\Microsoft.PowerShell.Host.psd1" = "Modules\Microsoft.PowerShell.Host" - "$($fullSymbolsFolder)\Modules\Microsoft.PowerShell.Management\Microsoft.PowerShell.Management.psd1" = "Modules\Microsoft.PowerShell.Management" - "$($fullSymbolsFolder)\Modules\Microsoft.PowerShell.Security\Microsoft.PowerShell.Security.psd1" = "Modules\Microsoft.PowerShell.Security" - "$($fullSymbolsFolder)\Modules\Microsoft.PowerShell.Utility\Microsoft.PowerShell.Utility.psd1" = "Modules\Microsoft.PowerShell.Utility" - "$($fullSymbolsFolder)\pwsh.dll" = "" - "$($fullSymbolsFolder)\System.Management.Automation.dll" = "" - } - - ## Windows only modules - - if('$(ArtifactPlatform)' -eq 'windows') { - $itemsToCopy += @{ - "$($fullSymbolsFolder)\pwsh.exe" = "" - "$($fullSymbolsFolder)\Microsoft.Management.Infrastructure.CimCmdlets.dll" = "" - "$($fullSymbolsFolder)\Microsoft.WSMan.*.dll" = "" - "$($fullSymbolsFolder)\Modules\CimCmdlets\CimCmdlets.psd1" = "Modules\CimCmdlets" - "$($fullSymbolsFolder)\Modules\Microsoft.PowerShell.Diagnostics\Diagnostics.format.ps1xml" = "Modules\Microsoft.PowerShell.Diagnostics" - "$($fullSymbolsFolder)\Modules\Microsoft.PowerShell.Diagnostics\Event.format.ps1xml" = "Modules\Microsoft.PowerShell.Diagnostics" - "$($fullSymbolsFolder)\Modules\Microsoft.PowerShell.Diagnostics\GetEvent.types.ps1xml" = "Modules\Microsoft.PowerShell.Diagnostics" - "$($fullSymbolsFolder)\Modules\Microsoft.PowerShell.Security\Security.types.ps1xml" = "Modules\Microsoft.PowerShell.Security" - "$($fullSymbolsFolder)\Modules\Microsoft.PowerShell.Diagnostics\Microsoft.PowerShell.Diagnostics.psd1" = "Modules\Microsoft.PowerShell.Diagnostics" - "$($fullSymbolsFolder)\Modules\Microsoft.WSMan.Management\Microsoft.WSMan.Management.psd1" = "Modules\Microsoft.WSMan.Management" - "$($fullSymbolsFolder)\Modules\Microsoft.WSMan.Management\WSMan.format.ps1xml" = "Modules\Microsoft.WSMan.Management" - "$($fullSymbolsFolder)\Modules\PSDiagnostics\PSDiagnostics.ps?1" = "Modules\PSDiagnostics" - } - } - else { - $itemsToCopy += @{ - "$($fullSymbolsFolder)\pwsh" = "" - } - } - - $itemsToExclude = @( - # This package is retrieved from https://www.github.com/powershell/MarkdownRender - "$($fullSymbolsFolder)\Microsoft.PowerShell.MarkdownRender.dll" - ) - - Write-Verbose -verbose "recusively copying $($itemsToCopyWithRecurse | out-string) to $filesToSignDirectory" - Copy-Item -Path $itemsToCopyWithRecurse -Destination $filesToSignDirectory -Recurse -verbose -exclude $itemsToExclude - - foreach($pattern in $itemsToCopy.Keys) { - $destinationFolder = Join-Path $filesToSignDirectory -ChildPath $itemsToCopy.$pattern - $null = New-Item -ItemType Directory -Path $destinationFolder -Force - Write-Verbose -verbose "copying $pattern to $destinationFolder" - Copy-Item -Path $pattern -Destination $destinationFolder -Recurse -verbose - } - displayName: 'Prepare files to be signed' - -- template: EsrpSign.yml@ComplianceRepo - parameters: - buildOutputPath: $(System.ArtifactsDirectory)\toBeSigned - signOutputPath: $(System.ArtifactsDirectory)\signed - certificateId: "$(AUTHENTICODE_CERT)" - pattern: | - **\*.dll - **\*.psd1 - **\*.psm1 - **\*.ps1xml - **\*.ps1 - **\*.exe - useMinimatch: true - shouldSign: $(SHOULD_SIGN) - displayName: Authenticode sign our binaries - -- pwsh: | - Import-Module $(PowerShellRoot)/build.psm1 -Force - Import-Module $(PowerShellRoot)/tools/packaging -Force - $signedFilesPath = '$(System.ArtifactsDirectory)\signed\' - $BuildPath = '$(BinPath)' - Write-Verbose -Verbose -Message "BuildPath: $BuildPath" - - Update-PSSignedBuildFolder -BuildPath $BuildPath -SignedFilesPath $SignedFilesPath - $dlls = Get-ChildItem $BuildPath\*.dll, $BuildPath\*.exe -Recurse - $signatures = $dlls | Get-AuthenticodeSignature - $missingSignatures = $signatures | Where-Object { $_.status -eq 'notsigned' -or $_.SignerCertificate.Issuer -notmatch '^CN=Microsoft.*'}| select-object -ExpandProperty Path - - Write-Verbose -verbose "to be signed:`r`n $($missingSignatures | Out-String)" - - $filesToSignDirectory = "$(System.ArtifactsDirectory)\thirdPartyToBeSigned" - if (Test-Path $filesToSignDirectory) { - Remove-Item -Path $filesToSignDirectory -Recurse -Force - } - - $null = New-Item -ItemType Directory -Path $filesToSignDirectory -Force -Verbose - - $signedFilesDirectory = "$(System.ArtifactsDirectory)\thirdPartySigned" - if (Test-Path $signedFilesDirectory) { - Remove-Item -Path $signedFilesDirectory -Recurse -Force - } - - $null = New-Item -ItemType Directory -Path $signedFilesDirectory -Force -Verbose - - $missingSignatures | ForEach-Object { - $pathWithoutLeaf = Split-Path $_ - $relativePath = $pathWithoutLeaf.replace($BuildPath,'') - Write-Verbose -Verbose -Message "relativePath: $relativePath" - $targetDirectory = Join-Path -Path $filesToSignDirectory -ChildPath $relativePath - Write-Verbose -Verbose -Message "targetDirectory: $targetDirectory" - if(!(Test-Path $targetDirectory)) - { - $null = New-Item -ItemType Directory -Path $targetDirectory -Force -Verbose - } - Copy-Item -Path $_ -Destination $targetDirectory - } - - displayName: Create ThirdParty Signing Folder - condition: and(succeeded(), eq(variables['SHOULD_SIGN'], 'true')) - -- template: EsrpSign.yml@ComplianceRepo - parameters: - buildOutputPath: $(System.ArtifactsDirectory)\thirdPartyToBeSigned - signOutputPath: $(System.ArtifactsDirectory)\thirdPartySigned - certificateId: "CP-231522" - pattern: | - **\*.dll - useMinimatch: true - shouldSign: $(SHOULD_SIGN) - displayName: Sign ThirdParty binaries - -- pwsh: | - Get-ChildItem '$(System.ArtifactsDirectory)\thirdPartySigned\*' - displayName: Capture ThirdParty Signed files - condition: and(succeeded(), eq(variables['SHOULD_SIGN'], 'true')) - -- pwsh: | - Import-Module '$(PowerShellRoot)/build.psm1' -Force - Import-Module '$(PowerShellRoot)/tools/packaging' -Force - $signedFilesPath = '$(System.ArtifactsDirectory)\thirdPartySigned' - $BuildPath = '$(BinPath)' - - Update-PSSignedBuildFolder -BuildPath $BuildPath -SignedFilesPath $SignedFilesPath - if ($env:BuildConfiguration -eq 'minSize') { - ## Remove XML files when making a min-size package. - Remove-Item "$BuildPath/*.xml" -Force - } - displayName: Merge ThirdParty signed files with Build - condition: and(succeeded(), eq(variables['SHOULD_SIGN'], 'true')) - -- pwsh: | - $uploadFolder = '$(BinPath)' - $containerName = '$(signedArtifactContainer)' - - Write-Verbose -Verbose "File permissions after signing" - Get-ChildItem $uploadFolder\pwsh | Select-Object -Property 'unixmode', 'size', 'name' - - $uploadTarFilePath = Join-Path '$(System.ArtifactsDirectory)' '$(signedBuildArtifactName)' - Write-Verbose -Verbose -Message "Creating tar.gz - $uploadTarFilePath" - tar -czvf $uploadTarFilePath -C $uploadFolder * - - Get-ChildItem '$(System.ArtifactsDirectory)' | Out-String | Write-Verbose -Verbose - - Write-Host "##vso[artifact.upload containerfolder=$containerName;artifactname=$containerName]$uploadTarFilePath" - displayName: Upload signed tar.gz files to artifacts - condition: eq(variables['ArtifactPlatform'], 'linux') - retryCountOnTaskFailure: 2 - - -- pwsh: | - $uploadFolder = '$(BinPath)' - $containerName = '$(signedArtifactContainer)' - - Get-ChildItem $uploadFolder -Recurse | Out-String | Write-Verbose -Verbose - - $uploadZipFilePath = Join-Path '$(System.ArtifactsDirectory)' 'PowerShell-$(Version)$(signedBuildArtifactName)' - Write-Verbose -Verbose -Message "Creating zip - $uploadZipFilePath" - Compress-Archive -Path $uploadFolder/* -DestinationPath $uploadZipFilePath -Verbose - - Get-ChildItem '$(System.ArtifactsDirectory)' | Out-String | Write-Verbose -Verbose - - Write-Host "##vso[artifact.upload containerfolder=$containerName;artifactname=$containerName]$uploadZipFilePath" - displayName: Upload signed zip files to artifacts - condition: eq(variables['ArtifactPlatform'], 'windows') - retryCountOnTaskFailure: 2 - - -- template: /tools/releaseBuild/azureDevOps/templates/step/finalize.yml diff --git a/tools/releaseBuild/azureDevOps/templates/signBuildFiles.yml b/tools/releaseBuild/azureDevOps/templates/signBuildFiles.yml deleted file mode 100644 index a7c7c640ce7..00000000000 --- a/tools/releaseBuild/azureDevOps/templates/signBuildFiles.yml +++ /dev/null @@ -1,189 +0,0 @@ -parameters: - binLocation: '' - buildPrefixName: '' - addWindowsModules: 'false' - -steps: -- pwsh: | - $fullSymbolsFolder = Join-Path $(System.ArtifactsDirectory) "${{ parameters.binLocation }}" - - Write-Verbose -Verbose "fullSymbolsFolder == $fullSymbolsFolder" - - Get-ChildItem -Recurse $fullSymbolsFolder | out-string | Write-Verbose -Verbose - - $filesToSignDirectory = "$(System.ArtifactsDirectory)\toBeSigned" - - if ((Test-Path -Path $filesToSignDirectory)) { - Remove-Item -Path $filesToSignDirectory -Recurse -Force - } - - $null = New-Item -ItemType Directory -Path $filesToSignDirectory -Force - - $signedFilesDirectory = "$(System.ArtifactsDirectory)\signed" - - if ((Test-Path -Path $signedFilesDirectory)) { - Remove-Item -Path $signedFilesDirectory -Recurse -Force - } - - $null = New-Item -ItemType Directory -Path $signedFilesDirectory -Force - - $itemsToCopyWithRecurse = @( - "$($fullSymbolsFolder)\*.ps1" - "$($fullSymbolsFolder)\Microsoft.PowerShell*.dll" - ) - - $itemsToCopy = @{ - "$($fullSymbolsFolder)\*.ps1" = "" - "$($fullSymbolsFolder)\Modules\Microsoft.PowerShell.Host\Microsoft.PowerShell.Host.psd1" = "Modules\Microsoft.PowerShell.Host" - "$($fullSymbolsFolder)\Modules\Microsoft.PowerShell.Management\Microsoft.PowerShell.Management.psd1" = "Modules\Microsoft.PowerShell.Management" - "$($fullSymbolsFolder)\Modules\Microsoft.PowerShell.Security\Microsoft.PowerShell.Security.psd1" = "Modules\Microsoft.PowerShell.Security" - "$($fullSymbolsFolder)\Modules\Microsoft.PowerShell.Utility\Microsoft.PowerShell.Utility.psd1" = "Modules\Microsoft.PowerShell.Utility" - "$($fullSymbolsFolder)\pwsh.dll" = "" - "$($fullSymbolsFolder)\System.Management.Automation.dll" = "" - } - - ## Windows only modules - - if('${{ parameters.addWindowsModules }}' -ne 'false') { - $itemsToCopy += @{ - "$($fullSymbolsFolder)\pwsh.exe" = "" - "$($fullSymbolsFolder)\Microsoft.Management.Infrastructure.CimCmdlets.dll" = "" - "$($fullSymbolsFolder)\Microsoft.WSMan.*.dll" = "" - "$($fullSymbolsFolder)\Modules\CimCmdlets\CimCmdlets.psd1" = "Modules\CimCmdlets" - "$($fullSymbolsFolder)\Modules\Microsoft.PowerShell.Diagnostics\Diagnostics.format.ps1xml" = "Modules\Microsoft.PowerShell.Diagnostics" - "$($fullSymbolsFolder)\Modules\Microsoft.PowerShell.Diagnostics\Event.format.ps1xml" = "Modules\Microsoft.PowerShell.Diagnostics" - "$($fullSymbolsFolder)\Modules\Microsoft.PowerShell.Diagnostics\GetEvent.types.ps1xml" = "Modules\Microsoft.PowerShell.Diagnostics" - "$($fullSymbolsFolder)\Modules\Microsoft.PowerShell.Security\Security.types.ps1xml" = "Modules\Microsoft.PowerShell.Security" - "$($fullSymbolsFolder)\Modules\Microsoft.PowerShell.Diagnostics\Microsoft.PowerShell.Diagnostics.psd1" = "Modules\Microsoft.PowerShell.Diagnostics" - "$($fullSymbolsFolder)\Modules\Microsoft.WSMan.Management\Microsoft.WSMan.Management.psd1" = "Modules\Microsoft.WSMan.Management" - "$($fullSymbolsFolder)\Modules\Microsoft.WSMan.Management\WSMan.format.ps1xml" = "Modules\Microsoft.WSMan.Management" - "$($fullSymbolsFolder)\Modules\PSDiagnostics\PSDiagnostics.ps?1" = "Modules\PSDiagnostics" - } - } - else { - $itemsToCopy += @{ - "$($fullSymbolsFolder)\pwsh" = "" - } - } - - $itemsToExclude = @( - # This package is retrieved from https://www.github.com/powershell/MarkdownRender - "$($fullSymbolsFolder)\Microsoft.PowerShell.MarkdownRender.dll" - ) - - Write-Verbose -verbose "recusively copying $($itemsToCopyWithRecurse | out-string) to $filesToSignDirectory" - Copy-Item -Path $itemsToCopyWithRecurse -Destination $filesToSignDirectory -Recurse -verbose -exclude $itemsToExclude - - foreach($pattern in $itemsToCopy.Keys) { - $destinationFolder = Join-Path $filesToSignDirectory -ChildPath $itemsToCopy.$pattern - $null = New-Item -ItemType Directory -Path $destinationFolder -Force - Write-Verbose -verbose "copying $pattern to $destinationFolder" - Copy-Item -Path $pattern -Destination $destinationFolder -Recurse -verbose - } - displayName: '${{ parameters.buildPrefixName }} - Prepare files to be signed' - -- template: EsrpSign.yml@ComplianceRepo - parameters: - buildOutputPath: $(System.ArtifactsDirectory)\toBeSigned - signOutputPath: $(System.ArtifactsDirectory)\signed - certificateId: "$(AUTHENTICODE_CERT)" - pattern: | - **\*.dll - **\*.psd1 - **\*.psm1 - **\*.ps1xml - **\*.ps1 - **\*.exe - useMinimatch: true - shouldSign: $(SHOULD_SIGN) - displayName: ${{ parameters.buildPrefixName }} - Authenticode - -- pwsh: | - Import-Module $(PowerShellRoot)/build.psm1 -Force - Import-Module $(PowerShellRoot)/tools/packaging -Force - $signedFilesPath = '$(System.ArtifactsDirectory)\signed\' - $BuildPath = Join-Path $(System.ArtifactsDirectory) '${{ parameters.binLocation }}' - Write-Verbose -Verbose -Message "BuildPath: $BuildPath" - - Update-PSSignedBuildFolder -BuildPath $BuildPath -SignedFilesPath $SignedFilesPath - $dlls = Get-ChildItem $BuildPath\*.dll, $BuildPath\*.exe -Recurse - $signatures = $dlls | Get-AuthenticodeSignature - $missingSignatures = $signatures | Where-Object { $_.status -eq 'notsigned' -or $_.SignerCertificate.Issuer -notmatch '^CN=Microsoft.*'}| select-object -ExpandProperty Path - - Write-Verbose -verbose "to be signed:`r`n $($missingSignatures | Out-String)" - - $filesToSignDirectory = "$(System.ArtifactsDirectory)\thirdPartyToBeSigned" - if (Test-Path $filesToSignDirectory) { - Remove-Item -Path $filesToSignDirectory -Recurse -Force - } - - $null = New-Item -ItemType Directory -Path $filesToSignDirectory -Force -Verbose - - $signedFilesDirectory = "$(System.ArtifactsDirectory)\thirdPartySigned" - if (Test-Path $signedFilesDirectory) { - Remove-Item -Path $signedFilesDirectory -Recurse -Force - } - - $null = New-Item -ItemType Directory -Path $signedFilesDirectory -Force -Verbose - - $missingSignatures | ForEach-Object { - $pathWithoutLeaf = Split-Path $_ - $relativePath = $pathWithoutLeaf.replace($BuildPath,'') - Write-Verbose -Verbose -Message "relativePath: $relativePath" - $targetDirectory = Join-Path -Path $filesToSignDirectory -ChildPath $relativePath - Write-Verbose -Verbose -Message "targetDirectory: $targetDirectory" - if(!(Test-Path $targetDirectory)) - { - $null = New-Item -ItemType Directory -Path $targetDirectory -Force -Verbose - } - Copy-Item -Path $_ -Destination $targetDirectory - } - - displayName: ${{ parameters.buildPrefixName }} - Create ThirdParty Signing Folder - condition: and(succeeded(), eq(variables['SHOULD_SIGN'], 'true')) - -- template: EsrpSign.yml@ComplianceRepo - parameters: - buildOutputPath: $(System.ArtifactsDirectory)\thirdPartyToBeSigned - signOutputPath: $(System.ArtifactsDirectory)\thirdPartySigned - certificateId: "CP-231522" - pattern: | - **\*.dll - useMinimatch: true - shouldSign: $(SHOULD_SIGN) - displayName: Sign ThirdParty binaries - -- pwsh: | - Get-ChildItem '$(System.ArtifactsDirectory)\thirdPartySigned\*' - displayName: ${{ parameters.buildPrefixName }} - Capture ThirdParty Signed files - condition: and(succeeded(), eq(variables['SHOULD_SIGN'], 'true')) - -- pwsh: | - Import-Module $(PowerShellRoot)/build.psm1 -Force - Import-Module $(PowerShellRoot)/tools/packaging -Force - $signedFilesPath = '$(System.ArtifactsDirectory)\thirdPartySigned' - $BuildPath = Join-Path $(System.ArtifactsDirectory) '${{ parameters.binLocation }}' - - Update-PSSignedBuildFolder -BuildPath $BuildPath -SignedFilesPath $SignedFilesPath - if ($env:BuildConfiguration -eq 'minSize') { - ## Remove XML files when making a min-size package. - Remove-Item "$BuildPath/*.xml" -Force - } - displayName: ${{ parameters.buildPrefixName }} - Merge ThirdParty signed files with Build - condition: and(succeeded(), eq(variables['SHOULD_SIGN'], 'true')) - -- pwsh: | - $uploadFolder = '$(System.ArtifactsDirectory)/${{ parameters.binLocation }}' - $containerName = 'authenticode-signed' - - Write-Verbose -Verbose "File permissions after signing" - Get-ChildItem $uploadFolder\pwsh | Select-Object -Property 'unixmode', 'size', 'name' - - $uploadTarFilePath = '$(System.ArtifactsDirectory)/${{ parameters.binLocation }}.tar.gz' - Write-Verbose -Verbose -Message "Creating tar.gz - $uploadTarFilePath" - tar -czvf $uploadTarFilePath -C $uploadFolder * - - Write-Host "##vso[artifact.upload containerfolder=$containerName;artifactname=$containerName]$uploadTarFilePath" - displayName: ${{ parameters.buildPrefixName }} - Upload signed files to artifacts - retryCountOnTaskFailure: 2 - diff --git a/tools/releaseBuild/azureDevOps/templates/step/finalize.yml b/tools/releaseBuild/azureDevOps/templates/step/finalize.yml deleted file mode 100644 index 72a677fec9a..00000000000 --- a/tools/releaseBuild/azureDevOps/templates/step/finalize.yml +++ /dev/null @@ -1,5 +0,0 @@ -steps: - - pwsh: | - throw "Jobs with an Issue will not work for release. Please fix the issue and try again." - displayName: Check for SucceededWithIssues - condition: eq(variables['Agent.JobStatus'],'SucceededWithIssues') diff --git a/tools/releaseBuild/azureDevOps/templates/testartifacts.yml b/tools/releaseBuild/azureDevOps/templates/testartifacts.yml deleted file mode 100644 index 43c09236da9..00000000000 --- a/tools/releaseBuild/azureDevOps/templates/testartifacts.yml +++ /dev/null @@ -1,126 +0,0 @@ -jobs: -- job: build_testartifacts_win - variables: - - name: runCodesignValidationInjection - value: false - - name: NugetSecurityAnalysisWarningLevel - value: none - - group: DotNetPrivateBuildAccess - displayName: Build windows test artifacts - condition: succeeded() - pool: - name: PowerShell1ES - demands: - - ImageOverride -equals PSMMS2019-Secure - steps: - - checkout: self - clean: true - - - template: /tools/releaseBuild/azureDevOps/templates/insert-nuget-config-azfeed.yml - parameters: - repoRoot: $(Build.SourcesDirectory) - - - pwsh: | - Import-Module ./build.psm1 - Start-PSBootstrap - displayName: Bootstrap - env: - __DOTNET_RUNTIME_FEED_KEY: $(RUNTIME_SOURCEFEED_KEY) - - - pwsh: | - Import-Module ./build.psm1 - - function BuildTestPackage([string] $runtime) - { - Write-Verbose -Verbose "Starting to build package for $runtime" - - New-TestPackage -Destination $(System.ArtifactsDirectory) -Runtime $runtime - - if (-not (Test-Path $(System.ArtifactsDirectory)/TestPackage.zip)) - { - throw "Test Package was not found at: $(System.ArtifactsDirectory)" - } - - switch ($runtime) - { - win7-x64 { $packageName = "TestPackage-win-x64.zip" } - win7-x86 { $packageName = "TestPackage-win-x86.zip" } - win-arm64 { $packageName = "TestPackage-win-arm64.zip" } - } - - Rename-Item $(System.ArtifactsDirectory)/TestPackage.zip $packageName - Write-Host "##vso[artifact.upload containerfolder=testArtifacts;artifactname=testArtifacts]$(System.ArtifactsDirectory)/$packageName" - } - - BuildTestPackage -runtime win7-x64 - BuildTestPackage -runtime win7-x86 - BuildTestPackage -runtime win-arm64 - - displayName: Build test package and upload - retryCountOnTaskFailure: 1 - -- job: build_testartifacts_nonwin - variables: - - name: runCodesignValidationInjection - value: false - - name: NugetSecurityAnalysisWarningLevel - value: none - - group: DotNetPrivateBuildAccess - displayName: Build non-windows test artifacts - condition: succeeded() - pool: - name: PowerShell1ES - demands: - - ImageOverride -equals PSMMSUbuntu20.04-Secure - steps: - - checkout: self - clean: true - - - template: /tools/releaseBuild/azureDevOps/templates/insert-nuget-config-azfeed.yml - parameters: - repoRoot: $(Build.SourcesDirectory) - - - pwsh: | - Import-Module ./build.psm1 - Start-PSBootstrap - displayName: Bootstrap - env: - __DOTNET_RUNTIME_FEED_KEY: $(RUNTIME_SOURCEFEED_KEY) - - - pwsh: | - Import-Module ./build.psm1 - - function BuildTestPackage([string] $runtime) - { - Write-Verbose -Verbose "Starting to build package for $runtime" - - New-TestPackage -Destination $(System.ArtifactsDirectory) -Runtime $runtime - - if (-not (Test-Path $(System.ArtifactsDirectory)/TestPackage.zip)) - { - throw "Test Package was not found at: $(System.ArtifactsDirectory)" - } - - switch ($runtime) - { - linux-x64 { $packageName = "TestPackage-linux-x64.zip" } - linux-arm { $packageName = "TestPackage-linux-arm.zip" } - linux-arm64 { $packageName = "TestPackage-linux-arm64.zip" } - osx-x64 { $packageName = "TestPackage-macOS.zip" } - linux-musl-x64 { $packageName = "TestPackage-alpine-x64.zip"} - } - - Rename-Item $(System.ArtifactsDirectory)/TestPackage.zip $packageName - Write-Host "##vso[artifact.upload containerfolder=testArtifacts;artifactname=testArtifacts]$(System.ArtifactsDirectory)/$packageName" - } - - BuildTestPackage -runtime linux-x64 - BuildTestPackage -runtime linux-arm - BuildTestPackage -runtime linux-arm64 - BuildTestPackage -runtime osx-x64 - BuildTestPackage -runtime linux-musl-x64 - - displayName: Build test package and upload - retryCountOnTaskFailure: 1 - - - template: /tools/releaseBuild/azureDevOps/templates/step/finalize.yml diff --git a/tools/releaseBuild/azureDevOps/templates/upload-final-results.yml b/tools/releaseBuild/azureDevOps/templates/upload-final-results.yml deleted file mode 100644 index 596b61fb6ed..00000000000 --- a/tools/releaseBuild/azureDevOps/templates/upload-final-results.yml +++ /dev/null @@ -1,17 +0,0 @@ -parameters: - artifactPath: - artifactFilter: '*' - condition: succeeded() - artifactName: finalResults - -steps: - - powershell: | - Get-ChildItem -Path '${{ parameters.artifactPath }}' -Recurse -File -filter '${{ parameters.artifactFilter }}' -ErrorAction SilentlyContinue | - Select-Object -ExpandProperty FullName | - ForEach-Object { - Write-Host "##vso[artifact.upload containerfolder=${{ parameters.artifactName }};artifactname=${{ parameters.artifactName }}]$_" - } - displayName: Upload ${{ parameters.artifactName }} Artifacts ${{ parameters.artifactFilter }} from ${{ parameters.artifactPath }} - condition: ${{ parameters.condition }} - retryCountOnTaskFailure: 2 - diff --git a/tools/releaseBuild/azureDevOps/templates/upload.yml b/tools/releaseBuild/azureDevOps/templates/upload.yml deleted file mode 100644 index c745a02c2a4..00000000000 --- a/tools/releaseBuild/azureDevOps/templates/upload.yml +++ /dev/null @@ -1,83 +0,0 @@ -parameters: - architecture: x86 - version: 6.2.0 - msi: yes - msix: yes - pdb: no - -steps: -- template: upload-final-results.yml - parameters: - artifactPath: $(System.ArtifactsDirectory)\signed - artifactFilter: PowerShell-${{ parameters.version }}-win-${{ parameters.architecture }}*.zip - -- task: AzureFileCopy@4 - displayName: 'upload signed zip to Azure - ${{ parameters.architecture }}' - inputs: - SourcePath: '$(System.ArtifactsDirectory)\signed\PowerShell-${{ parameters.version }}-win-${{ parameters.architecture }}.zip' - azureSubscription: '$(AzureFileCopySubscription)' - Destination: AzureBlob - storage: '$(StorageAccount)' - ContainerName: '$(AzureVersion)' - resourceGroup: '$(StorageResourceGroup)' - condition: succeeded() - retryCountOnTaskFailure: 2 - -- task: AzureFileCopy@4 - displayName: 'upload signed min-size package (for Guest Config) to Azure - ${{ parameters.architecture }}' - inputs: - SourcePath: '$(System.ArtifactsDirectory)\signed\PowerShell-${{ parameters.version }}-win-${{ parameters.architecture }}-gc.zip' - azureSubscription: '$(AzureFileCopySubscription)' - Destination: AzureBlob - storage: '$(StorageAccount)' - ContainerName: '$(AzureVersion)-gc' - resourceGroup: '$(StorageResourceGroup)' - condition: and(eq('${{ parameters.architecture }}', 'x64'), succeeded()) - retryCountOnTaskFailure: 2 - -- template: upload-final-results.yml - parameters: - artifactPath: $(System.ArtifactsDirectory)\signedPackages - artifactFilter: PowerShell-${{ parameters.version }}-win-${{ parameters.architecture }}.exe - condition: and(succeeded(), eq('${{ parameters.msi }}', 'yes')) - -- task: AzureFileCopy@4 - displayName: 'upload signed exe to Azure - ${{ parameters.architecture }}' - inputs: - SourcePath: '$(System.ArtifactsDirectory)\signedPackages\PowerShell-${{ parameters.version }}-win-${{ parameters.architecture }}.exe' - azureSubscription: '$(AzureFileCopySubscription)' - Destination: AzureBlob - storage: '$(StorageAccount)' - ContainerName: '$(AzureVersion)-private' - resourceGroup: '$(StorageResourceGroup)' - condition: and(succeeded(), eq('${{ parameters.msi }}', 'yes')) - retryCountOnTaskFailure: 2 - -# Disable upload task as the symbols package is not currently used and we want to avoid publishing this in releases -#- task: AzureFileCopy@4 -# displayName: 'upload pbd zip to Azure - ${{ parameters.architecture }}' -# inputs: -# SourcePath: '$(System.ArtifactsDirectory)\signed\PowerShell-Symbols-${{ parameters.version }}-win-${{ parameters.architecture }}.zip' -# azureSubscription: '$(AzureFileCopySubscription)' -# Destination: AzureBlob -# storage: '$(StorageAccount)' -# ContainerName: '$(AzureVersion)' -# condition: and(succeeded(), eq('${{ parameters.pdb }}', 'yes')) - -- template: upload-final-results.yml - parameters: - artifactPath: $(Build.StagingDirectory)\signedPackages - artifactFilter: PowerShell-${{ parameters.version }}-win-${{ parameters.architecture }}.msix - condition: and(succeeded(), eq('${{ parameters.msix }}', 'yes')) - -- task: AzureFileCopy@4 - displayName: 'upload signed msix to Azure - ${{ parameters.architecture }}' - inputs: - SourcePath: '$(Build.StagingDirectory)\signedPackages\PowerShell-${{ parameters.version }}-win-${{ parameters.architecture }}.msix' - azureSubscription: '$(AzureFileCopySubscription)' - Destination: AzureBlob - storage: '$(StorageAccount)' - ContainerName: '$(AzureVersion)-private' - resourceGroup: '$(StorageResourceGroup)' - condition: and(succeeded(), eq('${{ parameters.msix }}', 'yes'), eq(variables['SHOULD_SIGN'], 'true')) - retryCountOnTaskFailure: 2 diff --git a/tools/releaseBuild/azureDevOps/templates/vpackReleaseJob.yml b/tools/releaseBuild/azureDevOps/templates/vpackReleaseJob.yml deleted file mode 100644 index 83779c75aa0..00000000000 --- a/tools/releaseBuild/azureDevOps/templates/vpackReleaseJob.yml +++ /dev/null @@ -1,113 +0,0 @@ -parameters: - architecture: x64 - -jobs: -- job: vpack_${{ parameters.architecture }} - variables: - - group: vPack - - group: ReleasePipelineSecrets - - displayName: Build and Publish VPack - ${{ parameters.architecture }} - condition: succeeded() - pool: - name: PowerShell1ES - demands: - - ImageOverride -equals PSMMS2019-Secure - steps: - - checkout: self - clean: true - - - task: UseDotNet@2 - displayName: 'Use .NET Core sdk' - inputs: - packageType: sdk - version: 3.1.x - installationPath: $(Agent.ToolsDirectory)/dotnet - - - template: ./SetVersionVariables.yml - parameters: - ReleaseTagVar: $(ReleaseTagVar) - - - pwsh: | - Import-module '$(BUILD.SOURCESDIRECTORY)/build.psm1' - Install-AzCopy - displayName: Install AzCopy - retryCountOnTaskFailure: 2 - - - pwsh: | - Import-module '$(BUILD.SOURCESDIRECTORY)/build.psm1' - $azcopy = Find-AzCopy - Write-Verbose -Verbose "Found AzCopy: $azcopy" - - Write-Host "running: $azcopy cp https://$(StorageAccount).blob.core.windows.net/$(AzureVersion)/PowerShell-$(Version)-win-${{ parameters.architecture }}.zip $(System.ArtifactsDirectory)" - - & $azcopy cp https://$(StorageAccount).blob.core.windows.net/$(AzureVersion)/PowerShell-$(Version)-win-${{ parameters.architecture }}.zip $(System.ArtifactsDirectory) - displayName: 'Download Azure Artifacts' - retryCountOnTaskFailure: 2 - env: - AZCOPY_AUTO_LOGIN_TYPE: MSI - - - pwsh: 'Get-ChildItem $(System.ArtifactsDirectory)\* -recurse | Select-Object -ExpandProperty Name' - displayName: 'Capture Artifact Listing' - - - pwsh: | - $message = @() - Get-ChildItem $(System.ArtifactsDirectory)\* -recurse -include *.zip, *.msi | ForEach-Object { - if($_.Name -notmatch 'PowerShell-\d+\.\d+\.\d+\-([a-z]*.\d+\-)?win\-(fxdependent|x64|arm64|x86|fxdependentWinDesktop)\.(msi|zip){1}') - { - $messageInstance = "$($_.Name) is not a valid package name" - $message += $messageInstance - Write-Warning $messageInstance - } - } - - if($message.count -gt 0){throw ($message | out-string)} - displayName: 'Validate Zip and MSI Package Names' - - - pwsh: | - Get-ChildItem $(System.ArtifactsDirectory)\* -recurse -include *.zip, *.msi | ForEach-Object { - if($_.Name -match 'PowerShell-\d+\.\d+\.\d+\-([a-z]*.\d+\-)?win\-(${{ parameters.architecture }})\.(zip){1}') - { - $destDir = "$(System.ArtifactsDirectory)\vpack${{ parameters.architecture }}" - $null = new-item -ItemType Directory -Path $destDir - Expand-Archive -Path $_.FullName -DestinationPath $destDir - $vstsCommandString = "vso[task.setvariable variable=vpackDir]$destDir" - Write-Host "sending " + $vstsCommandString - Write-Host "##$vstsCommandString" - } - } - displayName: 'Extract Zip' - - - pwsh: | - $vpackVersion = '$(version)' - - if('$(VPackPublishOverride)' -ne '' -and '$(VPackPublishOverride)' -ne 'None' ) - { - Write-Host "Using VPackPublishOverride varabile" - $vpackVersion = '$(VPackPublishOverride)' - } - - $vstsCommandString = "vso[task.setvariable variable=vpackVersion]$vpackVersion" - Write-Host "sending " + $vstsCommandString - Write-Host "##$vstsCommandString" - displayName: 'Set vpackVersion' - - - pwsh: | - Get-ChildItem -Path env: - displayName: Capture Environment - condition: succeededOrFailed() - - - task: PkgESVPack@12 - displayName: 'Package ES - VPack ' - inputs: - sourceDirectory: '$(vpackDir)' - description: PowerShell ${{ parameters.architecture }} $(version) - pushPkgName: 'PowerShell.${{ parameters.architecture }}' - configurations: Release - platforms: x64 - target: '$(System.ArtifactsDirectory)' - owner: tplunk - provData: true - version: '$(vpackVersion)' - vpackToken: $(vPackPat) - condition: and(succeeded(), eq(variables['Build.Reason'], 'Manual')) diff --git a/tools/releaseBuild/azureDevOps/templates/windows-component-governance.yml b/tools/releaseBuild/azureDevOps/templates/windows-component-governance.yml deleted file mode 100644 index 53947655d90..00000000000 --- a/tools/releaseBuild/azureDevOps/templates/windows-component-governance.yml +++ /dev/null @@ -1,71 +0,0 @@ - -jobs: -- job: ComponentRegistrationJob - variables: - - name: runCodesignValidationInjection - value: false - - name: NugetSecurityAnalysisWarningLevel - value: none - displayName: Component Registration - condition: succeeded() - - pool: - name: PowerShell1ES - demands: - - ImageOverride -equals PSMMS2019-Secure - - steps: - - checkout: self - clean: true - - - template: SetVersionVariables.yml - parameters: - ReleaseTagVar: $(ReleaseTagVar) - - - powershell: | - docker container prune --force - docker container ls --all --format '{{ json .ID }}' | ConvertFrom-Json | ForEach-Object {docker container rm --force --volumes $_} - displayName: 'Remove all containers' - # Cleanup is not critical it passes every time it runs - continueOnError: true - - - powershell: | - docker image ls --format '{{ json .}}'|ConvertFrom-Json| ForEach-Object { - if($_.tag -eq '') - { - $formatString = 'yyyy-MM-dd HH:mm:ss zz00' - $createdAtString = $_.CreatedAt.substring(0,$_.CreatedAt.Length -4) - $createdAt = [DateTime]::ParseExact($createdAtString, $formatString,[System.Globalization.CultureInfo]::InvariantCulture) - if($createdAt -lt (Get-Date).adddays(-1)) - { - docker image rm $_.ID - } - } - } - exit 0 - displayName: 'Remove old images' - # Cleanup is not critical it passes every time it runs - continueOnError: true - - - powershell: | - Write-verbose "--docker info---" -verbose - docker info - Write-verbose "--docker image ls---" -verbose - docker image ls - Write-verbose "--docker container ls --all---" -verbose - docker container ls --all - displayName: 'Capture Docker Info' - # Diagnostics is not critical it passes every time it runs - continueOnError: true - - - template: insert-nuget-config-azfeed.yml - - - powershell: | - ./tools/releaseBuild/vstsbuild.ps1 -ReleaseTag $(ReleaseTagVar) -Name win-x64-component-registration - displayName: 'Build Windows Universal - Component Registration' - - - task: ms.vss-governance-buildtask.governance-build-task-component-detection.ComponentGovernanceComponentDetection@0 - displayName: 'Component Detection' - inputs: - sourceScanPath: '$(componentregistration)' - snapshotForceEnabled: true diff --git a/tools/releaseBuild/azureDevOps/templates/windows-hosted-build.yml b/tools/releaseBuild/azureDevOps/templates/windows-hosted-build.yml deleted file mode 100644 index 4b36f6f396e..00000000000 --- a/tools/releaseBuild/azureDevOps/templates/windows-hosted-build.yml +++ /dev/null @@ -1,84 +0,0 @@ -parameters: - - name: BuildConfiguration - default: release - - name: BuildPlatform - default: any cpu - - name: Architecture - default: x64 - - name: parentJob - default: '' - -jobs: -- job: build_windows_${{ parameters.Architecture }}_${{ parameters.BuildConfiguration }} - displayName: Build Windows - ${{ parameters.Architecture }} ${{ parameters.BuildConfiguration }} - condition: succeeded() - dependsOn: ${{ parameters.parentJob }} - pool: - name: $(windowsPool) - demands: - - ImageOverride -equals PSMMS2019-Secure - variables: - - name: runCodesignValidationInjection - value: false - - name: NugetSecurityAnalysisWarningLevel - value: none - - name: BuildConfiguration - value: ${{ parameters.BuildConfiguration }} - - name: BuildPlatform - value: ${{ parameters.BuildPlatform }} - - name: Architecture - value: ${{ parameters.Architecture }} - - name: DOTNET_SKIP_FIRST_TIME_EXPERIENCE - value: 1 - - group: DotNetPrivateBuildAccess - - steps: - - - checkout: self - clean: true - - - template: SetVersionVariables.yml - parameters: - ReleaseTagVar: $(ReleaseTagVar) - - - template: cloneToOfficialPath.yml - - - template: /tools/releaseBuild/azureDevOps/templates/insert-nuget-config-azfeed.yml - parameters: - repoRoot: $(PowerShellRoot) - - - pwsh: | - - $runtime = switch ($env:Architecture) - { - "x64" { "win7-x64" } - "x86" { "win7-x86" } - "arm64" { "win-arm64" } - "fxdependent" { "fxdependent" } - "fxdependentWinDesktop" { "fxdependent-win-desktop" } - } - - $params = @{} - if ($env:BuildConfiguration -eq 'minSize') { - $params['ForMinimalSize'] = $true - } - - tools/releaseBuild/Images/microsoft_powershell_windowsservercore/PowerShellPackage.ps1 -location '$(PowerShellRoot)' -destination '$(Build.ArtifactStagingDirectory)/Symbols_$(Architecture)' -Runtime $runtime -ReleaseTag '$(ReleaseTagVar)' -Symbols @params - displayName: 'Build Windows Universal - $(Architecture)-$(BuildConfiguration) Symbols zip' - env: - __DOTNET_RUNTIME_FEED_KEY: $(RUNTIME_SOURCEFEED_KEY) - - - pwsh: | - $packageName = (Get-ChildItem '$(Build.ArtifactStagingDirectory)\Symbols_$(Architecture)').FullName - $vstsCommandString = "vso[artifact.upload containerfolder=results;artifactname=results]$packageName" - Write-Host ("sending " + $vstsCommandString) - Write-Host "##$vstsCommandString" - displayName: Upload symbols package - - - task: ms.vss-governance-buildtask.governance-build-task-component-detection.ComponentGovernanceComponentDetection@0 - displayName: 'Component Detection' - inputs: - sourceScanPath: '$(PowerShellRoot)\tools' - snapshotForceEnabled: true - - - template: /tools/releaseBuild/azureDevOps/templates/step/finalize.yml diff --git a/tools/releaseBuild/azureDevOps/templates/windows-package-signing.yml b/tools/releaseBuild/azureDevOps/templates/windows-package-signing.yml deleted file mode 100644 index 75153ce0592..00000000000 --- a/tools/releaseBuild/azureDevOps/templates/windows-package-signing.yml +++ /dev/null @@ -1,132 +0,0 @@ -parameters: - parentJobs: [] - -jobs: -- job: WinPackageSigningJob - displayName: Windows Package signing and upload - dependsOn: - ${{ parameters.parentJobs }} - condition: succeeded() - pool: - name: $(windowsPool) - demands: - - ImageOverride -equals PSMMS2019-Secure - variables: - - name: DOTNET_SKIP_FIRST_TIME_EXPERIENCE - value: 1 - - group: ESRP - - name: repoFolder - value: PowerShell - - name: repoRoot - value: $(Agent.BuildDirectory)\$(repoFolder) - - name: complianceRepoFolder - value: compliance - - steps: - - checkout: self - clean: true - path: $(repoFolder) - - - checkout: ComplianceRepo - clean: true - path: $(complianceRepoFolder) - - - template: SetVersionVariables.yml - parameters: - ReleaseTagVar: $(ReleaseTagVar) - - - template: shouldSign.yml - - - task: DownloadBuildArtifacts@0 - displayName: 'Download artifacts' - inputs: - buildType: current - downloadType: single - artifactName: signed - downloadPath: '$(System.ArtifactsDirectory)' - - - powershell: | - dir "$(System.ArtifactsDirectory)\*" -Recurse - displayName: 'Capture Downloaded Artifacts' - # Diagnostics is not critical it passes every time it runs - continueOnError: true - - - template: EsrpSign.yml@ComplianceRepo - parameters: - buildOutputPath: $(System.ArtifactsDirectory)\signed - signOutputPath: $(Build.StagingDirectory)\signedPackages - certificateId: $(MSIX_CERT) - pattern: | - **\*.msix - useMinimatch: true - shouldSign: $(SHOULD_SIGN) - displayName: Sign msix - - - template: EsrpSign.yml@ComplianceRepo - parameters: - buildOutputPath: $(System.ArtifactsDirectory)\signed - signOutputPath: $(Build.StagingDirectory)\signedPackages - certificateId: $(AUTHENTICODE_CERT) - pattern: | - **\*.exe - useMinimatch: true - shouldSign: $(SHOULD_SIGN) - displayName: Sign exe - - - powershell: | - new-item -itemtype Directory -path '$(Build.StagingDirectory)\signedPackages' - Get-ChildItem "$(System.ArtifactsDirectory)\signed\PowerShell-$(Version)-win-*.msi*" | copy-item -Destination '$(Build.StagingDirectory)\signedPackages' - displayName: 'Fake msi* Signing' - condition: and(succeeded(), ne(variables['SHOULD_SIGN'], 'true')) - - - pwsh: | - Get-ChildItem "$(System.ArtifactsDirectory)\signed\PowerShell-$(Version)-win-*.exe" | copy-item -Destination '$(Build.StagingDirectory)\signedPackages' - displayName: 'Fake exe Signing' - condition: and(succeeded(), ne(variables['SHOULD_SIGN'], 'true')) - - - template: upload.yml - parameters: - architecture: x86 - version: $(version) - - - template: upload.yml - parameters: - architecture: x64 - version: $(version) - pdb: yes - - - template: upload.yml - parameters: - architecture: arm64 - version: $(version) - msi: yes - - - template: upload.yml - parameters: - architecture: fxdependent - version: $(version) - msi: no - msix: no - - - template: upload.yml - parameters: - architecture: fxdependentWinDesktop - version: $(version) - msi: no - msix: no - - - template: EsrpScan.yml@ComplianceRepo - parameters: - scanPath: $(Build.StagingDirectory) - pattern: | - **\*.msix - **\*.msi - **\*.zip - - - task: ms.vss-governance-buildtask.governance-build-task-component-detection.ComponentGovernanceComponentDetection@0 - displayName: 'Component Detection' - inputs: - sourceScanPath: '$(repoRoot)\tools' - snapshotForceEnabled: true - - - template: /tools/releaseBuild/azureDevOps/templates/step/finalize.yml diff --git a/tools/releaseBuild/azureDevOps/templates/windows-packaging.yml b/tools/releaseBuild/azureDevOps/templates/windows-packaging.yml deleted file mode 100644 index 915db9301ac..00000000000 --- a/tools/releaseBuild/azureDevOps/templates/windows-packaging.yml +++ /dev/null @@ -1,369 +0,0 @@ -parameters: - - name: BuildConfiguration - default: release - - name: BuildPlatform - default: any cpu - - name: Architecture - default: x64 - - name: parentJob - default: '' - -jobs: -- job: sign_windows_${{ parameters.Architecture }}_${{ parameters.BuildConfiguration }} - displayName: Package Windows - ${{ parameters.Architecture }} ${{ parameters.BuildConfiguration }} - condition: succeeded() - pool: - name: $(windowsPool) - demands: - - ImageOverride -equals PSMMS2019-Secure - variables: - - name: BuildConfiguration - value: ${{ parameters.BuildConfiguration }} - - name: BuildPlatform - value: ${{ parameters.BuildPlatform }} - - name: Architecture - value: ${{ parameters.Architecture }} - - name: DOTNET_SKIP_FIRST_TIME_EXPERIENCE - value: 1 - - group: ESRP - - group: DotNetPrivateBuildAccess - - steps: - - - checkout: self - clean: true - - - checkout: ComplianceRepo - clean: true - - - template: SetVersionVariables.yml - parameters: - ReleaseTagVar: $(ReleaseTagVar) - - - template: shouldSign.yml - - - pwsh: | - $pkgFilter = '$(Architecture)' - if ($env:BuildConfiguration -eq 'minSize') { $pkgFilter += '-gc' } - - $vstsCommandString = "vso[task.setvariable variable=PkgFilter]$pkgFilter" - Write-Host ("sending " + $vstsCommandString) - Write-Host "##$vstsCommandString" - displayName: Set packageName variable - - - task: DownloadBuildArtifacts@0 - inputs: - artifactName: 'results' - itemPattern: '**/*$(PkgFilter).zip' - downloadPath: '$(System.ArtifactsDirectory)\Symbols' - - - template: cloneToOfficialPath.yml - - - pwsh: | - $zipPathString = '$(System.ArtifactsDirectory)\Symbols\results\*$(PkgFilter).zip' - Write-Verbose -Verbose "Zip Path: $zipPathString" - $zipPath = Get-Item $zipPathString - if(@($zipPath).Count -eq 0) { - throw "No files found at '$zipPathString'" - } - elseif(@($zipPath).Count -ne 1) { - $names = $zipPath.Name -join "', '" - throw "multiple files '${names}' found with '${zipPathString}'" - } - - $expandedFolder = $zipPath.BaseName - Write-Host "sending.. vso[task.setvariable variable=SymbolsFolder]$expandedFolder" - Write-Host "##vso[task.setvariable variable=SymbolsFolder]$expandedFolder" - - Expand-Archive -Path $zipPath -Destination "$(System.ArtifactsDirectory)\$expandedFolder" -Force - displayName: Expand symbols zip - - - pwsh: | - $fullSymbolsFolder = "$(System.ArtifactsDirectory)\$($env:SYMBOLSFOLDER)" - - $filesToSignDirectory = "$(System.ArtifactsDirectory)\toBeSigned" - $null = New-Item -ItemType Directory -Path $filesToSignDirectory -Force - - $signedFilesDirectory = "$(System.ArtifactsDirectory)\signed" - $null = New-Item -ItemType Directory -Path $signedFilesDirectory -Force - - $itemsToCopyWithRecurse = @( - "$($fullSymbolsFolder)\*.ps1" - "$($fullSymbolsFolder)\Microsoft.PowerShell*.dll" - ) - - $itemsToCopy = @{ - "$($fullSymbolsFolder)\*.ps1" = "" - "$($fullSymbolsFolder)\Microsoft.Management.Infrastructure.CimCmdlets.dll" = "" - "$($fullSymbolsFolder)\Microsoft.WSMan.*.dll" = "" - "$($fullSymbolsFolder)\Modules\CimCmdlets\CimCmdlets.psd1" = "Modules\CimCmdlets" - "$($fullSymbolsFolder)\Modules\Microsoft.PowerShell.Diagnostics\Diagnostics.format.ps1xml" = "Modules\Microsoft.PowerShell.Diagnostics" - "$($fullSymbolsFolder)\Modules\Microsoft.PowerShell.Diagnostics\Event.format.ps1xml" = "Modules\Microsoft.PowerShell.Diagnostics" - "$($fullSymbolsFolder)\Modules\Microsoft.PowerShell.Diagnostics\GetEvent.types.ps1xml" = "Modules\Microsoft.PowerShell.Diagnostics" - "$($fullSymbolsFolder)\Modules\Microsoft.PowerShell.Diagnostics\Microsoft.PowerShell.Diagnostics.psd1" = "Modules\Microsoft.PowerShell.Diagnostics" - "$($fullSymbolsFolder)\Modules\Microsoft.PowerShell.Host\Microsoft.PowerShell.Host.psd1" = "Modules\Microsoft.PowerShell.Host" - "$($fullSymbolsFolder)\Modules\Microsoft.PowerShell.Management\Microsoft.PowerShell.Management.psd1" = "Modules\Microsoft.PowerShell.Management" - "$($fullSymbolsFolder)\Modules\Microsoft.PowerShell.Security\Microsoft.PowerShell.Security.psd1" = "Modules\Microsoft.PowerShell.Security" - "$($fullSymbolsFolder)\Modules\Microsoft.PowerShell.Security\Security.types.ps1xml" = "Modules\Microsoft.PowerShell.Security" - "$($fullSymbolsFolder)\Modules\Microsoft.PowerShell.Utility\Microsoft.PowerShell.Utility.psd1" = "Modules\Microsoft.PowerShell.Utility" - "$($fullSymbolsFolder)\Modules\Microsoft.WSMan.Management\Microsoft.WSMan.Management.psd1" = "Modules\Microsoft.WSMan.Management" - "$($fullSymbolsFolder)\Modules\Microsoft.WSMan.Management\WSMan.format.ps1xml" = "Modules\Microsoft.WSMan.Management" - "$($fullSymbolsFolder)\Modules\PSDiagnostics\PSDiagnostics.ps?1" = "Modules\PSDiagnostics" - "$($fullSymbolsFolder)\pwsh.dll" = "" - "$($fullSymbolsFolder)\System.Management.Automation.dll" = "" - "$($fullSymbolsFolder)\pwsh.exe" = "" - } - - $itemsToExclude = @( - # This package is retrieved from https://www.github.com/powershell/MarkdownRender - "$($fullSymbolsFolder)\Microsoft.PowerShell.MarkdownRender.dll" - ) - - Write-Verbose -verbose "recusively copying $($itemsToCopyWithRecurse | out-string) to $filesToSignDirectory" - Copy-Item -Path $itemsToCopyWithRecurse -Destination $filesToSignDirectory -Recurse -verbose -exclude $itemsToExclude - - foreach($pattern in $itemsToCopy.Keys) { - $destinationFolder = Join-Path $filesToSignDirectory -ChildPath $itemsToCopy.$pattern - $null = New-Item -ItemType Directory -Path $destinationFolder -Force - Write-Verbose -verbose "copying $pattern to $destinationFolder" - Copy-Item -Path $pattern -Destination $destinationFolder -Recurse -verbose - } - displayName: 'Prepare files to be signed' - - - template: EsrpSign.yml@ComplianceRepo - parameters: - buildOutputPath: $(System.ArtifactsDirectory)\toBeSigned - signOutputPath: $(System.ArtifactsDirectory)\signed - certificateId: "$(AUTHENTICODE_CERT)" - pattern: | - **\*.dll - **\*.psd1 - **\*.psm1 - **\*.ps1xml - **\*.ps1 - **\*.exe - useMinimatch: true - shouldSign: $(SHOULD_SIGN) - displayName: Sign our binaries - - - pwsh: | - Import-Module $(PowerShellRoot)/build.psm1 -Force - Import-Module $(PowerShellRoot)/tools/packaging -Force - $signedFilesPath = '$(System.ArtifactsDirectory)\signed\' - $BuildPath = '$(System.ArtifactsDirectory)\$(SymbolsFolder)' - - Update-PSSignedBuildFolder -BuildPath $BuildPath -SignedFilesPath $SignedFilesPath - $dlls = Get-ChildItem $BuildPath\*.dll, $BuildPath\*.exe -Recurse - $signatures = $dlls | Get-AuthenticodeSignature - $missingSignatures = $signatures | Where-Object { $_.status -eq 'notsigned' -or $_.SignerCertificate.Issuer -notmatch '^CN=Microsoft.*'}| select-object -ExpandProperty Path - - Write-Verbose -verbose "to be signed:`r`n $($missingSignatures | Out-String)" - - $filesToSignDirectory = "$(System.ArtifactsDirectory)\thirdPartyToBeSigned" - $null = New-Item -ItemType Directory -Path $filesToSignDirectory -Force - - $signedFilesDirectory = "$(System.ArtifactsDirectory)\thirdPartySigned" - $null = New-Item -ItemType Directory -Path $signedFilesDirectory -Force - - $missingSignatures | ForEach-Object { - $pathWithoutLeaf = Split-Path $_ - $relativePath = $pathWithoutLeaf.replace($BuildPath,'') - $targetDirectory = Join-Path -Path $filesToSignDirectory -ChildPath $relativePath - if(!(Test-Path $targetDirectory)) - { - $null = New-Item -ItemType Directory -Path $targetDirectory -Force - } - Copy-Item -Path $_ -Destination $targetDirectory - } - - displayName: Create ThirdParty Signing Folder - condition: and(succeeded(), eq(variables['SHOULD_SIGN'], 'true')) - - - template: EsrpSign.yml@ComplianceRepo - parameters: - buildOutputPath: $(System.ArtifactsDirectory)\thirdPartyToBeSigned - signOutputPath: $(System.ArtifactsDirectory)\thirdPartySigned - certificateId: "CP-231522" - pattern: | - **\*.dll - useMinimatch: true - shouldSign: $(SHOULD_SIGN) - displayName: Sign ThirdParty binaries - - - pwsh: | - Get-ChildItem '$(System.ArtifactsDirectory)\thirdPartySigned\*' - displayName: Capture ThirdParty Signed files - condition: and(succeeded(), eq(variables['SHOULD_SIGN'], 'true')) - - - pwsh: | - Import-Module $(PowerShellRoot)/build.psm1 -Force - Import-Module $(PowerShellRoot)/tools/packaging -Force - $signedFilesPath = '$(System.ArtifactsDirectory)\thirdPartySigned' - $BuildPath = '$(System.ArtifactsDirectory)\$(SymbolsFolder)' - - Update-PSSignedBuildFolder -BuildPath $BuildPath -SignedFilesPath $SignedFilesPath - if ($env:BuildConfiguration -eq 'minSize') { - ## Remove XML files when making a min-size package. - Remove-Item "$BuildPath/*.xml" -Force - } - displayName: Merge ThirdParty signed files with Build - condition: and(succeeded(), eq(variables['SHOULD_SIGN'], 'true')) - - - template: Sbom.yml@ComplianceRepo - parameters: - BuildDropPath: '$(System.ArtifactsDirectory)\$(SymbolsFolder)' - Build_Repository_Uri: $(Github_Build_Repository_Uri) - PackageName: PowerShell Windows ${{ parameters.Architecture }} ${{ parameters.BuildConfiguration }} - PackageVersion: $(Version) - sourceScanPath: '$(PowerShellRoot)\tools' - - - pwsh: | - Import-Module $(PowerShellRoot)/build.psm1 -Force - Import-Module $(PowerShellRoot)/tools/packaging -Force - - $destFolder = '$(System.ArtifactsDirectory)\signedZip' - $BuildPath = '$(System.ArtifactsDirectory)\$(SymbolsFolder)' - - New-Item -ItemType Directory -Path $destFolder -Force - - $BuildPackagePath = New-PSBuildZip -BuildPath $BuildPath -DestinationFolder $destFolder - - Write-Verbose -Verbose "New-PSSignedBuildZip returned `$BuildPackagePath as: $BuildPackagePath" - Write-Host "##vso[artifact.upload containerfolder=results;artifactname=results]$BuildPackagePath" - - $vstsCommandString = "vso[task.setvariable variable=BuildPackagePath]$BuildPackagePath" - Write-Host ("sending " + $vstsCommandString) - Write-Host "##$vstsCommandString" - displayName: Compress signed files - retryCountOnTaskFailure: 2 - - - - pwsh: | - $runtime = switch ($env:Architecture) - { - "x64" { "win7-x64" } - "x86" { "win7-x86" } - "arm64" { "win-arm64" } - "fxdependent" { "fxdependent" } - "fxdependentWinDesktop" { "fxdependent-win-desktop" } - } - - $signedPkg = "$(BuildPackagePath)" - Write-Verbose -Verbose -Message "signedPkg = $signedPkg" - - $params = @{} - if ($env:BuildConfiguration -eq 'minSize') { - $params['ForMinimalSize'] = $true - } - - $(PowerShellRoot)/tools/releaseBuild/Images/microsoft_powershell_windowsservercore/PowerShellPackage.ps1 -BuildZip $signedPkg -location '$(PowerShellRoot)' -destination '$(System.ArtifactsDirectory)\pkgSigned' -Runtime $runtime -ReleaseTag '$(ReleaseTagVar)' @params - displayName: 'Build Windows Universal - $(Architecture) Package' - env: - __DOTNET_RUNTIME_FEED_KEY: $(RUNTIME_SOURCEFEED_KEY) - - - pwsh: | - Get-ChildItem '$(System.ArtifactsDirectory)\pkgSigned' | ForEach-Object { - $packagePath = $_.FullName - Write-Host "Uploading $packagePath" - Write-Host "##vso[artifact.upload containerfolder=signed;artifactname=signed]$packagePath" - } - displayName: Upload unsigned packages - retryCountOnTaskFailure: 2 - - - ${{ if and(ne(variables['BuildConfiguration'],'minSize'), in(variables['Architecture'], 'x64', 'x86', 'arm64')) }}: - - template: EsrpSign.yml@ComplianceRepo - parameters: - buildOutputPath: $(System.ArtifactsDirectory)\pkgSigned - signOutputPath: $(Build.StagingDirectory)\signedPackages - certificateId: "$(AUTHENTICODE_CERT)" - pattern: | - **\*.msi - useMinimatch: true - shouldSign: $(SHOULD_SIGN) - displayName: Sign MSI - alwaysCopy: true - - - pwsh: | - Get-ChildItem '$(System.ArtifactsDirectory)\signedPackages' | ForEach-Object { - $packagePath = $_.FullName - Write-Host "Uploading $packagePath" - Write-Host "##vso[artifact.upload containerfolder=finalResults;artifactname=finalResults]$packagePath" - } - displayName: Upload signed MSI to finalResults - retryCountOnTaskFailure: 2 - - - task: AzureFileCopy@4 - displayName: 'upload signed msi to Azure - ${{ parameters.architecture }}' - inputs: - SourcePath: '$(Build.StagingDirectory)\signedPackages\PowerShell-$(version)-win-${{ parameters.architecture }}.msi' - azureSubscription: '$(AzureFileCopySubscription)' - Destination: AzureBlob - storage: '$(StorageAccount)' - ContainerName: '$(AzureVersion)' - resourceGroup: '$(StorageResourceGroup)' - retryCountOnTaskFailure: 2 - - - pwsh: | - cd $(PowerShellRoot) - Import-Module $(PowerShellRoot)/build.psm1 -Force - Import-Module $(PowerShellRoot)/tools/packaging -Force - - $msiPath = '$(Build.StagingDirectory)\signedPackages\PowerShell-$(version)-win-${{ parameters.architecture }}.msi' - - New-ExePackage -ProductVersion '$(version)' -MsiLocationPath $msiPath -ProductTargetArchitecture ${{ parameters.architecture }} - $exePath = Get-ChildItem '.\PowerShell-*.exe' | Select-Object -First 1 -ExpandProperty fullname - $enginePath = Join-Path -Path '$(System.ArtifactsDirectory)\unsignedEngine' -ChildPath engine.exe - # Expand Burn Engine so we can sign it. - Expand-ExePackageEngine -ExePath $exePath -EnginePath $enginePath - displayName: Create exe wrapper - - - template: EsrpSign.yml@ComplianceRepo - parameters: - buildOutputPath: $(System.ArtifactsDirectory)\unsignedEngine - signOutputPath: $(System.ArtifactsDirectory)\signedEngine - certificateId: "$(AUTHENTICODE_CERT)" - pattern: | - **\*.exe - useMinimatch: true - shouldSign: $(SHOULD_SIGN) - displayName: Sign Burn Engine - alwaysCopy: true - - - pwsh: | - cd '$(PowerShellRoot)' - Import-Module '$(PowerShellRoot)/build.psm1' -Force - Import-Module '$(PowerShellRoot)/tools/packaging' -Force - - $exePath = Get-ChildItem '.\PowerShell-*.exe' | Select-Object -First 1 -ExpandProperty fullname - $enginePath = Join-Path -Path '$(System.ArtifactsDirectory)\signedEngine' -ChildPath engine.exe - $enginePath | Get-AuthenticodeSignature | out-string | Write-Verbose -verbose - Compress-ExePackageEngine -ExePath $exePath -EnginePath $enginePath - displayName: Re-attach the signed Burn engine in exe wrapper - - - pwsh: | - cd '$(PowerShellRoot)' - Get-ChildItem '.\PowerShell-*.exe' | ForEach-Object { - $packagePath = $_.FullName - Write-Host "Uploading $packagePath" - Write-Host "##vso[artifact.upload containerfolder=signed;artifactname=signed]$packagePath" - } - displayName: Upload unsigned exe - retryCountOnTaskFailure: 2 - - - task: ms.vss-governance-buildtask.governance-build-task-component-detection.ComponentGovernanceComponentDetection@0 - displayName: 'Component Detection' - inputs: - sourceScanPath: '$(PowerShellRoot)\tools' - snapshotForceEnabled: true - - - pwsh: | - if ((Test-Path "\PowerShell")) { - Remove-Item -Path "\PowerShell" -Force -Recurse -Verbose - } - else { - Write-Verbose -Verbose -Message "No cleanup required." - } - displayName: Clean up local Clone - condition: always() - - - template: /tools/releaseBuild/azureDevOps/templates/step/finalize.yml diff --git a/tools/releaseBuild/azureDevOps/vpackRelease.yml b/tools/releaseBuild/azureDevOps/vpackRelease.yml deleted file mode 100644 index 14368ffb8f8..00000000000 --- a/tools/releaseBuild/azureDevOps/vpackRelease.yml +++ /dev/null @@ -1,72 +0,0 @@ -name: vpack-$(Build.BuildId) -trigger: - branches: - include: - - master - - release* -pr: - branches: - include: - - master - - release* - -variables: - - name: DOTNET_CLI_TELEMETRY_OPTOUT - value: 1 - - name: POWERSHELL_TELEMETRY_OPTOUT - value: 1 - - name: nugetMultiFeedWarnLevel - value: none - - - group: Azure Blob variable group - # adds the pat to publish the vPack - # instructions to create are in the description of the library - - group: vPack - -stages: -- stage: prep - displayName: Create buildInfo and name the Pipeline - jobs: - - job: rename - displayName: Name the build - condition: succeeded() - - pool: - name: PowerShell1ES - demands: - - ImageOverride -equals PSMMS2019-Secure - - steps: - - checkout: self - clean: true - - - template: ./templates/SetVersionVariables.yml - parameters: - ReleaseTagVar: $(ReleaseTagVar) - CreateJson: yes - UseJson: no - - - powershell: | - if($env:RELEASETAGVAR -match '-') { - throw "Don't release a preview build without coordinating with Windows Engineering Build Tools Team" - } - displayName: Stop any preview release - - - powershell: Write-Host "##vso[build.updatebuildnumber]$env:BUILD_SOURCEBRANCHNAME-$env:BUILD_SOURCEVERSION-$((get-date).ToString("yyyyMMddhhss"))" - displayName: Set Build Name for Non-PR - condition: ne(variables['Build.Reason'], 'PullRequest') - -- stage: release - displayName: Release - jobs: - - template: ./templates/vpackReleaseJob.yml - parameters: - architecture: x64 - - - template: ./templates/vpackReleaseJob.yml - parameters: - architecture: x86 - - - template: ./templates/vpackReleaseJob.yml - parameters: - architecture: arm64 diff --git a/tools/releaseBuild/build.json b/tools/releaseBuild/build.json deleted file mode 100644 index fe2f9d96f17..00000000000 --- a/tools/releaseBuild/build.json +++ /dev/null @@ -1,336 +0,0 @@ -{ - "Windows": [ - { - "Name": "win7-x64", - "RepoDestinationPath": "C:\\PowerShell", - "BuildCommand": "C:\\PowerShellPackage.ps1 -location _RepoDestinationPath_ -destination _DockerVolume_ -Runtime win7-x64 -ReleaseTag _ReleaseTag_", - "BuildDockerOptions": [ - "-m", - "3968m" - ], - "DockerFile": ".\\tools\\releaseBuild\\Images\\microsoft_powershell_windowsservercore\\DockerFile", - "AdditionalContextFiles" :[ - ".\\tools\\releaseBuild\\Images\\microsoft_powershell_windowsservercore\\PowerShellPackage.ps1", - ".\\tools\\releaseBuild\\Images\\microsoft_powershell_windowsservercore\\wix.psm1", - ".\\tools\\releaseBuild\\Images\\microsoft_powershell_windowsservercore\\dockerInstall.psm1" - ], - "DockerImageName": "ps-winsrvcore", - "BinaryBucket": "release", - "EnableFeature": [ "ArtifactAsFolder" ] - }, - { - "Name": "win7-x86", - "RepoDestinationPath": "C:\\PowerShell", - "BuildCommand": "C:\\PowerShellPackage.ps1 -location _RepoDestinationPath_ -destination _DockerVolume_ -Runtime win7-x86 -ReleaseTag _ReleaseTag_", - "BuildDockerOptions": [ - "-m", - "3968m" - ], - "DockerFile": ".\\tools\\releaseBuild\\Images\\microsoft_powershell_windowsservercore\\Dockerfile", - "AdditionalContextFiles" :[ - ".\\tools\\releaseBuild\\Images\\microsoft_powershell_windowsservercore\\PowerShellPackage.ps1", - ".\\tools\\releaseBuild\\Images\\microsoft_powershell_windowsservercore\\wix.psm1", - ".\\tools\\releaseBuild\\Images\\microsoft_powershell_windowsservercore\\dockerInstall.psm1" - ], - "DockerImageName": "ps-winsrvcore", - "BinaryBucket": "release", - "EnableFeature": [ "ArtifactAsFolder" ] - }, - { - "Name": "win-x64-component-registration", - "RepoDestinationPath": "C:\\PowerShell", - "BuildCommand": "C:\\PowerShellPackage.ps1 -location _RepoDestinationPath_ -destination _DockerVolume_ -Runtime win7-x64 -ReleaseTag _ReleaseTag_ -ComponentRegistration", - "BuildDockerOptions": [ - "-m", - "3968m" - ], - "DockerFile": ".\\tools\\releaseBuild\\Images\\microsoft_powershell_windowsservercore\\Dockerfile", - "AdditionalContextFiles" :[ - ".\\tools\\releaseBuild\\Images\\microsoft_powershell_windowsservercore\\PowerShellPackage.ps1", - ".\\tools\\releaseBuild\\Images\\microsoft_powershell_windowsservercore\\wix.psm1", - ".\\tools\\releaseBuild\\Images\\microsoft_powershell_windowsservercore\\dockerInstall.psm1" - ], - "DockerImageName": "ps-winsrvcore", - "BinaryBucket": "results", - "ArtifactsExpected": 1, - "VariableForExtractedBinariesPath": "componentregistration", - "EnableFeature": [ "ArtifactAsFolder" ] - }, - { - "Name": "win-x64-symbols", - "RepoDestinationPath": "C:\\PowerShell", - "BuildCommand": "C:\\PowerShellPackage.ps1 -location _RepoDestinationPath_ -destination _DockerVolume_ -Runtime win7-x64 -ReleaseTag _ReleaseTag_ -Symbols", - "BuildDockerOptions": [ - "-m", - "3968m" - ], - "DockerFile": ".\\tools\\releaseBuild\\Images\\microsoft_powershell_windowsservercore\\Dockerfile", - "AdditionalContextFiles" :[ - ".\\tools\\releaseBuild\\Images\\microsoft_powershell_windowsservercore\\PowerShellPackage.ps1", - ".\\tools\\releaseBuild\\Images\\microsoft_powershell_windowsservercore\\wix.psm1", - ".\\tools\\releaseBuild\\Images\\microsoft_powershell_windowsservercore\\dockerInstall.psm1" - ], - "DockerImageName": "ps-winsrvcore", - "BinaryBucket": "results", - "ArtifactsExpected": 1, - "VariableForExtractedBinariesPath": "Symbols_x64", - "EnableFeature": [ "ArtifactAsFolder" ] - }, - { - "Name": "win-x86-symbols", - "RepoDestinationPath": "C:\\PowerShell", - "BuildCommand": "C:\\PowerShellPackage.ps1 -location _RepoDestinationPath_ -destination _DockerVolume_ -Runtime win7-x86 -ReleaseTag _ReleaseTag_ -Symbols", - "BuildDockerOptions": [ - "-m", - "3968m" - ], - "DockerFile": ".\\tools\\releaseBuild\\Images\\microsoft_powershell_windowsservercore\\Dockerfile", - "AdditionalContextFiles" :[ - ".\\tools\\releaseBuild\\Images\\microsoft_powershell_windowsservercore\\PowerShellPackage.ps1", - ".\\tools\\releaseBuild\\Images\\microsoft_powershell_windowsservercore\\wix.psm1", - ".\\tools\\releaseBuild\\Images\\microsoft_powershell_windowsservercore\\dockerInstall.psm1" - ], - "DockerImageName": "ps-winsrvcore", - "BinaryBucket": "results", - "ArtifactsExpected": 1, - "VariableForExtractedBinariesPath": "Symbols_x86", - "EnableFeature": [ "ArtifactAsFolder" ] - }, - { - "Name": "win-arm-symbols", - "RepoDestinationPath": "C:\\PowerShell", - "BuildCommand": "C:\\PowerShellPackage.ps1 -location _RepoDestinationPath_ -destination _DockerVolume_ -Runtime win-arm -ReleaseTag _ReleaseTag_ -Symbols", - "BuildDockerOptions": [ - "-m", - "3968m" - ], - "DockerFile": ".\\tools\\releaseBuild\\Images\\microsoft_powershell_windowsservercore\\Dockerfile", - "AdditionalContextFiles" :[ - ".\\tools\\releaseBuild\\Images\\microsoft_powershell_windowsservercore\\PowerShellPackage.ps1", - ".\\tools\\releaseBuild\\Images\\microsoft_powershell_windowsservercore\\wix.psm1", - ".\\tools\\releaseBuild\\Images\\microsoft_powershell_windowsservercore\\dockerInstall.psm1" - ], - "DockerImageName": "ps-winsrvcore", - "BinaryBucket": "results", - "ArtifactsExpected": 1, - "VariableForExtractedBinariesPath": "Symbols_arm", - "EnableFeature": [ "ArtifactAsFolder" ] - }, - { - "Name": "win-arm64-symbols", - "RepoDestinationPath": "C:\\PowerShell", - "BuildCommand": "C:\\PowerShellPackage.ps1 -location _RepoDestinationPath_ -destination _DockerVolume_ -Runtime win-arm64 -ReleaseTag _ReleaseTag_ -Symbols", - "BuildDockerOptions": [ - "-m", - "3968m" - ], - "DockerFile": ".\\tools\\releaseBuild\\Images\\microsoft_powershell_windowsservercore\\Dockerfile", - "AdditionalContextFiles" :[ - ".\\tools\\releaseBuild\\Images\\microsoft_powershell_windowsservercore\\PowerShellPackage.ps1", - ".\\tools\\releaseBuild\\Images\\microsoft_powershell_windowsservercore\\wix.psm1", - ".\\tools\\releaseBuild\\Images\\microsoft_powershell_windowsservercore\\dockerInstall.psm1" - ], - "DockerImageName": "ps-winsrvcore", - "BinaryBucket": "results", - "ArtifactsExpected": 1, - "VariableForExtractedBinariesPath": "Symbols_arm64", - "EnableFeature": [ "ArtifactAsFolder" ] - }, - { - "Name": "win-x64-package", - "RepoDestinationPath": "C:\\PowerShell", - "BuildCommand": "C:\\PowerShellPackage.ps1 -BuildZip _RepoDestinationPath_\\_BuildPackageName_ -location _RepoDestinationPath_ -destination _DockerVolume_ -Runtime win7-x64 -ReleaseTag _ReleaseTag_", - "BuildDockerOptions": [ - "-m", - "3968m" - ], - "DockerFile": ".\\tools\\releaseBuild\\Images\\microsoft_powershell_windowsservercore\\Dockerfile", - "AdditionalContextFiles" :[ - ".\\tools\\releaseBuild\\Images\\microsoft_powershell_windowsservercore\\PowerShellPackage.ps1", - ".\\tools\\releaseBuild\\Images\\microsoft_powershell_windowsservercore\\wix.psm1", - ".\\tools\\releaseBuild\\Images\\microsoft_powershell_windowsservercore\\dockerInstall.psm1" - ], - "DockerImageName": "ps-winsrvcore", - "BinaryBucket": "signed", - "ArtifactsExpected": 4, - "EnableFeature": [ "ArtifactAsFolder" ] - }, - { - "Name": "win-x86-package", - "RepoDestinationPath": "C:\\PowerShell", - "BuildCommand": "C:\\PowerShellPackage.ps1 -BuildZip _RepoDestinationPath_\\_BuildPackageName_ -location _RepoDestinationPath_ -destination _DockerVolume_ -Runtime win7-x86 -ReleaseTag _ReleaseTag_", - "BuildDockerOptions": [ - "-m", - "3968m" - ], - "DockerFile": ".\\tools\\releaseBuild\\Images\\microsoft_powershell_windowsservercore\\Dockerfile", - "AdditionalContextFiles" :[ - ".\\tools\\releaseBuild\\Images\\microsoft_powershell_windowsservercore\\PowerShellPackage.ps1", - ".\\tools\\releaseBuild\\Images\\microsoft_powershell_windowsservercore\\wix.psm1", - ".\\tools\\releaseBuild\\Images\\microsoft_powershell_windowsservercore\\dockerInstall.psm1" - ], - "DockerImageName": "ps-winsrvcore", - "BinaryBucket": "signed", - "ArtifactsExpected": 4, - "EnableFeature": [ "ArtifactAsFolder" ] - }, - { - "Name": "win-arm-package", - "RepoDestinationPath": "C:\\PowerShell", - "BuildCommand": "C:\\PowerShellPackage.ps1 -BuildZip _RepoDestinationPath_\\_BuildPackageName_ -location _RepoDestinationPath_ -destination _DockerVolume_ -Runtime win-arm -ReleaseTag _ReleaseTag_", - "BuildDockerOptions": [ - "-m", - "3968m" - ], - "DockerFile": ".\\tools\\releaseBuild\\Images\\microsoft_powershell_windowsservercore\\Dockerfile", - "AdditionalContextFiles" :[ - ".\\tools\\releaseBuild\\Images\\microsoft_powershell_windowsservercore\\PowerShellPackage.ps1", - ".\\tools\\releaseBuild\\Images\\microsoft_powershell_windowsservercore\\wix.psm1", - ".\\tools\\releaseBuild\\Images\\microsoft_powershell_windowsservercore\\dockerInstall.psm1" - ], - "DockerImageName": "ps-winsrvcore", - "BinaryBucket": "signed", - "ArtifactsExpected": 2, - "EnableFeature": [ "ArtifactAsFolder" ] - }, - { - "Name": "win-arm64-package", - "RepoDestinationPath": "C:\\PowerShell", - "BuildCommand": "C:\\PowerShellPackage.ps1 -BuildZip _RepoDestinationPath_\\_BuildPackageName_ -location _RepoDestinationPath_ -destination _DockerVolume_ -Runtime win-arm64 -ReleaseTag _ReleaseTag_", - "BuildDockerOptions": [ - "-m", - "3968m" - ], - "DockerFile": ".\\tools\\releaseBuild\\Images\\microsoft_powershell_windowsservercore\\Dockerfile", - "AdditionalContextFiles" :[ - ".\\tools\\releaseBuild\\Images\\microsoft_powershell_windowsservercore\\PowerShellPackage.ps1", - ".\\tools\\releaseBuild\\Images\\microsoft_powershell_windowsservercore\\wix.psm1", - ".\\tools\\releaseBuild\\Images\\microsoft_powershell_windowsservercore\\dockerInstall.psm1" - ], - "DockerImageName": "ps-winsrvcore", - "BinaryBucket": "signed", - "ArtifactsExpected": 2, - "EnableFeature": [ "ArtifactAsFolder" ] - }, - { - "Name": "win-fxdependent-symbols", - "RepoDestinationPath": "C:\\PowerShell", - "BuildCommand": "C:\\PowerShellPackage.ps1 -location _RepoDestinationPath_ -destination _DockerVolume_ -Runtime fxdependent -ReleaseTag _ReleaseTag_ -Symbols", - "BuildDockerOptions": [ - "-m", - "3968m" - ], - "DockerFile": ".\\tools\\releaseBuild\\Images\\microsoft_powershell_windowsservercore\\Dockerfile", - "AdditionalContextFiles" :[ - ".\\tools\\releaseBuild\\Images\\microsoft_powershell_windowsservercore\\PowerShellPackage.ps1", - ".\\tools\\releaseBuild\\Images\\microsoft_powershell_windowsservercore\\wix.psm1", - ".\\tools\\releaseBuild\\Images\\microsoft_powershell_windowsservercore\\dockerInstall.psm1" - ], - "DockerImageName": "ps-winsrvcore", - "BinaryBucket": "results", - "ArtifactsExpected": 1, - "VariableForExtractedBinariesPath": "Symbols_fxdependent", - "EnableFeature": [ "ArtifactAsFolder" ] - }, - { - "Name": "win-fxdependent-package", - "RepoDestinationPath": "C:\\PowerShell", - "BuildCommand": "C:\\PowerShellPackage.ps1 -BuildZip _RepoDestinationPath_\\_BuildPackageName_ -location _RepoDestinationPath_ -destination _DockerVolume_ -Runtime fxdependent -ReleaseTag _ReleaseTag_", - "BuildDockerOptions": [ - "-m", - "3968m" - ], - "DockerFile": ".\\tools\\releaseBuild\\Images\\microsoft_powershell_windowsservercore\\Dockerfile", - "AdditionalContextFiles" :[ - ".\\tools\\releaseBuild\\Images\\microsoft_powershell_windowsservercore\\PowerShellPackage.ps1", - ".\\tools\\releaseBuild\\Images\\microsoft_powershell_windowsservercore\\wix.psm1", - ".\\tools\\releaseBuild\\Images\\microsoft_powershell_windowsservercore\\dockerInstall.psm1" - ], - "DockerImageName": "ps-winsrvcore", - "BinaryBucket": "signed", - "ArtifactsExpected": 1, - "EnableFeature": [ "ArtifactAsFolder" ] - }, - { - "Name": "win-fxdependentWinDesktop-symbols", - "RepoDestinationPath": "C:\\PowerShell", - "BuildCommand": "C:\\PowerShellPackage.ps1 -location _RepoDestinationPath_ -destination _DockerVolume_ -Runtime fxdependent-win-desktop -ReleaseTag _ReleaseTag_ -Symbols", - "BuildDockerOptions": [ - "-m", - "3968m" - ], - "DockerFile": ".\\tools\\releaseBuild\\Images\\microsoft_powershell_windowsservercore\\Dockerfile", - "AdditionalContextFiles" :[ - ".\\tools\\releaseBuild\\Images\\microsoft_powershell_windowsservercore\\PowerShellPackage.ps1", - ".\\tools\\releaseBuild\\Images\\microsoft_powershell_windowsservercore\\wix.psm1", - ".\\tools\\releaseBuild\\Images\\microsoft_powershell_windowsservercore\\dockerInstall.psm1" - ], - "DockerImageName": "ps-winsrvcore", - "BinaryBucket": "results", - "ArtifactsExpected": 1, - "VariableForExtractedBinariesPath": "Symbols_fxdependentWinDesktop", - "EnableFeature": [ "ArtifactAsFolder" ] - }, - { - "Name": "win-fxdependentWinDesktop-package", - "RepoDestinationPath": "C:\\PowerShell", - "BuildCommand": "C:\\PowerShellPackage.ps1 -BuildZip _RepoDestinationPath_\\_BuildPackageName_ -location _RepoDestinationPath_ -destination _DockerVolume_ -Runtime fxdependent-win-desktop -ReleaseTag _ReleaseTag_", - "BuildDockerOptions": [ - "-m", - "3968m" - ], - "DockerFile": ".\\tools\\releaseBuild\\Images\\microsoft_powershell_windowsservercore\\Dockerfile", - "AdditionalContextFiles" :[ - ".\\tools\\releaseBuild\\Images\\microsoft_powershell_windowsservercore\\PowerShellPackage.ps1", - ".\\tools\\releaseBuild\\Images\\microsoft_powershell_windowsservercore\\wix.psm1", - ".\\tools\\releaseBuild\\Images\\microsoft_powershell_windowsservercore\\dockerInstall.psm1" - ], - "DockerImageName": "ps-winsrvcore", - "BinaryBucket": "signed", - "ArtifactsExpected": 1, - "EnableFeature": [ "ArtifactAsFolder" ] - } - ], - "Linux": [ - { - "Name": "deb", - "RepoDestinationPath": "/PowerShell", - "BuildCommand": "/PowerShellPackage.ps1 -location _RepoDestinationPath_ -destination _DockerVolume_ -ReleaseTag _ReleaseTag_ -TarX64 -TarArm -TarArm64 -TarMinSize", - "DockerFile": "./tools/releaseBuild/Images/microsoft_powershell_ubuntu18.04/Dockerfile", - "AdditionalContextFiles" :[ "./tools/releaseBuild/Images/GenericLinuxFiles/PowerShellPackage.ps1"], - "DockerImageName": "ps-ubunutu-18-04", - "BinaryBucket": "release", - "EnableFeature": [ "ArtifactAsFolder" ] - }, - { - "Name": "rpm", - "RepoDestinationPath": "/PowerShell", - "BuildCommand": "/PowerShellPackage.ps1 -location _RepoDestinationPath_ -destination _DockerVolume_ -ReleaseTag _ReleaseTag_", - "AdditionalContextFiles" :[ "./tools/releaseBuild/Images/GenericLinuxFiles/PowerShellPackage.ps1"], - "DockerFile": "./tools/releaseBuild/Images/microsoft_powershell_centos7/Dockerfile", - "DockerImageName": "ps-centos-7", - "BinaryBucket": "release", - "EnableFeature": [ "ArtifactAsFolder" ] - }, - { - "Name": "alpine", - "RepoDestinationPath": "/PowerShell", - "BuildCommand": "/PowerShellPackage.ps1 -location _RepoDestinationPath_ -destination _DockerVolume_ -ReleaseTag _ReleaseTag_ -Alpine", - "AdditionalContextFiles" :[ "./tools/releaseBuild/Images/GenericLinuxFiles/PowerShellPackage.ps1"], - "DockerFile": "./tools/releaseBuild/Images/microsoft_powershell_alpine3/Dockerfile", - "DockerImageName": "ps-alpine-3", - "BinaryBucket": "release", - "EnableFeature": [ "ArtifactAsFolder" ] - }, - { - "Name": "fxdependent", - "RepoDestinationPath": "/PowerShell", - "BuildCommand": "/PowerShellPackage.ps1 -location _RepoDestinationPath_ -destination _DockerVolume_ -ReleaseTag _ReleaseTag_ -FxDependent", - "AdditionalContextFiles" :[ "./tools/releaseBuild/Images/GenericLinuxFiles/PowerShellPackage.ps1"], - "DockerFile": "./tools/releaseBuild/Images/microsoft_powershell_centos7/Dockerfile", - "DockerImageName": "ps-centos-7", - "BinaryBucket": "release", - "EnableFeature": [ "ArtifactAsFolder" ] - } - ] -} diff --git a/tools/releaseBuild/createComplianceFolder.ps1 b/tools/releaseBuild/createComplianceFolder.ps1 deleted file mode 100644 index c462a09ebdb..00000000000 --- a/tools/releaseBuild/createComplianceFolder.ps1 +++ /dev/null @@ -1,59 +0,0 @@ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. -param( - [Parameter(HelpMessage="Artifact folder to find compliance files in.")] - [string[]] - $ArtifactFolder, - [Parameter(HelpMessage="VSTS Variable to set path to complinance Files.")] - [string] - $VSTSVariableName -) - -$compliancePath = $null -foreach($folder in $ArtifactFolder) -{ - # Find Symbols zip which contains compliance files - Write-Host "ArtifactFolder: $folder" - $filename = Join-Path -Path $folder -ChildPath 'symbols.zip' - - $parentName = Split-Path -Path $folder -Leaf - - # Use simplified names because some of the compliance tools didn't like the full names - # decided not to use hashes because the names need to be consistent otherwise the tool also has issues - # which is another problem with the full name, it includes version. - if ($parentName -match 'x64' -or $parentName -match 'amd64') - { - $name = 'x64' - } - elseif ($parentName -match 'x86') { - $name = 'x86' - } - elseif ($parentName -match 'fxdependent') { - $name = 'fxd' - } - else - { - throw "$parentName could not be classified as x86 or x64" - } - - # Throw is compliance zip does not exist - if (!(Test-Path $filename)) - { - throw "symbols.zip for $VSTSVariableName does not exist" - } - - # make sure we have a single parent for everything - if (!$compliancePath) - { - $parent = Split-Path -Path $folder - $compliancePath = Join-Path -Path $parent -ChildPath 'compliance' - } - - # Extract complance files to individual folder to avoid overwriting files. - $unzipPath = Join-Path -Path $compliancePath -ChildPath $name - Write-Host "Symbols-zip: $filename ; unzipPath: $unzipPath" - Expand-Archive -Path $fileName -DestinationPath $unzipPath -} - -# set VSTS variable with path to compliance files -Write-Host "##vso[task.setvariable variable=$VSTSVariableName]$unzipPath" diff --git a/tools/releaseBuild/generatePackgeSigning.ps1 b/tools/releaseBuild/generatePackgeSigning.ps1 deleted file mode 100644 index ff848892097..00000000000 --- a/tools/releaseBuild/generatePackgeSigning.ps1 +++ /dev/null @@ -1,112 +0,0 @@ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. -param( - [Parameter(Mandatory)] - [string] $Path, - [string[]] $AuthenticodeDualFiles, - [string[]] $AuthenticodeFiles, - [string[]] $NuPkgFiles, - [string[]] $MacDeveloperFiles, - [string[]] $LinuxFiles, - [string[]] $ThirdPartyFiles, - [string[]] $MsixFiles, - [ValidateSet('release','preview')] - [string] $MsixCertType = 'preview' -) - -if ((!$AuthenticodeDualFiles -or $AuthenticodeDualFiles.Count -eq 0) -and - (!$AuthenticodeFiles -or $AuthenticodeFiles.Count -eq 0) -and - (!$NuPkgFiles -or $NuPkgFiles.Count -eq 0) -and - (!$MacDeveloperFiles -or $MacDeveloperFiles.Count -eq 0) -and - (!$LinuxFiles -or $LinuxFiles.Count -eq 0) -and - (!$MsixFiles -or $MsixFiles.Count -eq 0) -and - (!$ThirdPartyFiles -or $ThirdPartyFiles.Count -eq 0)) -{ - throw "At least one file must be specified" -} - -function New-Attribute -{ - param( - [Parameter(Mandatory)] - [string]$Name, - [Parameter(Mandatory)] - [object]$Value, - [Parameter(Mandatory)] - [System.Xml.XmlElement]$Element - ) - - $attribute = $signingXml.CreateAttribute($Name) - $attribute.Value = $value - $null = $fileElement.Attributes.Append($attribute) -} - -function New-FileElement -{ - param( - [Parameter(Mandatory)] - [string]$File, - [Parameter(Mandatory)] - [string]$SignType, - [Parameter(Mandatory)] - [System.Xml.XmlDocument]$XmlDoc, - [Parameter(Mandatory)] - [System.Xml.XmlElement]$Job - ) - - if(Test-Path -Path $file) - { - $name = Split-Path -Leaf -Path $File - $fileElement = $XmlDoc.CreateElement("file") - New-Attribute -Name 'src' -value $file -Element $fileElement - New-Attribute -Name 'signType' -value $SignType -Element $fileElement - New-Attribute -Name 'dest' -value "__OUTPATHROOT__\$name" -Element $fileElement - $null = $job.AppendChild($fileElement) - } - else - { - Write-Warning -Message "Skipping $SignType; $File because it does not exist" - } -} - -[xml]$signingXml = Get-Content (Join-Path -Path $PSScriptRoot -ChildPath 'packagesigning.xml') -$job = $signingXml.SignConfigXML.job - -foreach($file in $AuthenticodeDualFiles) -{ - New-FileElement -File $file -SignType 'AuthenticodeDual' -XmlDoc $signingXml -Job $job -} - -foreach($file in $AuthenticodeFiles) -{ - New-FileElement -File $file -SignType 'AuthenticodeFormer' -XmlDoc $signingXml -Job $job -} - -foreach($file in $NuPkgFiles) -{ - New-FileElement -File $file -SignType 'NuGet' -XmlDoc $signingXml -Job $job -} - -foreach ($file in $MacDeveloperFiles) { - New-FileElement -File $file -SignType 'MacDeveloper' -XmlDoc $signingXml -Job $job -} - -foreach ($file in $LinuxFiles) { - New-FileElement -File $file -SignType 'LinuxPack' -XmlDoc $signingXml -Job $job -} - -foreach ($file in $ThirdPartyFiles) { - New-FileElement -File $file -SignType 'ThirdParty' -XmlDoc $signingXml -Job $job -} - -foreach ($file in $MsixFiles) { - # 'CP-459155' is supposed to work for the store - # AuthenticodeFormer works for sideloading and via a workaround, through the store - # ---------------------------------------------- - # update releasePublisher in packaging.psm1 when this is changed - New-FileElement -File $file -SignType 'AuthenticodeFormer' -XmlDoc $signingXml -Job $job -} - -$signingXml.Save($path) -$updateScriptPath = Join-Path -Path $PSScriptRoot -ChildPath 'updateSigning.ps1' -& $updateScriptPath -SigningXmlPath $path diff --git a/tools/releaseBuild/macOS/PowerShellPackageVsts.ps1 b/tools/releaseBuild/macOS/PowerShellPackageVsts.ps1 deleted file mode 100644 index acedbdd3388..00000000000 --- a/tools/releaseBuild/macOS/PowerShellPackageVsts.ps1 +++ /dev/null @@ -1,143 +0,0 @@ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. - -# PowerShell Script to build and package PowerShell from specified form and branch -# Script is intented to use in Docker containers -# Ensure PowerShell is available in the provided image - -param ( - # Set default location to where VSTS cloned the repository locally. - [string] $location = $env:BUILD_REPOSITORY_LOCALPATH, - - # Destination location of the package on docker host - [Parameter(Mandatory, ParameterSetName = 'packageSigned')] - [Parameter(Mandatory, ParameterSetName = 'IncludeSymbols')] - [Parameter(Mandatory, ParameterSetName = 'Build')] - [string] $destination = '/mnt', - - [Parameter(Mandatory, ParameterSetName = 'packageSigned')] - [Parameter(Mandatory, ParameterSetName = 'IncludeSymbols')] - [Parameter(Mandatory, ParameterSetName = 'Build')] - [ValidatePattern("^v\d+\.\d+\.\d+(-\w+(\.\d{1,2})?)?$")] - [ValidateNotNullOrEmpty()] - [string]$ReleaseTag, - - [Parameter(ParameterSetName = 'packageSigned')] - [Parameter(ParameterSetName = 'IncludeSymbols')] - [Parameter(ParameterSetName = 'Build')] - [ValidateSet("zip", "tar")] - [string[]]$ExtraPackage, - - [Parameter(Mandatory, ParameterSetName = 'Bootstrap')] - [switch] $BootStrap, - - [Parameter(Mandatory, ParameterSetName = 'IncludeSymbols')] - [Parameter(Mandatory, ParameterSetName = 'Build')] - [switch] $Build, - - [Parameter(Mandatory, ParameterSetName = 'IncludeSymbols')] - [switch] $Symbols, - - [Parameter(Mandatory, ParameterSetName = 'packageSigned')] - [ValidatePattern("-signed.zip$")] - [string]$BuildZip, - - [Parameter(Mandatory, ParameterSetName = 'packageSigned')] - [Parameter(Mandatory, ParameterSetName = 'IncludeSymbols')] - [Parameter(Mandatory, ParameterSetName = 'Build')] - [ValidateSet('osx-x64', 'osx-arm64')] - [string]$Runtime, - - [string]$ArtifactName = 'result', - - [switch]$SkipReleaseChecks -) - -$repoRoot = $location - -if ($Build -or $PSCmdlet.ParameterSetName -eq 'packageSigned') { - $releaseTagParam = @{} - if ($ReleaseTag) { - $releaseTagParam['ReleaseTag'] = $ReleaseTag - - #Remove the initial 'v' from the ReleaseTag - $version = $ReleaseTag -replace '^v' - $semVersion = [System.Management.Automation.SemanticVersion] $version - - $metadata = Get-Content "$location/tools/metadata.json" -Raw | ConvertFrom-Json - - $LTS = $metadata.LTSRelease.Package - - Write-Verbose -Verbose -Message "LTS is set to: $LTS" - } -} - -Push-Location -try { - $pspackageParams = @{ SkipReleaseChecks = $SkipReleaseChecks; MacOSRuntime = $Runtime } - Write-Verbose -Message "Init..." -Verbose - Set-Location $repoRoot - Import-Module "$repoRoot/build.psm1" - Import-Module "$repoRoot/tools/packaging" - Sync-PSTags -AddRemoteIfMissing - - if ($BootStrap) { - Start-PSBootstrap -Package - } - - if ($PSCmdlet.ParameterSetName -eq 'packageSigned') { - Write-Verbose "Expanding signed build $BuildZip ..." -Verbose - Expand-PSSignedBuild -BuildZip $BuildZip - - Remove-Item -Path $BuildZip - - Start-PSPackage @pspackageParams @releaseTagParam - switch ($ExtraPackage) { - "tar" { Start-PSPackage -Type tar @pspackageParams @releaseTagParam } - } - - if ($LTS) { - Start-PSPackage @pspackageParams @releaseTagParam -LTS - switch ($ExtraPackage) { - "tar" { Start-PSPackage -Type tar @pspackageParams @releaseTagParam -LTS } - } - } - } - - if ($Build) { - if ($Symbols) { - Start-PSBuild -Clean -Configuration 'Release' -NoPSModuleRestore @releaseTagParam -Runtime $Runtime - $pspackageParams['Type']='zip' - $pspackageParams['IncludeSymbols']=$Symbols.IsPresent - Write-Verbose "Starting powershell packaging(zip)..." -Verbose - Start-PSPackage @pspackageParams @releaseTagParam - } else { - Start-PSBuild -Configuration 'Release' -PSModuleRestore @releaseTagParam -Runtime $Runtime - Start-PSPackage @pspackageParams @releaseTagParam - switch ($ExtraPackage) { - "tar" { Start-PSPackage -Type tar @pspackageParams @releaseTagParam } - } - - if ($LTS) { - Start-PSPackage @releaseTagParam -LTS - switch ($ExtraPackage) { - "tar" { Start-PSPackage -Type tar @pspackageParams @releaseTagParam -LTS } - } - } - } - } -} finally { - Pop-Location -} - -if ($Build -or $PSCmdlet.ParameterSetName -eq 'packageSigned') { - $macPackages = Get-ChildItem "$repoRoot/powershell*" -Include *.pkg, *.tar.gz, *.zip - foreach ($macPackage in $macPackages) { - $filePath = $macPackage.FullName - $extension = (Split-Path -Extension -Path $filePath).Replace('.', '') - Write-Verbose "Copying $filePath to $destination" -Verbose - Write-Host "##vso[artifact.upload containerfolder=$ArtifactName;artifactname=$ArtifactName]$filePath" - Write-Host "##vso[task.setvariable variable=Package-$extension]$filePath" - Copy-Item -Path $filePath -Destination $destination -Force - } -} diff --git a/tools/releaseBuild/macOS/PowerShellPackageVsts.sh b/tools/releaseBuild/macOS/PowerShellPackageVsts.sh deleted file mode 100644 index b7bfa7315d8..00000000000 --- a/tools/releaseBuild/macOS/PowerShellPackageVsts.sh +++ /dev/null @@ -1 +0,0 @@ -pwsh -command ".\PowerShellPackageVsts.ps1 $*" diff --git a/tools/releaseBuild/macOS/createPowerShell.sh b/tools/releaseBuild/macOS/createPowerShell.sh deleted file mode 100644 index 5b0b681716c..00000000000 --- a/tools/releaseBuild/macOS/createPowerShell.sh +++ /dev/null @@ -1,8 +0,0 @@ -# print version for diags -sw_vers -productVersion - -# create folder -sudo mkdir /PowerShell - -# make the current user the owner -sudo chown $USER /PowerShell diff --git a/tools/releaseBuild/packagesigning.xml b/tools/releaseBuild/packagesigning.xml deleted file mode 100644 index a243e5fbd98..00000000000 --- a/tools/releaseBuild/packagesigning.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/tools/releaseBuild/setReleaseTag.ps1 b/tools/releaseBuild/setReleaseTag.ps1 deleted file mode 100644 index c5f2f016554..00000000000 --- a/tools/releaseBuild/setReleaseTag.ps1 +++ /dev/null @@ -1,161 +0,0 @@ -param( - [Parameter(HelpMessage='ReleaseTag from the job. Set to "fromBranch" or $null to update using the branch name')] - [string]$ReleaseTag, - - [Parameter(HelpMessage='The branch name used to update the release tag.')] - [string]$Branch=$env:BUILD_SOURCEBRANCH, - - [Parameter(HelpMessage='The variable name to put the new release tagin.')] - [string]$Variable='ReleaseTag', - - [switch]$CreateJson -) - -function New-BuildInfoJson { - param( - [parameter(Mandatory = $true)] - [string] - $ReleaseTag, - [switch] $IsDaily - ) - - $blobName = $ReleaseTag -replace '\.', '-' - - $isPreview = $ReleaseTag -like '*-*' - - $filename = 'stable.json' - if($isPreview) - { - $filename = 'preview.json' - } - if($IsDaily.IsPresent) - { - $filename = 'daily.json' - } - - ## Get the UTC time and round up to the second. - $dateTime = [datetime]::UtcNow - $dateTime = [datetime]::new($dateTime.Ticks - ($dateTime.Ticks % [timespan]::TicksPerSecond), $dateTime.Kind) - - @{ - ReleaseTag = $ReleaseTag - ReleaseDate = $dateTime - BlobName = $blobName - BaseUrl = 'https://powershellinfraartifacts-gkhedzdeaghdezhr.z01.azurefd.net/install' - } | ConvertTo-Json | Out-File -Encoding ascii -Force -FilePath $filename - - $resolvedPath = (Resolve-Path -Path $filename).ProviderPath - $vstsCommandString = "vso[task.setvariable variable=BuildInfoPath]$resolvedPath" - Write-Verbose -Message "$vstsCommandString" -Verbose - Write-Host -Object "##$vstsCommandString" - - # Upload for ADO pipelines - Write-Host "##vso[artifact.upload containerfolder=BuildInfoJson;artifactname=BuildInfoJson]$resolvedPath" - - # Copy to location where OneBranch Pipelines uploads from - - # if the environment variable does not exist, we are not in OneBranch. So just return. - if (-not $env:ob_outputDirectory) { - return - } - - if (-not (Test-Path $env:ob_outputDirectory)) { - $null = New-Item -Path $env:ob_outputDirectory -ItemType Directory -Force -Verbose - } - - Copy-Item $resolvedPath -Destination $env:ob_outputDirectory -Force -Verbose -} - -# Script to set the release tag based on the branch name if it is not set or it is "fromBranch" -# the branch name is expected to be release- or -# VSTS passes it as 'refs/heads/release-v6.0.2' - -$branchOnly = $Branch -replace '^refs/heads/'; -$branchOnly = $branchOnly -replace '[_\-]' - -$msixType = 'preview' - -$isDaily = $false - -if($ReleaseTag -eq 'fromBranch' -or !$ReleaseTag) -{ - # Branch is named release- - $releaseBranchRegex = '^.*((release/|rebuild/.*rebuild))' - if($Branch -match $releaseBranchRegex) - { - $msixType = 'release' - Write-Verbose "release branch:" -Verbose - $releaseTag = $Branch -replace '^.*((release|rebuild)/)' - $vstsCommandString = "vso[task.setvariable variable=$Variable]$releaseTag" - Write-Verbose -Message "setting $Variable to $releaseTag" -Verbose - Write-Host -Object "##$vstsCommandString" - - if ($CreateJson.IsPresent) - { - New-BuildInfoJson -ReleaseTag $releaseTag - } - } - elseif(($branchOnly -eq 'master' -and $env:BUILD_REASON -ne 'Manual') -or $branchOnly -like '*dailytest*') - { - $isDaily = $true - Write-Verbose "daily build" -Verbose - $jsonPath = "${env:SYSTEM_ARTIFACTSDIRECTORY}\BuildInfoJson\daily.json" - if (test-path -Path $jsonPath) { - Write-Verbose "restoring from buildinfo json..." -Verbose - $buildInfo = Get-Content -Path $jsonPath | ConvertFrom-Json - $releaseTag = $buildInfo.ReleaseTag - } else { - Write-Verbose "creating from branch counter and metadata.json..." -Verbose - $metaDataJsonPath = Join-Path $PSScriptRoot -ChildPath '..\metadata.json' - $metadata = Get-Content $metaDataJsonPath | ConvertFrom-Json - $versionPart = $metadata.PreviewReleaseTag - if ($versionPart -match '-.*$') { - $versionPart = $versionPart -replace '-.*$' - } - - $releaseTag = "$versionPart-daily$((Get-Date).ToString('yyyyMMdd')).$($env:BRANCHCOUNTER)" - } - - $vstsCommandString = "vso[task.setvariable variable=$Variable]$releaseTag" - Write-Verbose -Message "setting $Variable to $releaseTag" -Verbose - Write-Host -Object "##$vstsCommandString" - - if ($CreateJson.IsPresent) - { - New-BuildInfoJson -ReleaseTag $releaseTag -IsDaily - } - } - else - { - Write-Verbose "non-release branch" -Verbose - # Branch is named - # Get version from metadata and append - - $metaDataJsonPath = Join-Path $PSScriptRoot -ChildPath '..\metadata.json' - $metadata = Get-Content $metaDataJsonPath | ConvertFrom-Json - $versionPart = $metadata.PreviewReleaseTag - if($versionPart -match '-.*$') - { - $versionPart = $versionPart -replace '-.*$' - } - - $releaseTag = "$versionPart-$branchOnly" - $vstsCommandString = "vso[task.setvariable variable=$Variable]$releaseTag" - Write-Verbose -Message "setting $Variable to $releaseTag" -Verbose - Write-Host -Object "##$vstsCommandString" - - if ($CreateJson.IsPresent) - { - New-BuildInfoJson -ReleaseTag $releaseTag - } - } -} - -$vstsCommandString = "vso[task.setvariable variable=IS_DAILY]$($isDaily.ToString().ToLowerInvariant())" -Write-Verbose -Message "$vstsCommandString" -Verbose -Write-Host -Object "##$vstsCommandString" - -$vstsCommandString = "vso[task.setvariable variable=MSIX_TYPE]$msixType" -Write-Verbose -Message "$vstsCommandString" -Verbose -Write-Host -Object "##$vstsCommandString" - -Write-Output $releaseTag diff --git a/tools/releaseBuild/setReleaseTag.sh b/tools/releaseBuild/setReleaseTag.sh deleted file mode 100644 index 842ba1e755b..00000000000 --- a/tools/releaseBuild/setReleaseTag.sh +++ /dev/null @@ -1 +0,0 @@ -pwsh -command ".\setReleaseTag.ps1 $*" diff --git a/tools/releaseBuild/signing.xml b/tools/releaseBuild/signing.xml deleted file mode 100644 index a6b19f6a07a..00000000000 --- a/tools/releaseBuild/signing.xml +++ /dev/null @@ -1,49 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/tools/releaseBuild/updateSigning.ps1 b/tools/releaseBuild/updateSigning.ps1 deleted file mode 100644 index bace3aec2b7..00000000000 --- a/tools/releaseBuild/updateSigning.ps1 +++ /dev/null @@ -1,46 +0,0 @@ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. -param( - [string] $SigningXmlPath = (Join-Path -Path $PSScriptRoot -ChildPath 'signing.xml'), - [switch] $SkipPwshExe -) -# Script for use in VSTS to update signing.xml - -if ($SkipPwshExe) { - ## This is required for fxdependent package as no .exe is generated. - $xmlContent = Get-Content $SigningXmlPath | Where-Object { $_ -notmatch '__INPATHROOT__\\pwsh.exe' } -} else { - ## We skip the global tool shim assembly for regular builds. - $xmlContent = Get-Content $signingXmlPath | Where-Object { $_ -notmatch '__INPATHROOT__\\Microsoft.PowerShell.GlobalTool.Shim.dll' } -} - -# Parse the signing xml -$signingXml = [xml] $xmlContent - -# Get any variables to updating 'signType' in the XML -# Define a varabile named `SignType' in VSTS to updating that signing type -# Example: $env:AuthenticodeSignType='newvalue' -# will cause all files with the 'Authenticode' signtype to be updated with the 'newvalue' signtype -$signTypes = @{} -Get-ChildItem -Path env:/*SignType | ForEach-Object -Process { - $signType = $_.Name.ToUpperInvariant().Replace('SIGNTYPE','') - Write-Host "Found SigningType $signType with value $($_.value)" - $signTypes[$signType] = $_.Value -} - -# examine each job in the xml -$signingXml.SignConfigXML.job | ForEach-Object -Process { - # examine each file in the job - $_.file | ForEach-Object -Process { - # if the sign type is one of the variables we found, update it to the new value - $signType = $_.SignType.ToUpperInvariant() - if($signTypes.ContainsKey($signType)) - { - $newSignType = $signTypes[$signType] - Write-Host "Updating $($_.src) to $newSignType" - $_.signType = $newSignType - } - } -} - -$signingXml.Save($signingXmlPath) diff --git a/tools/releaseBuild/vstsbuild.ps1 b/tools/releaseBuild/vstsbuild.ps1 deleted file mode 100644 index 1c2d740c418..00000000000 --- a/tools/releaseBuild/vstsbuild.ps1 +++ /dev/null @@ -1,120 +0,0 @@ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. -[cmdletbinding(DefaultParameterSetName='Build')] -param( - [Parameter(ParameterSetName='packageSigned')] - [Parameter(ParameterSetName='Build')] - [ValidatePattern("^v\d+\.\d+\.\d+(-\w+(\.\d{1,2})?)?$")] - [string]$ReleaseTag, - - # full paths to files to add to container to run the build - [Parameter(Mandatory,ParameterSetName='packageSigned')] - [string] - $BuildPath, - - [Parameter(Mandatory,ParameterSetName='packageSigned')] - [string] - $SignedFilesPath -) - -DynamicParam { - # Add a dynamic parameter '-Name' which specifies the name of the build to run - - # Get the names of the builds. - $buildJsonPath = (Join-Path -Path $PSScriptRoot -ChildPath 'build.json') - $build = Get-Content -Path $buildJsonPath | ConvertFrom-Json - $names = @($build.Windows.Name) - foreach($name in $build.Linux.Name) - { - $names += $name - } - - # Create the parameter attributs - $ParameterAttr = New-Object "System.Management.Automation.ParameterAttribute" - $ValidateSetAttr = New-Object "System.Management.Automation.ValidateSetAttribute" -ArgumentList $names - $Attributes = New-Object "System.Collections.ObjectModel.Collection``1[System.Attribute]" - $Attributes.Add($ParameterAttr) > $null - $Attributes.Add($ValidateSetAttr) > $null - - # Create the parameter - $Parameter = New-Object "System.Management.Automation.RuntimeDefinedParameter" -ArgumentList ("Name", [string], $Attributes) - $Dict = New-Object "System.Management.Automation.RuntimeDefinedParameterDictionary" - $Dict.Add("Name", $Parameter) > $null - return $Dict -} - -Begin { - $Name = $PSBoundParameters['Name'] -} - -End { - $ErrorActionPreference = 'Stop' - - $additionalFiles = @() - $buildPackageName = $null - # If specified, Add package file to container - if ($BuildPath) - { - Import-Module (Join-Path -Path $PSScriptRoot -ChildPath '..\..\build.psm1') - Import-Module (Join-Path -Path $PSScriptRoot -ChildPath '..\packaging') - - # Use temp as destination if not running in VSTS - $destFolder = $env:temp - if($env:BUILD_STAGINGDIRECTORY) - { - # Use artifact staging if running in VSTS - $destFolder = $env:BUILD_STAGINGDIRECTORY - } - - $BuildPackagePath = New-PSSignedBuildZip -BuildPath $BuildPath -SignedFilesPath $SignedFilesPath -DestinationFolder $destFolder - Write-Verbose -Verbose "New-PSSignedBuildZip returned `$BuildPackagePath as: $BuildPackagePath" - Write-Host "##vso[artifact.upload containerfolder=results;artifactname=results]$BuildPackagePath" - $buildPackageName = Split-Path -Path $BuildPackagePath -Leaf - $additionalFiles += $BuildPackagePath - } - - $psReleaseBranch = 'master' - $psReleaseFork = 'PowerShell' - $location = Join-Path -Path $PSScriptRoot -ChildPath 'PSRelease' - if(Test-Path $location) - { - Remove-Item -Path $location -Recurse -Force - } - - $gitBinFullPath = (Get-Command -Name git).Source - if (-not $gitBinFullPath) - { - throw "Git is required to proceed. Install from 'https://git-scm.com/download/win'" - } - - Write-Verbose "cloning -b $psReleaseBranch --quiet https://github.com/$psReleaseFork/PSRelease.git" -Verbose - & $gitBinFullPath clone -b $psReleaseBranch --quiet https://github.com/$psReleaseFork/PSRelease.git $location - - Push-Location -Path $PWD.Path - - $unresolvedRepoRoot = Join-Path -Path $PSScriptRoot '../..' - $resolvedRepoRoot = (Resolve-Path -Path $unresolvedRepoRoot).ProviderPath - - try - { - Write-Verbose "Starting build at $resolvedRepoRoot ..." -Verbose - Import-Module "$location/vstsBuild" -Force - Import-Module "$location/dockerBasedBuild" -Force - Clear-VstsTaskState - - $buildParameters = @{ - ReleaseTag = $ReleaseTag - BuildPackageName = $buildPackageName - } - - Invoke-Build -RepoPath $resolvedRepoRoot -BuildJsonPath './tools/releaseBuild/build.json' -Name $Name -Parameters $buildParameters -AdditionalFiles $AdditionalFiles - } - catch - { - Write-VstsError -Error $_ - } - finally{ - Write-VstsTaskState - exit 0 - } -} diff --git a/tools/releaseBuild/vstsbuild.sh b/tools/releaseBuild/vstsbuild.sh deleted file mode 100644 index d7d0363745f..00000000000 --- a/tools/releaseBuild/vstsbuild.sh +++ /dev/null @@ -1 +0,0 @@ -pwsh -command ".\vstsbuild.ps1 $*" From 91d919cc32712a9bf2559dba911b0546f46269f7 Mon Sep 17 00:00:00 2001 From: Travis Plunk Date: Wed, 2 Apr 2025 18:46:10 -0700 Subject: [PATCH 081/173] [release/v7.5]Add setup dotnet action to the build composite action (#25235) --- .github/actions/build/ci/action.yml | 3 +++ .github/actions/test/nix/action.yml | 6 +++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/.github/actions/build/ci/action.yml b/.github/actions/build/ci/action.yml index 90968d81cfe..93adaf6b17a 100644 --- a/.github/actions/build/ci/action.yml +++ b/.github/actions/build/ci/action.yml @@ -11,6 +11,9 @@ runs: if: github.event_name != 'PullRequest' run: Write-Host "##vso[build.updatebuildnumber]$env:BUILD_SOURCEBRANCHNAME-$env:BUILD_SOURCEVERSION-$((get-date).ToString("yyyyMMddhhmmss"))" shell: pwsh + - uses: actions/setup-dotnet@v4 + with: + global-json-file: ./global.json - name: Bootstrap if: success() run: |- diff --git a/.github/actions/test/nix/action.yml b/.github/actions/test/nix/action.yml index 97575b6b54d..03c44a151c7 100644 --- a/.github/actions/test/nix/action.yml +++ b/.github/actions/test/nix/action.yml @@ -30,7 +30,11 @@ runs: continue-on-error: true run: Get-ChildItem "${{ github.workspace }}/build/*" -Recurse shell: pwsh - + + - uses: actions/setup-dotnet@v4 + with: + global-json-file: ./global.json + - name: Bootstrap shell: pwsh run: |- From f0e645cc32c4deedb4f7453fd8a365f1aee9ed9c Mon Sep 17 00:00:00 2001 From: Travis Plunk Date: Fri, 4 Apr 2025 15:11:58 -0700 Subject: [PATCH 082/173] [release/v7.5]Remove obsolete template from Windows Packaging CI (#25237) --- .vsts-ci/windows/templates/windows-packaging.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.vsts-ci/windows/templates/windows-packaging.yml b/.vsts-ci/windows/templates/windows-packaging.yml index 84b02d14dfd..b0e97d7f6a9 100644 --- a/.vsts-ci/windows/templates/windows-packaging.yml +++ b/.vsts-ci/windows/templates/windows-packaging.yml @@ -47,9 +47,6 @@ jobs: displayName: Capture PowerShell Version Table condition: succeededOrFailed() - - - template: /tools/releaseBuild/azureDevOps/templates/insert-nuget-config-azfeed.yml - - pwsh: | Import-Module .\tools\ci.psm1 Switch-PSNugetConfig -Source Public From efb55e20acaef57a9b54dbfa4ebc1e1c79eef5c3 Mon Sep 17 00:00:00 2001 From: Travis Plunk Date: Fri, 4 Apr 2025 15:56:37 -0700 Subject: [PATCH 083/173] [release/v7.5] Add UseDotnet task for installing dotnet (#25281) Co-authored-by: Aditya Patwardhan --- .../actions/test/linux-packaging/action.yml | 2 +- .github/actions/test/windows/action.yml | 5 +- .github/workflows/linux-ci.yml | 5 ++ .github/workflows/macos-ci.yml | 2 +- .pipelines/templates/compliance/apiscan.yml | 14 ++-- .pipelines/templates/linux-package-build.yml | 2 +- .pipelines/templates/linux.yml | 8 +- .pipelines/templates/mac-package-build.yml | 2 +- .pipelines/templates/mac.yml | 9 ++- .pipelines/templates/nupkg.yml | 9 ++- .../release-validate-fxdpackages.yml | 38 ++-------- .../release-validate-globaltools.yml | 43 ++--------- .pipelines/templates/release-validate-sdk.yml | 42 ++--------- .pipelines/templates/testartifacts.yml | 22 +++--- .pipelines/templates/windows-hosted-build.yml | 12 ++- .../templates/windows-package-build.yml | 11 ++- .vsts-ci/linux/templates/packaging.yml | 8 +- .vsts-ci/mac.yml | 2 +- .vsts-ci/psresourceget-acr.yml | 1 - .vsts-ci/templates/ci-build.yml | 6 ++ .vsts-ci/templates/nix-test.yml | 6 ++ .../templates/test/nix-container-test.yml | 6 ++ .vsts-ci/templates/windows-test.yml | 8 +- .vsts-ci/windows-daily.yml | 11 ++- .../windows/templates/windows-packaging.yml | 7 ++ build.psm1 | 75 ++++++++++--------- tools/ci.psm1 | 6 +- tools/packaging/packaging.psm1 | 4 +- 28 files changed, 178 insertions(+), 188 deletions(-) diff --git a/.github/actions/test/linux-packaging/action.yml b/.github/actions/test/linux-packaging/action.yml index 61d23742056..b4a9c3b55c0 100644 --- a/.github/actions/test/linux-packaging/action.yml +++ b/.github/actions/test/linux-packaging/action.yml @@ -27,7 +27,7 @@ runs: - name: Bootstrap run: |- Import-Module ./build.psm1 - Start-PSBootstrap -Package + Start-PSBootstrap -Scenario Package shell: pwsh - name: Capture Artifacts Directory continue-on-error: true diff --git a/.github/actions/test/windows/action.yml b/.github/actions/test/windows/action.yml index c8e1c86024a..d2af55ce5a9 100644 --- a/.github/actions/test/windows/action.yml +++ b/.github/actions/test/windows/action.yml @@ -31,6 +31,10 @@ runs: run: Get-ChildItem "${{ github.workspace }}\build\*" -Recurse shell: pwsh + - uses: actions/setup-dotnet@v4 + with: + global-json-file: .\global.json + - name: Bootstrap shell: powershell run: |- @@ -50,7 +54,6 @@ runs: if: success() run: |- Import-Module .\build.psm1 -force - Start-PSBootstrap Import-Module .\tools\ci.psm1 Restore-PSOptions -PSOptionsPath '${{ github.workspace }}\build\psoptions.json' $options = (Get-PSOptions) diff --git a/.github/workflows/linux-ci.yml b/.github/workflows/linux-ci.yml index 8f15e9a080d..68b651c7e46 100644 --- a/.github/workflows/linux-ci.yml +++ b/.github/workflows/linux-ci.yml @@ -77,6 +77,7 @@ jobs: uses: actions/checkout@v4.1.0 with: fetch-depth: 1000 + - name: Build uses: "./.github/actions/build/ci" linux_test_unelevated_ci: @@ -187,6 +188,10 @@ jobs: with: fetch-depth: '0' + - uses: actions/setup-dotnet@v4 + with: + global-json-file: ./global.json + # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL uses: github/codeql-action/init@df409f7d9260372bd5f19e5b04e83cb3c43714ae # v3.27.9 diff --git a/.github/workflows/macos-ci.yml b/.github/workflows/macos-ci.yml index fafb6140285..b414afebfc9 100644 --- a/.github/workflows/macos-ci.yml +++ b/.github/workflows/macos-ci.yml @@ -174,7 +174,7 @@ jobs: if: success() || failure() run: |- import-module ./build.psm1 - start-psbootstrap -package + start-psbootstrap -Scenario package shell: pwsh ready_to_merge: name: macos ready to merge diff --git a/.pipelines/templates/compliance/apiscan.yml b/.pipelines/templates/compliance/apiscan.yml index b30d72f6a56..bfe97827801 100644 --- a/.pipelines/templates/compliance/apiscan.yml +++ b/.pipelines/templates/compliance/apiscan.yml @@ -61,14 +61,12 @@ jobs: parameters: repoRoot: '$(repoRoot)' - - pwsh: | - Import-Module .\build.psm1 -force - Start-PSBootstrap - workingDirectory: '$(repoRoot)' - retryCountOnTaskFailure: 2 - displayName: 'Bootstrap' - env: - __DOTNET_RUNTIME_FEED_KEY: $(RUNTIME_SOURCEFEED_KEY) + - task: UseDotNet@2 + displayName: 'Use .NET Core sdk' + inputs: + useGlobalJson: true + packageType: 'sdk' + workingDirectory: $(Build.SourcesDirectory)" - pwsh: | Import-Module .\build.psm1 -force diff --git a/.pipelines/templates/linux-package-build.yml b/.pipelines/templates/linux-package-build.yml index 05c798cd2c3..a9f4833cc1d 100644 --- a/.pipelines/templates/linux-package-build.yml +++ b/.pipelines/templates/linux-package-build.yml @@ -103,7 +103,7 @@ jobs: Import-Module "$repoRoot/build.psm1" Import-Module "$repoRoot/tools/packaging" - Start-PSBootstrap -Package + Start-PSBootstrap -Scenario Package $psOptionsPath = "$(Pipeline.Workspace)/CoOrdinatedBuildPipeline/${unsignedDrop}/psoptions/psoptions.json" diff --git a/.pipelines/templates/linux.yml b/.pipelines/templates/linux.yml index 2e6f9c3e5e3..d6026dc5336 100644 --- a/.pipelines/templates/linux.yml +++ b/.pipelines/templates/linux.yml @@ -62,6 +62,13 @@ jobs: AnalyzeInPipeline: true Language: csharp + - task: UseDotNet@2 + inputs: + useGlobalJson: true + workingDirectory: $(PowerShellRoot) + env: + ob_restore_phase: true + - pwsh: | $runtime = $env:RUNTIME @@ -75,7 +82,6 @@ jobs: Import-Module -Name $(PowerShellRoot)/build.psm1 -Force $buildWithSymbolsPath = New-Item -ItemType Directory -Path $(Pipeline.Workspace)/Symbols_$(Runtime) -Force - Start-PSBootstrap $null = New-Item -ItemType Directory -Path $buildWithSymbolsPath -Force -Verbose $ReleaseTagParam = @{} diff --git a/.pipelines/templates/mac-package-build.yml b/.pipelines/templates/mac-package-build.yml index 2da8c2b7615..f009fdae06f 100644 --- a/.pipelines/templates/mac-package-build.yml +++ b/.pipelines/templates/mac-package-build.yml @@ -110,7 +110,7 @@ jobs: Write-Verbose -Message "LTS Release: $LTS" } - Start-PSBootstrap -Package + Start-PSBootstrap -Scenario Package $macosRuntime = "osx-$buildArch" diff --git a/.pipelines/templates/mac.yml b/.pipelines/templates/mac.yml index 4f9604ea100..310c5695979 100644 --- a/.pipelines/templates/mac.yml +++ b/.pipelines/templates/mac.yml @@ -39,9 +39,16 @@ jobs: sudo chown $env:USER "$(Agent.TempDirectory)/PowerShell" displayName: 'Create $(Agent.TempDirectory)/PowerShell' + - task: UseDotNet@2 + displayName: 'Use .NET Core sdk' + inputs: + useGlobalJson: true + packageType: 'sdk' + workingDirectory: $(PowerShellRoot) + - pwsh: | Import-Module $(PowerShellRoot)/build.psm1 -Force - Start-PSBootstrap -Package + Start-PSBootstrap -Scenario Package displayName: 'Bootstrap VM' env: __DOTNET_RUNTIME_FEED_KEY: $(RUNTIME_SOURCEFEED_KEY) diff --git a/.pipelines/templates/nupkg.yml b/.pipelines/templates/nupkg.yml index be4b704557e..d7837c5c3dc 100644 --- a/.pipelines/templates/nupkg.yml +++ b/.pipelines/templates/nupkg.yml @@ -97,12 +97,17 @@ jobs: - task: NuGetToolInstaller@1 displayName: 'Install NuGet.exe' + - task: UseDotNet@2 + displayName: 'Use .NET Core sdk' + inputs: + useGlobalJson: true + packageType: 'sdk' + workingDirectory: '$(PowerShellRoot)' + - pwsh: | Set-Location -Path '$(PowerShellRoot)' Import-Module "$(PowerShellRoot)/build.psm1" -Force - Start-PSBootstrap -Verbose - $sharedModules = @('Microsoft.PowerShell.Commands.Management', 'Microsoft.PowerShell.Commands.Utility', 'Microsoft.PowerShell.ConsoleHost', diff --git a/.pipelines/templates/release-validate-fxdpackages.yml b/.pipelines/templates/release-validate-fxdpackages.yml index 62e907fcf36..baf6c431787 100644 --- a/.pipelines/templates/release-validate-fxdpackages.yml +++ b/.pipelines/templates/release-validate-fxdpackages.yml @@ -44,38 +44,12 @@ jobs: Get-ChildItem "$(Pipeline.Workspace)/PSPackagesOfficial/$artifactName" -Recurse displayName: 'Capture Downloaded Artifacts' - - pwsh: | - $repoRoot = "$(Build.SourcesDirectory)/PowerShell" - $dotnetMetadataPath = "$repoRoot/DotnetRuntimeMetadata.json" - $dotnetMetadataJson = Get-Content $dotnetMetadataPath -Raw | ConvertFrom-Json - - # Channel is like: $Channel = "5.0.1xx-preview2" - $Channel = $dotnetMetadataJson.sdk.channel - - $sdkVersion = (Get-Content "$repoRoot/global.json" -Raw | ConvertFrom-Json).sdk.version - Import-Module "$repoRoot/build.psm1" -Force - - Find-Dotnet - - if(-not (Get-PackageSource -Name 'dotnet' -ErrorAction SilentlyContinue)) - { - $nugetFeed = ([xml](Get-Content $repoRoot/nuget.config -Raw)).Configuration.packagesources.add | Where-Object { $_.Key -eq 'dotnet' } | Select-Object -ExpandProperty Value - if ($nugetFeed) { - Register-PackageSource -Name 'dotnet' -Location $nugetFeed -ProviderName NuGet - Write-Verbose -Message "Register new package source 'dotnet'" -verbose - } - } - - ## Install latest version from the channel - - #Install-Dotnet -Channel "$Channel" -Version $sdkVersion - Start-PSBootstrap - - Write-Verbose -Message "Installing .NET SDK completed." -Verbose - - displayName: Install .NET - env: - __DOTNET_RUNTIME_FEED_KEY: $(RUNTIME_SOURCEFEED_KEY) + - task: UseDotNet@2 + displayName: 'Use .NET Core sdk' + inputs: + useGlobalJson: true + packageType: 'sdk' + workingDirectory: $(Build.SourcesDirectory)/PowerShell" - pwsh: | $artifactName = '$(artifactName)' diff --git a/.pipelines/templates/release-validate-globaltools.yml b/.pipelines/templates/release-validate-globaltools.yml index 0820e5591f6..3c88a278791 100644 --- a/.pipelines/templates/release-validate-globaltools.yml +++ b/.pipelines/templates/release-validate-globaltools.yml @@ -38,44 +38,15 @@ jobs: Get-ChildItem "$(Pipeline.Workspace)/PSPackagesOfficial/drop_nupkg_build_nupkg" -Recurse displayName: 'Capture Downloaded Artifacts' - - pwsh: | - $repoRoot = "$(Build.SourcesDirectory)/PowerShell" - $dotnetMetadataPath = "$repoRoot/DotnetRuntimeMetadata.json" - $dotnetMetadataJson = Get-Content $dotnetMetadataPath -Raw | ConvertFrom-Json - - # Channel is like: $Channel = "5.0.1xx-preview2" - $Channel = $dotnetMetadataJson.sdk.channel - - $sdkVersion = (Get-Content "$repoRoot/global.json" -Raw | ConvertFrom-Json).sdk.version - Import-Module "$repoRoot/build.psm1" -Force - - Find-Dotnet - - if(-not (Get-PackageSource -Name 'dotnet' -ErrorAction SilentlyContinue)) - { - $nugetFeed = ([xml](Get-Content $repoRoot/nuget.config -Raw)).Configuration.packagesources.add | Where-Object { $_.Key -eq 'dotnet' } | Select-Object -ExpandProperty Value - if ($nugetFeed) { - Register-PackageSource -Name 'dotnet' -Location $nugetFeed -ProviderName NuGet - Write-Verbose -Message "Register new package source 'dotnet'" -verbose - } - } - - ## Install latest version from the channel - - #Install-Dotnet -Channel "$Channel" -Version $sdkVersion - Start-PSBootstrap - - Write-Verbose -Message "Installing .NET SDK completed." -Verbose - - displayName: Install .NET - env: - __DOTNET_RUNTIME_FEED_KEY: $(RUNTIME_SOURCEFEED_KEY) + - task: UseDotNet@2 + displayName: 'Use .NET Core sdk' + inputs: + useGlobalJson: true + packageType: 'sdk' + workingDirectory: $(REPOROOT) - pwsh: | $repoRoot = "$(Build.SourcesDirectory)/PowerShell" - $env:DOTNET_SKIP_FIRST_TIME_EXPERIENCE=1 - Import-Module "$repoRoot/build.psm1" -Force - Start-PSBootstrap $toolPath = New-Item -ItemType Directory "$(System.DefaultWorkingDirectory)/toolPath" | Select-Object -ExpandProperty FullName @@ -108,8 +79,6 @@ jobs: - pwsh: | $repoRoot = "$(Build.SourcesDirectory)/PowerShell" - Import-Module "$repoRoot/build.psm1" -Force - Start-PSBootstrap $exeName = if ($IsWindows) { "pwsh.exe" } else { "pwsh" } diff --git a/.pipelines/templates/release-validate-sdk.yml b/.pipelines/templates/release-validate-sdk.yml index 3f365f5ebb9..0d50b213961 100644 --- a/.pipelines/templates/release-validate-sdk.yml +++ b/.pipelines/templates/release-validate-sdk.yml @@ -46,47 +46,17 @@ jobs: Get-ChildItem "$(Pipeline.Workspace)/PSPackagesOfficial/drop_nupkg_build_nupkg" -Recurse displayName: 'Capture Downloaded Artifacts' - - pwsh: | - $repoRoot = "$(Build.SourcesDirectory)" - - $dotnetMetadataPath = "$repoRoot/DotnetRuntimeMetadata.json" - $dotnetMetadataJson = Get-Content $dotnetMetadataPath -Raw | ConvertFrom-Json - - # Channel is like: $Channel = "5.0.1xx-preview2" - $Channel = $dotnetMetadataJson.sdk.channel - - $sdkVersion = (Get-Content "$repoRoot/global.json" -Raw | ConvertFrom-Json).sdk.version - Import-Module "$repoRoot/build.psm1" -Force - - Find-Dotnet - - if(-not (Get-PackageSource -Name 'dotnet' -ErrorAction SilentlyContinue)) - { - $nugetFeed = ([xml](Get-Content $repoRoot/nuget.config -Raw)).Configuration.packagesources.add | Where-Object { $_.Key -eq 'dotnet' } | Select-Object -ExpandProperty Value - - if ($nugetFeed) { - Register-PackageSource -Name 'dotnet' -Location $nugetFeed -ProviderName NuGet - Write-Verbose -Message "Register new package source 'dotnet'" -verbose - } - } - - ## Install latest version from the channel - #Install-Dotnet -Channel "$Channel" -Version $sdkVersion - - Start-PSBootstrap - - Write-Verbose -Message "Installing .NET SDK completed." -Verbose - - displayName: Install .NET - env: - __DOTNET_RUNTIME_FEED_KEY: $(RUNTIME_SOURCEFEED_KEY) + - task: UseDotNet@2 + displayName: 'Use .NET Core sdk' + inputs: + useGlobalJson: true + packageType: 'sdk' + workingDirectory: $(REPOROOT) - pwsh: | $repoRoot = "$(Build.SourcesDirectory)" $env:DOTNET_SKIP_FIRST_TIME_EXPERIENCE=1 - Import-Module "$repoRoot/build.psm1" -Force - Start-PSBootstrap $localLocation = "$(Pipeline.Workspace)/PSPackagesOfficial/drop_nupkg_build_nupkg" $xmlElement = @" diff --git a/.pipelines/templates/testartifacts.yml b/.pipelines/templates/testartifacts.yml index 039e9336d7c..240ceae80f7 100644 --- a/.pipelines/templates/testartifacts.yml +++ b/.pipelines/templates/testartifacts.yml @@ -30,12 +30,13 @@ jobs: repoRoot: $(Build.SourcesDirectory)/PowerShell ob_restore_phase: true - - pwsh: | - Import-Module $(Build.SourcesDirectory)/PowerShell/build.psm1 - Start-PSBootstrap - displayName: Bootstrap + - task: UseDotNet@2 + displayName: 'Use .NET Core sdk' + inputs: + useGlobalJson: true + packageType: 'sdk' + workingDirectory: $(Build.SourcesDirectory)/PowerShell" env: - __DOTNET_RUNTIME_FEED_KEY: $(RUNTIME_SOURCEFEED_KEY) ob_restore_phase: true - pwsh: | @@ -97,12 +98,13 @@ jobs: repoRoot: $(Build.SourcesDirectory)/PowerShell ob_restore_phase: true - - pwsh: | - Import-Module $(Build.SourcesDirectory)/PowerShell/build.psm1 - Start-PSBootstrap - displayName: Bootstrap + - task: UseDotNet@2 + displayName: 'Use .NET Core sdk' + inputs: + useGlobalJson: true + packageType: 'sdk' + workingDirectory: $(Build.SourcesDirectory)/PowerShell" env: - __DOTNET_RUNTIME_FEED_KEY: $(RUNTIME_SOURCEFEED_KEY) ob_restore_phase: true - pwsh: | diff --git a/.pipelines/templates/windows-hosted-build.yml b/.pipelines/templates/windows-hosted-build.yml index 735ed7cc48f..8f8273f4ec8 100644 --- a/.pipelines/templates/windows-hosted-build.yml +++ b/.pipelines/templates/windows-hosted-build.yml @@ -63,6 +63,13 @@ jobs: AnalyzeInPipeline: true Language: csharp + - task: UseDotNet@2 + inputs: + useGlobalJson: true + workingDirectory: $(PowerShellRoot) + env: + ob_restore_phase: true + - pwsh: | $runtime = switch ($env:Architecture) { @@ -86,7 +93,7 @@ jobs: Import-Module -Name $(PowerShellRoot)/build.psm1 -Force $buildWithSymbolsPath = New-Item -ItemType Directory -Path $(Pipeline.Workspace)/Symbols_$(Architecture) -Force - Start-PSBootstrap -Package + Start-PSBootstrap -Scenario Package $null = New-Item -ItemType Directory -Path $buildWithSymbolsPath -Force -Verbose $ReleaseTagParam = @{} @@ -135,7 +142,6 @@ jobs: } Import-Module -Name $(PowerShellRoot)/build.psm1 -Force - Start-PSBootstrap ## Build global tool Write-Verbose -Message "Building PowerShell global tool for Windows.x64" -Verbose @@ -229,8 +235,6 @@ jobs: After that, we repack using Compress-Archive and rename it back to a nupkg. #> - Import-Module -Name $(PowerShellRoot)/build.psm1 -Force - Start-PSBootstrap $packagingStrings = Import-PowerShellDataFile "$(PowerShellRoot)\tools\packaging\packaging.strings.psd1" $outputPath = Join-Path '$(ob_outputDirectory)' 'globaltool' diff --git a/.pipelines/templates/windows-package-build.yml b/.pipelines/templates/windows-package-build.yml index da2579d75a3..08dd15fc79f 100644 --- a/.pipelines/templates/windows-package-build.yml +++ b/.pipelines/templates/windows-package-build.yml @@ -78,6 +78,13 @@ jobs: env: ob_restore_phase: true # This ensures this done in restore phase to workaround signing issue + - task: UseDotNet@2 + inputs: + useGlobalJson: true + workingDirectory: $(REPOROOT) + env: + ob_restore_phase: true + - pwsh: | $msixUrl = '$(makeappUrl)' Invoke-RestMethod -Uri $msixUrl -OutFile '$(Pipeline.Workspace)\makeappx.zip' @@ -105,7 +112,7 @@ jobs: Import-Module "$repoRoot\build.psm1" Import-Module "$repoRoot\tools\packaging" - Start-PSBootstrap -Package + Start-PSBootstrap -Scenario Package $signedFilesPath, $psoptionsFilePath = if ($env:RUNTIME -eq 'minsize') { "$(Pipeline.Workspace)\CoOrdinatedBuildPipeline\drop_windows_build_windows_x64_${runtime}\$signedFolder" @@ -136,7 +143,7 @@ jobs: Write-Verbose -Message "LTS Release: $LTS" } - Start-PSBootstrap -Package + Start-PSBootstrap -Scenario Package $WindowsRuntime = switch ($runtime) { 'x64' { 'win7-x64' } diff --git a/.vsts-ci/linux/templates/packaging.yml b/.vsts-ci/linux/templates/packaging.yml index fab2e1101fa..e6294951cb6 100644 --- a/.vsts-ci/linux/templates/packaging.yml +++ b/.vsts-ci/linux/templates/packaging.yml @@ -13,6 +13,12 @@ jobs: displayName: ${{ parameters.name }} packaging steps: + - task: UseDotNet@2 + displayName: 'Use .NET Core sdk' + inputs: + useGlobalJson: true + packageType: 'sdk' + - pwsh: | Get-ChildItem -Path env: displayName: Capture Environment @@ -33,7 +39,7 @@ jobs: - pwsh: | Import-Module .\build.psm1 - Start-PSBootstrap -Package + Start-PSBootstrap -Scenario Package displayName: Bootstrap - pwsh: | diff --git a/.vsts-ci/mac.yml b/.vsts-ci/mac.yml index bfb0b3afd21..05d6d71ea71 100644 --- a/.vsts-ci/mac.yml +++ b/.vsts-ci/mac.yml @@ -110,6 +110,6 @@ stages: clean: true - pwsh: | import-module ./build.psm1 - start-psbootstrap -package + start-psbootstrap -Scenario package displayName: Bootstrap packaging condition: succeededOrFailed() diff --git a/.vsts-ci/psresourceget-acr.yml b/.vsts-ci/psresourceget-acr.yml index c4211d35d95..1a24983b5b5 100644 --- a/.vsts-ci/psresourceget-acr.yml +++ b/.vsts-ci/psresourceget-acr.yml @@ -137,7 +137,6 @@ stages: - pwsh: | Import-Module .\build.psm1 -force - Start-PSBootstrap Import-Module .\tools\ci.psm1 Restore-PSOptions -PSOptionsPath '$(System.ArtifactsDirectory)\build\psoptions.json' $options = (Get-PSOptions) diff --git a/.vsts-ci/templates/ci-build.yml b/.vsts-ci/templates/ci-build.yml index 59d63002567..2c2fbe8d91d 100644 --- a/.vsts-ci/templates/ci-build.yml +++ b/.vsts-ci/templates/ci-build.yml @@ -57,6 +57,12 @@ jobs: - ${{ if ne(variables['UseAzDevOpsFeed'], '') }}: - template: /tools/releaseBuild/azureDevOps/templates/insert-nuget-config-azfeed.yml + - task: UseDotNet@2 + displayName: 'Use .NET Core sdk' + inputs: + useGlobalJson: true + packageType: 'sdk' + - pwsh: | Import-Module .\tools\ci.psm1 Invoke-CIInstall -SkipUser diff --git a/.vsts-ci/templates/nix-test.yml b/.vsts-ci/templates/nix-test.yml index ab3985dacd6..214ae14b2c6 100644 --- a/.vsts-ci/templates/nix-test.yml +++ b/.vsts-ci/templates/nix-test.yml @@ -13,6 +13,12 @@ jobs: displayName: ${{ parameters.name }} Test - ${{ parameters.purpose }} - ${{ parameters.tagSet }} steps: + - task: UseDotNet@2 + displayName: 'Use .NET Core sdk' + inputs: + useGlobalJson: true + packageType: 'sdk' + - template: ./test/nix-test-steps.yml parameters: purpose: ${{ parameters.purpose }} diff --git a/.vsts-ci/templates/test/nix-container-test.yml b/.vsts-ci/templates/test/nix-container-test.yml index 931af6fc675..37c60a4c53b 100644 --- a/.vsts-ci/templates/test/nix-container-test.yml +++ b/.vsts-ci/templates/test/nix-container-test.yml @@ -23,6 +23,12 @@ jobs: displayName: ${{ parameters.name }} Test - ${{ parameters.purpose }} - ${{ parameters.tagSet }} steps: + - task: UseDotNet@2 + displayName: 'Use .NET Core sdk' + inputs: + useGlobalJson: true + packageType: 'sdk' + - template: ./nix-test-steps.yml parameters: purpose: ${{ parameters.purpose }} diff --git a/.vsts-ci/templates/windows-test.yml b/.vsts-ci/templates/windows-test.yml index 50ff67a32a8..02a8ddd1ea8 100644 --- a/.vsts-ci/templates/windows-test.yml +++ b/.vsts-ci/templates/windows-test.yml @@ -54,6 +54,13 @@ jobs: displayName: 'Capture Artifacts Directory' continueOnError: true + - task: UseDotNet@2 + displayName: 'Use .NET Core sdk' + inputs: + useGlobalJson: true + packageType: 'sdk' + workingDirectory: $(Build.SourcesDirectory)" + # must be run frow Windows PowerShell - powershell: | # Remove "Program Files\dotnet" from the env variable PATH, so old SDKs won't affect us. @@ -74,7 +81,6 @@ jobs: - pwsh: | Import-Module .\build.psm1 -force - Start-PSBootstrap Import-Module .\tools\ci.psm1 Restore-PSOptions -PSOptionsPath '$(System.ArtifactsDirectory)\build\psoptions.json' $options = (Get-PSOptions) diff --git a/.vsts-ci/windows-daily.yml b/.vsts-ci/windows-daily.yml index 4abcf8ec966..5a2f5ed2425 100644 --- a/.vsts-ci/windows-daily.yml +++ b/.vsts-ci/windows-daily.yml @@ -93,6 +93,13 @@ stages: displayName: Bootstrap condition: succeededOrFailed() + - task: UseDotNet@2 + displayName: 'Use .NET Core sdk' + inputs: + useGlobalJson: true + packageType: 'sdk' + workingDirectory: $(Build.SourcesDirectory)" + - pwsh: | Import-Module .\build.psm1 Restore-PSOptions -PSOptionsPath '$(System.ArtifactsDirectory)\build\psoptions.json' @@ -104,7 +111,6 @@ stages: - pwsh: | Import-Module .\build.psm1 - Start-PSBootstrap Import-Module .\tools\ci.psm1 Restore-PSOptions -PSOptionsPath '$(System.ArtifactsDirectory)\build\psoptions.json' Invoke-CITest -Purpose UnelevatedPesterTests -TagSet CI @@ -113,7 +119,6 @@ stages: - pwsh: | Import-Module .\build.psm1 - Start-PSBootstrap Import-Module .\tools\ci.psm1 Restore-PSOptions -PSOptionsPath '$(System.ArtifactsDirectory)\build\psoptions.json' Invoke-CITest -Purpose ElevatedPesterTests -TagSet CI @@ -122,7 +127,6 @@ stages: - pwsh: | Import-Module .\build.psm1 - Start-PSBootstrap Import-Module .\tools\ci.psm1 Restore-PSOptions -PSOptionsPath '$(System.ArtifactsDirectory)\build\psoptions.json' Invoke-CITest -Purpose UnelevatedPesterTests -TagSet Others @@ -131,7 +135,6 @@ stages: - pwsh: | Import-Module .\build.psm1 - Start-PSBootstrap Import-Module .\tools\ci.psm1 Restore-PSOptions -PSOptionsPath '$(System.ArtifactsDirectory)\build\psoptions.json' Invoke-CITest -Purpose ElevatedPesterTests -TagSet Others diff --git a/.vsts-ci/windows/templates/windows-packaging.yml b/.vsts-ci/windows/templates/windows-packaging.yml index b0e97d7f6a9..cc32837a304 100644 --- a/.vsts-ci/windows/templates/windows-packaging.yml +++ b/.vsts-ci/windows/templates/windows-packaging.yml @@ -54,6 +54,13 @@ jobs: condition: succeeded() workingDirectory: $(repoPath) + - task: UseDotNet@2 + displayName: 'Use .NET Core sdk' + inputs: + useGlobalJson: true + packageType: 'sdk' + workingDirectory: $(repoPath) + - pwsh: | Import-Module .\tools\ci.psm1 Invoke-CIInstall -SkipUser diff --git a/build.psm1 b/build.psm1 index e05b5639af1..e882e2f797c 100644 --- a/build.psm1 +++ b/build.psm1 @@ -2226,10 +2226,12 @@ function Start-PSBootstrap { # we currently pin dotnet-cli version, and will # update it when more stable version comes out. [string]$Version = $dotnetCLIRequiredVersion, - [switch]$Package, [switch]$NoSudo, [switch]$BuildLinuxArm, - [switch]$Force + [switch]$Force, + [Parameter(Mandatory = $true)] + [ValidateSet("Package", "DotNet", "Both")] + [string]$Scenario = "Package" ) Write-Log -message "Installing PowerShell build dependencies" @@ -2262,7 +2264,7 @@ function Start-PSBootstrap { elseif ($environment.IsUbuntu18) { $Deps += "libicu60"} # Packaging tools - if ($Package) { $Deps += "ruby-dev", "groff", "libffi-dev", "rpm", "g++", "make" } + if ($Scenario -eq 'Both' -or $Scenario -eq 'Package') { $Deps += "ruby-dev", "groff", "libffi-dev", "rpm", "g++", "make" } # Install dependencies # change the fontend from apt-get to noninteractive @@ -2286,7 +2288,7 @@ function Start-PSBootstrap { $Deps += "libicu", "openssl-libs" # Packaging tools - if ($Package) { $Deps += "ruby-devel", "rpm-build", "groff", 'libffi-devel', "gcc-c++" } + if ($Scenario -eq 'Both' -or $Scenario -eq 'Package') { $Deps += "ruby-devel", "rpm-build", "groff", 'libffi-devel', "gcc-c++" } $PackageManager = Get-RedHatPackageManager @@ -2307,7 +2309,7 @@ function Start-PSBootstrap { $Deps += "wget" # Packaging tools - if ($Package) { $Deps += "ruby-devel", "rpmbuild", "groff", 'libffi-devel', "gcc" } + if ($Scenario -eq 'Both' -or $Scenario -eq 'Package') { $Deps += "ruby-devel", "rpmbuild", "groff", 'libffi-devel', "gcc" } $PackageManager = "zypper --non-interactive install" $baseCommand = "$sudo $PackageManager" @@ -2347,7 +2349,7 @@ function Start-PSBootstrap { } # Install [fpm](https://github.com/jordansissel/fpm) - if ($Package) { + if ($Scenario -eq 'Both' -or $Scenario -eq 'Package') { Install-GlobalGem -Sudo $sudo -GemName "dotenv" -GemVersion "2.8.1" Install-GlobalGem -Sudo $sudo -GemName "ffi" -GemVersion "1.16.3" Install-GlobalGem -Sudo $sudo -GemName "fpm" -GemVersion "1.15.1" @@ -2355,42 +2357,45 @@ function Start-PSBootstrap { } } - Write-Verbose -Verbose "Calling Find-Dotnet from Start-PSBootstrap" + if ($Scenario -eq 'DotNet' -or $Scenario -eq 'Both') { - # Try to locate dotnet-SDK before installing it - Find-Dotnet + Write-Verbose -Verbose "Calling Find-Dotnet from Start-PSBootstrap" - Write-Verbose -Verbose "Back from calling Find-Dotnet from Start-PSBootstrap" + # Try to locate dotnet-SDK before installing it + Find-Dotnet - # Install dotnet-SDK - $dotNetExists = precheck 'dotnet' $null - $dotNetVersion = [string]::Empty - if($dotNetExists) { - $dotNetVersion = Find-RequiredSDK $dotnetCLIRequiredVersion - } + Write-Verbose -Verbose "Back from calling Find-Dotnet from Start-PSBootstrap" - if(!$dotNetExists -or $dotNetVersion -ne $dotnetCLIRequiredVersion -or $Force.IsPresent) { - if($Force.IsPresent) { - Write-Log -message "Installing dotnet due to -Force." - } - elseif(!$dotNetExists) { - Write-Log -message "dotnet not present. Installing dotnet." - } - else { - Write-Log -message "dotnet out of date ($dotNetVersion). Updating dotnet." + # Install dotnet-SDK + $dotNetExists = precheck 'dotnet' $null + $dotNetVersion = [string]::Empty + if($dotNetExists) { + $dotNetVersion = Find-RequiredSDK $dotnetCLIRequiredVersion } - $DotnetArguments = @{ Channel=$Channel; Version=$Version; NoSudo=$NoSudo } + if(!$dotNetExists -or $dotNetVersion -ne $dotnetCLIRequiredVersion -or $Force.IsPresent) { + if($Force.IsPresent) { + Write-Log -message "Installing dotnet due to -Force." + } + elseif(!$dotNetExists) { + Write-Log -message "dotnet not present. Installing dotnet." + } + else { + Write-Log -message "dotnet out of date ($dotNetVersion). Updating dotnet." + } + + $DotnetArguments = @{ Channel=$Channel; Version=$Version; NoSudo=$NoSudo } - if ($dotnetAzureFeed) { - $null = $DotnetArguments.Add("AzureFeed", $dotnetAzureFeed) - $null = $DotnetArguments.Add("FeedCredential", $dotnetAzureFeedSecret) - } + if ($dotnetAzureFeed) { + $null = $DotnetArguments.Add("AzureFeed", $dotnetAzureFeed) + $null = $DotnetArguments.Add("FeedCredential", $dotnetAzureFeedSecret) + } - Install-Dotnet @DotnetArguments - } - else { - Write-Log -message "dotnet is already installed. Skipping installation." + Install-Dotnet @DotnetArguments + } + else { + Write-Log -message "dotnet is already installed. Skipping installation." + } } # Install Windows dependencies if `-Package` or `-BuildWindowsNative` is specified @@ -2402,7 +2407,7 @@ function Start-PSBootstrap { $psInstallFile = [System.IO.Path]::Combine($PSScriptRoot, "tools", "install-powershell.ps1") & $psInstallFile -AddToPath } - if ($Package) { + if ($Scenario -eq 'Both' -or $Scenario -eq 'Package') { Import-Module "$PSScriptRoot\tools\wix\wix.psm1" $isArm64 = "$env:RUNTIME" -eq 'arm64' Install-Wix -arm64:$isArm64 diff --git a/tools/ci.psm1 b/tools/ci.psm1 index f09d159b4c8..317f05effd0 100644 --- a/tools/ci.psm1 +++ b/tools/ci.psm1 @@ -188,8 +188,6 @@ function Invoke-CIInstall } Set-BuildVariable -Name TestPassed -Value False - Write-Verbose -Verbose -Message "Calling Start-PSBootstrap from Invoke-CIInstall" - Start-PSBootstrap } function Invoke-CIxUnit @@ -402,8 +400,6 @@ function New-CodeCoverageAndTestPackage if (Test-DailyBuild) { - Start-PSBootstrap -Verbose - Start-PSBuild -Configuration 'CodeCoverage' -Clean $codeCoverageOutput = Split-Path -Parent (Get-PSOutput) @@ -691,7 +687,7 @@ function Invoke-BootstrapStage Write-Log -Message "Executing ci.psm1 Bootstrap Stage" # Make sure we have all the tags Sync-PSTags -AddRemoteIfMissing - Start-PSBootstrap -Package:$createPackages + Start-PSBootstrap -Scenario Package:$createPackages } # Run pester tests for Linux and macOS diff --git a/tools/packaging/packaging.psm1 b/tools/packaging/packaging.psm1 index 6e88df19dec..43a8d5d8dd4 100644 --- a/tools/packaging/packaging.psm1 +++ b/tools/packaging/packaging.psm1 @@ -1637,7 +1637,7 @@ function Get-PackageDependencies function Test-Dependencies { foreach ($Dependency in "fpm") { - if (!(precheck $Dependency "Package dependency '$Dependency' not found. Run Start-PSBootstrap -Package")) { + if (!(precheck $Dependency "Package dependency '$Dependency' not found. Run Start-PSBootstrap -Scenario Package")) { # These tools are not added to the path automatically on OpenSUSE 13.2 # try adding them to the path and re-tesing first [string] $gemsPath = $null @@ -1647,7 +1647,7 @@ function Test-Dependencies $depenencyPath = Get-ChildItem -Path (Join-Path -Path $gemsPath -ChildPath "gems" -AdditionalChildPath $Dependency) -Recurse | Sort-Object -Property LastWriteTime -Descending | Select-Object -First 1 -ExpandProperty DirectoryName $originalPath = $env:PATH $env:PATH = $ENV:PATH +":" + $depenencyPath - if ((precheck $Dependency "Package dependency '$Dependency' not found. Run Start-PSBootstrap -Package")) { + if ((precheck $Dependency "Package dependency '$Dependency' not found. Run Start-PSBootstrap -Scenario Package")) { continue } else { From 99c93ee38a6417311a9ff9058b2103c15efc8c42 Mon Sep 17 00:00:00 2001 From: PowerShell Team Bot <69177312+pwshBot@users.noreply.github.com> Date: Thu, 10 Apr 2025 13:14:01 -0700 Subject: [PATCH 084/173] [release/v7.5] Migrate MacOS Signing to OneBranch (#25304) Co-authored-by: Justin Chung <124807742+jshigetomi@users.noreply.github.com> Co-authored-by: Justin Chung --- .pipelines/templates/mac-package-build.yml | 59 +++++++++------------- 1 file changed, 23 insertions(+), 36 deletions(-) diff --git a/.pipelines/templates/mac-package-build.yml b/.pipelines/templates/mac-package-build.yml index f009fdae06f..40a6faef06c 100644 --- a/.pipelines/templates/mac-package-build.yml +++ b/.pipelines/templates/mac-package-build.yml @@ -173,56 +173,43 @@ jobs: Get-ChildItem -Path $(Pipeline.Workspace) -Filter "*.zip" -File | Write-Verbose -Verbose displayName: Compress package files for signing - - task: SFP.build-tasks.custom-build-task-1.EsrpCodeSigning@5 - displayName: 'ESRP CodeSigning' + - task: onebranch.pipeline.signing@1 + displayName: 'OneBranch CodeSigning Package' inputs: - ConnectedServiceName: 'ESRPMacOSSigning' - AppRegistrationClientId: '$(AppRegistrationClientId)' - AppRegistrationTenantId: '$(AppRegistrationTenantId)' - AuthAKVName: 'pwsh-CICD-Keyvault' - AuthCertName: 'PS-macos-signing' - AuthSignCertName: 'ESRP-OneCert' # this is not needed for pkg signing - FolderPath: $(Pipeline.Workspace) - Pattern: '*.zip' - signConfigType: inlineSignParams - inlineOperation: | - [{ + command: 'sign' + files_to_sign: '**/*-osx-*.zip' + search_root: '$(Pipeline.Workspace)' + inline_operation: | + [ + { "KeyCode": "$(KeyCode)", - "OperationSetCode": "MacAppDeveloperSign", - "parameters": [ - { - "parameterName": "hardening", - "parameterValue": "enable" - }, - { - "parameterName": "OpusInfo", - "parameterValue": "http://Microsoft.com" - } - ], + "OperationCode": "MacAppDeveloperSign", "ToolName": "sign", - "ToolVersion": "1.0" - }] - SessionTimeout: 90 - ServiceEndpointUrl: '$(ServiceEndpointUrl)' - MaxConcurrency: 25 + "ToolVersion": "1.0", + "Parameters": { + "Hardening": "Enable", + "OpusInfo": "http://microsoft.com" + } + } + ] - pwsh: | $signedPkg = Get-ChildItem -Path $(Pipeline.Workspace) -Filter "*osx*.zip" -File - + $signedPkg | ForEach-Object { Write-Verbose -Verbose "Signed package zip: $_" - + if (-not (Test-Path $_)) { throw "Package not found: $_" } - - if (-not (Test-Path $env:ob_outputDirectory)) { - $null = New-Item -Path $env:ob_outputDirectory -ItemType Directory + + if (-not (Test-Path $(ob_outputDirectory))) { + $null = New-Item -Path $(ob_outputDirectory) -ItemType Directory } - Expand-Archive -Path $_ -DestinationPath $env:ob_outputDirectory -Verbose + Expand-Archive -Path $_ -DestinationPath $(ob_outputDirectory) -Verbose } Write-Verbose -Verbose "Expanded pkg file:" - Get-ChildItem -Path $env:ob_outputDirectory | Write-Verbose -Verbose + Get-ChildItem -Path $(ob_outputDirectory) | Write-Verbose -Verbose displayName: Expand signed file From a4fef36995bbe415218533ba3a997abd92b5820b Mon Sep 17 00:00:00 2001 From: PowerShell Team Bot <69177312+pwshBot@users.noreply.github.com> Date: Thu, 10 Apr 2025 16:20:09 -0700 Subject: [PATCH 085/173] [release/v7.5] Give the pipeline runs meaningful names (#25309) Co-authored-by: Travis Plunk --- .pipelines/PowerShell-Coordinated_Packages-Official.yml | 2 +- .pipelines/PowerShell-Packages-Official.yml | 2 ++ .pipelines/PowerShell-Release-Official-Azure.yml | 2 ++ .pipelines/PowerShell-Release-Official.yml | 2 ++ .pipelines/PowerShell-vPack-Official.yml | 4 ++-- 5 files changed, 9 insertions(+), 3 deletions(-) diff --git a/.pipelines/PowerShell-Coordinated_Packages-Official.yml b/.pipelines/PowerShell-Coordinated_Packages-Official.yml index d478f351252..672674a21b7 100644 --- a/.pipelines/PowerShell-Coordinated_Packages-Official.yml +++ b/.pipelines/PowerShell-Coordinated_Packages-Official.yml @@ -1,4 +1,4 @@ -name: UnifiedPackageBuild-$(Build.BuildId) +name: bins-$(BUILD.SOURCEBRANCHNAME)-$(Build.BuildId) trigger: none parameters: diff --git a/.pipelines/PowerShell-Packages-Official.yml b/.pipelines/PowerShell-Packages-Official.yml index a39b4e866fc..7fce394ca19 100644 --- a/.pipelines/PowerShell-Packages-Official.yml +++ b/.pipelines/PowerShell-Packages-Official.yml @@ -24,6 +24,8 @@ parameters: # parameters are shown up in ADO UI in a build queue time displayName: Skip Signing type: string default: 'NO' + +name: pkgs-$(BUILD.SOURCEBRANCHNAME)-$(Build.BuildId) variables: - name: CDP_DEFINITION_BUILD_COUNT diff --git a/.pipelines/PowerShell-Release-Official-Azure.yml b/.pipelines/PowerShell-Release-Official-Azure.yml index db6b114d901..acba669ffa3 100644 --- a/.pipelines/PowerShell-Release-Official-Azure.yml +++ b/.pipelines/PowerShell-Release-Official-Azure.yml @@ -14,6 +14,8 @@ parameters: # parameters are shown up in ADO UI in a build queue time type: string default: 'NO' +name: ev2-$(BUILD.SOURCEBRANCHNAME)-$(Build.BuildId) + variables: - name: CDP_DEFINITION_BUILD_COUNT value: $[counter('', 0)] diff --git a/.pipelines/PowerShell-Release-Official.yml b/.pipelines/PowerShell-Release-Official.yml index 30c820cabcc..8cda2f5c3b1 100644 --- a/.pipelines/PowerShell-Release-Official.yml +++ b/.pipelines/PowerShell-Release-Official.yml @@ -26,6 +26,8 @@ parameters: # parameters are shown up in ADO UI in a build queue time type: boolean default: false +name: release-$(BUILD.SOURCEBRANCHNAME)-$(Build.BuildId) + variables: - name: CDP_DEFINITION_BUILD_COUNT value: $[counter('', 0)] diff --git a/.pipelines/PowerShell-vPack-Official.yml b/.pipelines/PowerShell-vPack-Official.yml index 33eddc88d0e..6a4ceda5cac 100644 --- a/.pipelines/PowerShell-vPack-Official.yml +++ b/.pipelines/PowerShell-vPack-Official.yml @@ -1,5 +1,3 @@ -name: $(BuildDefinitionName)_$(date:yyMM).$(date:dd)$(rev:rrr) - trigger: none parameters: # parameters are shown up in ADO UI in a build queue time @@ -28,6 +26,8 @@ parameters: # parameters are shown up in ADO UI in a build queue time displayName: 'Release Tag Var:' default: 'fromBranch' +name: vPack_${{ parameters.architecture }}_$(date:yyMM).$(date:dd)$(rev:rrr) + variables: - name: CDP_DEFINITION_BUILD_COUNT value: $[counter('', 0)] From b09675d12024205f6935c3f5666e6488f795c712 Mon Sep 17 00:00:00 2001 From: PowerShell Team Bot <69177312+pwshBot@users.noreply.github.com> Date: Thu, 10 Apr 2025 16:20:37 -0700 Subject: [PATCH 086/173] [release/v7.5] Add Justin Chung as PowerShell team member in `releaseTools.psm1` (#25302) Co-authored-by: Justin Chung <124807742+jshigetomi@users.noreply.github.com> Co-authored-by: Justin Chung --- tools/releaseTools.psm1 | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/releaseTools.psm1 b/tools/releaseTools.psm1 index a50651d8889..71277a1c92e 100644 --- a/tools/releaseTools.psm1 +++ b/tools/releaseTools.psm1 @@ -43,6 +43,7 @@ $Script:powershell_team = @( "Patrick Meinecke" "Steven Bucher" "PowerShell Team Bot" + "Justin Chung" ) # They are very active contributors, so we keep their email-login mappings here to save a few queries to Github. From da482a8f17c4d57ea1e7e1dceba8009eb90e3c38 Mon Sep 17 00:00:00 2001 From: PowerShell Team Bot <69177312+pwshBot@users.noreply.github.com> Date: Thu, 10 Apr 2025 16:31:09 -0700 Subject: [PATCH 087/173] [release/v7.5] Update path filters for Windows CI (#25312) Co-authored-by: Travis Plunk --- .vsts-ci/windows.yml | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/.vsts-ci/windows.yml b/.vsts-ci/windows.yml index ca5352cb4e2..f2f47698ee2 100644 --- a/.vsts-ci/windows.yml +++ b/.vsts-ci/windows.yml @@ -25,22 +25,17 @@ pr: - feature* paths: include: - - '*' + - src/* + - .vsts-ci/windows.yml + - .vsts-ci/templates/* + - test/* + - build.psm1 + - tools/buildCommon/* + - tools/ci.psm1 + - tools/WindowsCI.psm1 exclude: - - .dependabot/config.yml - - .github/ISSUE_TEMPLATE/* - - .github/workflows/* - - .vsts-ci/misc-analysis.yml - - tools/cgmanifest.json - - LICENSE.txt - test/common/markdown/* - - test/perf/* - - tools/packaging/* - - tools/releaseBuild/* - - tools/releaseBuild/azureDevOps/templates/* - - README.md - - .spelling - - .pipelines/* + - test/perf/* variables: GIT_CONFIG_PARAMETERS: "'core.autocrlf=false'" From 33e9d5810404b69bfa327548bc82fd6d0b8ae542 Mon Sep 17 00:00:00 2001 From: PowerShell Team Bot <69177312+pwshBot@users.noreply.github.com> Date: Thu, 10 Apr 2025 16:34:08 -0700 Subject: [PATCH 088/173] [release/v7.5] Fix V-Pack download package name (#25314) Co-authored-by: Justin Chung <124807742+jshigetomi@users.noreply.github.com> Co-authored-by: Justin Chung Co-authored-by: Travis Plunk --- .pipelines/PowerShell-vPack-Official.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pipelines/PowerShell-vPack-Official.yml b/.pipelines/PowerShell-vPack-Official.yml index 6a4ceda5cac..3bf03b89e3f 100644 --- a/.pipelines/PowerShell-vPack-Official.yml +++ b/.pipelines/PowerShell-vPack-Official.yml @@ -138,7 +138,7 @@ extends: installationPath: $(Agent.ToolsDirectory)/dotnet - pwsh: | - $packageArtifactName = 'drop_windows_package_package_${{ parameters.architecture }}' + $packageArtifactName = 'drop_windows_package_package_win_${{ parameters.architecture }}' $vstsCommandString = "vso[task.setvariable variable=PackageArtifactName]$packageArtifactName" Write-Host "sending " + $vstsCommandString Write-Host "##$vstsCommandString" From 9d14d5068a07ac48913f91a586b1b9e7de3208a3 Mon Sep 17 00:00:00 2001 From: PowerShell Team Bot <69177312+pwshBot@users.noreply.github.com> Date: Thu, 10 Apr 2025 16:35:51 -0700 Subject: [PATCH 089/173] [release/v7.5] Add *.props and sort path filters for windows CI (#25316) Co-authored-by: Travis Plunk --- .vsts-ci/windows.yml | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/.vsts-ci/windows.yml b/.vsts-ci/windows.yml index f2f47698ee2..c0f08f54a41 100644 --- a/.vsts-ci/windows.yml +++ b/.vsts-ci/windows.yml @@ -25,17 +25,18 @@ pr: - feature* paths: include: - - src/* - - .vsts-ci/windows.yml - .vsts-ci/templates/* - - test/* + - .vsts-ci/windows.yml + - '*.props' - build.psm1 + - src/* + - test/* - tools/buildCommon/* - tools/ci.psm1 - tools/WindowsCI.psm1 exclude: - test/common/markdown/* - - test/perf/* + - test/perf/* variables: GIT_CONFIG_PARAMETERS: "'core.autocrlf=false'" From 8ee12f6c526594ffeae070defcb16bdc5fe2efc9 Mon Sep 17 00:00:00 2001 From: PowerShell Team Bot <69177312+pwshBot@users.noreply.github.com> Date: Fri, 11 Apr 2025 12:39:54 -0700 Subject: [PATCH 090/173] [release/v7.5] Make sure the vPack pipeline does not produce an empty package (#25320) Co-authored-by: Travis Plunk --- .pipelines/PowerShell-vPack-Official.yml | 25 ++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/.pipelines/PowerShell-vPack-Official.yml b/.pipelines/PowerShell-vPack-Official.yml index 3bf03b89e3f..33c72f8963f 100644 --- a/.pipelines/PowerShell-vPack-Official.yml +++ b/.pipelines/PowerShell-vPack-Official.yml @@ -142,18 +142,27 @@ extends: $vstsCommandString = "vso[task.setvariable variable=PackageArtifactName]$packageArtifactName" Write-Host "sending " + $vstsCommandString Write-Host "##$vstsCommandString" - displayName: 'Set package artifact name' + + $packageArtifactPath = '$(Pipeline.Workspace)\PSPackagesOfficial' + $vstsCommandString = "vso[task.setvariable variable=PackageArtifactPath]$packageArtifactPath" + Write-Host "sending " + $vstsCommandString + Write-Host "##$vstsCommandString" + displayName: 'Set package artifact variables' - download: PSPackagesOfficial artifact: $(PackageArtifactName) displayName: Download package - - pwsh: 'Get-ChildItem $(System.ArtifactsDirectory)\* -recurse | Select-Object -ExpandProperty Name' + - pwsh: 'Get-ChildItem $(PackageArtifactPath)\* -recurse | Select-Object -ExpandProperty Name' displayName: 'Capture Artifact Listing' - pwsh: | $message = @() - Get-ChildItem $(System.ArtifactsDirectory)\* -recurse -include *.zip, *.msi | ForEach-Object { + $packages = Get-ChildItem $(PackageArtifactPath)\* -recurse -include *.zip, *.msi + + if($packages.count -eq 0) {throw "No packages found in $(PackageArtifactPath)"} + + $packages | ForEach-Object { if($_.Name -notmatch 'PowerShell-\d+\.\d+\.\d+\-([a-z]*.\d+\-)?win\-(fxdependent|x64|arm64|x86|fxdependentWinDesktop)\.(msi|zip){1}') { $messageInstance = "$($_.Name) is not a valid package name" @@ -166,7 +175,7 @@ extends: displayName: 'Validate Zip and MSI Package Names' - pwsh: | - Get-ChildItem $(System.ArtifactsDirectory)\* -recurse -include *.zip, *.msi | ForEach-Object { + Get-ChildItem $(PackageArtifactPath)\* -recurse -include *.zip | ForEach-Object { if($_.Name -match 'PowerShell-\d+\.\d+\.\d+\-([a-z]*.\d+\-)?win\-(${{ parameters.architecture }})\.(zip){1}') { Expand-Archive -Path $_.FullName -DestinationPath $(ob_outputDirectory) @@ -197,7 +206,11 @@ extends: - pwsh: | Write-Verbose "VPack Version: $(ob_createvpack_version)" -Verbose - Get-ChildItem -Path $(ob_outputDirectory)\* -Recurse + $vpackFiles = Get-ChildItem -Path $(ob_outputDirectory)\* -Recurse + if($vpackFiles.Count -eq 0) { + throw "No files found in $(ob_outputDirectory)" + } + $vpackFiles displayName: Debug Output Directory and Version condition: succeededOrFailed() @@ -207,5 +220,5 @@ extends: command: 'sign' signing_environment: 'azure-ado' cp_code: $(windows_build_tools_cert_id) - files_to_sign: '**/*.exe;**/*.dll;**/*.ps1;**/*.psm1' + files_to_sign: '**/*.exe;**/System.Management.Automation.dll' search_root: $(ob_outputDirectory) From dc5833b71ab9aa72487985913a27fc76b92658a0 Mon Sep 17 00:00:00 2001 From: PowerShell Team Bot <69177312+pwshBot@users.noreply.github.com> Date: Fri, 11 Apr 2025 13:02:24 -0700 Subject: [PATCH 091/173] [release/v7.5]!!!MERGE_CONFLICT!!! Remove Az module installs and AzureRM uninstalls in pipeline (#25327) Co-authored-by: Justin Chung <124807742+jshigetomi@users.noreply.github.com> Co-authored-by: Travis Plunk --- .pipelines/PowerShell-Packages-Official.yml | 2 +- .../PowerShell-Release-Official-Azure.yml | 2 +- .pipelines/PowerShell-Release-Official.yml | 2 +- .pipelines/templates/checkAzureContainer.yml | 10 -------- .pipelines/templates/compliance/apiscan.yml | 13 ----------- .../templates/compliance/generateNotice.yml | 23 ------------------- .../templates/release-MakeBlobPublic.yml | 22 ------------------ .pipelines/templates/release-create-msix.yml | 3 ++- .../templates/release-upload-buildinfo.yml | 11 --------- .../release-validate-packagenames.yml | 12 ---------- .pipelines/templates/uploadToAzure.yml | 12 ---------- 11 files changed, 5 insertions(+), 107 deletions(-) diff --git a/.pipelines/PowerShell-Packages-Official.yml b/.pipelines/PowerShell-Packages-Official.yml index 7fce394ca19..13fc4cf54be 100644 --- a/.pipelines/PowerShell-Packages-Official.yml +++ b/.pipelines/PowerShell-Packages-Official.yml @@ -64,7 +64,7 @@ variables: resources: pipelines: - pipeline: CoOrdinatedBuildPipeline - source: 'PowerShell-Coordinated Packages-Official' + source: 'PowerShell-Coordinated Binaries-Official' trigger: branches: include: diff --git a/.pipelines/PowerShell-Release-Official-Azure.yml b/.pipelines/PowerShell-Release-Official-Azure.yml index acba669ffa3..2d644c7a5dd 100644 --- a/.pipelines/PowerShell-Release-Official-Azure.yml +++ b/.pipelines/PowerShell-Release-Official-Azure.yml @@ -56,7 +56,7 @@ resources: pipelines: - pipeline: CoOrdinatedBuildPipeline - source: 'PowerShell-Coordinated Packages-Official' + source: 'PowerShell-Coordinated Binaries-Official' - pipeline: PSPackagesOfficial source: 'PowerShell-Packages-Official' diff --git a/.pipelines/PowerShell-Release-Official.yml b/.pipelines/PowerShell-Release-Official.yml index 8cda2f5c3b1..6f7a6b5348a 100644 --- a/.pipelines/PowerShell-Release-Official.yml +++ b/.pipelines/PowerShell-Release-Official.yml @@ -72,7 +72,7 @@ resources: pipelines: - pipeline: CoOrdinatedBuildPipeline - source: 'PowerShell-Coordinated Packages-Official' + source: 'PowerShell-Coordinated Binaries-Official' - pipeline: PSPackagesOfficial source: 'PowerShell-Packages-Official' diff --git a/.pipelines/templates/checkAzureContainer.yml b/.pipelines/templates/checkAzureContainer.yml index a5ce2b1c666..f5e36f38a92 100644 --- a/.pipelines/templates/checkAzureContainer.yml +++ b/.pipelines/templates/checkAzureContainer.yml @@ -51,16 +51,6 @@ jobs: } displayName: 'Check suppress.json' - # Needed as per FAQ here: https://eng.ms/docs/products/onebranch/build/troubleshootingfaqs - - task: PowerShell@2 - displayName: 'Update Az.Storage Module' - inputs: - targetType: 'inline' - script: | - Get-PackageProvider -Name NuGet -ForceBootstrap - Install-Module -Name Az.Storage -Verbose -Force -AllowClobber - Uninstall-AzureRm -Verbose - - task: AzurePowerShell@5 displayName: Check if blob exists and delete if specified inputs: diff --git a/.pipelines/templates/compliance/apiscan.yml b/.pipelines/templates/compliance/apiscan.yml index bfe97827801..4e945b40349 100644 --- a/.pipelines/templates/compliance/apiscan.yml +++ b/.pipelines/templates/compliance/apiscan.yml @@ -78,19 +78,6 @@ jobs: workingDirectory: '$(repoRoot)' retryCountOnTaskFailure: 2 - - pwsh: | - $modules = 'Az.Accounts', 'Az.Storage' - foreach($module in $modules) { - if(!(get-module $module -listavailable)) { - Write-Verbose "installing $module..." -verbose - Install-Module $module -force -AllowClobber - } else { - Write-Verbose "$module already installed." -verbose - } - } - displayName: Install PowerShell modules - workingDirectory: '$(repoRoot)' - - task: AzurePowerShell@5 displayName: Download winverify-private Artifacts inputs: diff --git a/.pipelines/templates/compliance/generateNotice.yml b/.pipelines/templates/compliance/generateNotice.yml index 9a00ed6f01d..b9d489795b1 100644 --- a/.pipelines/templates/compliance/generateNotice.yml +++ b/.pipelines/templates/compliance/generateNotice.yml @@ -95,29 +95,6 @@ jobs: Get-PackageProvider -Name NuGet -ForceBootstrap displayName: Initalize PowerShellGet - - powershell: | - $modules = 'Az.Accounts', 'Az.Storage' - foreach($module in $modules) { - if(!(get-module $module -listavailable)) { - Write-Verbose "installing $module..." -verbose - Install-Module $module -force -AllowClobber - } else { - Write-Verbose "$module already installed." -verbose - #Update-Module $module -verbose - } - } - displayName: Install PowerShell modules - - - powershell: | - if(Get-Command -Name Uninstall-AzureRm -ErrorAction Ignore){ - Write-Verbose "running Uninstall-AzureRm" -verbose - Uninstall-AzureRm - } else { - Write-Verbose "Uninstall-AzureRm not present" -verbose - } - displayName: Uninstall Uninstall-AzureRm - continueOnError: true - - task: AzurePowerShell@5 displayName: Upload Notice inputs: diff --git a/.pipelines/templates/release-MakeBlobPublic.yml b/.pipelines/templates/release-MakeBlobPublic.yml index 84a02c9e0f0..bfa07c9b27f 100644 --- a/.pipelines/templates/release-MakeBlobPublic.yml +++ b/.pipelines/templates/release-MakeBlobPublic.yml @@ -52,17 +52,6 @@ jobs: Get-ChildItem Env: displayName: 'Capture Environment Variables' - - pwsh: | - $azureRmModule = Get-InstalledModule AzureRM -ErrorAction SilentlyContinue -Verbose - if ($azureRmModule) { - Write-Host 'AzureRM module exists. Removing it' - Uninstall-AzureRm - Write-Host 'AzureRM module removed' - } - - Install-Module -Name Az.Storage -Force -AllowClobber -Scope CurrentUser -Verbose - displayName: Remove AzRM modules - - task: AzurePowerShell@5 displayName: Copy blobs to PSInfra storage inputs: @@ -150,17 +139,6 @@ jobs: Get-ChildItem Env: displayName: 'Capture Environment Variables' - - pwsh: | - $azureRmModule = Get-InstalledModule AzureRM -ErrorAction SilentlyContinue -Verbose - if ($azureRmModule) { - Write-Host 'AzureRM module exists. Removing it' - Uninstall-AzureRm - Write-Host 'AzureRM module removed' - } - - Install-Module -Name Az.Storage -Force -AllowClobber -Scope CurrentUser -Verbose - displayName: Remove AzRM modules - - task: AzurePowerShell@5 displayName: Copy blobs to PSInfra storage inputs: diff --git a/.pipelines/templates/release-create-msix.yml b/.pipelines/templates/release-create-msix.yml index 3b1573d9777..90d2acd493b 100644 --- a/.pipelines/templates/release-create-msix.yml +++ b/.pipelines/templates/release-create-msix.yml @@ -27,7 +27,8 @@ jobs: artifact: drop_windows_package_package_win_x86 displayName: Download x86 msix patterns: '**/*.msix' - + + # Finds the makeappx tool on the machine with image: 'onebranch.azurecr.io/windows/ltsc2022/vse2022:latest' - pwsh: | $cmd = Get-Command makeappx.exe -ErrorAction Ignore if ($cmd) { diff --git a/.pipelines/templates/release-upload-buildinfo.yml b/.pipelines/templates/release-upload-buildinfo.yml index ea7b90db8e3..d35630168a0 100644 --- a/.pipelines/templates/release-upload-buildinfo.yml +++ b/.pipelines/templates/release-upload-buildinfo.yml @@ -104,17 +104,6 @@ jobs: } displayName: Create json files - - pwsh: | - $azureRmModule = Get-InstalledModule AzureRM -ErrorAction SilentlyContinue -Verbose - if ($azureRmModule) { - Write-Host 'AzureRM module exists. Removing it' - Uninstall-AzureRm - Write-Host 'AzureRM module removed' - } - - Install-Module -Name Az.Storage -Force -AllowClobber -Scope CurrentUser -Verbose - displayName: Remove AzRM modules - - task: AzurePowerShell@5 displayName: Upload buildjson to blob inputs: diff --git a/.pipelines/templates/release-validate-packagenames.yml b/.pipelines/templates/release-validate-packagenames.yml index 3e2987591aa..1eaf9c070ee 100644 --- a/.pipelines/templates/release-validate-packagenames.yml +++ b/.pipelines/templates/release-validate-packagenames.yml @@ -28,18 +28,6 @@ jobs: Write-Host "##vso[build.updatebuildnumber]$name" displayName: Set Release Name - - pwsh: | - $azureRmModule = Get-InstalledModule AzureRM -ErrorAction SilentlyContinue -Verbose - if ($azureRmModule) { - Write-Host 'AzureRM module exists. Removing it' - Uninstall-AzureRm - Write-Host 'AzureRM module removed' - } - - Install-Module -Name Az.Storage -Force -AllowClobber -Scope CurrentUser -Verbose - - displayName: Remove AzRM modules and install Az.Storage - - task: AzurePowerShell@5 displayName: Upload packages to blob inputs: diff --git a/.pipelines/templates/uploadToAzure.yml b/.pipelines/templates/uploadToAzure.yml index 35a11ec383c..5c0d80ec10f 100644 --- a/.pipelines/templates/uploadToAzure.yml +++ b/.pipelines/templates/uploadToAzure.yml @@ -256,18 +256,6 @@ jobs: New-Item -Path $(Build.ArtifactStagingDirectory)/uploaded -ItemType Directory -Force displayName: Create output directory for packages - - pwsh: | - $azureRmModule = Get-InstalledModule AzureRM -ErrorAction SilentlyContinue -Verbose - if ($azureRmModule) { - Write-Host 'AzureRM module exists. Removing it' - Uninstall-AzureRm - Write-Host 'AzureRM module removed' - } - - Install-Module -Name Az.Storage -Force -AllowClobber -Scope CurrentUser -Verbose - - displayName: Remove AzRM modules - - task: AzurePowerShell@5 displayName: Upload packages to blob inputs: From 7ff28d37381bc77d5f736e5f79a26657571d7b2d Mon Sep 17 00:00:00 2001 From: PowerShell Team Bot <69177312+pwshBot@users.noreply.github.com> Date: Fri, 11 Apr 2025 13:09:10 -0700 Subject: [PATCH 092/173] [release/v7.5] Make Component Manifest Updater use neutral target in addition to RID target (#25325) Co-authored-by: Travis Plunk --- tools/findMissingNotices.ps1 | 63 +++++++++++++++++++++++++++--------- 1 file changed, 47 insertions(+), 16 deletions(-) diff --git a/tools/findMissingNotices.ps1 b/tools/findMissingNotices.ps1 index 490edebb81b..d02f5eedb36 100644 --- a/tools/findMissingNotices.ps1 +++ b/tools/findMissingNotices.ps1 @@ -203,28 +203,34 @@ function Get-CGRegistrations { "alpine-.*" { $folder = $unixProjectName $target = "$dotnetTargetName|$Runtime" + $neutralTarget = "$dotnetTargetName" } "linux-.*" { $folder = $unixProjectName $target = "$dotnetTargetName|$Runtime" + $neutralTarget = "$dotnetTargetName" } "osx-.*" { $folder = $unixProjectName $target = "$dotnetTargetName|$Runtime" + $neutralTarget = "$dotnetTargetName" } "win-x*" { $sdkToUse = $winDesktopSdk $folder = $windowsProjectName $target = "$dotnetTargetNameWin7|$Runtime" + $neutralTarget = "$dotnetTargetNameWin7" } "win-.*" { $folder = $windowsProjectName $target = "$dotnetTargetNameWin7|$Runtime" + $neutralTarget = "$dotnetTargetNameWin7" } "modules" { $folder = "modules" $actualRuntime = 'linux-x64' $target = "$dotnetTargetName|$actualRuntime" + $neutralTarget = "$dotnetTargetName" } Default { throw "Invalid runtime name: $Runtime" @@ -241,6 +247,7 @@ function Get-CGRegistrations { $null = New-PADrive -Path $PSScriptRoot\..\src\$folder\obj\project.assets.json -Name $folder try { $targets = Get-ChildItem -Path "${folder}:/targets/$target" -ErrorAction Stop | Where-Object { $_.Type -eq 'package' } | select-object -ExpandProperty name + $targets += Get-ChildItem -Path "${folder}:/targets/$neutralTarget" -ErrorAction Stop | Where-Object { $_.Type -eq 'project' } | select-object -ExpandProperty name } catch { Get-ChildItem -Path "${folder}:/targets" | Out-String | Write-Verbose -Verbose throw @@ -250,27 +257,51 @@ function Get-CGRegistrations { Get-PSDrive -Name $folder -ErrorAction Ignore | Remove-PSDrive } + # Name to skip for TPN generation + $skipNames = @( + "Microsoft.PowerShell.Native" + "Microsoft.Management.Infrastructure.Runtime.Unix" + "Microsoft.Management.Infrastructure" + "Microsoft.PowerShell.Commands.Diagnostics" + "Microsoft.PowerShell.Commands.Management" + "Microsoft.PowerShell.Commands.Utility" + "Microsoft.PowerShell.ConsoleHost" + "Microsoft.PowerShell.SDK" + "Microsoft.PowerShell.Security" + "Microsoft.Management.Infrastructure.CimCmdlets" + "Microsoft.WSMan.Management" + "Microsoft.WSMan.Runtime" + "System.Management.Automation" + ) + + Write-Verbose "Found $($targets.Count) targets to process..." -Verbose $targets | ForEach-Object { $target = $_ $parts = ($target -split '\|') $name = $parts[0] - $targetVersion = $parts[1] - $publicVersion = Get-NuGetPublicVersion -Name $name -Version $targetVersion - - # Add the registration to the cgmanifest if the TPN does not contain the name of the target OR - # the exisitng CG contains the registration, because if the existing CG contains the registration, - # that might be the only reason it is in the TPN. - if (!$RegistrationTable.ContainsKey($target)) { - $DevelopmentDependency = $false - if (!$existingRegistrationTable.ContainsKey($name) -or $existingRegistrationTable.$name.Component.Version() -ne $publicVersion) { - $registrationChanged = $true - } - if ($existingRegistrationTable.ContainsKey($name) -and $existingRegistrationTable.$name.DevelopmentDependency) { - $DevelopmentDependency = $true - } - $registration = New-NugetComponent -Name $name -Version $publicVersion -DevelopmentDependency:$DevelopmentDependency - $RegistrationTable.Add($target, $registration) + if ($name -in $skipNames) { + Write-Verbose "Skipping $name..." + + } else { + $targetVersion = $parts[1] + $publicVersion = Get-NuGetPublicVersion -Name $name -Version $targetVersion + + # Add the registration to the cgmanifest if the TPN does not contain the name of the target OR + # the exisitng CG contains the registration, because if the existing CG contains the registration, + # that might be the only reason it is in the TPN. + if (!$RegistrationTable.ContainsKey($target)) { + $DevelopmentDependency = $false + if (!$existingRegistrationTable.ContainsKey($name) -or $existingRegistrationTable.$name.Component.Version() -ne $publicVersion) { + $registrationChanged = $true + } + if ($existingRegistrationTable.ContainsKey($name) -and $existingRegistrationTable.$name.DevelopmentDependency) { + $DevelopmentDependency = $true + } + + $registration = New-NugetComponent -Name $name -Version $publicVersion -DevelopmentDependency:$DevelopmentDependency + $RegistrationTable.Add($target, $registration) + } } } From 9b4168119229169db75f087b38072a0ff48c7c57 Mon Sep 17 00:00:00 2001 From: PowerShell Team Bot <69177312+pwshBot@users.noreply.github.com> Date: Fri, 11 Apr 2025 13:24:00 -0700 Subject: [PATCH 093/173] [release/v7.5] Only build Linux for packaging changes (#25326) Co-authored-by: Travis Plunk --- .vsts-ci/linux-internal.yml | 116 ++++++++++++++++++++++++++++++++++++ .vsts-ci/linux.yml | 28 ++++----- 2 files changed, 126 insertions(+), 18 deletions(-) create mode 100644 .vsts-ci/linux-internal.yml diff --git a/.vsts-ci/linux-internal.yml b/.vsts-ci/linux-internal.yml new file mode 100644 index 00000000000..6286a03fb52 --- /dev/null +++ b/.vsts-ci/linux-internal.yml @@ -0,0 +1,116 @@ +# Pipeline to run Linux CI internally +name: PR-$(System.PullRequest.PullRequestNumber)-$(Date:yyyyMMdd)$(Rev:.rr) +trigger: + # Batch merge builds together while a merge build is running + batch: true + branches: + include: + - master + - release* + - feature* + paths: + include: + - '*' + exclude: + - .vsts-ci/misc-analysis.yml + - .github/ISSUE_TEMPLATE/* + - .github/workflows/* + - .dependabot/config.yml + - .pipelines/* + - test/perf/* +pr: + branches: + include: + - master + - release* + - feature* + paths: + include: + - '*' + exclude: + - .dependabot/config.yml + - .github/ISSUE_TEMPLATE/* + - .github/workflows/* + - .vsts-ci/misc-analysis.yml + - .vsts-ci/windows.yml + - .vsts-ci/windows/* + - tools/cgmanifest.json + - LICENSE.txt + - test/common/markdown/* + - test/perf/* + - tools/releaseBuild/* + - tools/install* + - tools/releaseBuild/azureDevOps/templates/* + - README.md + - .spelling + - .pipelines/* + +variables: + DOTNET_CLI_TELEMETRY_OPTOUT: 1 + POWERSHELL_TELEMETRY_OPTOUT: 1 + # Avoid expensive initialization of dotnet cli, see: https://donovanbrown.com/post/Stop-wasting-time-during-NET-Core-builds + DOTNET_SKIP_FIRST_TIME_EXPERIENCE: 1 + __SuppressAnsiEscapeSequences: 1 + nugetMultiFeedWarnLevel: none + +resources: + repositories: + - repository: Docker + type: github + endpoint: PowerShell + name: PowerShell/PowerShell-Docker + ref: master + +stages: +- stage: BuildLinuxStage + displayName: Build for Linux + jobs: + - template: templates/ci-build.yml + parameters: + pool: ubuntu-20.04 + jobName: linux_build + displayName: linux Build + +- stage: TestUbuntu + displayName: Test for Ubuntu + dependsOn: [BuildLinuxStage] + jobs: + - template: templates/nix-test.yml + parameters: + name: Ubuntu + pool: ubuntu-20.04 + purpose: UnelevatedPesterTests + tagSet: CI + + - template: templates/nix-test.yml + parameters: + name: Ubuntu + pool: ubuntu-20.04 + purpose: ElevatedPesterTests + tagSet: CI + + - template: templates/nix-test.yml + parameters: + name: Ubuntu + pool: ubuntu-20.04 + purpose: UnelevatedPesterTests + tagSet: Others + + - template: templates/nix-test.yml + parameters: + name: Ubuntu + pool: ubuntu-20.04 + purpose: ElevatedPesterTests + tagSet: Others + + - template: templates/verify-xunit.yml + parameters: + pool: ubuntu-20.04 + +- stage: PackageLinux + displayName: Package Linux + dependsOn: ["BuildLinuxStage"] + jobs: + - template: linux/templates/packaging.yml + parameters: + pool: ubuntu-20.04 diff --git a/.vsts-ci/linux.yml b/.vsts-ci/linux.yml index b1bb74197a0..338821e37dd 100644 --- a/.vsts-ci/linux.yml +++ b/.vsts-ci/linux.yml @@ -34,24 +34,16 @@ pr: - feature* paths: include: - - '*' - exclude: - - .dependabot/config.yml - - .github/ISSUE_TEMPLATE/* - - .github/workflows/* - - .vsts-ci/misc-analysis.yml - - .vsts-ci/windows.yml - - .vsts-ci/windows/* - - tools/cgmanifest.json - - LICENSE.txt - - test/common/markdown/* - - test/perf/* - - tools/releaseBuild/* - - tools/install* - - tools/releaseBuild/azureDevOps/templates/* - - README.md - - .spelling - - .pipelines/* + - .vsts-ci/linux.yml + - .vsts-ci/linux/templates/packaging.yml + - assets/manpage/* + - build.psm1 + - global.json + - nuget.config + - PowerShell.Common.props + - src/*.csproj + - tools/ci.psm1 + - tools/packaging/* variables: DOTNET_CLI_TELEMETRY_OPTOUT: 1 From c6bb5074a3a38614c521040887f3c2b29e580017 Mon Sep 17 00:00:00 2001 From: PowerShell Team Bot <69177312+pwshBot@users.noreply.github.com> Date: Fri, 11 Apr 2025 13:25:39 -0700 Subject: [PATCH 094/173] [release/v7.5] Check GH token availability for Get-Changelog (#25328) Co-authored-by: Justin Chung <124807742+jshigetomi@users.noreply.github.com> Co-authored-by: Justin Chung Co-authored-by: Travis Plunk --- tools/releaseTools.psm1 | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/tools/releaseTools.psm1 b/tools/releaseTools.psm1 index 71277a1c92e..6207c4be3f7 100644 --- a/tools/releaseTools.psm1 +++ b/tools/releaseTools.psm1 @@ -151,13 +151,20 @@ function Get-ChangeLog [Parameter(Mandatory = $true)] [string]$ThisReleaseTag, - [Parameter(Mandatory)] + [Parameter(Mandatory = $false)] [string]$Token, [Parameter()] [switch]$HasCherryPick ) + if(-not $Token) { + $Token = Get-GHDefaultAuthToken + if(-not $Token) { + throw "No GitHub Auth Token provided" + } + } + $tag_hash = git rev-parse "$LastReleaseTag^0" $format = '%H||%P||%aN||%aE||%s' $header = @{"Authorization"="token $Token"} @@ -361,6 +368,29 @@ function Get-ChangeLog Write-Output "[${version}]: https://github.com/PowerShell/PowerShell/compare/${LastReleaseTag}...${ThisReleaseTag}`n" } +function Get-GHDefaultAuthToken { + $IsGHCLIInstalled = $false + if (Get-command -CommandType Application -Name gh -ErrorAction SilentlyContinue) { + $IsGHCLIInstalled = $true + } else { + Write-Error -Message "GitHub CLI is not installed. Please install it from https://cli.github.com/" -ErrorAction Stop + } + + if ($IsGHCLIInstalled) { + try { + $Token = & gh auth token + } catch { + Write-Error -Message "Please login to GitHub CLI using 'gh auth login'" + } + } + + if (-not $Token) { + $Token = Read-Host -Prompt "Enter GitHub Auth Token" + } + + return $Token +} + function PrintChangeLog($clSection, $sectionTitle, [switch] $Compress) { if ($clSection.Count -gt 0) { "### $sectionTitle`n" From 6781b392276d286e94469bca4c30683d053fab5d Mon Sep 17 00:00:00 2001 From: PowerShell Team Bot <69177312+pwshBot@users.noreply.github.com> Date: Fri, 11 Apr 2025 13:32:19 -0700 Subject: [PATCH 095/173] [release/v7.5] Skip additional packages when generating component manifest (#25329) Co-authored-by: Travis Plunk --- tools/findMissingNotices.ps1 | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/findMissingNotices.ps1 b/tools/findMissingNotices.ps1 index d02f5eedb36..3200bdeeaaf 100644 --- a/tools/findMissingNotices.ps1 +++ b/tools/findMissingNotices.ps1 @@ -272,6 +272,8 @@ function Get-CGRegistrations { "Microsoft.WSMan.Management" "Microsoft.WSMan.Runtime" "System.Management.Automation" + "Microsoft.PowerShell.GraphicalHost" + "Microsoft.PowerShell.CoreCLR.Eventing" ) Write-Verbose "Found $($targets.Count) targets to process..." -Verbose From dc5461e90ef05cd91e69b06edcd6a13c396c479b Mon Sep 17 00:00:00 2001 From: PowerShell Team Bot <69177312+pwshBot@users.noreply.github.com> Date: Fri, 11 Apr 2025 13:34:28 -0700 Subject: [PATCH 096/173] [release/v7.5] Update package pipeline windows image version (#25331) Co-authored-by: Justin Chung <124807742+jshigetomi@users.noreply.github.com> Co-authored-by: Justin Chung Co-authored-by: Travis Plunk --- .pipelines/PowerShell-Packages-Official.yml | 5 ++++- .pipelines/templates/checkAzureContainer.yml | 3 ++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/.pipelines/PowerShell-Packages-Official.yml b/.pipelines/PowerShell-Packages-Official.yml index 13fc4cf54be..30b9e415215 100644 --- a/.pipelines/PowerShell-Packages-Official.yml +++ b/.pipelines/PowerShell-Packages-Official.yml @@ -51,7 +51,7 @@ variables: - name: ob_outputDirectory value: '$(Build.ArtifactStagingDirectory)/ONEBRANCH_ARTIFACT' - name: WindowsContainerImage - value: 'onebranch.azurecr.io/windows/ltsc2019/vse2022:latest' # Docker image which is used to build the project + value: 'onebranch.azurecr.io/windows/ltsc2022/vse2022:latest' # Docker image which is used to build the project - name: LinuxContainerImage value: mcr.microsoft.com/onebranch/cbl-mariner/build:2.0 - group: mscodehub-feed-read-general @@ -83,6 +83,9 @@ extends: cloudvault: enabled: false featureFlags: + WindowsHostVersion: + Version: 2022 + Network: KS3 linuxEsrpSigning: true globalSdl: disableLegacyManifest: true diff --git a/.pipelines/templates/checkAzureContainer.yml b/.pipelines/templates/checkAzureContainer.yml index f5e36f38a92..a6a86214d07 100644 --- a/.pipelines/templates/checkAzureContainer.yml +++ b/.pipelines/templates/checkAzureContainer.yml @@ -56,7 +56,8 @@ jobs: inputs: azureSubscription: az-blob-cicd-infra scriptType: inlineScript - azurePowerShellVersion: latestVersion + azurePowerShellVersion: LatestVersion + pwsh: true inline: | $containersToDelete = @('$(AzureVersion)', '$(AzureVersion)-private', '$(AzureVersion)-nuget', '$(AzureVersion)-gc') From e671bffe56e487c8926ca01ba7ca40c6d77d600f Mon Sep 17 00:00:00 2001 From: PowerShell Team Bot <69177312+pwshBot@users.noreply.github.com> Date: Fri, 11 Apr 2025 13:41:12 -0700 Subject: [PATCH 097/173] [release/v7.5] Simplify PR Template (#25333) Co-authored-by: Travis Plunk Co-authored-by: Dongbo Wang --- .github/PULL_REQUEST_TEMPLATE.md | 18 ++---------------- .github/workflows/markdownLink.yml | 19 +++++++++++++------ .prettierrc | 4 ++++ tools/super-linter/config/super-linter.env | 8 ++++++++ tools/super-linter/super-linter.ps1 | 15 +++++++++++++++ 5 files changed, 42 insertions(+), 22 deletions(-) create mode 100644 .prettierrc create mode 100644 tools/super-linter/config/super-linter.env create mode 100644 tools/super-linter/super-linter.ps1 diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index a3dc6fd5198..27089847987 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -14,8 +14,7 @@ - Use the present tense and imperative mood when describing your changes - [ ] [Summarized changes](https://github.com/PowerShell/PowerShell/blob/master/.github/CONTRIBUTING.md#pull-request---submission) - [ ] [Make sure all `.h`, `.cpp`, `.cs`, `.ps1` and `.psm1` files have the correct copyright header](https://github.com/PowerShell/PowerShell/blob/master/.github/CONTRIBUTING.md#pull-request---submission) -- [ ] This PR is ready to merge and is not [Work in Progress](https://github.com/PowerShell/PowerShell/blob/master/.github/CONTRIBUTING.md#pull-request---work-in-progress). - - If the PR is work in progress, please add the prefix `WIP:` or `[ WIP ]` to the beginning of the title (the `WIP` bot will keep its status check at `Pending` while the prefix is present) and remove the prefix when the PR is ready. +- [ ] This PR is ready to merge. If this PR is a work in progress, please open this as a [Draft Pull Request and mark it as Ready to Review when it is ready to merge](https://docs.github.com/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/about-pull-requests#draft-pull-requests). - **[Breaking changes](https://github.com/PowerShell/PowerShell/blob/master/.github/CONTRIBUTING.md#making-breaking-changes)** - [ ] None - **OR** @@ -25,21 +24,8 @@ - [ ] Not Applicable - **OR** - [ ] [Documentation needed](https://github.com/PowerShell/PowerShell/blob/master/.github/CONTRIBUTING.md#pull-request---submission) - - [ ] Issue filed: + - [ ] Issue filed: - **Testing - New and feature** - [ ] N/A or can only be tested interactively - **OR** - [ ] [Make sure you've added a new test if existing tests do not effectively test the code changed](https://github.com/PowerShell/PowerShell/blob/master/.github/CONTRIBUTING.md#before-submitting) -- **Tooling** - - [ ] I have considered the user experience from a tooling perspective and don't believe tooling will be impacted. - - **OR** - - [ ] I have considered the user experience from a tooling perspective and opened an issue in the relevant tool repository. This may include: - - [ ] Impact on [PowerShell Editor Services](https://github.com/PowerShell/PowerShellEditorServices) which is used in the [PowerShell extension](https://github.com/PowerShell/vscode-powershell) for VSCode - (which runs in a different PS Host). - - [ ] Issue filed: - - [ ] Impact on Completions (both in the console and in editors) - one of PowerShell's most powerful features. - - [ ] Issue filed: - - [ ] Impact on [PSScriptAnalyzer](https://github.com/PowerShell/PSScriptAnalyzer) (which provides linting & formatting in the editor extensions). - - [ ] Issue filed: - - [ ] Impact on [EditorSyntax](https://github.com/PowerShell/EditorSyntax) (which provides syntax highlighting with in VSCode, GitHub, and many other editors). - - [ ] Issue filed: diff --git a/.github/workflows/markdownLink.yml b/.github/workflows/markdownLink.yml index baf668d83d1..950534f1e56 100644 --- a/.github/workflows/markdownLink.yml +++ b/.github/workflows/markdownLink.yml @@ -31,13 +31,20 @@ jobs: # Full git history is needed to get a proper # list of changed files within `super-linter` fetch-depth: 0 + - name: Load super-linter configuration + # Use grep inverse matching to exclude eventual comments in the .env file + # because the GitHub Actions command to set environment variables doesn't + # support comments. + # Ref: https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/workflow-commands-for-github-actions#setting-an-environment-variable + run: grep -v '^#' tools/super-linter/config/super-linter.env >> "$GITHUB_ENV" - name: Lint Markdown uses: super-linter/super-linter@b4515bd4ad9d0aa4681960e053916ab991bdbe96 # v6.8.0 env: - VALIDATE_ALL_CODEBASE: false - DEFAULT_BRANCH: master - FILTER_REGEX_INCLUDE: .*\.md GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - VALIDATE_EDITORCONFIG: false - VALIDATE_JSCPD: false - VALIDATE_CHECKOV: false + - name: Super-Linter correction instructions + if: failure() + uses: actions/github-script@v7.0.1 + with: + script: | + const message = "Super-Linter found issues in the changed files. Please check the logs for details. You can run the linter locally using the command: `./tools/super-lister/super-lister.ps1`."; + core.setFailed(message); diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 00000000000..222861c3415 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,4 @@ +{ + "tabWidth": 2, + "useTabs": false +} diff --git a/tools/super-linter/config/super-linter.env b/tools/super-linter/config/super-linter.env new file mode 100644 index 00000000000..e7324b0feb9 --- /dev/null +++ b/tools/super-linter/config/super-linter.env @@ -0,0 +1,8 @@ +VALIDATE_ALL_CODEBASE=false +DEFAULT_BRANCH=master +FILTER_REGEX_INCLUDE=.*\.md +VALIDATE_EDITORCONFIG=false +VALIDATE_JSCPD=false +VALIDATE_CHECKOV=false +FIX_MARKDOWN_PRETTIER=true +FIX_MARKDOWN=true diff --git a/tools/super-linter/super-linter.ps1 b/tools/super-linter/super-linter.ps1 new file mode 100644 index 00000000000..571ba9c7f8d --- /dev/null +++ b/tools/super-linter/super-linter.ps1 @@ -0,0 +1,15 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + +param( + [string]$RepoRoot = (Join-Path -Path $PSScriptRoot -ChildPath '../..'), + [string]$Platform +) + +$resolvedPath = (Resolve-Path $RepoRoot).ProviderPath +$platformParam = @() +if ($Platform) { + $platformParam = @("--platform", $Platform) +} + +docker run $platformParam -e RUN_LOCAL=true --env-file "$PSScriptRoot/config/super-linter.env" -v "${resolvedPath}:/tmp/lint" ghcr.io/super-linter/super-linter:latest From 8b196aa3edb611210e73e022b590944cb6a34367 Mon Sep 17 00:00:00 2001 From: PowerShell Team Bot <69177312+pwshBot@users.noreply.github.com> Date: Fri, 11 Apr 2025 13:47:19 -0700 Subject: [PATCH 098/173] [release/v7.5] Update CODEOWNERS (#25321) Co-authored-by: Aditya Patwardhan Co-authored-by: Travis Plunk --- .github/CODEOWNERS | 52 ++++++++++++++++++---------------------------- 1 file changed, 20 insertions(+), 32 deletions(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 26e01101693..d4adcefefad 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -6,72 +6,60 @@ # Area: Performance # @adityapatwardhan -# Area: Portability -# @JamesWTruher - # Area: Security -# @TravisEz13 @PaulHigin -src/System.Management.Automation/security/wldpNativeMethods.cs @TravisEz13 @PaulHigin - -# Area: Documentation -.github/ @joeyaiello @TravisEz13 +src/System.Management.Automation/security/wldpNativeMethods.cs @TravisEz13 @seeminglyscience -# Area: Test -# @JamesWTruher @TravisEz13 @adityapatwardhan - -# Area: Cmdlets Core -# @JamesWTruher @SteveL-MSFT @anmenaga +# Area: CI Build +.github/workflows @PowerShell/powershell-maintainers +.github/actions @PowerShell/powershell-maintainers # Now, areas that should have paths or filters, although we might not have them defined # According to the docs, order here must be by precedence of the filter, with later rules overwritting # but the feature seems to make taking a union of all the matching rules. # Area: Cmdlets Management -src/Microsoft.PowerShell.Commands.Management/ @daxian-dbw @adityapatwardhan +# src/Microsoft.PowerShell.Commands.Management/ @daxian-dbw @adityapatwardhan # Area: Utility Cmdlets -src/Microsoft.PowerShell.Commands.Utility/ @JamesWTruher @PaulHigin +# src/Microsoft.PowerShell.Commands.Utility/ # Area: Console -src/Microsoft.PowerShell.ConsoleHost/ @daxian-dbw @anmenaga @TylerLeonhardt - -# Area: Demos -demos/ @joeyaiello @SteveL-MSFT @HemantMahawar +# src/Microsoft.PowerShell.ConsoleHost/ @daxian-dbw # Area: DSC -src/System.Management.Automation/DscSupport @TravisEz13 @SteveL-MSFT +# src/System.Management.Automation/DscSupport @TravisEz13 @SteveL-MSFT # Area: Engine # src/System.Management.Automation/engine @daxian-dbw # Area: Debugging # Must be below engine to override -src/System.Management.Automation/engine/debugger/ @PaulHigin +# src/System.Management.Automation/engine/debugger/ # Area: Help -src/System.Management.Automation/help @adityapatwardhan +src/System.Management.Automation/help @adityapatwardhan @daxian-dbw # Area: Intellisense # @daxian-dbw # Area: Language -src/System.Management.Automation/engine/parser @daxian-dbw +src/System.Management.Automation/engine/parser @daxian-dbw @seeminglyscience # Area: Providers -src/System.Management.Automation/namespaces @anmenaga +# src/System.Management.Automation/namespaces # Area: Remoting -src/System.Management.Automation/engine/remoting @PaulHigin +src/System.Management.Automation/engine/remoting @daxian-dbw @TravisEz13 # Areas: Build # Must be last -*.config @daxian-dbw @TravisEz13 @adityapatwardhan @anmenaga @PaulHigin -*.props @daxian-dbw @TravisEz13 @adityapatwardhan @anmenaga @PaulHigin -*.yml @daxian-dbw @TravisEz13 @adityapatwardhan @anmenaga @PaulHigin -*.csproj @daxian-dbw @TravisEz13 @adityapatwardhan @anmenaga @PaulHigin -build.* @daxian-dbw @TravisEz13 @adityapatwardhan @anmenaga @PaulHigin -tools/ @daxian-dbw @TravisEz13 @adityapatwardhan @anmenaga @PaulHigin -docker/ @daxian-dbw @TravisEz13 @adityapatwardhan @anmenaga @PaulHigin +*.config @PowerShell/powershell-maintainers +*.props @PowerShell/powershell-maintainers +*.yml @PowerShell/powershell-maintainers +*.csproj @PowerShell/powershell-maintainers +build.* @PowerShell/powershell-maintainers +tools/ @PowerShell/powershell-maintainers +# docker/ @PowerShell/powershell-maintainers # Area: Compliance tools/terms @TravisEz13 From 307c0d9c23965420c74846a0d57d7ed16fe8e9f4 Mon Sep 17 00:00:00 2001 From: PowerShell Team Bot <69177312+pwshBot@users.noreply.github.com> Date: Fri, 11 Apr 2025 13:49:15 -0700 Subject: [PATCH 099/173] [release/v7.5] Remove call to NuGet (#25334) Co-authored-by: Justin Chung <124807742+jshigetomi@users.noreply.github.com> Co-authored-by: Justin Chung --- .pipelines/templates/compliance/generateNotice.yml | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/.pipelines/templates/compliance/generateNotice.yml b/.pipelines/templates/compliance/generateNotice.yml index b9d489795b1..7de316e8b49 100644 --- a/.pipelines/templates/compliance/generateNotice.yml +++ b/.pipelines/templates/compliance/generateNotice.yml @@ -84,17 +84,6 @@ jobs: displayName: Capture Notice continueOnError: true - - powershell: | - [System.Net.ServicePointManager]::SecurityProtocol = - [System.Net.ServicePointManager]::SecurityProtocol -bor - [System.Security.Authentication.SslProtocols]::Tls12 -bor - [System.Security.Authentication.SslProtocols]::Tls11 - - Set-ItemProperty -Path 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\.NetFramework\v4.0.30319' -Name 'SchUseStrongCrypto' -Value '1' -Type DWord - Set-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\.NetFramework\v4.0.30319' -Name 'SchUseStrongCrypto' -Value '1' -Type DWord - Get-PackageProvider -Name NuGet -ForceBootstrap - displayName: Initalize PowerShellGet - - task: AzurePowerShell@5 displayName: Upload Notice inputs: From de9f4c8c170a5348ed00f9a9f54eb768035a9764 Mon Sep 17 00:00:00 2001 From: PowerShell Team Bot <69177312+pwshBot@users.noreply.github.com> Date: Fri, 11 Apr 2025 13:59:05 -0700 Subject: [PATCH 100/173] [release/v7.5] Revert "Cleanup old release pipelines (#25201)" (#25335) Co-authored-by: Aditya Patwardhan --- tools/releaseBuild/setReleaseTag.ps1 | 161 +++++++++++++++++++++++++++ tools/releaseBuild/setReleaseTag.sh | 1 + 2 files changed, 162 insertions(+) create mode 100644 tools/releaseBuild/setReleaseTag.ps1 create mode 100644 tools/releaseBuild/setReleaseTag.sh diff --git a/tools/releaseBuild/setReleaseTag.ps1 b/tools/releaseBuild/setReleaseTag.ps1 new file mode 100644 index 00000000000..c5f2f016554 --- /dev/null +++ b/tools/releaseBuild/setReleaseTag.ps1 @@ -0,0 +1,161 @@ +param( + [Parameter(HelpMessage='ReleaseTag from the job. Set to "fromBranch" or $null to update using the branch name')] + [string]$ReleaseTag, + + [Parameter(HelpMessage='The branch name used to update the release tag.')] + [string]$Branch=$env:BUILD_SOURCEBRANCH, + + [Parameter(HelpMessage='The variable name to put the new release tagin.')] + [string]$Variable='ReleaseTag', + + [switch]$CreateJson +) + +function New-BuildInfoJson { + param( + [parameter(Mandatory = $true)] + [string] + $ReleaseTag, + [switch] $IsDaily + ) + + $blobName = $ReleaseTag -replace '\.', '-' + + $isPreview = $ReleaseTag -like '*-*' + + $filename = 'stable.json' + if($isPreview) + { + $filename = 'preview.json' + } + if($IsDaily.IsPresent) + { + $filename = 'daily.json' + } + + ## Get the UTC time and round up to the second. + $dateTime = [datetime]::UtcNow + $dateTime = [datetime]::new($dateTime.Ticks - ($dateTime.Ticks % [timespan]::TicksPerSecond), $dateTime.Kind) + + @{ + ReleaseTag = $ReleaseTag + ReleaseDate = $dateTime + BlobName = $blobName + BaseUrl = 'https://powershellinfraartifacts-gkhedzdeaghdezhr.z01.azurefd.net/install' + } | ConvertTo-Json | Out-File -Encoding ascii -Force -FilePath $filename + + $resolvedPath = (Resolve-Path -Path $filename).ProviderPath + $vstsCommandString = "vso[task.setvariable variable=BuildInfoPath]$resolvedPath" + Write-Verbose -Message "$vstsCommandString" -Verbose + Write-Host -Object "##$vstsCommandString" + + # Upload for ADO pipelines + Write-Host "##vso[artifact.upload containerfolder=BuildInfoJson;artifactname=BuildInfoJson]$resolvedPath" + + # Copy to location where OneBranch Pipelines uploads from + + # if the environment variable does not exist, we are not in OneBranch. So just return. + if (-not $env:ob_outputDirectory) { + return + } + + if (-not (Test-Path $env:ob_outputDirectory)) { + $null = New-Item -Path $env:ob_outputDirectory -ItemType Directory -Force -Verbose + } + + Copy-Item $resolvedPath -Destination $env:ob_outputDirectory -Force -Verbose +} + +# Script to set the release tag based on the branch name if it is not set or it is "fromBranch" +# the branch name is expected to be release- or +# VSTS passes it as 'refs/heads/release-v6.0.2' + +$branchOnly = $Branch -replace '^refs/heads/'; +$branchOnly = $branchOnly -replace '[_\-]' + +$msixType = 'preview' + +$isDaily = $false + +if($ReleaseTag -eq 'fromBranch' -or !$ReleaseTag) +{ + # Branch is named release- + $releaseBranchRegex = '^.*((release/|rebuild/.*rebuild))' + if($Branch -match $releaseBranchRegex) + { + $msixType = 'release' + Write-Verbose "release branch:" -Verbose + $releaseTag = $Branch -replace '^.*((release|rebuild)/)' + $vstsCommandString = "vso[task.setvariable variable=$Variable]$releaseTag" + Write-Verbose -Message "setting $Variable to $releaseTag" -Verbose + Write-Host -Object "##$vstsCommandString" + + if ($CreateJson.IsPresent) + { + New-BuildInfoJson -ReleaseTag $releaseTag + } + } + elseif(($branchOnly -eq 'master' -and $env:BUILD_REASON -ne 'Manual') -or $branchOnly -like '*dailytest*') + { + $isDaily = $true + Write-Verbose "daily build" -Verbose + $jsonPath = "${env:SYSTEM_ARTIFACTSDIRECTORY}\BuildInfoJson\daily.json" + if (test-path -Path $jsonPath) { + Write-Verbose "restoring from buildinfo json..." -Verbose + $buildInfo = Get-Content -Path $jsonPath | ConvertFrom-Json + $releaseTag = $buildInfo.ReleaseTag + } else { + Write-Verbose "creating from branch counter and metadata.json..." -Verbose + $metaDataJsonPath = Join-Path $PSScriptRoot -ChildPath '..\metadata.json' + $metadata = Get-Content $metaDataJsonPath | ConvertFrom-Json + $versionPart = $metadata.PreviewReleaseTag + if ($versionPart -match '-.*$') { + $versionPart = $versionPart -replace '-.*$' + } + + $releaseTag = "$versionPart-daily$((Get-Date).ToString('yyyyMMdd')).$($env:BRANCHCOUNTER)" + } + + $vstsCommandString = "vso[task.setvariable variable=$Variable]$releaseTag" + Write-Verbose -Message "setting $Variable to $releaseTag" -Verbose + Write-Host -Object "##$vstsCommandString" + + if ($CreateJson.IsPresent) + { + New-BuildInfoJson -ReleaseTag $releaseTag -IsDaily + } + } + else + { + Write-Verbose "non-release branch" -Verbose + # Branch is named + # Get version from metadata and append - + $metaDataJsonPath = Join-Path $PSScriptRoot -ChildPath '..\metadata.json' + $metadata = Get-Content $metaDataJsonPath | ConvertFrom-Json + $versionPart = $metadata.PreviewReleaseTag + if($versionPart -match '-.*$') + { + $versionPart = $versionPart -replace '-.*$' + } + + $releaseTag = "$versionPart-$branchOnly" + $vstsCommandString = "vso[task.setvariable variable=$Variable]$releaseTag" + Write-Verbose -Message "setting $Variable to $releaseTag" -Verbose + Write-Host -Object "##$vstsCommandString" + + if ($CreateJson.IsPresent) + { + New-BuildInfoJson -ReleaseTag $releaseTag + } + } +} + +$vstsCommandString = "vso[task.setvariable variable=IS_DAILY]$($isDaily.ToString().ToLowerInvariant())" +Write-Verbose -Message "$vstsCommandString" -Verbose +Write-Host -Object "##$vstsCommandString" + +$vstsCommandString = "vso[task.setvariable variable=MSIX_TYPE]$msixType" +Write-Verbose -Message "$vstsCommandString" -Verbose +Write-Host -Object "##$vstsCommandString" + +Write-Output $releaseTag diff --git a/tools/releaseBuild/setReleaseTag.sh b/tools/releaseBuild/setReleaseTag.sh new file mode 100644 index 00000000000..842ba1e755b --- /dev/null +++ b/tools/releaseBuild/setReleaseTag.sh @@ -0,0 +1 @@ +pwsh -command ".\setReleaseTag.ps1 $*" From 2e0faf7ca31d3bfc56cbcac648d1be6766157001 Mon Sep 17 00:00:00 2001 From: PowerShell Team Bot <69177312+pwshBot@users.noreply.github.com> Date: Fri, 11 Apr 2025 14:02:06 -0700 Subject: [PATCH 101/173] [release/v7.5] Update GitHub Actions to work in private GitHub repo (#25332) Co-authored-by: Travis Plunk --- .github/workflows/AssignPrs.yml | 1 + .github/workflows/createReminders.yml | 2 ++ .github/workflows/labels.yml | 2 +- .github/workflows/linux-ci.yml | 5 +++-- .github/workflows/macos-ci.yml | 5 +++-- .github/workflows/markdownLink.yml | 2 ++ .github/workflows/processReminders.yml | 1 + .github/workflows/scorecards.yml | 1 + .github/workflows/windows-ci.yml | 5 +++-- 9 files changed, 17 insertions(+), 7 deletions(-) diff --git a/.github/workflows/AssignPrs.yml b/.github/workflows/AssignPrs.yml index d398cd7cffe..a01c0bb0950 100644 --- a/.github/workflows/AssignPrs.yml +++ b/.github/workflows/AssignPrs.yml @@ -7,6 +7,7 @@ permissions: jobs: run: + if: github.repository_owner == 'PowerShell' runs-on: ubuntu-latest permissions: issues: write diff --git a/.github/workflows/createReminders.yml b/.github/workflows/createReminders.yml index ef2c5fa1cce..0333b635d59 100644 --- a/.github/workflows/createReminders.yml +++ b/.github/workflows/createReminders.yml @@ -9,6 +9,8 @@ permissions: jobs: reminder: + if: github.repository_owner == 'PowerShell' + permissions: issues: write # for agrc/create-reminder-action to set reminders on issues pull-requests: write # for agrc/create-reminder-action to set reminders on PRs diff --git a/.github/workflows/labels.yml b/.github/workflows/labels.yml index 794ef64b213..fdb0ae4cd77 100644 --- a/.github/workflows/labels.yml +++ b/.github/workflows/labels.yml @@ -13,7 +13,7 @@ permissions: jobs: verify-labels: - if: github.repository_owner == 'PowerShell' + if: startsWith(github.repository_owner, 'azure') || github.repository_owner == 'PowerShell' runs-on: ubuntu-latest steps: diff --git a/.github/workflows/linux-ci.yml b/.github/workflows/linux-ci.yml index 68b651c7e46..d7d76310846 100644 --- a/.github/workflows/linux-ci.yml +++ b/.github/workflows/linux-ci.yml @@ -37,6 +37,7 @@ env: system_debug: 'false' jobs: changes: + if: startsWith(github.repository_owner, 'azure') || github.repository_owner == 'PowerShell' name: Change Detection runs-on: ubuntu-latest # Required permissions @@ -50,7 +51,7 @@ jobs: uses: actions/checkout@v4.1.0 # For pull requests it's not necessary to checkout the code - - uses: dorny/paths-filter@v3 + - uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3.2.0 id: filter with: list-files: json @@ -232,7 +233,7 @@ jobs: - linux_test_unelevated_others - analyze if: always() - uses: PowerShell/compliance/.github/workflows/ready-to-merge.yml@master + uses: PowerShell/compliance/.github/workflows/ready-to-merge.yml@v1.0.0 with: needs_context: ${{ toJson(needs) }} # TODO: Enable this when we have a Linux packaging workflow diff --git a/.github/workflows/macos-ci.yml b/.github/workflows/macos-ci.yml index b414afebfc9..d7d5dc76d0b 100644 --- a/.github/workflows/macos-ci.yml +++ b/.github/workflows/macos-ci.yml @@ -38,6 +38,7 @@ jobs: changes: name: Change Detection runs-on: ubuntu-latest + if: startsWith(github.repository_owner, 'azure') || github.repository_owner == 'PowerShell' # Required permissions permissions: pull-requests: read @@ -49,7 +50,7 @@ jobs: uses: actions/checkout@v4.1.0 # For pull requests it's not necessary to checkout the code - - uses: dorny/paths-filter@v3 + - uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3.2.0 id: filter with: list-files: json @@ -186,6 +187,6 @@ jobs: - macos_test_unelevated_ci - macos_test_unelevated_others if: always() - uses: PowerShell/compliance/.github/workflows/ready-to-merge.yml@master + uses: PowerShell/compliance/.github/workflows/ready-to-merge.yml@v1.0.0 with: needs_context: ${{ toJson(needs) }} diff --git a/.github/workflows/markdownLink.yml b/.github/workflows/markdownLink.yml index 950534f1e56..85b9f51a742 100644 --- a/.github/workflows/markdownLink.yml +++ b/.github/workflows/markdownLink.yml @@ -11,6 +11,8 @@ permissions: jobs: markdown-link-check: runs-on: ubuntu-latest + if: github.repository_owner == 'PowerShell' + steps: - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 - uses: gaurav-nelson/github-action-markdown-link-check@5c5dfc0ac2e225883c0e5f03a85311ec2830d368 # v1 diff --git a/.github/workflows/processReminders.yml b/.github/workflows/processReminders.yml index c6ac936343c..a2d5b4dbd93 100644 --- a/.github/workflows/processReminders.yml +++ b/.github/workflows/processReminders.yml @@ -10,6 +10,7 @@ permissions: jobs: reminder: + if: github.repository_owner == 'PowerShell' permissions: issues: write # for agrc/reminder-action to set reminders on issues pull-requests: write # for agrc/reminder-action to set reminders on PRs diff --git a/.github/workflows/scorecards.yml b/.github/workflows/scorecards.yml index 21430546a1f..90ac8e0b762 100644 --- a/.github/workflows/scorecards.yml +++ b/.github/workflows/scorecards.yml @@ -20,6 +20,7 @@ permissions: read-all jobs: analysis: name: Scorecard analysis + if: github.repository_owner == 'PowerShell' runs-on: ubuntu-latest permissions: # Needed to upload the results to code-scanning dashboard. diff --git a/.github/workflows/windows-ci.yml b/.github/workflows/windows-ci.yml index c93983a765f..9f2aef06a59 100644 --- a/.github/workflows/windows-ci.yml +++ b/.github/workflows/windows-ci.yml @@ -39,6 +39,7 @@ jobs: changes: name: Change Detection runs-on: ubuntu-latest + if: startsWith(github.repository_owner, 'azure') || github.repository_owner == 'PowerShell' # Required permissions permissions: pull-requests: read @@ -50,7 +51,7 @@ jobs: uses: actions/checkout@v4.1.0 # For pull requests it's not necessary to checkout the code - - uses: dorny/paths-filter@v3 + - uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3.2.0 id: filter with: list-files: json @@ -170,6 +171,6 @@ jobs: - windows_test_unelevated_ci - windows_test_unelevated_others if: always() - uses: PowerShell/compliance/.github/workflows/ready-to-merge.yml@master + uses: PowerShell/compliance/.github/workflows/ready-to-merge.yml@v1.0.0 with: needs_context: ${{ toJson(needs) }} From 06782f0a886f6f2da3d1db2012fd80236abc10f7 Mon Sep 17 00:00:00 2001 From: PowerShell Team Bot <69177312+pwshBot@users.noreply.github.com> Date: Fri, 11 Apr 2025 14:04:23 -0700 Subject: [PATCH 102/173] [release/v7.5] Disable SBOM generation on set variables job in release build (#25340) Co-authored-by: Aditya Patwardhan --- .pipelines/PowerShell-Coordinated_Packages-Official.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.pipelines/PowerShell-Coordinated_Packages-Official.yml b/.pipelines/PowerShell-Coordinated_Packages-Official.yml index 672674a21b7..11215302e46 100644 --- a/.pipelines/PowerShell-Coordinated_Packages-Official.yml +++ b/.pipelines/PowerShell-Coordinated_Packages-Official.yml @@ -138,6 +138,8 @@ extends: value: $(Build.SourcesDirectory)\PowerShell\.config\tsaoptions.json - name: ob_signing_setup_enabled value: false + - name: ob_sdl_sbom_enabled + value: false steps: - checkout: self From d390c57b50bbbc1fc9c6ddc982edfaf2cba3a23d Mon Sep 17 00:00:00 2001 From: PowerShell Team Bot <69177312+pwshBot@users.noreply.github.com> Date: Fri, 11 Apr 2025 14:26:34 -0700 Subject: [PATCH 103/173] [release/v7.5] Update security extensions (#25322) Co-authored-by: Travis Plunk --- .../System.Management.Automation.csproj | 2 +- tools/cgmanifest.json | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/System.Management.Automation/System.Management.Automation.csproj b/src/System.Management.Automation/System.Management.Automation.csproj index d0ed69efaaf..ed65de03c1a 100644 --- a/src/System.Management.Automation/System.Management.Automation.csproj +++ b/src/System.Management.Automation/System.Management.Automation.csproj @@ -49,7 +49,7 @@ - + diff --git a/tools/cgmanifest.json b/tools/cgmanifest.json index d73e68035dd..feb4257f1d0 100644 --- a/tools/cgmanifest.json +++ b/tools/cgmanifest.json @@ -1,4 +1,5 @@ { + "$schema": "https://json.schemastore.org/component-detection-manifest.json", "Registrations": [ { "Component": { @@ -175,7 +176,7 @@ "Type": "nuget", "Nuget": { "Name": "Microsoft.Security.Extensions", - "Version": "1.3.0" + "Version": "1.4.0" } }, "DevelopmentDependency": false @@ -900,6 +901,5 @@ }, "DevelopmentDependency": false } - ], - "$schema": "https://json.schemastore.org/component-detection-manifest.json" + ] } From 27d193267a7879dd117d54d50e759d9c901a8aff Mon Sep 17 00:00:00 2001 From: PowerShell Team Bot <69177312+pwshBot@users.noreply.github.com> Date: Fri, 11 Apr 2025 14:46:34 -0700 Subject: [PATCH 104/173] [release/v7.5]Make GitHub Workflows work in the internal mirror (#25342) Co-authored-by: Travis Plunk --- .../infrastructure/path-filters/action.yml | 88 +++++++++++++++++ .github/actions/test/nix/action.yml | 27 +++++- .../test/process-pester-results/action.yml | 64 ++++++------- .github/workflows/linux-ci.yml | 26 ++--- .github/workflows/macos-ci.yml | 23 ++--- .github/workflows/windows-ci.yml | 23 ++--- build.psm1 | 95 ++++++++++++++++++- 7 files changed, 257 insertions(+), 89 deletions(-) create mode 100644 .github/actions/infrastructure/path-filters/action.yml diff --git a/.github/actions/infrastructure/path-filters/action.yml b/.github/actions/infrastructure/path-filters/action.yml new file mode 100644 index 00000000000..58255fab55c --- /dev/null +++ b/.github/actions/infrastructure/path-filters/action.yml @@ -0,0 +1,88 @@ +name: Path Filters +description: 'Path Filters' +inputs: + GITHUB_TOKEN: + description: 'GitHub token' + required: true +outputs: + source: + description: 'Source code changes (composite of all changes)' + value: ${{ steps.filter.outputs.source }} + githubChanged: + description: 'GitHub workflow changes' + value: ${{ steps.filter.outputs.githubChanged }} + toolsChanged: + description: 'Tools changes' + value: ${{ steps.filter.outputs.toolsChanged }} + propsChanged: + description: 'Props changes' + value: ${{ steps.filter.outputs.propsChanged }} + testsChanged: + description: 'Tests changes' + value: ${{ steps.filter.outputs.testsChanged }} + mainSourceChanged: + description: 'Main source code changes (any changes in src/)' + value: ${{ steps.filter.outputs.mainSourceChanged }} + buildModuleChanged: + description: 'Build module changes' + value: ${{ steps.filter.outputs.buildModuleChanged }} +runs: + using: composite + steps: + - name: Check if GitHubWorkflowChanges is present + id: filter + uses: actions/github-script@v7.0.1 + with: + github-token: ${{ inputs.GITHUB_TOKEN }} + script: | + // Fetch the list of files changed in the PR + let files = []; + let page = 1; + let fetchedFiles; + do { + fetchedFiles = await github.rest.pulls.listFiles({ + owner: context.repo.owner, + repo: context.repo.repo, + pull_number: context.issue.number, + per_page: 100, + page: page++ + }); + files = files.concat(fetchedFiles.data); + } while (fetchedFiles.data.length > 0); + + const actionsChanged = files.some(file => file.filename.startsWith('.github/actions')); + const workflowsChanged = files.some(file => file.filename.startsWith('.github/workflows')); + const githubChanged = actionsChanged || workflowsChanged; + + const toolsCiPsm1Changed = files.some(file => file.filename.startsWith('tools/ci.psm1')); + const toolsBuildCommonChanged = files.some(file => file.filename.startsWith('tools/buildCommon/')); + const toolsChanged = toolsCiPsm1Changed || toolsBuildCommonChanged; + + const propsChanged = files.some(file => file.filename.endsWith('.props')); + + const testsChanged = files.some(file => file.filename.startsWith('test/powershell/') || file.filename.startsWith('test/tools/') || file.filename.startsWith('test/xUnit/')); + + const mainSourceChanged = files.some(file => file.filename.startsWith('src/')); + + const buildModuleChanged = files.some(file => file.filename.startsWith('build.psm1')); + + const source = mainSourceChanged || toolsChanged || githubChanged || propsChanged || testsChanged; + + core.setOutput('toolsChanged', toolsChanged); + core.setOutput('githubChanged', githubChanged); + core.setOutput('propsChanged', propsChanged); + core.setOutput('testsChanged', testsChanged); + core.setOutput('mainSourceChanged', mainSourceChanged); + core.setOutput('buildModuleChanged', buildModuleChanged); + core.setOutput('source', source); + + - name: Capture outputs + run: | + Write-Verbose -Verbose "source: ${{ steps.filter.outputs.source }}" + Write-Verbose -Verbose "github: ${{ steps.filter.outputs.githubChanged }}" + Write-Verbose -Verbose "tools: ${{ steps.filter.outputs.toolsChanged }}" + Write-Verbose -Verbose "props: ${{ steps.filter.outputs.propsChanged }}" + Write-Verbose -Verbose "tests: ${{ steps.filter.outputs.testsChanged }}" + Write-Verbose -Verbose "mainSource: ${{ steps.filter.outputs.mainSourceChanged }}" + Write-Verbose -Verbose "buildModule: ${{ steps.filter.outputs.buildModuleChanged }}" + shell: pwsh diff --git a/.github/actions/test/nix/action.yml b/.github/actions/test/nix/action.yml index 03c44a151c7..cf586f894a0 100644 --- a/.github/actions/test/nix/action.yml +++ b/.github/actions/test/nix/action.yml @@ -20,26 +20,39 @@ runs: steps: - name: Capture Environment if: success() || failure() - run: 'Get-ChildItem -Path env: | Out-String -width 9999 -Stream | write-Verbose -Verbose' + run: |- + Import-Module ./build.psm1 + Write-LogGroupStart -Title 'Environment' + Get-ChildItem -Path env: | Out-String -width 9999 -Stream | write-Verbose -Verbose + Write-LogGroupEnd -Title 'Environment' shell: pwsh + - name: Download Build Artifacts uses: actions/download-artifact@v4 with: path: "${{ github.workspace }}" + - name: Capture Artifacts Directory continue-on-error: true - run: Get-ChildItem "${{ github.workspace }}/build/*" -Recurse + run: |- + Import-Module ./build.psm1 + Write-LogGroupStart -Title 'Artifacts Directory' + Get-ChildItem "${{ github.workspace }}/build/*" -Recurse + Write-LogGroupEnd -Title 'Artifacts Directory' shell: pwsh - + - uses: actions/setup-dotnet@v4 with: global-json-file: ./global.json - + - name: Bootstrap shell: pwsh run: |- + Import-Module ./build.psm1 + Write-LogGroupStart -Title 'Bootstrap' Import-Module ./tools/ci.psm1 Invoke-CIInstall -SkipUser + Write-LogGroupEnd -Title 'Bootstrap' - name: Extract Files uses: actions/github-script@v7.0.0 @@ -68,7 +81,11 @@ runs: - name: Capture Extracted Build ZIP continue-on-error: true - run: Get-ChildItem "${{ github.workspace }}/bins/*" -Recurse -ErrorAction SilentlyContinue + run: |- + Import-Module ./build.psm1 + Write-LogGroupStart -Title 'Extracted Build ZIP' + Get-ChildItem "${{ github.workspace }}/bins/*" -Recurse -ErrorAction SilentlyContinue + Write-LogGroupEnd -Title 'Extracted Build ZIP' shell: pwsh - name: Test diff --git a/.github/actions/test/process-pester-results/action.yml b/.github/actions/test/process-pester-results/action.yml index 758bbdfc353..e1072ec08ca 100644 --- a/.github/actions/test/process-pester-results/action.yml +++ b/.github/actions/test/process-pester-results/action.yml @@ -18,36 +18,39 @@ inputs: runs: using: composite steps: - - name: Convert JUnit to CTRF - run: |- + - name: Log Summary + run: | + if (-not $env:GITHUB_STEP_SUMMARY) { + Write-Error "GITHUB_STEP_SUMMARY is not set. Ensure this workflow is running in a GitHub Actions environment." + exit 1 + } + + $testCaseCount = 0 + $testErrorCount = 0 + $testFailureCount = 0 + $testDisabledCount = 0 Get-ChildItem -Path "${{ inputs.testResultsFolder }}/*.xml" -Recurse | ForEach-Object { - npx --yes junit-to-ctrf $_.FullName --output ./${{ inputs.ctrfFolder }}/$($_.BaseName).json --tool Pester + $results = [xml] (get-content $_.FullName) + $testCaseCount += $results.testsuites.tests + $testErrorCount += $results.testsuites.errors + $testFailureCount += $results.testsuites.failures + $testDisabledCount += $results.testsuites.disabled } - shell: pwsh - # this task only takes / as directory separators - - name: Publish Test Report - uses: ctrf-io/github-test-reporter@v1 - with: - report-path: './${{ inputs.ctrfFolder }}/*.json' - exit-on-fail: true - summary-report: true - test-report: false - test-list-report: false - failed-report: false - fail-rate-report: false - flaky-report: false - flaky-rate-report: false - failed-folded-report: true - previous-results-report: false - ai-report: true - skipped-report: false - suite-folded-report: false - suite-list-report: false - pull-request-report: false - commit-report: false - custom-report: false - if: always() + @" + + # Summary of ${{ inputs.name }} + + - Total Tests: $testCaseCount + - Total Errors: $testErrorCount + - Total Failures: $testFailureCount + - Total Disabled: $testDisabledCount + + "@ | Out-File -FilePath $ENV:GITHUB_STEP_SUMMARY -Append + + Write-Host "Summary written to $ENV:GITHUB_STEP_SUMMARY" + Get-Content $ENV:GITHUB_STEP_SUMMARY + shell: pwsh - name: Upload testResults artifact if: always() @@ -55,10 +58,3 @@ runs: with: name: junit-pester-${{ inputs.name }} path: ${{ runner.workspace }}/testResults - - - name: Upload ctrf artifact - if: always() - uses: actions/upload-artifact@v4 - with: - name: ctrf-pester-${{ inputs.name }} - path: ${{ inputs.ctrfFolder }} diff --git a/.github/workflows/linux-ci.yml b/.github/workflows/linux-ci.yml index d7d76310846..eda1ea56167 100644 --- a/.github/workflows/linux-ci.yml +++ b/.github/workflows/linux-ci.yml @@ -9,6 +9,7 @@ on: branches: - master - release/** + - github-mirror paths: - "**" - "!.github/ISSUE_TEMPLATE/**" @@ -19,6 +20,7 @@ on: branches: - master - release/** + - github-mirror # Path filters for PRs need to go into the changes job concurrency: @@ -43,30 +45,22 @@ jobs: # Required permissions permissions: pull-requests: read + contents: read + # Set job outputs to values from filter step outputs: source: ${{ steps.filter.outputs.source }} steps: - name: checkout - uses: actions/checkout@v4.1.0 + uses: actions/checkout@v4 + with: + persist-credentials: false - # For pull requests it's not necessary to checkout the code - - uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3.2.0 + - name: Change Detection id: filter + uses: "./.github/actions/infrastructure/path-filters" with: - list-files: json - filters: .github/action-filters.yml - - - name: Capture outputs - run: | - "source: ${{ steps.filter.outputs.source }}" - "github: ${{ steps.filter.outputs.github }}" - "tools: ${{ steps.filter.outputs.tools }}" - "props: ${{ steps.filter.outputs.props }}" - "tests: ${{ steps.filter.outputs.tests }}" - "mainSource: ${{ steps.filter.outputs.mainSource }}" - "buildModule: ${{ steps.filter.outputs.buildModule }}" - shell: pwsh + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} ci_build: name: Build PowerShell diff --git a/.github/workflows/macos-ci.yml b/.github/workflows/macos-ci.yml index d7d5dc76d0b..9184dc088f0 100644 --- a/.github/workflows/macos-ci.yml +++ b/.github/workflows/macos-ci.yml @@ -7,6 +7,7 @@ on: branches: - master - release/** + - github-mirror paths: - "**" - "!.github/ISSUE_TEMPLATE/**" @@ -17,6 +18,7 @@ on: branches: - master - release/** + - github-mirror # Path filters for PRs need to go into the changes job concurrency: @@ -34,6 +36,7 @@ env: __SuppressAnsiEscapeSequences: 1 nugetMultiFeedWarnLevel: none system_debug: 'false' + jobs: changes: name: Change Detection @@ -42,6 +45,8 @@ jobs: # Required permissions permissions: pull-requests: read + contents: read + # Set job outputs to values from filter step outputs: source: ${{ steps.filter.outputs.source }} @@ -49,23 +54,11 @@ jobs: - name: checkout uses: actions/checkout@v4.1.0 - # For pull requests it's not necessary to checkout the code - - uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3.2.0 + - name: Change Detection id: filter + uses: "./.github/actions/infrastructure/path-filters" with: - list-files: json - filters: .github/action-filters.yml - - - name: Capture outputs - run: | - "source: ${{ steps.filter.outputs.source }}" - "github: ${{ steps.filter.outputs.github }}" - "tools: ${{ steps.filter.outputs.tools }}" - "props: ${{ steps.filter.outputs.props }}" - "tests: ${{ steps.filter.outputs.tests }}" - "mainSource: ${{ steps.filter.outputs.mainSource }}" - "buildModule: ${{ steps.filter.outputs.buildModule }}" - shell: pwsh + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} ci_build: name: Build PowerShell diff --git a/.github/workflows/windows-ci.yml b/.github/workflows/windows-ci.yml index 9f2aef06a59..1e955c78be6 100644 --- a/.github/workflows/windows-ci.yml +++ b/.github/workflows/windows-ci.yml @@ -5,6 +5,7 @@ on: branches: - master - release/** + - github-mirror paths: - "**" - "!.vsts-ci/misc-analysis.yml" @@ -16,6 +17,8 @@ on: branches: - master - release/** + - github-mirror + # Path filters for PRs need to go into the changes job concurrency: @@ -43,6 +46,8 @@ jobs: # Required permissions permissions: pull-requests: read + contents: read + # Set job outputs to values from filter step outputs: source: ${{ steps.filter.outputs.source }} @@ -50,23 +55,11 @@ jobs: - name: checkout uses: actions/checkout@v4.1.0 - # For pull requests it's not necessary to checkout the code - - uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3.2.0 + - name: Change Detection id: filter + uses: "./.github/actions/infrastructure/path-filters" with: - list-files: json - filters: .github/action-filters.yml - - - name: Capture outputs - run: | - "source: ${{ steps.filter.outputs.source }}" - "github: ${{ steps.filter.outputs.github }}" - "tools: ${{ steps.filter.outputs.tools }}" - "props: ${{ steps.filter.outputs.props }}" - "tests: ${{ steps.filter.outputs.tests }}" - "mainSource: ${{ steps.filter.outputs.mainSource }}" - "buildModule: ${{ steps.filter.outputs.buildModule }}" - shell: pwsh + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} ci_build: name: Build PowerShell diff --git a/build.psm1 b/build.psm1 index e882e2f797c..73becb3f0d0 100644 --- a/build.psm1 +++ b/build.psm1 @@ -179,6 +179,8 @@ function Get-EnvironmentInformation $environment += @{'IsUbuntu16' = $environment.IsUbuntu -and $LinuxInfo.VERSION_ID -match '16.04'} $environment += @{'IsUbuntu18' = $environment.IsUbuntu -and $LinuxInfo.VERSION_ID -match '18.04'} $environment += @{'IsUbuntu20' = $environment.IsUbuntu -and $LinuxInfo.VERSION_ID -match '20.04'} + $environment += @{'IsUbuntu22' = $environment.IsUbuntu -and $LinuxInfo.VERSION_ID -match '22.04'} + $environment += @{'IsUbuntu24' = $environment.IsUbuntu -and $LinuxInfo.VERSION_ID -match '24.04'} $environment += @{'IsCentOS' = $LinuxInfo.ID -match 'centos' -and $LinuxInfo.VERSION_ID -match '7'} $environment += @{'IsFedora' = $LinuxInfo.ID -match 'fedora' -and $LinuxInfo.VERSION_ID -ge 24} $environment += @{'IsOpenSUSE' = $LinuxInfo.ID -match 'opensuse'} @@ -2693,6 +2695,10 @@ function script:Write-Log if ($isError) { Write-Host -Foreground Red $message + if($env:GITHUB_WORKFLOW) + { + Write-Host "::error::${message}" + } } else { @@ -2701,6 +2707,59 @@ function script:Write-Log #reset colors for older package to at return to default after error message on a compilation error [console]::ResetColor() } + +function script:Write-LogGroup { + param + ( + [Parameter(Position = 0, Mandatory)] + [ValidateNotNullOrEmpty()] + [string[]] $Message, + [Parameter(Mandatory)] + [string] $Title + ) + + + Write-LogGroupStart -Title $Title + + foreach ($line in $Message) { + Write-Log -Message $line + } + + Write-LogGroupEnd -Title $Title +} + +$script:logGroupColor = [System.ConsoleColor]::Cyan + +function script:Write-LogGroupStart { + param + ( + [Parameter(Mandatory)] + [string] $Title + ) + + if ($env:GITHUB_WORKFLOW) { + Write-Host "::group::${Title}" + } + else { + Write-Host -ForegroundColor $script:logGroupColor "=== BEGIN: $Title ===" + } +} + +function script:Write-LogGroupEnd { + param + ( + [Parameter(Mandatory)] + [string] $Title + ) + + if ($env:GITHUB_WORKFLOW) { + Write-Host "::endgroup::" + } + else { + Write-Host -ForegroundColor $script:logGroupColor "==== END: $Title ====" + } +} + function script:precheck([string]$command, [string]$missedMessage) { $c = Get-Command $command -ErrorAction Ignore if (-not $c) { @@ -3619,22 +3678,50 @@ function Set-PipelineNugetAuthentication { function Set-CorrectLocale { + Write-LogGroupStart -Title "Set-CorrectLocale" + if (-not $IsLinux) { + Write-LogGroupEnd -Title "Set-CorrectLocale" return } $environment = Get-EnvironmentInformation - if ($environment.IsUbuntu -and $environment.IsUbuntu20) - { + if ($environment.IsUbuntu16 -or $environment.IsUbuntu18) { + Write-Verbose -Message "Don't set locale before Ubuntu 20" -Verbose + Write-LogGroupEnd -Title "Set-CorrectLocale" + Write-Locale + return + } + + if ($environment.IsUbuntu) { + Write-Log -Message "Setting locale to en_US.UTF-8" $env:LC_ALL = 'en_US.UTF-8' $env:LANG = 'en_US.UTF-8' sudo locale-gen $env:LANG - sudo update-locale + if ($environment.IsUbuntu20) { + Write-Log -Message "Updating locale for Ubuntu 20" + sudo update-locale + } else { + Write-Log -Message "Updating locale for Ubuntu 22 and newer" + sudo update-locale LANG=$env:LANG LC_ALL=$env:LC_ALL + } + } + + Write-LogGroupEnd -Title "Set-CorrectLocale" + Write-Locale + +} + +function Write-Locale { + if (-not $IsLinux -and -not $IsMacOS) { + Write-Verbose -Message "only supported on Linux and macOS" -Verbose + return } # Output the locale to log it - locale + $localOutput = & locale + Write-LogGroup -Title "Capture Locale" -Message $localOutput } function Install-AzCopy { From 8b7192eab84ce43403cd8323f20b98af16c9185f Mon Sep 17 00:00:00 2001 From: PowerShell Team Bot <69177312+pwshBot@users.noreply.github.com> Date: Fri, 11 Apr 2025 15:38:26 -0700 Subject: [PATCH 105/173] [release/v7.5] Fix MSIX stage in release pipeline (#25345) Co-authored-by: Justin Chung <124807742+jshigetomi@users.noreply.github.com> Co-authored-by: Travis Plunk --- .pipelines/PowerShell-Release-Official.yml | 17 +++++------ .pipelines/templates/release-create-msix.yml | 26 ++++------------- .../release-validate-fxdpackages.yml | 29 +++++++++++++++---- .pipelines/templates/uploadToAzure.yml | 4 +-- 4 files changed, 38 insertions(+), 38 deletions(-) diff --git a/.pipelines/PowerShell-Release-Official.yml b/.pipelines/PowerShell-Release-Official.yml index 6f7a6b5348a..1d986f872d6 100644 --- a/.pipelines/PowerShell-Release-Official.yml +++ b/.pipelines/PowerShell-Release-Official.yml @@ -204,8 +204,10 @@ extends: displayName: 'Validate Linux ARM64 Fxd Packages' jobtype: 'linux' artifactName: 'drop_linux_package_fxdependent' + # this is really an architecture independent package packageNamePattern: '**/*linux-x64-fxdependent.tar.gz' arm64: 'yes' + enableCredScan: false - stage: validatePackages displayName: 'Validate Packages' @@ -333,25 +335,20 @@ extends: displayName: Publish PMC dependsOn: PushGitTagAndMakeDraftPublic jobs: - - template: /.pipelines/templates/release-publish-pmc.yml@self + - template: /.pipelines/templates/approvalJob.yml@self parameters: - skipPublish: ${{ parameters.SkipPMCPublish }} + displayName: Publish to PMC + jobName: ReleaseToPMC + instructions: | + Run PowerShell-Release-Official-Azure.yml pipeline to publish to PMC - stage: ReleaseDocker dependsOn: PushGitTagAndMakeDraftPublic displayName: 'Docker Release' jobs: - - template: /.pipelines/templates/approvalJob.yml@self - parameters: - displayName: Start Docker Build - jobName: StartDockerBuild - instructions: | - Kick off Docker build - - template: /.pipelines/templates/approvalJob.yml@self parameters: displayName: Start Docker Release - dependsOnJob: StartDockerBuild jobName: StartDockerRelease instructions: | Kickoff docker release diff --git a/.pipelines/templates/release-create-msix.yml b/.pipelines/templates/release-create-msix.yml index 90d2acd493b..3714e623b5e 100644 --- a/.pipelines/templates/release-create-msix.yml +++ b/.pipelines/templates/release-create-msix.yml @@ -37,18 +37,16 @@ jobs: } else { $toolsDir = '$(Pipeline.Workspace)\releasePipeline\tools' New-Item $toolsDir -Type Directory -Force > $null - Invoke-RestMethod -Uri '$(makeappUrl)' -OutFile "$toolsDir\makeappx.zip" - Expand-Archive "$toolsDir\makeappx.zip" -DestinationPath "$toolsDir\makeappx" -Force - $exePath = "$toolsDir\makeappx\makeappx.exe" - - Write-Verbose -Verbose 'makeappx was installed:' - Get-ChildItem -Path $toolsDir -Recurse + $makeappx = Get-ChildItem -Recurse 'C:\Program Files (x86)\Windows Kits\10\makeappx.exe' | + Where-Object { $_.DirectoryName -match 'x64' } | + Select-Object -Last 1 + $exePath = $makeappx.FullName + Write-Verbose -Verbose 'makeappx was found:' } - $vstsCommandString = "vso[task.setvariable variable=MakeAppxPath]$exePath" Write-Host "sending " + $vstsCommandString Write-Host "##$vstsCommandString" - displayName: Install makeappx tool + displayName: Find makeappx tool retryCountOnTaskFailure: 1 - pwsh: | @@ -77,18 +75,6 @@ jobs: displayName: Create MsixBundle retryCountOnTaskFailure: 1 - - pwsh: | - $azureRmModule = Get-InstalledModule AzureRM -ErrorAction SilentlyContinue -Verbose - if ($azureRmModule) { - Write-Host 'AzureRM module exists. Removing it' - Uninstall-AzureRm - Write-Host 'AzureRM module removed' - } - - Install-Module -Name Az.Storage -Force -AllowClobber -Scope CurrentUser -Verbose - - displayName: Remove AzRM modules and install Az.Storage - - task: AzurePowerShell@5 displayName: Upload msix to blob inputs: diff --git a/.pipelines/templates/release-validate-fxdpackages.yml b/.pipelines/templates/release-validate-fxdpackages.yml index baf6c431787..53657e6414a 100644 --- a/.pipelines/templates/release-validate-fxdpackages.yml +++ b/.pipelines/templates/release-validate-fxdpackages.yml @@ -1,10 +1,25 @@ parameters: - jobName: "" - displayName: "" - jobtype: "" - artifactName: "" - packageNamePattern: "" - arm64: "no" + - name: jobName + type: string + default: "" + - name: displayName + type: string + default: "" + - name: jobtype + type: string + default: "" + - name: artifactName + type: string + default: "" + - name: packageNamePattern + type: string + default: "" + - name: arm64 + type: string + default: "no" + - name: enableCredScan + type: boolean + default: true jobs: - job: ${{ parameters.jobName }} @@ -19,6 +34,8 @@ jobs: value: $(Build.SourcesDirectory)\PowerShell\.config\suppress.json - name: ob_sdl_tsa_configFile value: $(Build.SourcesDirectory)\PowerShell\.config\tsaoptions.json + - name: ob_sdl_credscan_enabled + value: ${{ parameters.enableCredScan }} pool: type: ${{ parameters.jobtype }} diff --git a/.pipelines/templates/uploadToAzure.yml b/.pipelines/templates/uploadToAzure.yml index 5c0d80ec10f..0994c7ef2b0 100644 --- a/.pipelines/templates/uploadToAzure.yml +++ b/.pipelines/templates/uploadToAzure.yml @@ -6,7 +6,7 @@ jobs: type: windows variables: - name: ob_sdl_sbom_enabled - value: false + value: true - name: runCodesignValidationInjection value: false - name: NugetSecurityAnalysisWarningLevel @@ -241,7 +241,7 @@ jobs: Write-Verbose -Verbose "Creating output directory for GitHub Release files: $(ob_outputDirectory)/GitHubPackages" New-Item -Path $(ob_outputDirectory)/GitHubPackages -ItemType Directory -Force Get-ChildItem -Path "$(Build.ArtifactStagingDirectory)/downloads/*" -Recurse | - Where-Object { $_.Extension -notin '.msix', '.nupkg' } | + Where-Object { $_.Extension -notin '.msix', '.nupkg' -and $_.Name -notmatch '-gc'} | Copy-Item -Destination $(ob_outputDirectory)/GitHubPackages -Recurse -Verbose Write-Verbose -Verbose "Creating output directory for NuGet packages: $(ob_outputDirectory)/NuGetPackages" From 94c401c29c4915327f85f5d7e04bc00fdd7c672a Mon Sep 17 00:00:00 2001 From: PowerShell Team Bot <69177312+pwshBot@users.noreply.github.com> Date: Fri, 11 Apr 2025 15:39:21 -0700 Subject: [PATCH 106/173] [release/v7.5] Do not run labels workflow in the internal repo (#25343) Co-authored-by: Travis Plunk --- .github/workflows/labels.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/labels.yml b/.github/workflows/labels.yml index fdb0ae4cd77..794ef64b213 100644 --- a/.github/workflows/labels.yml +++ b/.github/workflows/labels.yml @@ -13,7 +13,7 @@ permissions: jobs: verify-labels: - if: startsWith(github.repository_owner, 'azure') || github.repository_owner == 'PowerShell' + if: github.repository_owner == 'PowerShell' runs-on: ubuntu-latest steps: From 156dba65a47b79d31e0209fedcb52864e182cfcb Mon Sep 17 00:00:00 2001 From: PowerShell Team Bot <69177312+pwshBot@users.noreply.github.com> Date: Fri, 11 Apr 2025 15:52:08 -0700 Subject: [PATCH 107/173] [release/v7.5] Update test result processing to use NUnitXml format and enhance logging for better clarity (#25344) Co-authored-by: Travis Plunk --- .github/actions/test/nix/action.yml | 2 +- .../test/process-pester-results/action.yml | 37 +--------- .../process-pester-results.ps1 | 68 +++++++++++++++++++ .github/actions/test/windows/action.yml | 20 ++++-- build.psm1 | 57 ++++++++++------ 5 files changed, 125 insertions(+), 59 deletions(-) create mode 100644 .github/actions/test/process-pester-results/process-pester-results.ps1 diff --git a/.github/actions/test/nix/action.yml b/.github/actions/test/nix/action.yml index cf586f894a0..b338c398340 100644 --- a/.github/actions/test/nix/action.yml +++ b/.github/actions/test/nix/action.yml @@ -101,7 +101,7 @@ runs: chmod a+x $pwshPath $options.Output = $pwshPath Set-PSOptions $options - Invoke-CITest -Purpose '${{ inputs.purpose }}' -TagSet '${{ inputs.tagSet }}' -TitlePrefix '${{ inputs.buildName }}' -OutputFormat JUnitXml + Invoke-CITest -Purpose '${{ inputs.purpose }}' -TagSet '${{ inputs.tagSet }}' -TitlePrefix '${{ inputs.buildName }}' -OutputFormat NUnitXml shell: pwsh - name: Convert, Publish, and Upload Pester Test Results diff --git a/.github/actions/test/process-pester-results/action.yml b/.github/actions/test/process-pester-results/action.yml index e1072ec08ca..27b94f6ebcb 100644 --- a/.github/actions/test/process-pester-results/action.yml +++ b/.github/actions/test/process-pester-results/action.yml @@ -10,46 +10,13 @@ inputs: required: false default: "${{ runner.workspace }}/testResults" type: string - ctrfFolder: - required: false - default: ctrf - type: string runs: using: composite steps: - name: Log Summary - run: | - if (-not $env:GITHUB_STEP_SUMMARY) { - Write-Error "GITHUB_STEP_SUMMARY is not set. Ensure this workflow is running in a GitHub Actions environment." - exit 1 - } - - $testCaseCount = 0 - $testErrorCount = 0 - $testFailureCount = 0 - $testDisabledCount = 0 - Get-ChildItem -Path "${{ inputs.testResultsFolder }}/*.xml" -Recurse | ForEach-Object { - $results = [xml] (get-content $_.FullName) - $testCaseCount += $results.testsuites.tests - $testErrorCount += $results.testsuites.errors - $testFailureCount += $results.testsuites.failures - $testDisabledCount += $results.testsuites.disabled - } - - @" - - # Summary of ${{ inputs.name }} - - - Total Tests: $testCaseCount - - Total Errors: $testErrorCount - - Total Failures: $testFailureCount - - Total Disabled: $testDisabledCount - - "@ | Out-File -FilePath $ENV:GITHUB_STEP_SUMMARY -Append - - Write-Host "Summary written to $ENV:GITHUB_STEP_SUMMARY" - Get-Content $ENV:GITHUB_STEP_SUMMARY + run: |- + & "$env:GITHUB_ACTION_PATH/process-pester-results.ps1" -Name '${{ inputs.name }}' -TestResultsFolder '${{ inputs.testResultsFolder }}' shell: pwsh - name: Upload testResults artifact diff --git a/.github/actions/test/process-pester-results/process-pester-results.ps1 b/.github/actions/test/process-pester-results/process-pester-results.ps1 new file mode 100644 index 00000000000..523de3bebaa --- /dev/null +++ b/.github/actions/test/process-pester-results/process-pester-results.ps1 @@ -0,0 +1,68 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + +param( + [parameter(Mandatory)] + [string]$Name, + [parameter(Mandatory)] + [string]$TestResultsFolder +) + +Import-Module "$PSScriptRoot/../../../../build.psm1" + +if (-not $env:GITHUB_STEP_SUMMARY) { + Write-Error "GITHUB_STEP_SUMMARY is not set. Ensure this workflow is running in a GitHub Actions environment." + exit 1 +} + +$testCaseCount = 0 +$testErrorCount = 0 +$testFailureCount = 0 +$testNotRunCount = 0 +$testInconclusiveCount = 0 +$testIgnoredCount = 0 +$testSkippedCount = 0 +$testInvalidCount = 0 + +Get-ChildItem -Path "${TestResultsFolder}/*.xml" -Recurse | ForEach-Object { + $results = [xml] (get-content $_.FullName) + + $testCaseCount += [int]$results.'test-results'.total + $testErrorCount += [int]$results.'test-results'.errors + $testFailureCount += [int]$results.'test-results'.failures + $testNotRunCount += [int]$results.'test-results'.'not-run' + $testInconclusiveCount += [int]$results.'test-results'.inconclusive + $testIgnoredCount += [int]$results.'test-results'.ignored + $testSkippedCount += [int]$results.'test-results'.skipped + $testInvalidCount += [int]$results.'test-results'.invalid +} + +@" + +# Summary of $Name + +- Total Tests: $testCaseCount +- Total Errors: $testErrorCount +- Total Failures: $testFailureCount +- Total Not Run: $testNotRunCount +- Total Inconclusive: $testInconclusiveCount +- Total Ignored: $testIgnoredCount +- Total Skipped: $testSkippedCount +- Total Invalid: $testInvalidCount + +"@ | Out-File -FilePath $ENV:GITHUB_STEP_SUMMARY -Append + +Write-Log "Summary written to $ENV:GITHUB_STEP_SUMMARY" + +Write-LogGroupStart -Title 'Test Results' +Get-Content $ENV:GITHUB_STEP_SUMMARY +Write-LogGroupEnd -Title 'Test Results' + +if ($testErrorCount -gt 0 -or $testFailureCount -gt 0) { + Write-Error "There were $testErrorCount/$testFailureCount errors/failures in the test results." + exit 1 +} +if ($testCaseCount -eq 0) { + Write-Error "No test cases were run." + exit 1 +} diff --git a/.github/actions/test/windows/action.yml b/.github/actions/test/windows/action.yml index d2af55ce5a9..734e30208f0 100644 --- a/.github/actions/test/windows/action.yml +++ b/.github/actions/test/windows/action.yml @@ -20,15 +20,25 @@ runs: steps: - name: Capture Environment if: success() || failure() - run: 'Get-ChildItem -Path env: | Out-String -width 9999 -Stream | write-Verbose -Verbose' + run: |- + Import-Module ./build.psm1 + Write-LogGroupStart -Title 'Environment' + Get-ChildItem -Path env: | Out-String -width 9999 -Stream | write-Verbose -Verbose + Write-LogGroupEnd -Title 'Environment' shell: pwsh + - name: Download Build Artifacts uses: actions/download-artifact@v4 with: path: "${{ github.workspace }}" + - name: Capture Artifacts Directory continue-on-error: true - run: Get-ChildItem "${{ github.workspace }}\build\*" -Recurse + run: |- + Import-Module ./build.psm1 + Write-LogGroupStart -Title 'Artifacts Directory' + Get-ChildItem "${{ github.workspace }}/build/*" -Recurse + Write-LogGroupEnd -Title 'Artifacts Directory' shell: pwsh - uses: actions/setup-dotnet@v4 @@ -38,7 +48,8 @@ runs: - name: Bootstrap shell: powershell run: |- - # Remove "Program Files\dotnet" from the env variable PATH, so old SDKs won't affect us. + Import-Module ./build.psm1 + Write-LogGroupStart -Title 'Bootstrap' Write-Host "Old Path:" Write-Host $env:Path $dotnetPath = Join-Path $env:SystemDrive 'Program Files\dotnet' @@ -49,6 +60,7 @@ runs: # Bootstrap Import-Module .\tools\ci.psm1 Invoke-CIInstall + Write-LogGroupEnd -Title 'Bootstrap' - name: Test if: success() @@ -60,7 +72,7 @@ runs: $path = split-path -path $options.Output $rootPath = split-Path -path $path Expand-Archive -Path '${{ github.workspace }}\build\build.zip' -DestinationPath $rootPath -Force - Invoke-CITest -Purpose '${{ inputs.purpose }}' -TagSet '${{ inputs.tagSet }}' -OutputFormat JUnitXml + Invoke-CITest -Purpose '${{ inputs.purpose }}' -TagSet '${{ inputs.tagSet }}' -OutputFormat NUnitXml shell: pwsh - name: Convert, Publish, and Upload Pester Test Results diff --git a/build.psm1 b/build.psm1 index 73becb3f0d0..b371891d706 100644 --- a/build.psm1 +++ b/build.psm1 @@ -1231,6 +1231,7 @@ function Get-PesterTag { # testing PowerShell remote custom connections. function Publish-CustomConnectionTestModule { + Write-LogGroupStart -Title "Publish-CustomConnectionTestModule" $sourcePath = "${PSScriptRoot}/test/tools/NamedPipeConnection" $outPath = "${PSScriptRoot}/test/tools/NamedPipeConnection/out/Microsoft.PowerShell.NamedPipeConnection" $publishPath = "${PSScriptRoot}/test/tools/Modules" @@ -1255,6 +1256,8 @@ function Publish-CustomConnectionTestModule finally { Pop-Location } + + Write-LogGroupEnd -Title "Publish-CustomConnectionTestModule" } function Publish-PSTestTools { @@ -1264,6 +1267,7 @@ function Publish-PSTestTools { $runtime ) + Write-LogGroupStart -Title "Publish-PSTestTools" Find-Dotnet $tools = @( @@ -1335,6 +1339,7 @@ function Publish-PSTestTools { # Publish the Microsoft.PowerShell.NamedPipeConnection module Publish-CustomConnectionTestModule + Write-LogGroupEnd -Title "Publish-PSTestTools" } function Get-ExperimentalFeatureTests { @@ -1822,12 +1827,16 @@ function Show-PSPesterError throw 'Unknown Show-PSPester parameter set' } - Write-Log -isError -message ("Description: " + $description) - Write-Log -isError -message ("Name: " + $name) - Write-Log -isError -message "message:" - Write-Log -isError -message $message - Write-Log -isError -message "stack-trace:" - Write-Log -isError -message $stack_trace + # Empty line at the end is intentional formatting + Write-Log -isError -message @" +Description: $description +Name: $name +message: +$message +stack-trace: +$stack_trace + +"@ } @@ -1867,13 +1876,17 @@ function Test-XUnitTestResults $message = $failure.failure.message $stack_trace = $failure.failure.'stack-trace' - Write-Log -isError -message ("Description: " + $description) - Write-Log -isError -message ("Name: " + $name) - Write-Log -isError -message "message:" - Write-Log -isError -message $message - Write-Log -isError -message "stack-trace:" - Write-Log -isError -message $stack_trace - Write-Log -isError -message " " + # Empty line at the end is intentional formatting + Write-Log -isError -message @" + Description: $description + Name: $name + message: + $message + stack-trace: + $stack_trace + +"@ + } throw "$($results.assemblies.assembly.failed) tests failed" @@ -1909,7 +1922,8 @@ function Test-PSPesterResults $x = [xml](Get-Content -Raw $testResultsFile) if ([int]$x.'test-results'.failures -gt 0) { - Write-Log -isError -message "TEST FAILURES" + Write-LogGroupStart -Title 'TEST FAILURES' + # switch between methods, SelectNode is not available on dotnet core if ( "System.Xml.XmlDocumentXPathExtensions" -as [Type] ) { @@ -1923,6 +1937,8 @@ function Test-PSPesterResults { Show-PSPesterError -testFailure $testfail } + + Write-LogGroupEnd -Title 'TEST FAILURES' throw "$($x.'test-results'.failures) tests in $TestArea failed" } } @@ -1943,11 +1959,12 @@ function Test-PSPesterResults } elseif ($ResultObject.FailedCount -gt 0) { - Write-Log -isError -message 'TEST FAILURES' + Write-LogGroupStart -Title 'TEST FAILURES' $ResultObject.TestResult | Where-Object {$_.Passed -eq $false} | ForEach-Object { Show-PSPesterError -testFailureObject $_ } + Write-LogGroupEnd -Title 'TEST FAILURES' throw "$($ResultObject.FailedCount) tests in $TestArea failed" } @@ -2694,10 +2711,12 @@ function script:Write-Log ) if ($isError) { - Write-Host -Foreground Red $message - if($env:GITHUB_WORKFLOW) - { - Write-Host "::error::${message}" + if ($env:GITHUB_WORKFLOW) { + # https://github.com/actions/toolkit/issues/193#issuecomment-605394935 + $escapedMessage = $message -replace "`n", "%0A" -replace "`r" + Write-Host "::error::${escapedMessage}" + } else { + Write-Host -Foreground Red $message } } else From b6f02c3cc1d05b7c6a37308a70c75644b476ea2a Mon Sep 17 00:00:00 2001 From: PowerShell Team Bot <69177312+pwshBot@users.noreply.github.com> Date: Fri, 11 Apr 2025 16:03:58 -0700 Subject: [PATCH 108/173] [release/v7.5] Fallback to AppLocker after `WldpCanExecuteFile` (#25305) Co-authored-by: Patrick Meinecke Co-authored-by: Travis Plunk --- .../security/wldpNativeMethods.cs | 197 ++++++++++-------- 1 file changed, 114 insertions(+), 83 deletions(-) diff --git a/src/System.Management.Automation/security/wldpNativeMethods.cs b/src/System.Management.Automation/security/wldpNativeMethods.cs index a59f37c0a8f..ab49f927614 100644 --- a/src/System.Management.Automation/security/wldpNativeMethods.cs +++ b/src/System.Management.Automation/security/wldpNativeMethods.cs @@ -6,6 +6,7 @@ // #if !UNIX +using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Management.Automation.Internal; using System.Management.Automation.Runspaces; @@ -148,7 +149,7 @@ public static SystemEnforcementMode GetSystemLockdownPolicy() { lock (s_systemLockdownPolicyLock) { - s_systemLockdownPolicy = GetDebugLockdownPolicy(path: null); + s_systemLockdownPolicy = GetDebugLockdownPolicy(path: null, out _); } } @@ -172,93 +173,89 @@ public static SystemScriptFileEnforcement GetFilePolicyEnforcement( System.IO.FileStream fileStream) { SafeHandle fileHandle = fileStream.SafeFileHandle; - var systemLockdownPolicy = SystemPolicy.GetSystemLockdownPolicy(); + SystemEnforcementMode systemLockdownPolicy = GetSystemLockdownPolicy(); // First check latest WDAC APIs if available. - // Revert to legacy APIs if system policy is in AUDIT mode or debug hook is in effect. - Exception errorException = null; - if (s_wldpCanExecuteAvailable && systemLockdownPolicy == SystemEnforcementMode.Enforce) + if (systemLockdownPolicy is SystemEnforcementMode.Enforce + && s_wldpCanExecuteAvailable + && TryGetWldpCanExecuteFileResult(filePath, fileHandle, out SystemScriptFileEnforcement wldpFilePolicy)) { - try - { - string fileName = System.IO.Path.GetFileNameWithoutExtension(filePath); - string auditMsg = $"PowerShell ExternalScriptInfo reading file: {fileName}"; + return GetLockdownPolicy(filePath, fileHandle, wldpFilePolicy); + } - int hr = WldpNativeMethods.WldpCanExecuteFile( - host: PowerShellHost, - options: WLDP_EXECUTION_EVALUATION_OPTIONS.WLDP_EXECUTION_EVALUATION_OPTION_NONE, - fileHandle: fileHandle.DangerousGetHandle(), - auditInfo: auditMsg, - result: out WLDP_EXECUTION_POLICY canExecuteResult); + // Failed to invoke WldpCanExecuteFile, revert to legacy APIs. + if (systemLockdownPolicy is SystemEnforcementMode.None) + { + return SystemScriptFileEnforcement.None; + } - PSEtwLog.LogWDACQueryEvent("WldpCanExecuteFile", filePath, hr, (int)canExecuteResult); + // WldpCanExecuteFile was invoked successfully so we can skip running + // legacy WDAC APIs. AppLocker must still be checked in case it is more + // strict than the current WDAC policy. + return GetLockdownPolicy(filePath, fileHandle, canExecuteResult: null); + } - if (hr >= 0) - { - switch (canExecuteResult) - { - case WLDP_EXECUTION_POLICY.WLDP_CAN_EXECUTE_ALLOWED: - return SystemScriptFileEnforcement.Allow; + private static SystemScriptFileEnforcement ConvertToModernFileEnforcement(SystemEnforcementMode legacyMode) + { + return legacyMode switch + { + SystemEnforcementMode.None => SystemScriptFileEnforcement.Allow, + SystemEnforcementMode.Audit => SystemScriptFileEnforcement.AllowConstrainedAudit, + SystemEnforcementMode.Enforce => SystemScriptFileEnforcement.AllowConstrained, + _ => SystemScriptFileEnforcement.Block, + }; + } - case WLDP_EXECUTION_POLICY.WLDP_CAN_EXECUTE_BLOCKED: - return SystemScriptFileEnforcement.Block; + private static bool TryGetWldpCanExecuteFileResult(string filePath, SafeHandle fileHandle, out SystemScriptFileEnforcement result) + { + try + { + string fileName = System.IO.Path.GetFileNameWithoutExtension(filePath); + string auditMsg = $"PowerShell ExternalScriptInfo reading file: {fileName}"; - case WLDP_EXECUTION_POLICY.WLDP_CAN_EXECUTE_REQUIRE_SANDBOX: - return SystemScriptFileEnforcement.AllowConstrained; + int hr = WldpNativeMethods.WldpCanExecuteFile( + host: PowerShellHost, + options: WLDP_EXECUTION_EVALUATION_OPTIONS.WLDP_EXECUTION_EVALUATION_OPTION_NONE, + fileHandle: fileHandle.DangerousGetHandle(), + auditInfo: auditMsg, + result: out WLDP_EXECUTION_POLICY canExecuteResult); - default: - // Fall through to legacy system policy checks. - System.Diagnostics.Debug.Assert(false, $"Unknown execution policy returned from WldCanExecute: {canExecuteResult}"); - break; - } - } + PSEtwLog.LogWDACQueryEvent("WldpCanExecuteFile", filePath, hr, (int)canExecuteResult); - // If HResult is unsuccessful (such as E_NOTIMPL (0x80004001)), fall through to legacy system checks. - } - catch (DllNotFoundException ex) - { - // Fall back to legacy system policy checks. - s_wldpCanExecuteAvailable = false; - errorException = ex; - } - catch (EntryPointNotFoundException ex) + if (hr >= 0) { - // Fall back to legacy system policy checks. - s_wldpCanExecuteAvailable = false; - errorException = ex; + switch (canExecuteResult) + { + case WLDP_EXECUTION_POLICY.WLDP_CAN_EXECUTE_ALLOWED: + result = SystemScriptFileEnforcement.Allow; + return true; + + case WLDP_EXECUTION_POLICY.WLDP_CAN_EXECUTE_BLOCKED: + result = SystemScriptFileEnforcement.Block; + return true; + + case WLDP_EXECUTION_POLICY.WLDP_CAN_EXECUTE_REQUIRE_SANDBOX: + result = SystemScriptFileEnforcement.AllowConstrained; + return true; + + default: + // Fall through to legacy system policy checks. + Debug.Assert(false, $"Unknown policy result returned from WldCanExecute: {canExecuteResult}"); + break; + } } - if (errorException != null) - { - PSEtwLog.LogWDACQueryEvent("WldpCanExecuteFile_Failed", filePath, errorException.HResult, 0); - } + // If HResult is unsuccessful (such as E_NOTIMPL (0x80004001)), fall through to legacy system checks. } - - // Original (legacy) WDAC and AppLocker system checks. - if (systemLockdownPolicy == SystemEnforcementMode.None) + catch (Exception ex) when (ex is DllNotFoundException or EntryPointNotFoundException) { - return SystemScriptFileEnforcement.None; + // Fall back to legacy system policy checks. + s_wldpCanExecuteAvailable = false; + PSEtwLog.LogWDACQueryEvent("WldpCanExecuteFile_Failed", filePath, ex.HResult, 0); } - // Check policy for file. - switch (SystemPolicy.GetLockdownPolicy(filePath, fileHandle)) - { - case SystemEnforcementMode.Enforce: - // File is not allowed by policy enforcement and must run in CL mode. - return SystemScriptFileEnforcement.AllowConstrained; - - case SystemEnforcementMode.Audit: - // File is allowed but would be run in CL mode if policy was enforced and not audit. - return SystemScriptFileEnforcement.AllowConstrainedAudit; - - case SystemEnforcementMode.None: - // No restrictions, file will run in FL mode. - return SystemScriptFileEnforcement.Allow; - - default: - System.Diagnostics.Debug.Assert(false, "GetFilePolicyEnforcement: Unknown SystemEnforcementMode."); - return SystemScriptFileEnforcement.Block; - } + result = default; + return false; } /// @@ -267,9 +264,32 @@ public static SystemScriptFileEnforcement GetFilePolicyEnforcement( /// An EnforcementMode that describes policy. public static SystemEnforcementMode GetLockdownPolicy(string path, SafeHandle handle) { + SystemScriptFileEnforcement modernMode = GetLockdownPolicy(path, handle, canExecuteResult: null); + Debug.Assert( + modernMode is not SystemScriptFileEnforcement.Block, + "Block should never be converted to legacy file enforcement."); + + return modernMode switch + { + SystemScriptFileEnforcement.Block => SystemEnforcementMode.Enforce, + SystemScriptFileEnforcement.AllowConstrained => SystemEnforcementMode.Enforce, + SystemScriptFileEnforcement.AllowConstrainedAudit => SystemEnforcementMode.Audit, + SystemScriptFileEnforcement.Allow => SystemEnforcementMode.None, + SystemScriptFileEnforcement.None => SystemEnforcementMode.None, + _ => throw new ArgumentOutOfRangeException(nameof(modernMode)), + }; + } + + private static SystemScriptFileEnforcement GetLockdownPolicy( + string path, + SafeHandle handle, + SystemScriptFileEnforcement? canExecuteResult) + { + SystemScriptFileEnforcement wldpFilePolicy = canExecuteResult + ?? ConvertToModernFileEnforcement(GetWldpPolicy(path, handle)); + // Check the WLDP File policy via API - var wldpFilePolicy = GetWldpPolicy(path, handle); - if (wldpFilePolicy == SystemEnforcementMode.Enforce) + if (wldpFilePolicy is SystemScriptFileEnforcement.Block or SystemScriptFileEnforcement.AllowConstrained) { return wldpFilePolicy; } @@ -281,29 +301,28 @@ public static SystemEnforcementMode GetLockdownPolicy(string path, SafeHandle ha var appLockerFilePolicy = GetAppLockerPolicy(path, handle); if (appLockerFilePolicy == SystemEnforcementMode.Enforce) { - return appLockerFilePolicy; + return ConvertToModernFileEnforcement(appLockerFilePolicy); } // At this point, LockdownPolicy = Audit or Allowed. // If there was a WLDP policy, but WLDP didn't block it, // then it was explicitly allowed. Therefore, return the result for the file. - SystemEnforcementMode systemWldpPolicy = s_cachedWldpSystemPolicy.GetValueOrDefault(SystemEnforcementMode.None); - if ((systemWldpPolicy == SystemEnforcementMode.Audit) || - (systemWldpPolicy == SystemEnforcementMode.Enforce)) + if (s_cachedWldpSystemPolicy is SystemEnforcementMode.Audit or SystemEnforcementMode.Enforce + || wldpFilePolicy is SystemScriptFileEnforcement.AllowConstrainedAudit) { return wldpFilePolicy; } // If there was a system-wide AppLocker policy, but AppLocker didn't block it, // then return AppLocker's status. - if (s_cachedSaferSystemPolicy.GetValueOrDefault(SaferPolicy.Allowed) == - SaferPolicy.Disallowed) + if (s_cachedSaferSystemPolicy is SaferPolicy.Disallowed) { - return appLockerFilePolicy; + return ConvertToModernFileEnforcement(appLockerFilePolicy); } // If it's not set to 'Enforce' by the platform, allow debug overrides - return GetDebugLockdownPolicy(path); + GetDebugLockdownPolicy(path, out SystemScriptFileEnforcement debugPolicy); + return debugPolicy; } [SuppressMessage("Microsoft.Reliability", "CA2001:AvoidCallingProblematicMethods", @@ -558,7 +577,7 @@ private static SaferPolicy TestSaferPolicy(string testPathScript, string testPat return result; } - private static SystemEnforcementMode GetDebugLockdownPolicy(string path) + private static SystemEnforcementMode GetDebugLockdownPolicy(string path, out SystemScriptFileEnforcement modernEnforcement) { s_allowDebugOverridePolicy = true; @@ -569,10 +588,19 @@ private static SystemEnforcementMode GetDebugLockdownPolicy(string path) // check so that we can actually put it in the filename during testing. if (path.Contains("System32", StringComparison.OrdinalIgnoreCase)) { + modernEnforcement = SystemScriptFileEnforcement.Allow; return SystemEnforcementMode.None; } // No explicit debug allowance for the file, so return the system policy if there is one. + modernEnforcement = s_systemLockdownPolicy switch + { + SystemEnforcementMode.Enforce => SystemScriptFileEnforcement.AllowConstrained, + SystemEnforcementMode.Audit => SystemScriptFileEnforcement.AllowConstrainedAudit, + SystemEnforcementMode.None => SystemScriptFileEnforcement.None, + _ => SystemScriptFileEnforcement.None, + }; + return s_systemLockdownPolicy.GetValueOrDefault(SystemEnforcementMode.None); } @@ -582,10 +610,13 @@ private static SystemEnforcementMode GetDebugLockdownPolicy(string path) if (result != null) { pdwLockdownState = LanguagePrimitives.ConvertTo(result); - return GetLockdownPolicyForResult(pdwLockdownState); + SystemEnforcementMode policy = GetLockdownPolicyForResult(pdwLockdownState); + modernEnforcement = ConvertToModernFileEnforcement(policy); + return policy; } // If the system-wide debug policy had no preference, then there is no enforcement. + modernEnforcement = SystemScriptFileEnforcement.None; return SystemEnforcementMode.None; } From e07cc52056ca367e3d6231ec91ca868be0ffd303 Mon Sep 17 00:00:00 2001 From: PowerShell Team Bot <69177312+pwshBot@users.noreply.github.com> Date: Wed, 16 Apr 2025 15:12:35 -0700 Subject: [PATCH 109/173] [release/v7.5] Add Windows Store Signing to MSIX bundle (#25370) Co-authored-by: Justin Chung <124807742+jshigetomi@users.noreply.github.com> Co-authored-by: Justin Chung --- .pipelines/PowerShell-Release-Official.yml | 1 + .pipelines/templates/release-create-msix.yml | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/.pipelines/PowerShell-Release-Official.yml b/.pipelines/PowerShell-Release-Official.yml index 1d986f872d6..bbbf7d86454 100644 --- a/.pipelines/PowerShell-Release-Official.yml +++ b/.pipelines/PowerShell-Release-Official.yml @@ -58,6 +58,7 @@ variables: - name: ReleaseTagVar value: ${{ parameters.ReleaseTagVar }} - group: PoolNames + - group: MSIXSigningProfile resources: repositories: diff --git a/.pipelines/templates/release-create-msix.yml b/.pipelines/templates/release-create-msix.yml index 3714e623b5e..751ce1ec5e2 100644 --- a/.pipelines/templates/release-create-msix.yml +++ b/.pipelines/templates/release-create-msix.yml @@ -75,6 +75,24 @@ jobs: displayName: Create MsixBundle retryCountOnTaskFailure: 1 + - task: onebranch.pipeline.signing@1 + displayName: Sign MsixBundle + inputs: + command: 'sign' + signing_profile: $(MSIXProfile) + files_to_sign: '**/*.msixbundle' + search_root: '$(BundleDir)' + + - pwsh: | + $signedBundle = Get-ChildItem -Path $(BundleDir) -Filter "*.msixbundle" -File + Write-Verbose -Verbose "Signed bundle: $signedBundle" + + Copy-Item -Path $signedBundle -Destination $(ob_outputDirectory) -Verbose + + Write-Verbose -Verbose "Uploaded Bundle:" + Get-ChildItem -Path $(ob_outputDirectory) | Write-Verbose -Verbose + displayName: Upload msixbundle to Artifacts + - task: AzurePowerShell@5 displayName: Upload msix to blob inputs: From 06334ccf772fe18ec4faa754394c71b3b75354e2 Mon Sep 17 00:00:00 2001 From: PowerShell Team Bot <69177312+pwshBot@users.noreply.github.com> Date: Wed, 16 Apr 2025 15:13:06 -0700 Subject: [PATCH 110/173] [release/v7.5] Combine GitHub and Nuget Release Stage (#25371) Co-authored-by: Justin Chung <124807742+jshigetomi@users.noreply.github.com> --- .pipelines/PowerShell-Release-Official.yml | 43 ++++---------- ...ithubtasks.yml => release-githubNuget.yml} | 58 +++++++++++++++++++ .../templates/release-publish-nuget.yml | 58 ------------------- 3 files changed, 68 insertions(+), 91 deletions(-) rename .pipelines/templates/{release-githubtasks.yml => release-githubNuget.yml} (61%) delete mode 100644 .pipelines/templates/release-publish-nuget.yml diff --git a/.pipelines/PowerShell-Release-Official.yml b/.pipelines/PowerShell-Release-Official.yml index bbbf7d86454..46a6926fd7a 100644 --- a/.pipelines/PowerShell-Release-Official.yml +++ b/.pipelines/PowerShell-Release-Official.yml @@ -17,8 +17,8 @@ parameters: # parameters are shown up in ADO UI in a build queue time displayName: Skip Signing type: string default: 'NO' - - name: SkipPMCPublish - displayName: Skip PMC Publish + - name: SkipPublish + displayName: Skip Publishing to GitHub and Nuget type: boolean default: false - name: SkipPSInfraInstallers @@ -281,19 +281,21 @@ extends: Update and merge the changelog for the release. This step is required for creating GitHub draft release. - - stage: PublishGitHubRelease - displayName: Publish GitHub Release - dependsOn: + - stage: PublishGitHubReleaseAndNuget + displayName: Publish GitHub and Nuget Release + dependsOn: - setReleaseTagAndUploadTools - UpdateChangeLog variables: ob_release_environment: Production jobs: - - template: /.pipelines/templates/release-githubtasks.yml@self + - template: /.pipelines/templates/release-githubNuget.yml@self + parameters: + skipPublish: ${{ parameters.SkipPublish }} - stage: PushGitTagAndMakeDraftPublic displayName: Push Git Tag and Make Draft Public - dependsOn: PublishGitHubRelease + dependsOn: PublishGitHubReleaseAndNuget jobs: - template: /.pipelines/templates/approvalJob.yml@self parameters: @@ -320,18 +322,6 @@ extends: parameters: SkipPSInfraInstallers: ${{ parameters.SkipPSInfraInstallers }} - - stage: PublishNuGet - displayName: Publish NuGet - dependsOn: - - setReleaseTagAndUploadTools - - PushGitTagAndMakeDraftPublic - variables: - ob_release_environment: Production - jobs: - - template: /.pipelines/templates/release-publish-nuget.yml@self - parameters: - skipPublish: true - - stage: PublishPMC displayName: Publish PMC dependsOn: PushGitTagAndMakeDraftPublic @@ -423,8 +413,7 @@ extends: - stage: ChangesToMaster displayName: Ensure changes are in GH master - dependsOn: - - PublishNuGet + dependsOn: - PublishPMC jobs: - template: /.pipelines/templates/approvalJob.yml@self @@ -434,17 +423,6 @@ extends: instructions: | Make sure that changes README.md and metadata.json are merged into master on GitHub. - - stage: ReleaseSnap - displayName: Release Snap - dependsOn: ChangesToMaster - jobs: - - template: /.pipelines/templates/approvalJob.yml@self - parameters: - displayName: Publish Snap - jobName: PublishSnapJob - instructions: | - Publish Snap - - stage: ReleaseToMU displayName: Release to MU dependsOn: PushGitTagAndMakeDraftPublic # This only needs the blob to be available @@ -460,7 +438,6 @@ extends: dependsOn: - ReleaseToMU - ReleaseSymbols - - ReleaseSnap jobs: - template: /.pipelines/templates/approvalJob.yml@self parameters: diff --git a/.pipelines/templates/release-githubtasks.yml b/.pipelines/templates/release-githubNuget.yml similarity index 61% rename from .pipelines/templates/release-githubtasks.yml rename to .pipelines/templates/release-githubNuget.yml index 31e66b793a4..2d76c13dc99 100644 --- a/.pipelines/templates/release-githubtasks.yml +++ b/.pipelines/templates/release-githubNuget.yml @@ -1,3 +1,7 @@ +parameters: + - name: skipPublish + type: boolean + jobs: - job: GithubReleaseDraft displayName: Create GitHub Release Draft @@ -58,6 +62,7 @@ jobs: displayName: List all files in the workspace - task: PowerShell@2 + condition: and(ne('${{ parameters.skipPublish }}', 'false'), succeeded()) inputs: targetType: inline pwsh: true @@ -86,3 +91,56 @@ jobs: Publish-ReleaseDraft -Tag '$(ReleaseTag)' -Name '$(ReleaseTag) Release of PowerShell' -Description $clContent -User PowerShell -Repository PowerShell -PackageFolder "$(Pipeline.Workspace)/GitHubPackages" -Token $(GitHubReleasePat) displayName: Publish Release Draft + +- job: NuGetPublish + displayName: Publish to NuGet + condition: succeeded() + pool: + type: release + os: windows + templateContext: + inputs: + - input: pipelineArtifact + artifactName: drop_setReleaseTagAndUploadTools_SetTagAndTools + - input: pipelineArtifact + pipeline: PSPackagesOfficial + artifactName: drop_upload_upload_packages + variables: + - template: ./variable/release-shared.yml@self + parameters: + VERSION: $[ stageDependencies.setReleaseTagAndUploadTools.SetTagAndTools.outputs['OutputVersion.Version'] ] + + steps: + - template: release-install-pwsh.yml + + - pwsh: | + Write-Verbose -Verbose "Version: $(Version)" + Get-ChildItem Env: | Out-String -width 9999 -Stream | write-Verbose -Verbose + displayName: 'Capture Environment Variables' + + - pwsh: | + #Exclude all global tool packages. Their names start with 'PowerShell.' + $null = New-Item -ItemType Directory -Path "$(Pipeline.Workspace)/release" + Copy-Item "$(Pipeline.Workspace)/NuGetPackages/*.nupkg" -Destination "$(Pipeline.Workspace)/release" -Exclude "PowerShell.*.nupkg" -Force -Verbose + + $releaseVersion = '$(Version)' + $globalToolPath = "$(Pipeline.Workspace)/NuGetPackages/PowerShell.$releaseVersion.nupkg" + + if ($releaseVersion -notlike '*-*') { + # Copy the global tool package for stable releases + Copy-Item $globalToolPath -Destination "$(Pipeline.Workspace)/release" + } + + Write-Verbose -Verbose "The .nupkgs below will be pushed:" + Get-ChildItem "$(Pipeline.Workspace)/release" -recurse + displayName: Download and capture nupkgs + condition: and(ne('${{ parameters.skipPublish }}', 'false'), succeeded()) + + - task: NuGetCommand@2 + displayName: 'NuGet push' + condition: and(ne('${{ parameters.skipPublish }}', 'false'), succeeded()) + inputs: + command: push + packagesToPush: '$(Pipeline.Workspace)/release/*.nupkg' + nuGetFeedType: external + publishFeedCredentials: PowerShellNuGetOrgPush diff --git a/.pipelines/templates/release-publish-nuget.yml b/.pipelines/templates/release-publish-nuget.yml deleted file mode 100644 index 98249844d4c..00000000000 --- a/.pipelines/templates/release-publish-nuget.yml +++ /dev/null @@ -1,58 +0,0 @@ -parameters: - - name: skipPublish - default: false - type: boolean - -jobs: -- job: NuGetPublish - displayName: Publish to NuGet - condition: succeeded() - pool: - type: release - os: windows - templateContext: - inputs: - - input: pipelineArtifact - artifactName: drop_setReleaseTagAndUploadTools_SetTagAndTools - - input: pipelineArtifact - pipeline: PSPackagesOfficial - artifactName: drop_upload_upload_packages - variables: - - template: ./variable/release-shared.yml@self - parameters: - VERSION: $[ stageDependencies.setReleaseTagAndUploadTools.SetTagAndTools.outputs['OutputVersion.Version'] ] - - steps: - - template: release-install-pwsh.yml - - - pwsh: | - Write-Verbose -Verbose "Version: $(Version)" - Get-ChildItem Env: | Out-String -width 9999 -Stream | write-Verbose -Verbose - displayName: 'Capture Environment Variables' - - - pwsh: | - #Exclude all global tool packages. Their names start with 'PowerShell.' - $null = New-Item -ItemType Directory -Path "$(Pipeline.Workspace)/release" - Copy-Item "$(Pipeline.Workspace)/NuGetPackages/*.nupkg" -Destination "$(Pipeline.Workspace)/release" -Exclude "PowerShell.*.nupkg" -Force -Verbose - - $releaseVersion = '$(Version)' - $globalToolPath = "$(Pipeline.Workspace)/NuGetPackages/PowerShell.$releaseVersion.nupkg" - - if ($releaseVersion -notlike '*-*') { - # Copy the global tool package for stable releases - Copy-Item $globalToolPath -Destination "$(Pipeline.Workspace)/release" - } - - Write-Verbose -Verbose "The .nupkgs below will be pushed:" - Get-ChildItem "$(Pipeline.Workspace)/release" -recurse - displayName: Download and capture nupkgs - condition: and(ne('${{ parameters.skipPublish }}', 'false'), succeeded()) - - - task: NuGetCommand@2 - displayName: 'NuGet push' - condition: and(ne('${{ parameters.skipPublish }}', 'false'), succeeded()) - inputs: - command: push - packagesToPush: '$(Pipeline.Workspace)/release/*.nupkg' - nuGetFeedType: external - publishFeedCredentials: PowerShellNuGetOrgPush From c28e3ed09b37561cb51c9ef5e0df278d022f79c0 Mon Sep 17 00:00:00 2001 From: PowerShell Team Bot <69177312+pwshBot@users.noreply.github.com> Date: Wed, 16 Apr 2025 15:13:33 -0700 Subject: [PATCH 111/173] [release/v7.5] Add default .NET install path for SDK validation (#25338) Co-authored-by: Aditya Patwardhan --- .pipelines/templates/release-validate-sdk.yml | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/.pipelines/templates/release-validate-sdk.yml b/.pipelines/templates/release-validate-sdk.yml index 0d50b213961..bba29ee0c34 100644 --- a/.pipelines/templates/release-validate-sdk.yml +++ b/.pipelines/templates/release-validate-sdk.yml @@ -87,7 +87,16 @@ jobs: Get-Content $nugetPath # Add workaround to unblock xUnit testing see issue: https://github.com/dotnet/sdk/issues/26462 - $dotnetPath = if ($IsWindows) { "$env:LocalAppData\Microsoft\dotnet" } else { "$env:HOME/.dotnet" } + + $possibleDotnetLocation = "$env:ProgramFiles\dotnet" + + $dotnetPath = if ($IsWindows) { + if (Test-Path $possibleDotnetLocation) { $possibleDotnetLocation } else { "$env:LocalAppData\Microsoft\dotnet" } + } + else { + "$env:HOME/.dotnet" + } + $env:DOTNET_ROOT = $dotnetPath dotnet --info From 0997007528dc22889834e18f99d4531265ab99b1 Mon Sep 17 00:00:00 2001 From: PowerShell Team Bot <69177312+pwshBot@users.noreply.github.com> Date: Thu, 17 Apr 2025 10:05:59 -0700 Subject: [PATCH 112/173] [release/v7.5] Switch to ubuntu-lastest for CI (#25374) Co-authored-by: Travis Plunk --- .github/workflows/linux-ci.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/linux-ci.yml b/.github/workflows/linux-ci.yml index eda1ea56167..a7523f430cf 100644 --- a/.github/workflows/linux-ci.yml +++ b/.github/workflows/linux-ci.yml @@ -64,7 +64,7 @@ jobs: ci_build: name: Build PowerShell - runs-on: ubuntu-20.04 + runs-on: ubuntu-latest needs: changes if: ${{ needs.changes.outputs.source == 'true' }} steps: @@ -81,7 +81,7 @@ jobs: - ci_build - changes if: ${{ needs.changes.outputs.source == 'true' }} - runs-on: ubuntu-20.04 + runs-on: ubuntu-latest steps: - name: checkout uses: actions/checkout@v4.1.0 @@ -98,7 +98,7 @@ jobs: - ci_build - changes if: ${{ needs.changes.outputs.source == 'true' }} - runs-on: ubuntu-20.04 + runs-on: ubuntu-latest steps: - name: checkout uses: actions/checkout@v4.1.0 @@ -115,7 +115,7 @@ jobs: - ci_build - changes if: ${{ needs.changes.outputs.source == 'true' }} - runs-on: ubuntu-20.04 + runs-on: ubuntu-latest steps: - name: checkout uses: actions/checkout@v4.1.0 @@ -132,7 +132,7 @@ jobs: - ci_build - changes if: ${{ needs.changes.outputs.source == 'true' }} - runs-on: ubuntu-20.04 + runs-on: ubuntu-latest steps: - name: checkout uses: actions/checkout@v4.1.0 From c2e858b9beb44a00d915803ea9927ab2e72e9189 Mon Sep 17 00:00:00 2001 From: PowerShell Team Bot <69177312+pwshBot@users.noreply.github.com> Date: Thu, 17 Apr 2025 12:37:01 -0700 Subject: [PATCH 113/173] [release/v7.5] Update to .NET SDK 9.0.203 (#25373) --- DotnetRuntimeMetadata.json | 2 +- global.json | 2 +- ...oft.PowerShell.Commands.Diagnostics.csproj | 8 +- ...soft.PowerShell.Commands.Management.csproj | 4 +- ...crosoft.PowerShell.Commands.Utility.csproj | 6 +- ...crosoft.PowerShell.CoreCLR.Eventing.csproj | 2 +- .../Microsoft.PowerShell.SDK.csproj | 98 ++++++------- .../Microsoft.WSMan.Management.csproj | 4 +- .../System.Management.Automation.csproj | 24 ++-- .../BenchmarkDotNet.Extensions.csproj | 4 +- .../ResultsComparer/ResultsComparer.csproj | 4 +- ...soft.PowerShell.NamedPipeConnection.csproj | 24 ++-- test/tools/TestService/TestService.csproj | 94 ++++++------ test/tools/WebListener/WebListener.csproj | 6 +- tools/cgmanifest.json | 136 +++++++----------- 15 files changed, 194 insertions(+), 224 deletions(-) diff --git a/DotnetRuntimeMetadata.json b/DotnetRuntimeMetadata.json index e0869f46def..f78f43e709b 100644 --- a/DotnetRuntimeMetadata.json +++ b/DotnetRuntimeMetadata.json @@ -4,7 +4,7 @@ "quality": "daily", "qualityFallback": "preview", "packageVersionPattern": "9.0.0-preview.6", - "sdkImageVersion": "9.0.201", + "sdkImageVersion": "9.0.203", "nextChannel": "9.0.0-preview.7", "azureFeed": "", "sdkImageOverride": "" diff --git a/global.json b/global.json index 4667f91bae2..e4da652c648 100644 --- a/global.json +++ b/global.json @@ -1,5 +1,5 @@ { "sdk": { - "version": "9.0.201" + "version": "9.0.203" } } diff --git a/src/Microsoft.PowerShell.Commands.Diagnostics/Microsoft.PowerShell.Commands.Diagnostics.csproj b/src/Microsoft.PowerShell.Commands.Diagnostics/Microsoft.PowerShell.Commands.Diagnostics.csproj index d8ab11d9740..4952c8f6ad4 100644 --- a/src/Microsoft.PowerShell.Commands.Diagnostics/Microsoft.PowerShell.Commands.Diagnostics.csproj +++ b/src/Microsoft.PowerShell.Commands.Diagnostics/Microsoft.PowerShell.Commands.Diagnostics.csproj @@ -7,11 +7,11 @@ - - - + + + - + diff --git a/src/Microsoft.PowerShell.Commands.Management/Microsoft.PowerShell.Commands.Management.csproj b/src/Microsoft.PowerShell.Commands.Management/Microsoft.PowerShell.Commands.Management.csproj index 5494c8fa316..4fe6ed61803 100644 --- a/src/Microsoft.PowerShell.Commands.Management/Microsoft.PowerShell.Commands.Management.csproj +++ b/src/Microsoft.PowerShell.Commands.Management/Microsoft.PowerShell.Commands.Management.csproj @@ -47,8 +47,8 @@ - - + + diff --git a/src/Microsoft.PowerShell.Commands.Utility/Microsoft.PowerShell.Commands.Utility.csproj b/src/Microsoft.PowerShell.Commands.Utility/Microsoft.PowerShell.Commands.Utility.csproj index 797849a7e40..1cc347541a2 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/Microsoft.PowerShell.Commands.Utility.csproj +++ b/src/Microsoft.PowerShell.Commands.Utility/Microsoft.PowerShell.Commands.Utility.csproj @@ -13,7 +13,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive all - + @@ -41,8 +41,8 @@ - - + + diff --git a/src/Microsoft.PowerShell.CoreCLR.Eventing/Microsoft.PowerShell.CoreCLR.Eventing.csproj b/src/Microsoft.PowerShell.CoreCLR.Eventing/Microsoft.PowerShell.CoreCLR.Eventing.csproj index 21912472c59..e5f5b849645 100644 --- a/src/Microsoft.PowerShell.CoreCLR.Eventing/Microsoft.PowerShell.CoreCLR.Eventing.csproj +++ b/src/Microsoft.PowerShell.CoreCLR.Eventing/Microsoft.PowerShell.CoreCLR.Eventing.csproj @@ -8,7 +8,7 @@ - + diff --git a/src/Microsoft.PowerShell.SDK/Microsoft.PowerShell.SDK.csproj b/src/Microsoft.PowerShell.SDK/Microsoft.PowerShell.SDK.csproj index 549224f457d..1d1fc2f1291 100644 --- a/src/Microsoft.PowerShell.SDK/Microsoft.PowerShell.SDK.csproj +++ b/src/Microsoft.PowerShell.SDK/Microsoft.PowerShell.SDK.csproj @@ -17,55 +17,55 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - + + + + + + - - - - - - - - - - - - - - + + + + + + + + + + + + + + - - + + - + diff --git a/src/Microsoft.WSMan.Management/Microsoft.WSMan.Management.csproj b/src/Microsoft.WSMan.Management/Microsoft.WSMan.Management.csproj index 8c0f4165524..db972fa45c8 100644 --- a/src/Microsoft.WSMan.Management/Microsoft.WSMan.Management.csproj +++ b/src/Microsoft.WSMan.Management/Microsoft.WSMan.Management.csproj @@ -7,11 +7,11 @@ - + - + diff --git a/src/System.Management.Automation/System.Management.Automation.csproj b/src/System.Management.Automation/System.Management.Automation.csproj index ed65de03c1a..afc4c178cb3 100644 --- a/src/System.Management.Automation/System.Management.Automation.csproj +++ b/src/System.Management.Automation/System.Management.Automation.csproj @@ -32,25 +32,25 @@ - - - - - - + + + + + + - + - - - - + + + + - + diff --git a/test/perf/dotnet-tools/BenchmarkDotNet.Extensions/BenchmarkDotNet.Extensions.csproj b/test/perf/dotnet-tools/BenchmarkDotNet.Extensions/BenchmarkDotNet.Extensions.csproj index 8eb7c19141f..6f6ef0087ab 100644 --- a/test/perf/dotnet-tools/BenchmarkDotNet.Extensions/BenchmarkDotNet.Extensions.csproj +++ b/test/perf/dotnet-tools/BenchmarkDotNet.Extensions/BenchmarkDotNet.Extensions.csproj @@ -11,9 +11,9 @@ - + - + diff --git a/test/perf/dotnet-tools/ResultsComparer/ResultsComparer.csproj b/test/perf/dotnet-tools/ResultsComparer/ResultsComparer.csproj index a7b60b6eb1b..164023a0f62 100644 --- a/test/perf/dotnet-tools/ResultsComparer/ResultsComparer.csproj +++ b/test/perf/dotnet-tools/ResultsComparer/ResultsComparer.csproj @@ -11,9 +11,9 @@ - + - + diff --git a/test/tools/NamedPipeConnection/src/code/Microsoft.PowerShell.NamedPipeConnection.csproj b/test/tools/NamedPipeConnection/src/code/Microsoft.PowerShell.NamedPipeConnection.csproj index d0aeab862f9..aa15f08cb56 100644 --- a/test/tools/NamedPipeConnection/src/code/Microsoft.PowerShell.NamedPipeConnection.csproj +++ b/test/tools/NamedPipeConnection/src/code/Microsoft.PowerShell.NamedPipeConnection.csproj @@ -20,18 +20,18 @@ - - - - - - - + + + + + + + - - - - - + + + + + diff --git a/test/tools/TestService/TestService.csproj b/test/tools/TestService/TestService.csproj index 65837bc7e48..31a95e0b875 100644 --- a/test/tools/TestService/TestService.csproj +++ b/test/tools/TestService/TestService.csproj @@ -15,56 +15,56 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - + + + + + - - - - - - - - + + + + + + + + - + diff --git a/test/tools/WebListener/WebListener.csproj b/test/tools/WebListener/WebListener.csproj index d2181a374d7..b609555c9ad 100644 --- a/test/tools/WebListener/WebListener.csproj +++ b/test/tools/WebListener/WebListener.csproj @@ -7,9 +7,9 @@ - - + + - + diff --git a/tools/cgmanifest.json b/tools/cgmanifest.json index feb4257f1d0..e64601d8eaf 100644 --- a/tools/cgmanifest.json +++ b/tools/cgmanifest.json @@ -1,5 +1,4 @@ { - "$schema": "https://json.schemastore.org/component-detection-manifest.json", "Registrations": [ { "Component": { @@ -116,17 +115,7 @@ "Type": "nuget", "Nuget": { "Name": "Microsoft.Extensions.ObjectPool", - "Version": "8.0.14" - } - }, - "DevelopmentDependency": false - }, - { - "Component": { - "Type": "nuget", - "Nuget": { - "Name": "Microsoft.Management.Infrastructure.Runtime.Unix", - "Version": "3.0.0" + "Version": "8.0.15" } }, "DevelopmentDependency": false @@ -141,16 +130,6 @@ }, "DevelopmentDependency": true }, - { - "Component": { - "Type": "nuget", - "Nuget": { - "Name": "Microsoft.Management.Infrastructure", - "Version": "3.0.0" - } - }, - "DevelopmentDependency": false - }, { "Component": { "Type": "nuget", @@ -161,16 +140,6 @@ }, "DevelopmentDependency": false }, - { - "Component": { - "Type": "nuget", - "Nuget": { - "Name": "Microsoft.PowerShell.Native", - "Version": "7.4.0" - } - }, - "DevelopmentDependency": false - }, { "Component": { "Type": "nuget", @@ -186,7 +155,7 @@ "Type": "nuget", "Nuget": { "Name": "Microsoft.Win32.Registry.AccessControl", - "Version": "9.0.3" + "Version": "9.0.4" } }, "DevelopmentDependency": false @@ -206,7 +175,7 @@ "Type": "nuget", "Nuget": { "Name": "Microsoft.Win32.SystemEvents", - "Version": "9.0.3" + "Version": "9.0.4" } }, "DevelopmentDependency": false @@ -216,7 +185,7 @@ "Type": "nuget", "Nuget": { "Name": "Microsoft.Windows.Compatibility", - "Version": "9.0.3" + "Version": "9.0.4" } }, "DevelopmentDependency": false @@ -236,7 +205,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.android-arm.runtime.native.System.IO.Ports", - "Version": "9.0.3" + "Version": "9.0.4" } }, "DevelopmentDependency": false @@ -246,7 +215,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.android-arm64.runtime.native.System.IO.Ports", - "Version": "9.0.3" + "Version": "9.0.4" } }, "DevelopmentDependency": false @@ -256,7 +225,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.android-x64.runtime.native.System.IO.Ports", - "Version": "9.0.3" + "Version": "9.0.4" } }, "DevelopmentDependency": false @@ -266,7 +235,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.android-x86.runtime.native.System.IO.Ports", - "Version": "9.0.3" + "Version": "9.0.4" } }, "DevelopmentDependency": false @@ -276,7 +245,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.linux-arm.runtime.native.System.IO.Ports", - "Version": "9.0.3" + "Version": "9.0.4" } }, "DevelopmentDependency": false @@ -286,7 +255,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.linux-arm64.runtime.native.System.IO.Ports", - "Version": "9.0.3" + "Version": "9.0.4" } }, "DevelopmentDependency": false @@ -296,7 +265,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.linux-bionic-arm64.runtime.native.System.IO.Ports", - "Version": "9.0.3" + "Version": "9.0.4" } }, "DevelopmentDependency": false @@ -306,7 +275,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.linux-bionic-x64.runtime.native.System.IO.Ports", - "Version": "9.0.3" + "Version": "9.0.4" } }, "DevelopmentDependency": false @@ -316,7 +285,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.linux-musl-arm.runtime.native.System.IO.Ports", - "Version": "9.0.3" + "Version": "9.0.4" } }, "DevelopmentDependency": false @@ -326,7 +295,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.linux-musl-arm64.runtime.native.System.IO.Ports", - "Version": "9.0.3" + "Version": "9.0.4" } }, "DevelopmentDependency": false @@ -336,7 +305,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.linux-musl-x64.runtime.native.System.IO.Ports", - "Version": "9.0.3" + "Version": "9.0.4" } }, "DevelopmentDependency": false @@ -346,7 +315,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.linux-x64.runtime.native.System.IO.Ports", - "Version": "9.0.3" + "Version": "9.0.4" } }, "DevelopmentDependency": false @@ -356,7 +325,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.maccatalyst-arm64.runtime.native.System.IO.Ports", - "Version": "9.0.3" + "Version": "9.0.4" } }, "DevelopmentDependency": false @@ -366,7 +335,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.maccatalyst-x64.runtime.native.System.IO.Ports", - "Version": "9.0.3" + "Version": "9.0.4" } }, "DevelopmentDependency": false @@ -386,7 +355,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.native.System.IO.Ports", - "Version": "9.0.3" + "Version": "9.0.4" } }, "DevelopmentDependency": false @@ -396,7 +365,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.osx-arm64.runtime.native.System.IO.Ports", - "Version": "9.0.3" + "Version": "9.0.4" } }, "DevelopmentDependency": false @@ -406,7 +375,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.osx-x64.runtime.native.System.IO.Ports", - "Version": "9.0.3" + "Version": "9.0.4" } }, "DevelopmentDependency": false @@ -466,7 +435,7 @@ "Type": "nuget", "Nuget": { "Name": "System.CodeDom", - "Version": "9.0.3" + "Version": "9.0.4" } }, "DevelopmentDependency": false @@ -486,7 +455,7 @@ "Type": "nuget", "Nuget": { "Name": "System.ComponentModel.Composition.Registration", - "Version": "9.0.3" + "Version": "9.0.4" } }, "DevelopmentDependency": false @@ -496,7 +465,7 @@ "Type": "nuget", "Nuget": { "Name": "System.ComponentModel.Composition", - "Version": "9.0.3" + "Version": "9.0.4" } }, "DevelopmentDependency": false @@ -506,7 +475,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Configuration.ConfigurationManager", - "Version": "9.0.3" + "Version": "9.0.4" } }, "DevelopmentDependency": false @@ -516,7 +485,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Data.Odbc", - "Version": "9.0.3" + "Version": "9.0.4" } }, "DevelopmentDependency": false @@ -526,7 +495,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Data.OleDb", - "Version": "9.0.3" + "Version": "9.0.4" } }, "DevelopmentDependency": false @@ -546,7 +515,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Diagnostics.DiagnosticSource", - "Version": "9.0.3" + "Version": "9.0.4" } }, "DevelopmentDependency": false @@ -556,7 +525,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Diagnostics.EventLog", - "Version": "9.0.3" + "Version": "9.0.4" } }, "DevelopmentDependency": false @@ -566,7 +535,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Diagnostics.PerformanceCounter", - "Version": "9.0.3" + "Version": "9.0.4" } }, "DevelopmentDependency": false @@ -576,7 +545,7 @@ "Type": "nuget", "Nuget": { "Name": "System.DirectoryServices.AccountManagement", - "Version": "9.0.3" + "Version": "9.0.4" } }, "DevelopmentDependency": false @@ -586,7 +555,7 @@ "Type": "nuget", "Nuget": { "Name": "System.DirectoryServices.Protocols", - "Version": "9.0.3" + "Version": "9.0.4" } }, "DevelopmentDependency": false @@ -596,7 +565,7 @@ "Type": "nuget", "Nuget": { "Name": "System.DirectoryServices", - "Version": "9.0.3" + "Version": "9.0.4" } }, "DevelopmentDependency": false @@ -606,7 +575,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Drawing.Common", - "Version": "9.0.3" + "Version": "9.0.4" } }, "DevelopmentDependency": false @@ -616,7 +585,7 @@ "Type": "nuget", "Nuget": { "Name": "System.IO.Packaging", - "Version": "9.0.3" + "Version": "9.0.4" } }, "DevelopmentDependency": false @@ -626,7 +595,7 @@ "Type": "nuget", "Nuget": { "Name": "System.IO.Ports", - "Version": "9.0.3" + "Version": "9.0.4" } }, "DevelopmentDependency": false @@ -636,7 +605,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Management", - "Version": "9.0.3" + "Version": "9.0.4" } }, "DevelopmentDependency": false @@ -646,7 +615,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Net.Http.WinHttpHandler", - "Version": "9.0.3" + "Version": "9.0.4" } }, "DevelopmentDependency": false @@ -676,7 +645,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Reflection.Context", - "Version": "9.0.3" + "Version": "9.0.4" } }, "DevelopmentDependency": false @@ -706,7 +675,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Runtime.Caching", - "Version": "9.0.3" + "Version": "9.0.4" } }, "DevelopmentDependency": false @@ -726,7 +695,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Security.Cryptography.Pkcs", - "Version": "9.0.3" + "Version": "9.0.4" } }, "DevelopmentDependency": false @@ -736,7 +705,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Security.Cryptography.ProtectedData", - "Version": "9.0.3" + "Version": "9.0.4" } }, "DevelopmentDependency": false @@ -746,7 +715,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Security.Cryptography.Xml", - "Version": "9.0.3" + "Version": "9.0.4" } }, "DevelopmentDependency": false @@ -756,7 +725,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Security.Permissions", - "Version": "9.0.3" + "Version": "9.0.4" } }, "DevelopmentDependency": false @@ -826,7 +795,7 @@ "Type": "nuget", "Nuget": { "Name": "System.ServiceModel.Syndication", - "Version": "9.0.3" + "Version": "9.0.4" } }, "DevelopmentDependency": false @@ -836,7 +805,7 @@ "Type": "nuget", "Nuget": { "Name": "System.ServiceProcess.ServiceController", - "Version": "9.0.3" + "Version": "9.0.4" } }, "DevelopmentDependency": false @@ -846,7 +815,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Speech", - "Version": "9.0.3" + "Version": "9.0.4" } }, "DevelopmentDependency": false @@ -856,7 +825,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Text.Encoding.CodePages", - "Version": "9.0.3" + "Version": "9.0.4" } }, "DevelopmentDependency": false @@ -866,7 +835,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Text.Encodings.Web", - "Version": "9.0.3" + "Version": "9.0.4" } }, "DevelopmentDependency": false @@ -876,7 +845,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Threading.AccessControl", - "Version": "9.0.3" + "Version": "9.0.4" } }, "DevelopmentDependency": false @@ -896,10 +865,11 @@ "Type": "nuget", "Nuget": { "Name": "System.Windows.Extensions", - "Version": "9.0.3" + "Version": "9.0.4" } }, "DevelopmentDependency": false } - ] + ], + "$schema": "https://json.schemastore.org/component-detection-manifest.json" } From b7de3c5aea083dda0d041ef7102269d6cccaf2b0 Mon Sep 17 00:00:00 2001 From: PowerShell Team Bot <69177312+pwshBot@users.noreply.github.com> Date: Thu, 17 Apr 2025 12:38:47 -0700 Subject: [PATCH 114/173] [release/v7.5] Add CodeQL suppressions for PowerShell intended behavior (#25375) Co-authored-by: Anam Navied Co-authored-by: Travis Plunk --- .../commands/utility/AddType.cs | 1 + .../utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs | 1 + src/System.Management.Automation/engine/ExecutionContext.cs | 1 + 3 files changed, 3 insertions(+) diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/AddType.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/AddType.cs index 81ca82cb3c3..7dc0a9c3556 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/AddType.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/AddType.cs @@ -684,6 +684,7 @@ private void LoadAssemblies(IEnumerable assemblies) { // CoreCLR doesn't allow re-load TPA assemblies with different API (i.e. we load them by name and now want to load by path). // LoadAssemblyHelper helps us avoid re-loading them, if they already loaded. + // codeql[cs/dll-injection-remote] - This is expected PowerShell behavior and integral to the purpose of the class. It allows users to load any C# dependencies they need for their PowerShell application and add other types they require. Assembly assembly = LoadAssemblyHelper(assemblyName) ?? Assembly.LoadFrom(ResolveAssemblyName(assemblyName, false)); if (PassThru) diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs index 886c04919b6..810b54a8391 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs @@ -1771,6 +1771,7 @@ private static StringContent GetMultipartStringContent(object fieldName, object ContentDispositionHeaderValue contentDisposition = new("form-data"); contentDisposition.Name = LanguagePrimitives.ConvertTo(fieldName); + // codeql[cs/information-exposure-through-exception] - PowerShell is an on-premise product, meaning local users would already have access to the binaries and stack traces. Therefore, the information would not be exposed in the same way it would be for an ASP .NET service. StringContent result = new(LanguagePrimitives.ConvertTo(fieldValue)); result.Headers.ContentDisposition = contentDisposition; diff --git a/src/System.Management.Automation/engine/ExecutionContext.cs b/src/System.Management.Automation/engine/ExecutionContext.cs index 56f64c1a5c2..e0e078346e9 100644 --- a/src/System.Management.Automation/engine/ExecutionContext.cs +++ b/src/System.Management.Automation/engine/ExecutionContext.cs @@ -1385,6 +1385,7 @@ private static Assembly LoadAssembly(string name, string filePath, out Exception { try { + // codeql[cs/dll-injection-remote] - The dll is loaded during the initial state setup, which is expected behavior. This allows users hosting PowerShell to load additional C# types to enable their specific scenarios. loadedAssembly = Assembly.LoadFrom(filePath); return loadedAssembly; } From a873b33b65d507b613f09d569cb50b683cc8fdf0 Mon Sep 17 00:00:00 2001 From: PowerShell Team Bot <69177312+pwshBot@users.noreply.github.com> Date: Thu, 17 Apr 2025 15:00:53 -0700 Subject: [PATCH 115/173] [release/v7.5] Enhance path filters action to set outputs for all changes when not a PR (#25379) Co-authored-by: Travis Plunk --- .../infrastructure/path-filters/action.yml | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/.github/actions/infrastructure/path-filters/action.yml b/.github/actions/infrastructure/path-filters/action.yml index 58255fab55c..78426bdff03 100644 --- a/.github/actions/infrastructure/path-filters/action.yml +++ b/.github/actions/infrastructure/path-filters/action.yml @@ -35,6 +35,23 @@ runs: with: github-token: ${{ inputs.GITHUB_TOKEN }} script: | + console.log(`Event Name: ${context.eventName}`); + + // Just say everything changed if this is not a PR + if (context.eventName !== 'pull_request') { + console.log('Not a pull request, setting all outputs to true'); + core.setOutput('toolsChanged', true); + core.setOutput('githubChanged', true); + core.setOutput('propsChanged', true); + core.setOutput('testsChanged', true); + core.setOutput('mainSourceChanged', true); + core.setOutput('buildModuleChanged', true); + core.setOutput('source', true); + return; + } + + console.log(`Getting files changed in PR #${context.issue.number}`); + // Fetch the list of files changed in the PR let files = []; let page = 1; From 16f5b4552692c975e97bfda935b182da8e26ab37 Mon Sep 17 00:00:00 2001 From: PowerShell Team Bot <69177312+pwshBot@users.noreply.github.com> Date: Thu, 17 Apr 2025 15:01:59 -0700 Subject: [PATCH 116/173] [release/v7.5] Retry ClearlyDefined operations (#25387) Co-authored-by: Travis Plunk --- tools/clearlyDefined/src/ClearlyDefined/ClearlyDefined.psm1 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/clearlyDefined/src/ClearlyDefined/ClearlyDefined.psm1 b/tools/clearlyDefined/src/ClearlyDefined/ClearlyDefined.psm1 index 2a9434c9cbe..4d874402977 100644 --- a/tools/clearlyDefined/src/ClearlyDefined/ClearlyDefined.psm1 +++ b/tools/clearlyDefined/src/ClearlyDefined/ClearlyDefined.psm1 @@ -27,7 +27,7 @@ function Start-ClearlyDefinedHarvest { $coordinates = Get-ClearlyDefinedCoordinates @PSBoundParameters $body = @{tool='package';coordinates=$coordinates} | convertto-json Write-Verbose $body -Verbose - (Invoke-WebRequest -Method Post -Uri 'https://api.clearlydefined.io/harvest' -Body $body -ContentType 'application/json').Content + (Invoke-WebRequest -Method Post -Uri 'https://api.clearlydefined.io/harvest' -Body $body -ContentType 'application/json' -MaximumRetryCount 5 -RetryIntervalSec 60 -Verbose).Content } } @@ -117,7 +117,7 @@ Function Get-ClearlyDefinedData { continue } - Invoke-RestMethod -Uri "https://api.clearlydefined.io/definitions/$coordinates" | ForEach-Object { + Invoke-RestMethod -Uri "https://api.clearlydefined.io/definitions/$coordinates" -MaximumRetryCount 5 -RetryIntervalSec 60 | ForEach-Object { [bool] $harvested = if ($_.licensed.declared) { $true } else { $false } Add-Member -NotePropertyName cachedTime -NotePropertyValue (get-date) -InputObject $_ -PassThru | Add-Member -NotePropertyName harvested -NotePropertyValue $harvested -PassThru if ($_.harvested) { From 7b21583dc6aa55d9c74d083e41e805d1d985e2a0 Mon Sep 17 00:00:00 2001 From: PowerShell Team Bot <69177312+pwshBot@users.noreply.github.com> Date: Mon, 21 Apr 2025 14:43:01 -0700 Subject: [PATCH 117/173] [release/v7.5] Update APIScan to use new symbols server (#25399) Co-authored-by: Travis Plunk --- .pipelines/apiscan-gen-notice.yml | 5 ++++- .pipelines/templates/compliance/apiscan.yml | 20 ++++++++++++++++---- build.psm1 | 8 ++++++++ 3 files changed, 28 insertions(+), 5 deletions(-) diff --git a/.pipelines/apiscan-gen-notice.yml b/.pipelines/apiscan-gen-notice.yml index f4fd167d7a0..1507b9345bd 100644 --- a/.pipelines/apiscan-gen-notice.yml +++ b/.pipelines/apiscan-gen-notice.yml @@ -13,6 +13,9 @@ parameters: default: false variables: + # PAT permissions NOTE: Declare a SymbolServerPAT variable in this group with a 'microsoft' organizanization scoped PAT with 'Symbols' Read permission. + # A PAT in the wrong org will give a single Error 203. No PAT will give a single Error 401, and individual pdbs may be missing even if permissions are correct. + - group: symbols - name: ob_outputDirectory value: '$(Build.ArtifactStagingDirectory)/ONEBRANCH_ARTIFACT' - name: CDP_DEFINITION_BUILD_COUNT @@ -86,8 +89,8 @@ extends: softwareName: "PowerShell" # Default is repo name versionNumber: "7.5" # Default is build number isLargeApp: false # Default: false. + symbolsFolder: $(SymbolsServerUrl);$(ob_outputDirectory) #softwareFolder - relative path to a folder to be scanned. Default value is root of artifacts folder. -#symbolsFolder - relative path to a folder that contains symbols. Default value is root of artifacts folder. tsaOptionsFile: .config\tsaoptions.json diff --git a/.pipelines/templates/compliance/apiscan.yml b/.pipelines/templates/compliance/apiscan.yml index 4e945b40349..17f07a597b5 100644 --- a/.pipelines/templates/compliance/apiscan.yml +++ b/.pipelines/templates/compliance/apiscan.yml @@ -12,9 +12,6 @@ jobs: value: fromBranch # Defines the variables APIScanClient, APIScanTenant and APIScanSecret - group: PS-PS-APIScan - # PAT permissions NOTE: Declare a SymbolServerPAT variable in this group with a 'microsoft' organizanization scoped PAT with 'Symbols' Read permission. - # A PAT in the wrong org will give a single Error 203. No PAT will give a single Error 401, and individual pdbs may be missing even if permissions are correct. - - group: symbols - name: branchCounterKey value: $[format('{0:yyyyMMdd}-{1}', pipeline.startTime,variables['Build.SourceBranch'])] - name: branchCounter @@ -125,10 +122,25 @@ jobs: } Copy-Item -Path "$OutputFolder\*" -Destination '$(ob_outputDirectory)' -Recurse -Verbose - workingDirectory: '$(repoRoot)' displayName: 'Build PowerShell Source' + - pwsh: | + # Only key windows runtimes + Get-ChildItem -Path '$(ob_outputDirectory)\runtimes\*' -File -Recurse | Where-Object {$_.FullName -notmatch '.*\/runtimes\/win'} | Foreach-Object { + Write-Verbose -Verbose -Message "Deleting $($_.FullName)" + Remove-Item -Force -Verbose -Path $_.FullName + } + + # Temporarily remove runtimes/win-x64 due to issues with that runtime + Get-ChildItem -Path '$(ob_outputDirectory)\runtimes\*' -File -Recurse | Where-Object {$_.FullName -match '.*\/runtimes\/win-x86\/'} | Foreach-Object { + Write-Verbose -Verbose -Message "Deleting $($_.FullName)" + Remove-Item -Force -Verbose -Path $_.FullName + } + + workingDirectory: '$(repoRoot)' + displayName: 'Remove unused runtimes' + - task: CodeQL3000Finalize@0 # Add CodeQL Finalize task right after your 'Build' step. displayName: 🔏 CodeQL 3000 Finalize condition: eq(variables['CODEQL_ENABLED'], 'true') diff --git a/build.psm1 b/build.psm1 index b371891d706..ffaf7b02f9d 100644 --- a/build.psm1 +++ b/build.psm1 @@ -3676,6 +3676,14 @@ function New-NugetConfigFile { $content += $newLine + $nugetConfigFooterTemplate Set-Content -Path (Join-Path $Destination 'nuget.config') -Value $content -Force + + # Set the nuget.config file to be skipped by git + push-location $Destination + try { + git update-index --skip-worktree (Join-Path $Destination 'nuget.config') + } finally { + pop-location + } } function Clear-PipelineNugetAuthentication { From 61874845f400fc4261d5cba0d0a2546dfa55740d Mon Sep 17 00:00:00 2001 From: PowerShell Team Bot <69177312+pwshBot@users.noreply.github.com> Date: Mon, 21 Apr 2025 14:55:09 -0700 Subject: [PATCH 118/173] [release/v7.5] Use GitHubReleaseTask (#25402) Co-authored-by: Justin Chung <124807742+jshigetomi@users.noreply.github.com> Co-authored-by: Travis Plunk --- .pipelines/PowerShell-Release-Official.yml | 8 ++-- ...ols.yml => release-SetTagAndChangelog.yml} | 30 +------------ .pipelines/templates/release-githubNuget.yml | 43 +++++++++++++++---- 3 files changed, 40 insertions(+), 41 deletions(-) rename .pipelines/templates/{release-SetTagAndTools.yml => release-SetTagAndChangelog.yml} (59%) diff --git a/.pipelines/PowerShell-Release-Official.yml b/.pipelines/PowerShell-Release-Official.yml index 46a6926fd7a..12b2c839c69 100644 --- a/.pipelines/PowerShell-Release-Official.yml +++ b/.pipelines/PowerShell-Release-Official.yml @@ -117,10 +117,10 @@ extends: tsaOptionsFile: .config\tsaoptions.json stages: - - stage: setReleaseTagAndUploadTools - displayName: 'Set Release Tag and Upload Tools' + - stage: setReleaseTagAndChangelog + displayName: 'Set Release Tag and Upload Changelog' jobs: - - template: /.pipelines/templates/release-SetTagAndTools.yml@self + - template: /.pipelines/templates/release-SetTagAndChangelog.yml@self - stage: msixbundle displayName: 'Create MSIX Bundle' @@ -284,7 +284,7 @@ extends: - stage: PublishGitHubReleaseAndNuget displayName: Publish GitHub and Nuget Release dependsOn: - - setReleaseTagAndUploadTools + - setReleaseTagAndChangelog - UpdateChangeLog variables: ob_release_environment: Production diff --git a/.pipelines/templates/release-SetTagAndTools.yml b/.pipelines/templates/release-SetTagAndChangelog.yml similarity index 59% rename from .pipelines/templates/release-SetTagAndTools.yml rename to .pipelines/templates/release-SetTagAndChangelog.yml index 7b8a946e323..f0c516dd28f 100644 --- a/.pipelines/templates/release-SetTagAndTools.yml +++ b/.pipelines/templates/release-SetTagAndChangelog.yml @@ -1,6 +1,6 @@ jobs: -- job: SetTagAndTools - displayName: Set Tag and Tools +- job: setTagAndChangelog + displayName: Set Tag and Upload Changelog condition: succeeded() pool: type: windows @@ -19,32 +19,6 @@ jobs: clean: true env: ob_restore_phase: true - - - checkout: PSInternalTools - clean: true - env: - ob_restore_phase: true - - - pwsh: | - New-Item -ItemType Directory -Path '$(Pipeline.Workspace)/ToolArtifact' - Get-ChildItem -Path '$(Build.SourcesDirectory)/Internal-PowerShellTeam-Tools/Scripts' -Filter 'GitHubRelease.psm1' -ErrorAction SilentlyContinue | - Copy-Item -Destination '$(Pipeline.Workspace)/ToolArtifact' -Verbose - displayName: Move GitHub Tool - - - task: onebranch.pipeline.signing@1 - displayName: Sign Tools - inputs: - command: 'sign' - signing_profile: internal_azure_service - files_to_sign: '*.ps1;*.psm1' - search_root: '$(Pipeline.Workspace)/ToolArtifact' - - - pwsh: | - Write-Verbose -Verbose "Creating output directory for release tools: $(ob_outputDirectory)/ToolArtifact" - New-Item -Path $(ob_outputDirectory)/ToolArtifact -ItemType Directory -Force - Get-ChildItem -Path "$(Pipeline.Workspace)/ToolArtifact/*" -Recurse | - Copy-Item -Destination $(ob_outputDirectory)/ToolArtifact -Recurse -Verbose - displayName: Upload Tools - pwsh: | Write-Verbose -Verbose "Release Tag: $(OutputReleaseTag.releaseTag)" diff --git a/.pipelines/templates/release-githubNuget.yml b/.pipelines/templates/release-githubNuget.yml index 2d76c13dc99..8aca980eff2 100644 --- a/.pipelines/templates/release-githubNuget.yml +++ b/.pipelines/templates/release-githubNuget.yml @@ -12,14 +12,14 @@ jobs: templateContext: inputs: - input: pipelineArtifact - artifactName: drop_setReleaseTagAndUploadTools_SetTagAndTools + artifactName: drop_setReleaseTagAndChangelog_SetTagAndChangelog - input: pipelineArtifact pipeline: PSPackagesOfficial artifactName: drop_upload_upload_packages variables: - template: ./variable/release-shared.yml@self parameters: - RELEASETAG: $[ stageDependencies.setReleaseTagAndUploadTools.SetTagAndTools.outputs['OutputReleaseTag.releaseTag'] ] + RELEASETAG: $[ stageDependencies.setReleaseTagAndChangelog.setTagAndChangelog.outputs['OutputReleaseTag.releaseTag'] ] steps: - task: PowerShell@2 @@ -62,12 +62,10 @@ jobs: displayName: List all files in the workspace - task: PowerShell@2 - condition: and(ne('${{ parameters.skipPublish }}', 'false'), succeeded()) inputs: targetType: inline pwsh: true script: | - Import-module '$(Pipeline.Workspace)/ToolArtifact/GitHubRelease.psm1' $releaseVersion = '$(ReleaseTag)' -replace '^v','' Write-Verbose -Verbose "Available modules: " Get-Module | Write-Verbose -Verbose @@ -89,8 +87,37 @@ jobs: Write-Verbose -Verbose "Selected content: `n$clContent" - Publish-ReleaseDraft -Tag '$(ReleaseTag)' -Name '$(ReleaseTag) Release of PowerShell' -Description $clContent -User PowerShell -Repository PowerShell -PackageFolder "$(Pipeline.Workspace)/GitHubPackages" -Token $(GitHubReleasePat) - displayName: Publish Release Draft + $releaseNotesFilePath = "$(Pipeline.Workspace)/release-notes.md" + $clContent | Out-File -FilePath $releaseNotesFilePath -Encoding utf8 + + Write-Host "##vso[task.setvariable variable=ReleaseNotesFilePath;]$releaseNotesFilePath" + + #if name has prelease then make prerelease true as a variable + if ($releaseVersion -like '*-*') { + Write-Host "##vso[task.setvariable variable=IsPreRelease;]true" + } else { + Write-Host "##vso[task.setvariable variable=IsPreRelease;]false" + } + displayName: Set variables for GitHub release task + + - pwsh: | + Write-Host "ReleaseNotes content:" + Get-Content "$(Pipeline.Workspace)/release-notes.md" -Raw | Out-String -width 9999 | Write-Host + displayName: Verify Release Notes + + - task: GitHubRelease@1 + inputs: + gitHubConnection: GitHubReleasePAT + repositoryName: PowerShell/PowerShell + target: master + assets: '$(Pipeline.Workspace)/GitHubPackages/*' + tagSource: 'userSpecifiedTag' + tag: '$(ReleaseTag)' + isDraft: true + addChangeLog: false + action: 'create' + releaseNotesFilePath: '$(ReleaseNotesFilePath)' + isPrerelease: '$(IsPreRelease)' - job: NuGetPublish displayName: Publish to NuGet @@ -100,15 +127,13 @@ jobs: os: windows templateContext: inputs: - - input: pipelineArtifact - artifactName: drop_setReleaseTagAndUploadTools_SetTagAndTools - input: pipelineArtifact pipeline: PSPackagesOfficial artifactName: drop_upload_upload_packages variables: - template: ./variable/release-shared.yml@self parameters: - VERSION: $[ stageDependencies.setReleaseTagAndUploadTools.SetTagAndTools.outputs['OutputVersion.Version'] ] + VERSION: $[ stageDependencies.setReleaseTagAndChangelog.SetTagAndChangelog.outputs['OutputVersion.Version'] ] steps: - template: release-install-pwsh.yml From c67404200ba69f11a219ec4c3ae8f66d7c8a42fe Mon Sep 17 00:00:00 2001 From: Justin Chung <124807742+jshigetomi@users.noreply.github.com> Date: Tue, 22 Apr 2025 14:32:30 -0500 Subject: [PATCH 119/173] Updated Third Party Notices (#25422) --- ThirdPartyNotices.txt | 104 +++++++++++++++++++++--------------------- 1 file changed, 52 insertions(+), 52 deletions(-) diff --git a/ThirdPartyNotices.txt b/ThirdPartyNotices.txt index 4abb1717d67..d48be300df3 100644 --- a/ThirdPartyNotices.txt +++ b/ThirdPartyNotices.txt @@ -284,7 +284,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI --------------------------------------------------------- -Microsoft.Extensions.ObjectPool 8.0.12 - MIT +Microsoft.Extensions.ObjectPool 8.0.15 - MIT Copyright Jorn Zaefferer @@ -354,7 +354,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI --------------------------------------------------------- -Microsoft.Security.Extensions 1.3.0 - MIT +Microsoft.Security.Extensions 1.4.0 - MIT (c) Microsoft Corporation @@ -446,7 +446,7 @@ SOFTWARE. --------------------------------------------------------- -Microsoft.Win32.Registry.AccessControl 9.0.1 - MIT +Microsoft.Win32.Registry.AccessControl 9.0.4 - MIT Copyright (c) 2021 @@ -536,7 +536,7 @@ SOFTWARE. --------------------------------------------------------- -Microsoft.Win32.SystemEvents 9.0.1 - MIT +Microsoft.Win32.SystemEvents 9.0.4 - MIT Copyright (c) 2021 @@ -626,7 +626,7 @@ SOFTWARE. --------------------------------------------------------- -Microsoft.Windows.Compatibility 9.0.1 - MIT +Microsoft.Windows.Compatibility 9.0.4 - MIT (c) Microsoft Corporation @@ -679,7 +679,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. --------------------------------------------------------- -runtime.android-arm.runtime.native.System.IO.Ports 9.0.1 - MIT +runtime.android-arm.runtime.native.System.IO.Ports 9.0.4 - MIT Copyright (c) 2021 @@ -769,7 +769,7 @@ SOFTWARE. --------------------------------------------------------- -runtime.android-arm64.runtime.native.System.IO.Ports 9.0.1 - MIT +runtime.android-arm64.runtime.native.System.IO.Ports 9.0.4 - MIT Copyright (c) 2021 @@ -859,7 +859,7 @@ SOFTWARE. --------------------------------------------------------- -runtime.android-x64.runtime.native.System.IO.Ports 9.0.1 - MIT +runtime.android-x64.runtime.native.System.IO.Ports 9.0.4 - MIT Copyright (c) 2021 @@ -949,7 +949,7 @@ SOFTWARE. --------------------------------------------------------- -runtime.android-x86.runtime.native.System.IO.Ports 9.0.1 - MIT +runtime.android-x86.runtime.native.System.IO.Ports 9.0.4 - MIT Copyright (c) 2021 @@ -1039,7 +1039,7 @@ SOFTWARE. --------------------------------------------------------- -runtime.linux-arm.runtime.native.System.IO.Ports 9.0.1 - MIT +runtime.linux-arm.runtime.native.System.IO.Ports 9.0.4 - MIT Copyright (c) 2021 @@ -1129,7 +1129,7 @@ SOFTWARE. --------------------------------------------------------- -runtime.linux-arm64.runtime.native.System.IO.Ports 9.0.1 - MIT +runtime.linux-arm64.runtime.native.System.IO.Ports 9.0.4 - MIT Copyright (c) 2021 @@ -1219,7 +1219,7 @@ SOFTWARE. --------------------------------------------------------- -runtime.linux-bionic-arm64.runtime.native.System.IO.Ports 9.0.1 - MIT +runtime.linux-bionic-arm64.runtime.native.System.IO.Ports 9.0.4 - MIT Copyright (c) 2021 @@ -1309,7 +1309,7 @@ SOFTWARE. --------------------------------------------------------- -runtime.linux-bionic-x64.runtime.native.System.IO.Ports 9.0.1 - MIT +runtime.linux-bionic-x64.runtime.native.System.IO.Ports 9.0.4 - MIT Copyright (c) 2021 @@ -1399,7 +1399,7 @@ SOFTWARE. --------------------------------------------------------- -runtime.linux-musl-arm.runtime.native.System.IO.Ports 9.0.1 - MIT +runtime.linux-musl-arm.runtime.native.System.IO.Ports 9.0.4 - MIT Copyright (c) 2021 @@ -1489,7 +1489,7 @@ SOFTWARE. --------------------------------------------------------- -runtime.linux-musl-arm64.runtime.native.System.IO.Ports 9.0.1 - MIT +runtime.linux-musl-arm64.runtime.native.System.IO.Ports 9.0.4 - MIT Copyright (c) 2021 @@ -1579,7 +1579,7 @@ SOFTWARE. --------------------------------------------------------- -runtime.linux-musl-x64.runtime.native.System.IO.Ports 9.0.1 - MIT +runtime.linux-musl-x64.runtime.native.System.IO.Ports 9.0.4 - MIT Copyright (c) 2021 @@ -1669,7 +1669,7 @@ SOFTWARE. --------------------------------------------------------- -runtime.linux-x64.runtime.native.System.IO.Ports 9.0.1 - MIT +runtime.linux-x64.runtime.native.System.IO.Ports 9.0.4 - MIT Copyright (c) 2021 @@ -1759,7 +1759,7 @@ SOFTWARE. --------------------------------------------------------- -runtime.maccatalyst-arm64.runtime.native.System.IO.Ports 9.0.1 - MIT +runtime.maccatalyst-arm64.runtime.native.System.IO.Ports 9.0.4 - MIT Copyright (c) 2021 @@ -1849,7 +1849,7 @@ SOFTWARE. --------------------------------------------------------- -runtime.maccatalyst-x64.runtime.native.System.IO.Ports 9.0.1 - MIT +runtime.maccatalyst-x64.runtime.native.System.IO.Ports 9.0.4 - MIT Copyright (c) 2021 @@ -1992,7 +1992,7 @@ SOFTWARE. --------------------------------------------------------- -runtime.native.System.IO.Ports 9.0.1 - MIT +runtime.native.System.IO.Ports 9.0.4 - MIT Copyright (c) 2021 @@ -2082,7 +2082,7 @@ SOFTWARE. --------------------------------------------------------- -runtime.osx-arm64.runtime.native.System.IO.Ports 9.0.1 - MIT +runtime.osx-arm64.runtime.native.System.IO.Ports 9.0.4 - MIT Copyright (c) 2021 @@ -2172,7 +2172,7 @@ SOFTWARE. --------------------------------------------------------- -runtime.osx-x64.runtime.native.System.IO.Ports 9.0.1 - MIT +runtime.osx-x64.runtime.native.System.IO.Ports 9.0.4 - MIT Copyright (c) 2021 @@ -2262,7 +2262,7 @@ SOFTWARE. --------------------------------------------------------- -System.CodeDom 9.0.1 - MIT +System.CodeDom 9.0.4 - MIT Copyright (c) 2021 @@ -2438,7 +2438,7 @@ SOFTWARE. --------------------------------------------------------- -System.ComponentModel.Composition 9.0.1 - MIT +System.ComponentModel.Composition 9.0.4 - MIT Copyright (c) 2021 @@ -2528,7 +2528,7 @@ SOFTWARE. --------------------------------------------------------- -System.ComponentModel.Composition.Registration 9.0.1 - MIT +System.ComponentModel.Composition.Registration 9.0.4 - MIT Copyright (c) 2021 @@ -2618,7 +2618,7 @@ SOFTWARE. --------------------------------------------------------- -System.Configuration.ConfigurationManager 9.0.1 - MIT +System.Configuration.ConfigurationManager 9.0.4 - MIT Copyright (c) 2021 @@ -2708,7 +2708,7 @@ SOFTWARE. --------------------------------------------------------- -System.Data.Odbc 9.0.1 - MIT +System.Data.Odbc 9.0.4 - MIT Copyright (c) 2021 @@ -2798,7 +2798,7 @@ SOFTWARE. --------------------------------------------------------- -System.Data.OleDb 9.0.1 - MIT +System.Data.OleDb 9.0.4 - MIT Copyright (c) 2021 @@ -2941,7 +2941,7 @@ SOFTWARE. --------------------------------------------------------- -System.Diagnostics.DiagnosticSource 9.0.1 - MIT +System.Diagnostics.DiagnosticSource 9.0.4 - MIT Copyright (c) 2021 @@ -3031,7 +3031,7 @@ SOFTWARE. --------------------------------------------------------- -System.Diagnostics.EventLog 9.0.1 - MIT +System.Diagnostics.EventLog 9.0.4 - MIT Copyright (c) 2021 @@ -3121,7 +3121,7 @@ SOFTWARE. --------------------------------------------------------- -System.Diagnostics.PerformanceCounter 9.0.1 - MIT +System.Diagnostics.PerformanceCounter 9.0.4 - MIT Copyright (c) 2021 @@ -3211,7 +3211,7 @@ SOFTWARE. --------------------------------------------------------- -System.DirectoryServices 9.0.1 - MIT +System.DirectoryServices 9.0.4 - MIT Copyright (c) 2021 @@ -3301,7 +3301,7 @@ SOFTWARE. --------------------------------------------------------- -System.DirectoryServices.AccountManagement 9.0.1 - MIT +System.DirectoryServices.AccountManagement 9.0.4 - MIT Copyright (c) 2021 @@ -3391,7 +3391,7 @@ SOFTWARE. --------------------------------------------------------- -System.DirectoryServices.Protocols 9.0.1 - MIT +System.DirectoryServices.Protocols 9.0.4 - MIT Copyright (c) 2021 @@ -3481,7 +3481,7 @@ SOFTWARE. --------------------------------------------------------- -System.Drawing.Common 9.0.1 - MIT +System.Drawing.Common 9.0.4 - MIT (c) Microsoft Corporation @@ -3516,7 +3516,7 @@ SOFTWARE. --------------------------------------------------------- -System.IO.Packaging 9.0.1 - MIT +System.IO.Packaging 9.0.4 - MIT Copyright (c) 2021 @@ -3606,7 +3606,7 @@ SOFTWARE. --------------------------------------------------------- -System.IO.Ports 9.0.1 - MIT +System.IO.Ports 9.0.4 - MIT Copyright (c) 2021 @@ -3696,7 +3696,7 @@ SOFTWARE. --------------------------------------------------------- -System.Management 9.0.1 - MIT +System.Management 9.0.4 - MIT Copyright (c) 2021 @@ -3786,7 +3786,7 @@ SOFTWARE. --------------------------------------------------------- -System.Net.Http.WinHttpHandler 9.0.1 - MIT +System.Net.Http.WinHttpHandler 9.0.4 - MIT Copyright (c) 2021 @@ -3961,7 +3961,7 @@ SOFTWARE. --------------------------------------------------------- -System.Reflection.Context 9.0.1 - MIT +System.Reflection.Context 9.0.4 - MIT Copyright (c) 2021 @@ -4191,7 +4191,7 @@ SOFTWARE. --------------------------------------------------------- -System.Runtime.Caching 9.0.1 - MIT +System.Runtime.Caching 9.0.4 - MIT Copyright (c) 2021 @@ -4356,7 +4356,7 @@ SOFTWARE. --------------------------------------------------------- -System.Security.Cryptography.Pkcs 9.0.1 - MIT +System.Security.Cryptography.Pkcs 9.0.4 - MIT Copyright (c) 2021 @@ -4446,7 +4446,7 @@ SOFTWARE. --------------------------------------------------------- -System.Security.Cryptography.ProtectedData 9.0.1 - MIT +System.Security.Cryptography.ProtectedData 9.0.4 - MIT Copyright (c) 2021 @@ -4536,7 +4536,7 @@ SOFTWARE. --------------------------------------------------------- -System.Security.Cryptography.Xml 9.0.1 - MIT +System.Security.Cryptography.Xml 9.0.4 - MIT Copyright (c) 2021 @@ -4626,7 +4626,7 @@ SOFTWARE. --------------------------------------------------------- -System.Security.Permissions 9.0.1 - MIT +System.Security.Permissions 9.0.4 - MIT Copyright (c) 2021 @@ -4965,7 +4965,7 @@ SOFTWARE. --------------------------------------------------------- -System.ServiceModel.Syndication 9.0.1 - MIT +System.ServiceModel.Syndication 9.0.4 - MIT Copyright (c) 2021 @@ -5055,7 +5055,7 @@ SOFTWARE. --------------------------------------------------------- -System.ServiceProcess.ServiceController 9.0.1 - MIT +System.ServiceProcess.ServiceController 9.0.4 - MIT Copyright (c) 2021 @@ -5145,7 +5145,7 @@ SOFTWARE. --------------------------------------------------------- -System.Speech 9.0.1 - MIT +System.Speech 9.0.4 - MIT Copyright (c) 2021 @@ -5235,7 +5235,7 @@ SOFTWARE. --------------------------------------------------------- -System.Text.Encoding.CodePages 9.0.1 - MIT +System.Text.Encoding.CodePages 9.0.4 - MIT Copyright (c) 2021 @@ -5325,7 +5325,7 @@ SOFTWARE. --------------------------------------------------------- -System.Text.Encodings.Web 9.0.1 - MIT +System.Text.Encodings.Web 9.0.4 - MIT Copyright (c) 2021 @@ -5415,7 +5415,7 @@ SOFTWARE. --------------------------------------------------------- -System.Threading.AccessControl 9.0.1 - MIT +System.Threading.AccessControl 9.0.4 - MIT Copyright (c) 2021 @@ -5541,7 +5541,7 @@ SOFTWARE. --------------------------------------------------------- -System.Windows.Extensions 9.0.1 - MIT +System.Windows.Extensions 9.0.4 - MIT Copyright (c) 2021 From 00a041754bc7555cbfdfb1bef4ba101b79772d37 Mon Sep 17 00:00:00 2001 From: PowerShell Team Bot <69177312+pwshBot@users.noreply.github.com> Date: Wed, 23 Apr 2025 12:33:42 -0700 Subject: [PATCH 120/173] [release/v7.5] Add 7.5.1 Change log (#25424) Co-authored-by: Justin Chung <124807742+jshigetomi@users.noreply.github.com> Co-authored-by: Dongbo Wang --- CHANGELOG/7.5.md | 79 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) diff --git a/CHANGELOG/7.5.md b/CHANGELOG/7.5.md index 702c60346e7..37aa3e27995 100644 --- a/CHANGELOG/7.5.md +++ b/CHANGELOG/7.5.md @@ -1,5 +1,84 @@ # 7.5 Changelog +## [7.5.1] + +### Engine Updates and Fixes + +- Fallback to AppLocker after `WldpCanExecuteFile` (#25305) + +### Code Cleanup + +
+ +
    +
  • Cleanup old release pipelines (#25236)
  • +
+ +
+ +### Tools + +- Do not run labels workflow in the internal repository (#25343) +- Update `CODEOWNERS` (#25321) +- Check GitHub token availability for `Get-Changelog` (#25328) +- Update PowerShell team members in `releaseTools.psm1` (#25302) + +### Build and Packaging Improvements + +
+ + + +

Update to .NET SDK 9.0.203

+ +
+ +
    +
  • Finish 7.5.0 release (#24855)
  • +
  • Add CodeQL suppressions for PowerShell intended behavior (#25375)
  • +
  • Update to .NET SDK 9.0.203 (#25373)
  • +
  • Switch to ubuntu-lastest for CI (#25374)
  • +
  • Add default .NET install path for SDK validation (#25338)
  • +
  • Combine GitHub and Nuget Release Stage (#25371)
  • +
  • Add Windows Store Signing to MSIX bundle (#25370)
  • +
  • Update test result processing to use NUnitXml format and enhance logging for better clarity (#25344)
  • +
  • Fix MSIX stage in release pipeline (#25345)
  • +
  • Make GitHub Workflows work in the internal mirror (#25342)
  • +
  • Update security extensions (#25322)
  • +
  • Disable SBOM generation on set variables job in release build (#25340)
  • +
  • Update GitHub Actions to work in private GitHub repo (#25332)
  • +
  • Revert "Cleanup old release pipelines (#25201)" (#25335)
  • +
  • Remove call to NuGet (#25334)
  • +
  • Simplify PR Template (#25333)
  • +
  • Update package pipeline windows image version (#25331)
  • +
  • Skip additional packages when generating component manifest (#25329)
  • +
  • Only build Linux for packaging changes (#25326)
  • +
  • Make Component Manifest Updater use neutral target in addition to RID target (#25325)
  • +
  • Remove Az module installs and AzureRM uninstalls in pipeline (#25327)
  • +
  • Make sure the vPack pipeline does not produce an empty package (#25320)
  • +
  • Add *.props and sort path filters for windows CI (#25316)
  • +
  • Fix V-Pack download package name (#25314)
  • +
  • Update path filters for Windows CI (#25312)
  • +
  • Give the pipeline runs meaningful names (#25309)
  • +
  • Migrate MacOS Signing to OneBranch (#25304)
  • +
  • Add UseDotnet task for installing dotnet (#25281)
  • +
  • Remove obsolete template from Windows Packaging CI (#25237)
  • +
  • Add setup dotnet action to the build composite action (#25235)
  • +
  • Add GitHub Actions workflow to verify PR labels (#25159)
  • +
  • Update branch for release - Transitive - true - minor (#24994)
  • +
  • Fix GitHub Action filter overmatching (#24958)
  • +
  • Fix release branch filters (#24959)
  • +
  • Convert powershell/PowerShell-CI-macos to GitHub Actions (#24954)
  • +
  • Convert powershell/PowerShell-CI-linux to GitHub Actions (#24946)
  • +
  • Convert powershell/PowerShell-Windows-CI to GitHub Actions (#24931)
  • +
  • PMC parse state correctly from update command's response (#24859)
  • +
  • Add EV2 support for publishing PowerShell packages to PMC (#24856)
  • +
+ +
+ +[7.5.1]: https://github.com/PowerShell/PowerShell/compare/v7.5.0...v7.5.1 + ## [7.5.0] ### Build and Packaging Improvements From 85a60f332237baa6bc059dacc88b0913de24053e Mon Sep 17 00:00:00 2001 From: PowerShell Team Bot <69177312+pwshBot@users.noreply.github.com> Date: Wed, 23 Apr 2025 13:36:04 -0700 Subject: [PATCH 121/173] [release/v7.5] Fix the expected path of .NET after using UseDotnet 2 task to install (#25425) Co-authored-by: Aditya Patwardhan --- .pipelines/templates/release-validate-sdk.yml | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/.pipelines/templates/release-validate-sdk.yml b/.pipelines/templates/release-validate-sdk.yml index bba29ee0c34..d879ab7f06e 100644 --- a/.pipelines/templates/release-validate-sdk.yml +++ b/.pipelines/templates/release-validate-sdk.yml @@ -86,19 +86,6 @@ jobs: Get-Content $nugetPath - # Add workaround to unblock xUnit testing see issue: https://github.com/dotnet/sdk/issues/26462 - - $possibleDotnetLocation = "$env:ProgramFiles\dotnet" - - $dotnetPath = if ($IsWindows) { - if (Test-Path $possibleDotnetLocation) { $possibleDotnetLocation } else { "$env:LocalAppData\Microsoft\dotnet" } - } - else { - "$env:HOME/.dotnet" - } - - $env:DOTNET_ROOT = $dotnetPath - dotnet --info dotnet restore dotnet test /property:RELEASE_VERSION=$releaseVersion --test-adapter-path:. "--logger:xunit;LogFilePath=$(System.DefaultWorkingDirectory)/test-hosting.xml" From 3a9ea0db0615010f68c3604b74a1a5c77af3b58a Mon Sep 17 00:00:00 2001 From: PowerShell Team Bot <69177312+pwshBot@users.noreply.github.com> Date: Thu, 24 Apr 2025 15:13:26 -0700 Subject: [PATCH 122/173] [release/v7.5] Use new variables template for vPack (#25435) Co-authored-by: Justin Chung <124807742+jshigetomi@users.noreply.github.com> --- .pipelines/PowerShell-vPack-Official.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pipelines/PowerShell-vPack-Official.yml b/.pipelines/PowerShell-vPack-Official.yml index 33c72f8963f..829e374e606 100644 --- a/.pipelines/PowerShell-vPack-Official.yml +++ b/.pipelines/PowerShell-vPack-Official.yml @@ -118,7 +118,7 @@ extends: ob_createvpack_verbose: true steps: - - template: tools/releaseBuild/azureDevOps/templates/SetVersionVariables.yml@self + - template: ./templates/SetVersionVariables.yml parameters: ReleaseTagVar: $(ReleaseTagVar) CreateJson: yes From 2bab6df66a959e1dfe399045ba2820b81df08d6e Mon Sep 17 00:00:00 2001 From: PowerShell Team Bot <69177312+pwshBot@users.noreply.github.com> Date: Wed, 14 May 2025 14:56:12 -0700 Subject: [PATCH 123/173] [release/v7.5] Fix PSMethodInvocationConstraints.GetHashCode method (#25306) Co-authored-by: crazyjncsu --- src/System.Management.Automation/engine/MshMemberInfo.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/System.Management.Automation/engine/MshMemberInfo.cs b/src/System.Management.Automation/engine/MshMemberInfo.cs index 369e0f3fcd6..7474ae8d645 100644 --- a/src/System.Management.Automation/engine/MshMemberInfo.cs +++ b/src/System.Management.Automation/engine/MshMemberInfo.cs @@ -2009,7 +2009,7 @@ public override bool Equals(object obj) } public override int GetHashCode() - => HashCode.Combine(MethodTargetType, ParameterTypes, GenericTypeParameters); + => HashCode.Combine(MethodTargetType, ParameterTypes.SequenceGetHashCode(), GenericTypeParameters.SequenceGetHashCode()); public override string ToString() { From 3ad624280bc2afb24189002f5a29d51dee7e76c0 Mon Sep 17 00:00:00 2001 From: PowerShell Team Bot <69177312+pwshBot@users.noreply.github.com> Date: Tue, 3 Jun 2025 13:05:54 -0700 Subject: [PATCH 124/173] [release/v7.5] Remove the old fuzzy suggestion and fix the local script file name suggestion (#25330) Co-authored-by: Dongbo Wang --- .../FeedbackSubsystem/IFeedbackProvider.cs | 2 +- .../engine/hostifaces/HostUtilities.cs | 37 +++++-------------- .../resources/SuggestionStrings.resx | 3 ++ .../utils/Telemetry.cs | 2 +- test/xUnit/csharp/test_Feedback.cs | 4 +- 5 files changed, 16 insertions(+), 32 deletions(-) diff --git a/src/System.Management.Automation/engine/Subsystem/FeedbackSubsystem/IFeedbackProvider.cs b/src/System.Management.Automation/engine/Subsystem/FeedbackSubsystem/IFeedbackProvider.cs index 328eb4eee87..0af184f4e99 100644 --- a/src/System.Management.Automation/engine/Subsystem/FeedbackSubsystem/IFeedbackProvider.cs +++ b/src/System.Management.Automation/engine/Subsystem/FeedbackSubsystem/IFeedbackProvider.cs @@ -243,7 +243,7 @@ internal GeneralCommandErrorFeedback() public Guid Id => _guid; - public string Name => "general"; + public string Name => "General Feedback"; public string Description => "The built-in general feedback source for command errors."; diff --git a/src/System.Management.Automation/engine/hostifaces/HostUtilities.cs b/src/System.Management.Automation/engine/hostifaces/HostUtilities.cs index 9e5612189fa..003625791b1 100644 --- a/src/System.Management.Automation/engine/hostifaces/HostUtilities.cs +++ b/src/System.Management.Automation/engine/hostifaces/HostUtilities.cs @@ -8,7 +8,6 @@ using System.Globalization; using System.Management.Automation.Host; using System.Management.Automation.Internal; -using System.Management.Automation.Language; using System.Management.Automation.Runspaces; using System.Management.Automation.Subsystem.Feedback; using System.Runtime.InteropServices; @@ -67,13 +66,6 @@ public static class HostUtilities $formatString -f $lastError.TargetObject,"".\$($lastError.TargetObject)"" "; - private static readonly string s_getFuzzyMatchedCommands = @" - [System.Diagnostics.DebuggerHidden()] - param([string] $formatString) - - $formatString -f [string]::Join(', ', (Get-Command $lastError.TargetObject -UseFuzzyMatching -FuzzyMinimumDistance 1 | Select-Object -First 5 -Unique -ExpandProperty Name)) - "; - private static readonly List s_suggestions = InitializeSuggestions(); private static bool HostSupportUnicode() @@ -97,28 +89,17 @@ private static bool HostSupportUnicode() private static List InitializeSuggestions() { - var suggestions = new List( - new Hashtable[] - { - NewSuggestion( - id: 3, - category: "General", - matchType: SuggestionMatchType.Dynamic, - rule: ScriptBlock.CreateDelayParsedScriptBlock(s_checkForCommandInCurrentDirectoryScript, isProductCode: true), - suggestion: ScriptBlock.CreateDelayParsedScriptBlock(s_createCommandExistsInCurrentDirectoryScript, isProductCode: true), - suggestionArgs: new object[] { CodeGeneration.EscapeSingleQuotedStringContent(SuggestionStrings.Suggestion_CommandExistsInCurrentDirectory) }, - enabled: true) - }); - - suggestions.Add( + var suggestions = new List() + { NewSuggestion( - id: 4, + id: 3, category: "General", - matchType: SuggestionMatchType.ErrorId, - rule: "CommandNotFoundException", - suggestion: ScriptBlock.CreateDelayParsedScriptBlock(s_getFuzzyMatchedCommands, isProductCode: true), - suggestionArgs: new object[] { CodeGeneration.EscapeSingleQuotedStringContent(SuggestionStrings.Suggestion_CommandNotFound) }, - enabled: true)); + matchType: SuggestionMatchType.Dynamic, + rule: ScriptBlock.CreateDelayParsedScriptBlock(s_checkForCommandInCurrentDirectoryScript, isProductCode: true), + suggestion: ScriptBlock.CreateDelayParsedScriptBlock(s_createCommandExistsInCurrentDirectoryScript, isProductCode: true), + suggestionArgs: new object[] { SuggestionStrings.Suggestion_CommandExistsInCurrentDirectory_Legacy }, + enabled: true) + }; return suggestions; } diff --git a/src/System.Management.Automation/resources/SuggestionStrings.resx b/src/System.Management.Automation/resources/SuggestionStrings.resx index ea249db55e7..9e325b2616c 100644 --- a/src/System.Management.Automation/resources/SuggestionStrings.resx +++ b/src/System.Management.Automation/resources/SuggestionStrings.resx @@ -123,6 +123,9 @@ PowerShell does not load commands from the current location by default (see 'Get If you trust this command, run the following command instead: + + The command "{0}" was not found, but does exist in the current location. PowerShell does not load commands from the current location by default. If you trust this command, instead type: "{1}". See "get-help about_Command_Precedence" for more details. + The most similar commands are: diff --git a/src/System.Management.Automation/utils/Telemetry.cs b/src/System.Management.Automation/utils/Telemetry.cs index 9e40e60a4d6..3579401e810 100644 --- a/src/System.Management.Automation/utils/Telemetry.cs +++ b/src/System.Management.Automation/utils/Telemetry.cs @@ -635,7 +635,7 @@ static ApplicationInsightsTelemetry() s_knownSubsystemNames = new HashSet(StringComparer.OrdinalIgnoreCase) { "Completion", - "general", + "General Feedback", "Windows Package Manager - WinGet", "Az Predictor" }; diff --git a/test/xUnit/csharp/test_Feedback.cs b/test/xUnit/csharp/test_Feedback.cs index 2c90118be55..eba627f7b0d 100644 --- a/test/xUnit/csharp/test_Feedback.cs +++ b/test/xUnit/csharp/test_Feedback.cs @@ -97,7 +97,7 @@ public static void GetFeedback() // Test the result from the 'general' feedback provider. Assert.Single(feedbacks); - Assert.Equal("general", feedbacks[0].Name); + Assert.Equal("General Feedback", feedbacks[0].Name); Assert.Equal(expectedCmd, feedbacks[0].Item.RecommendedActions[0]); // Expect the result from both 'general' and the 'slow' feedback providers. @@ -107,7 +107,7 @@ public static void GetFeedback() Assert.Equal(2, feedbacks.Count); FeedbackResult entry1 = feedbacks[0]; - Assert.Equal("general", entry1.Name); + Assert.Equal("General Feedback", entry1.Name); Assert.Equal(expectedCmd, entry1.Item.RecommendedActions[0]); FeedbackResult entry2 = feedbacks[1]; From bd83cbabe290b5b2cde4d909e904cdc805178b2a Mon Sep 17 00:00:00 2001 From: PowerShell Team Bot <69177312+pwshBot@users.noreply.github.com> Date: Tue, 3 Jun 2025 13:07:35 -0700 Subject: [PATCH 125/173] [release/v7.5] Move .NET method invocation logging to after the needed type conversion is done for method arguments (#25357) Co-authored-by: Dongbo Wang Co-authored-by: Travis Plunk Co-authored-by: Travis Plunk --- .../engine/runtime/Binding/Binders.cs | 107 ++++++++++++++---- 1 file changed, 86 insertions(+), 21 deletions(-) diff --git a/src/System.Management.Automation/engine/runtime/Binding/Binders.cs b/src/System.Management.Automation/engine/runtime/Binding/Binders.cs index de36b9d7249..f4020547432 100644 --- a/src/System.Management.Automation/engine/runtime/Binding/Binders.cs +++ b/src/System.Management.Automation/engine/runtime/Binding/Binders.cs @@ -6943,20 +6943,6 @@ internal static DynamicMetaObject InvokeDotNetMethod( expr = Expression.Block(expr, ExpressionCache.AutomationNullConstant); } - // Expression block runs two expressions in order: - // - Log method invocation to AMSI Notifications (can throw PSSecurityException) - // - Invoke method - string targetName = methodInfo.ReflectedType?.FullName ?? string.Empty; - expr = Expression.Block( - Expression.Call( - CachedReflectionInfo.MemberInvocationLoggingOps_LogMemberInvocation, - Expression.Constant(targetName), - Expression.Constant(name), - Expression.NewArrayInit( - typeof(object), - args.Select(static e => e.Expression.Cast(typeof(object))))), - expr); - // If we're calling SteppablePipeline.{Begin|Process|End}, we don't want // to wrap exceptions - this is very much a special case to help error // propagation and ensure errors are attributed to the correct code (the @@ -7119,6 +7105,7 @@ internal static Expression InvokeMethod(MethodBase mi, DynamicMetaObject target, invocationType != MethodInvocationType.NonVirtual; var parameters = mi.GetParameters(); var argExprs = new Expression[parameters.Length]; + var argsToLog = new List(Math.Max(parameters.Length, args.Length)); for (int i = 0; i < parameters.Length; ++i) { @@ -7143,16 +7130,21 @@ internal static Expression InvokeMethod(MethodBase mi, DynamicMetaObject target, if (expandParameters) { - argExprs[i] = Expression.NewArrayInit( - paramElementType, - args.Skip(i).Select( - a => a.CastOrConvertMethodArgument( + IEnumerable elements = args + .Skip(i) + .Select(a => + a.CastOrConvertMethodArgument( paramElementType, paramName, mi.Name, allowCastingToByRefLikeType: false, temps, - initTemps))); + initTemps)) + .ToList(); + + argExprs[i] = Expression.NewArrayInit(paramElementType, elements); + // User specified the element arguments, so we log them instead of the compiler-created array. + argsToLog.AddRange(elements); } else { @@ -7163,13 +7155,18 @@ internal static Expression InvokeMethod(MethodBase mi, DynamicMetaObject target, allowCastingToByRefLikeType: false, temps, initTemps); + argExprs[i] = arg; + argsToLog.Add(arg); } } else if (i >= args.Length) { - Diagnostics.Assert(parameters[i].IsOptional, + // We don't log the default value for an optional parameter, as it's not specified by the user. + Diagnostics.Assert( + parameters[i].IsOptional, "if there are too few arguments, FindBestMethod should only succeed if parameters are optional"); + var argValue = parameters[i].DefaultValue; if (argValue == null) { @@ -7207,17 +7204,25 @@ internal static Expression InvokeMethod(MethodBase mi, DynamicMetaObject target, var psRefValue = Expression.Property(args[i].Expression.Cast(typeof(PSReference)), CachedReflectionInfo.PSReference_Value); initTemps.Add(Expression.Assign(temp, psRefValue.Convert(temp.Type))); copyOutTemps.Add(Expression.Assign(psRefValue, temp.Cast(typeof(object)))); + argExprs[i] = temp; + argsToLog.Add(temp); } else { - argExprs[i] = args[i].CastOrConvertMethodArgument( + var convertedArg = args[i].CastOrConvertMethodArgument( parameterType, paramName, mi.Name, allowCastingToByRefLikeType, temps, initTemps); + + argExprs[i] = convertedArg; + // If the converted arg is a byref-like type, then we log the original arg. + argsToLog.Add(convertedArg.Type.IsByRefLike + ? args[i].Expression + : convertedArg); } } } @@ -7263,6 +7268,12 @@ internal static Expression InvokeMethod(MethodBase mi, DynamicMetaObject target, } } + // We need to add one expression to log the .NET invocation before actually invoking: + // - Log method invocation to AMSI Notifications (can throw PSSecurityException) + // - Invoke method + string targetName = mi.ReflectedType?.FullName ?? string.Empty; + string methodName = mi.Name is ".ctor" ? "new" : mi.Name; + if (temps.Count > 0) { if (call.Type != typeof(void) && copyOutTemps.Count > 0) @@ -7273,8 +7284,13 @@ internal static Expression InvokeMethod(MethodBase mi, DynamicMetaObject target, copyOutTemps.Add(retValue); } + AddMemberInvocationLogging(initTemps, targetName, methodName, argsToLog); call = Expression.Block(call.Type, temps, initTemps.Append(call).Concat(copyOutTemps)); } + else + { + call = AddMemberInvocationLogging(call, targetName, methodName, argsToLog); + } return call; } @@ -7566,6 +7582,55 @@ internal static void InvalidateCache() } } +#nullable enable + private static Expression AddMemberInvocationLogging( + Expression expr, + string targetName, + string name, + List args) + { +#if UNIX + // For efficiency this is a no-op on non-Windows platforms. + return expr; +#else + Expression[] invocationArgs = new Expression[args.Count]; + for (int i = 0; i < args.Count; i++) + { + invocationArgs[i] = args[i].Cast(typeof(object)); + } + + return Expression.Block( + Expression.Call( + CachedReflectionInfo.MemberInvocationLoggingOps_LogMemberInvocation, + Expression.Constant(targetName), + Expression.Constant(name), + Expression.NewArrayInit(typeof(object), invocationArgs)), + expr); +#endif + } + + private static void AddMemberInvocationLogging( + List exprs, + string targetName, + string name, + List args) + { +#if !UNIX + Expression[] invocationArgs = new Expression[args.Count]; + for (int i = 0; i < args.Count; i++) + { + invocationArgs[i] = args[i].Cast(typeof(object)); + } + + exprs.Add(Expression.Call( + CachedReflectionInfo.MemberInvocationLoggingOps_LogMemberInvocation, + Expression.Constant(targetName), + Expression.Constant(name), + Expression.NewArrayInit(typeof(object), invocationArgs))); +#endif + } +#nullable disable + #endregion } From 8e4a10114234083871bf6d087cba8d1635c8b7c9 Mon Sep 17 00:00:00 2001 From: PowerShell Team Bot <69177312+pwshBot@users.noreply.github.com> Date: Tue, 3 Jun 2025 13:08:28 -0700 Subject: [PATCH 126/173] [release/v7.5] Move MSIXBundle to Packages and Release to GitHub (#25517) Co-authored-by: Justin Chung <124807742+jshigetomi@users.noreply.github.com> --- .pipelines/PowerShell-Packages-Official.yml | 9 ++- .pipelines/PowerShell-Release-Official.yml | 8 -- ...reate-msix.yml => package-create-msix.yml} | 77 ++++++++----------- .pipelines/templates/uploadToAzure.yml | 35 +++++++++ 4 files changed, 75 insertions(+), 54 deletions(-) rename .pipelines/templates/{release-create-msix.yml => package-create-msix.yml} (60%) diff --git a/.pipelines/PowerShell-Packages-Official.yml b/.pipelines/PowerShell-Packages-Official.yml index 30b9e415215..487e8cb9c6a 100644 --- a/.pipelines/PowerShell-Packages-Official.yml +++ b/.pipelines/PowerShell-Packages-Official.yml @@ -60,6 +60,7 @@ variables: value: $[format('{0:yyyyMMdd}-{1}', pipeline.startTime,variables['Build.SourceBranch'])] - name: branchCounter value: $[counter(variables['branchCounterKey'], 1)] + - group: MSIXSigningProfile resources: pipelines: @@ -246,7 +247,13 @@ extends: jobs: - template: /.pipelines/templates/nupkg.yml@self + - stage: msixbundle + displayName: 'Create MSIX Bundle' + dependsOn: [windows_package] + jobs: + - template: /.pipelines/templates/package-create-msix.yml@self + - stage: upload - dependsOn: [mac_package, windows_package, linux_package, nupkg] + dependsOn: [mac_package, windows_package, linux_package, nupkg, msixbundle] jobs: - template: /.pipelines/templates/uploadToAzure.yml@self diff --git a/.pipelines/PowerShell-Release-Official.yml b/.pipelines/PowerShell-Release-Official.yml index 12b2c839c69..71ff540cacd 100644 --- a/.pipelines/PowerShell-Release-Official.yml +++ b/.pipelines/PowerShell-Release-Official.yml @@ -58,7 +58,6 @@ variables: - name: ReleaseTagVar value: ${{ parameters.ReleaseTagVar }} - group: PoolNames - - group: MSIXSigningProfile resources: repositories: @@ -122,12 +121,6 @@ extends: jobs: - template: /.pipelines/templates/release-SetTagAndChangelog.yml@self - - stage: msixbundle - displayName: 'Create MSIX Bundle' - dependsOn: [] - jobs: - - template: /.pipelines/templates/release-create-msix.yml@self - - stage: validateSdk displayName: 'Validate SDK' dependsOn: [] @@ -270,7 +263,6 @@ extends: - fxdpackages - gbltool - validateSdk - - msixbundle jobs: - template: /.pipelines/templates/approvalJob.yml@self diff --git a/.pipelines/templates/release-create-msix.yml b/.pipelines/templates/package-create-msix.yml similarity index 60% rename from .pipelines/templates/release-create-msix.yml rename to .pipelines/templates/package-create-msix.yml index 751ce1ec5e2..0ab2408e6a7 100644 --- a/.pipelines/templates/release-create-msix.yml +++ b/.pipelines/templates/package-create-msix.yml @@ -13,20 +13,32 @@ jobs: steps: - template: release-SetReleaseTagandContainerName.yml@self - - download: PSPackagesOfficial - artifact: drop_windows_package_package_win_arm64 - displayName: Download arm64 msix - patterns: '**/*.msix' - - - download: PSPackagesOfficial - artifact: drop_windows_package_package_win_x64 - displayName: Download x64 msix - patterns: '**/*.msix' - - - download: PSPackagesOfficial - artifact: drop_windows_package_package_win_x86 - displayName: Download x86 msix - patterns: '**/*.msix' + - task: DownloadPipelineArtifact@2 + inputs: + buildType: 'current' + artifact: drop_windows_package_package_win_arm64 + itemPattern: | + **/*.msix + targetPath: '$(Build.ArtifactStagingDirectory)/downloads' + displayName: Download windows arm64 packages + + - task: DownloadPipelineArtifact@2 + inputs: + buildType: 'current' + artifact: drop_windows_package_package_win_x64 + itemPattern: | + **/*.msix + targetPath: '$(Build.ArtifactStagingDirectory)/downloads' + displayName: Download windows x64 packages + + - task: DownloadPipelineArtifact@2 + inputs: + buildType: 'current' + artifact: drop_windows_package_package_win_x86 + itemPattern: | + **/*.msix + targetPath: '$(Build.ArtifactStagingDirectory)/downloads' + displayName: Download windows x86 packages # Finds the makeappx tool on the machine with image: 'onebranch.azurecr.io/windows/ltsc2022/vse2022:latest' - pwsh: | @@ -53,7 +65,7 @@ jobs: $sourceDir = '$(Pipeline.Workspace)\releasePipeline\msix' $null = New-Item -Path $sourceDir -ItemType Directory -Force - $msixFiles = Get-ChildItem -Path "$(Pipeline.Workspace)/PSPackagesOfficial/*.msix" -Recurse + $msixFiles = Get-ChildItem -Path "$(Build.ArtifactStagingDirectory)/downloads/*.msix" -Recurse foreach ($msixFile in $msixFiles) { $null = Copy-Item -Path $msixFile.FullName -Destination $sourceDir -Force -Verbose } @@ -87,37 +99,12 @@ jobs: $signedBundle = Get-ChildItem -Path $(BundleDir) -Filter "*.msixbundle" -File Write-Verbose -Verbose "Signed bundle: $signedBundle" - Copy-Item -Path $signedBundle -Destination $(ob_outputDirectory) -Verbose + if (-not (Test-Path $(ob_outputDirectory))) { + New-Item -ItemType Directory -Path $(ob_outputDirectory) -Force + } + + Copy-Item -Path $signedBundle.FullName -Destination "$(ob_outputDirectory)" -Verbose Write-Verbose -Verbose "Uploaded Bundle:" Get-ChildItem -Path $(ob_outputDirectory) | Write-Verbose -Verbose displayName: Upload msixbundle to Artifacts - - - task: AzurePowerShell@5 - displayName: Upload msix to blob - inputs: - azureSubscription: az-blob-cicd-infra - scriptType: inlineScript - azurePowerShellVersion: LatestVersion - pwsh: true - inline: | - $containerName = '$(OutputVersion.AzureVersion)-private' - $storageAccount = '$(StorageAccount)' - - $storageContext = New-AzStorageContext -StorageAccountName $storageAccount -UseConnectedAccount - - if ($env:BundleDir) { - $bundleFile = Get-Item "$env:BundleDir\*.msixbundle" - $blobName = $bundleFile | Split-Path -Leaf - $existing = Get-AzStorageBlob -Container $containerName -Blob $blobName -Context $storageContext -ErrorAction Ignore - if ($existing) { - Write-Verbose -Verbose "MSIX bundle already exists at '$storageAccount/$containerName/$blobName', removing first." - $existingBlob | Remove-AzStorageBlob -ErrorAction Stop -Verbose - } - - Write-Verbose -Verbose "Uploading $bundleFile to $containerName/$blobName" - Set-AzStorageBlobContent -File $bundleFile -Container $containerName -Blob $blobName -Context $storageContext -Force - } - else{ - throw "BundleDir not found" - } diff --git a/.pipelines/templates/uploadToAzure.yml b/.pipelines/templates/uploadToAzure.yml index 0994c7ef2b0..5f43ab4cd7f 100644 --- a/.pipelines/templates/uploadToAzure.yml +++ b/.pipelines/templates/uploadToAzure.yml @@ -25,6 +25,7 @@ jobs: value: $(Build.SourcesDirectory)\PowerShell\.config\suppress.json - name: ob_sdl_codeql_compiled_enabled value: false + - group: 'Azure Blob variable group' steps: - checkout: self @@ -38,6 +39,8 @@ jobs: CreateJson: yes UseJson: no + - template: /.pipelines/templates/release-SetReleaseTagandContainerName.yml@self + - template: /.pipelines/templates/cloneToOfficialPath.yml@self - pwsh: | @@ -231,6 +234,15 @@ jobs: targetPath: '$(Build.ArtifactStagingDirectory)/downloads' displayName: Download macos x64 packages + - task: DownloadPipelineArtifact@2 + inputs: + buildType: 'current' + artifact: drop_msixbundle_CreateMSIXBundle + itemPattern: | + **/*.msixbundle + targetPath: '$(Build.ArtifactStagingDirectory)/downloads' + displayName: Download MSIXBundle + - pwsh: | Get-ChildItem '$(Build.ArtifactStagingDirectory)/downloads' | Select-Object -ExpandProperty FullName displayName: 'Capture downloads' @@ -397,3 +409,26 @@ jobs: Write-Host "File $blobName uploaded to $containerName container." Move-Item -Path $_.FullName -Destination $uploadedDirectory -Force -Verbose } + + $msixbundleFiles = Get-ChildItem -Path $downloadsDirectory -Filter "*.msixbundle" + + $containerName = '$(OutputVersion.AzureVersion)-private' + $storageAccount = '$(StorageAccount)' + + $storageContext = New-AzStorageContext -StorageAccountName $storageAccount -UseConnectedAccount + + if ($msixbundleFiles) { + $bundleFile = $msixbundleFiles[0].FullName + $blobName = $msixbundleFiles[0].Name + + $existing = Get-AzStorageBlob -Container $containerName -Blob $blobName -Context $storageContext -ErrorAction Ignore + if ($existing) { + Write-Verbose -Verbose "MSIX bundle already exists at '$storageAccount/$containerName/$blobName', removing first." + $existing | Remove-AzStorageBlob -ErrorAction Stop -Verbose + } + + Write-Verbose -Verbose "Uploading $bundleFile to $containerName/$blobName" + Set-AzStorageBlobContent -File $bundleFile -Container $containerName -Blob $blobName -Context $storageContext -Force + } else { + throw "MSIXBundle not found in $downloadsDirectory" + } From 2240ac8f5a9dbf1788d7f3b5f6ef2de8778e630d Mon Sep 17 00:00:00 2001 From: PowerShell Team Bot <69177312+pwshBot@users.noreply.github.com> Date: Tue, 3 Jun 2025 13:09:50 -0700 Subject: [PATCH 127/173] [release/v7.5] Make inherited protected internal instance members accessible in class scope. (#25547) Co-authored-by: Matthias Wolf <78562192+mawosoft@users.noreply.github.com> --- .../engine/CoreAdapter.cs | 4 +- .../engine/runtime/Binding/Binders.cs | 16 +- .../scripting.Classes.inheritance.tests.ps1 | 206 ++++++++++++++++++ 3 files changed, 217 insertions(+), 9 deletions(-) diff --git a/src/System.Management.Automation/engine/CoreAdapter.cs b/src/System.Management.Automation/engine/CoreAdapter.cs index 6183f98a0aa..907060bfe49 100644 --- a/src/System.Management.Automation/engine/CoreAdapter.cs +++ b/src/System.Management.Automation/engine/CoreAdapter.cs @@ -2835,7 +2835,7 @@ internal PropertyCacheEntry(PropertyInfo property) // Get the public or protected getter MethodInfo propertyGetter = property.GetGetMethod(true); - if (propertyGetter != null && (propertyGetter.IsPublic || propertyGetter.IsFamily)) + if (propertyGetter != null && (propertyGetter.IsPublic || propertyGetter.IsFamily || propertyGetter.IsFamilyOrAssembly)) { this.isStatic = propertyGetter.IsStatic; // Delegate is initialized later to avoid jit if it's not called @@ -2847,7 +2847,7 @@ internal PropertyCacheEntry(PropertyInfo property) // Get the public or protected setter MethodInfo propertySetter = property.GetSetMethod(true); - if (propertySetter != null && (propertySetter.IsPublic || propertySetter.IsFamily)) + if (propertySetter != null && (propertySetter.IsPublic || propertySetter.IsFamily || propertySetter.IsFamilyOrAssembly)) { this.isStatic = propertySetter.IsStatic; } diff --git a/src/System.Management.Automation/engine/runtime/Binding/Binders.cs b/src/System.Management.Automation/engine/runtime/Binding/Binders.cs index f4020547432..18dfc8fb429 100644 --- a/src/System.Management.Automation/engine/runtime/Binding/Binders.cs +++ b/src/System.Management.Automation/engine/runtime/Binding/Binders.cs @@ -5297,7 +5297,8 @@ public override DynamicMetaObject FallbackGetMember(DynamicMetaObject target, Dy var propertyAccessor = adapterData.member as PropertyInfo; if (propertyAccessor != null) { - if (propertyAccessor.GetMethod.IsFamily && + var propertyGetter = propertyAccessor.GetMethod; + if ((propertyGetter.IsFamily || propertyGetter.IsFamilyOrAssembly) && (_classScope == null || !_classScope.IsSubclassOf(propertyAccessor.DeclaringType))) { return GenerateGetPropertyException(restrictions).WriteToDebugLog(this); @@ -5757,8 +5758,8 @@ internal PSMemberInfo GetPSMemberInfo(DynamicMetaObject target, var getMethod = propertyInfo.GetGetMethod(nonPublic: true); var setMethod = propertyInfo.GetSetMethod(nonPublic: true); - if ((getMethod == null || getMethod.IsFamily || getMethod.IsPublic) && - (setMethod == null || setMethod.IsFamily || setMethod.IsPublic)) + if ((getMethod == null || getMethod.IsPublic || getMethod.IsFamily || getMethod.IsFamilyOrAssembly) && + (setMethod == null || setMethod.IsPublic || setMethod.IsFamily || setMethod.IsFamilyOrAssembly)) { memberInfo = new PSProperty(this.Name, PSObject.DotNetInstanceAdapter, target.Value, new DotNetAdapter.PropertyCacheEntry(propertyInfo)); } @@ -5768,7 +5769,7 @@ internal PSMemberInfo GetPSMemberInfo(DynamicMetaObject target, var fieldInfo = member as FieldInfo; if (fieldInfo != null) { - if (fieldInfo.IsFamily) + if (fieldInfo.IsFamily || fieldInfo.IsFamilyOrAssembly) { memberInfo = new PSProperty(this.Name, PSObject.DotNetInstanceAdapter, target.Value, new DotNetAdapter.PropertyCacheEntry(fieldInfo)); } @@ -5776,7 +5777,7 @@ internal PSMemberInfo GetPSMemberInfo(DynamicMetaObject target, else { var methodInfo = member as MethodInfo; - if (methodInfo != null && (methodInfo.IsPublic || methodInfo.IsFamily)) + if (methodInfo != null && (methodInfo.IsPublic || methodInfo.IsFamily || methodInfo.IsFamilyOrAssembly)) { candidateMethods ??= new List(); @@ -6291,7 +6292,8 @@ public override DynamicMetaObject FallbackSetMember(DynamicMetaObject target, Dy var targetExpr = _static ? null : PSGetMemberBinder.GetTargetExpr(target, data.member.DeclaringType); if (propertyInfo != null) { - if (propertyInfo.SetMethod.IsFamily && + var propertySetter = propertyInfo.SetMethod; + if ((propertySetter.IsFamily || propertySetter.IsFamilyOrAssembly) && (_classScope == null || !_classScope.IsSubclassOf(propertyInfo.DeclaringType))) { return GeneratePropertyAssignmentException(restrictions).WriteToDebugLog(this); @@ -7891,7 +7893,7 @@ public override DynamicMetaObject FallbackInvokeMember(DynamicMetaObject target, ? BindingRestrictions.GetTypeRestriction(target.Expression, target.Value.GetType()) : target.PSGetTypeRestriction(); restrictions = args.Aggregate(restrictions, static (current, arg) => current.Merge(arg.PSGetMethodArgumentRestriction())); - var newConstructors = DotNetAdapter.GetMethodInformationArray(ctors.Where(static c => c.IsPublic || c.IsFamily).ToArray()); + var newConstructors = DotNetAdapter.GetMethodInformationArray(ctors.Where(static c => c.IsPublic || c.IsFamily || c.IsFamilyOrAssembly).ToArray()); return PSInvokeMemberBinder.InvokeDotNetMethod(_callInfo, "new", _constraints, PSInvokeMemberBinder.MethodInvocationType.BaseCtor, target, args, restrictions, newConstructors, typeof(MethodException)); } diff --git a/test/powershell/Language/Classes/scripting.Classes.inheritance.tests.ps1 b/test/powershell/Language/Classes/scripting.Classes.inheritance.tests.ps1 index af013076029..d10291353cd 100644 --- a/test/powershell/Language/Classes/scripting.Classes.inheritance.tests.ps1 +++ b/test/powershell/Language/Classes/scripting.Classes.inheritance.tests.ps1 @@ -672,3 +672,209 @@ Describe 'Base type has abstract properties' -Tags "CI" { $failure.Exception.Message | Should -BeLike "*'get_Exists'*" } } + +Describe 'Classes inheritance with protected and protected internal members in base class' -Tags 'CI' { + + BeforeAll { + Set-StrictMode -Version 3 + $c1DefinitionProtectedInternal = @' + public class C1ProtectedInternal + { + protected internal string InstanceField = "C1_InstanceField"; + protected internal string InstanceProperty { get; set; } = "C1_InstanceProperty"; + protected internal string InstanceMethod() { return "C1_InstanceMethod"; } + + protected internal virtual string VirtualProperty1 { get; set; } = "C1_VirtualProperty1"; + protected internal virtual string VirtualProperty2 { get; set; } = "C1_VirtualProperty2"; + protected internal virtual string VirtualMethod1() { return "C1_VirtualMethod1"; } + protected internal virtual string VirtualMethod2() { return "C1_VirtualMethod2"; } + + public string CtorUsed { get; set; } + public C1ProtectedInternal() { CtorUsed = "default ctor"; } + protected internal C1ProtectedInternal(string p1) { CtorUsed = "C1_ctor_1args:" + p1; } + } +'@ + $c2DefinitionProtectedInternal = @' + class C2ProtectedInternal : C1ProtectedInternal { + C2ProtectedInternal() : base() { $this.VirtualProperty2 = 'C2_VirtualProperty2' } + C2ProtectedInternal([string]$p1) : base($p1) { $this.VirtualProperty2 = 'C2_VirtualProperty2' } + + [string]GetInstanceField() { return $this.InstanceField } + [string]SetInstanceField([string]$value) { $this.InstanceField = $value; return $this.InstanceField } + [string]GetInstanceProperty() { return $this.InstanceProperty } + [string]SetInstanceProperty([string]$value) { $this.InstanceProperty = $value; return $this.InstanceProperty } + [string]CallInstanceMethod() { return $this.InstanceMethod() } + + [string]GetVirtualProperty1() { return $this.VirtualProperty1 } + [string]SetVirtualProperty1([string]$value) { $this.VirtualProperty1 = $value; return $this.VirtualProperty1 } + [string]CallVirtualMethod1() { return $this.VirtualMethod1() } + + [string]$VirtualProperty2 + [string]VirtualMethod2() { return 'C2_VirtualMethod2' } + # Note: Overriding a virtual property in a derived PowerShell class prevents access to the + # base property via simple typecast ([base]$this).VirtualProperty2. + [string]GetVirtualProperty2() { return $this.VirtualProperty2 } + [string]SetVirtualProperty2([string]$value) { $this.VirtualProperty2 = $value; return $this.VirtualProperty2 } + [string]CallVirtualMethod2Base() { return ([C1ProtectedInternal]$this).VirtualMethod2() } + [string]CallVirtualMethod2Derived() { return $this.VirtualMethod2() } + + [string]GetInstanceMemberDynamic([string]$name) { return $this.$name } + [string]SetInstanceMemberDynamic([string]$name, [string]$value) { $this.$name = $value; return $this.$name } + [string]CallInstanceMemberDynamic([string]$name) { return $this.$name() } + } + + [C2ProtectedInternal] +'@ + + Add-Type -TypeDefinition $c1DefinitionProtectedInternal + Add-Type -TypeDefinition (($c1DefinitionProtectedInternal -creplace 'C1ProtectedInternal', 'C1Protected') -creplace 'protected internal', 'protected') + + $testCases = @( + @{ accessType = 'protected'; derivedType = Invoke-Expression ($c2DefinitionProtectedInternal -creplace 'ProtectedInternal', 'Protected') } + @{ accessType = 'protected internal'; derivedType = Invoke-Expression $c2DefinitionProtectedInternal } + ) + } + + AfterAll { + Set-StrictMode -Off + } + + Context 'Derived class can access instance base class members' { + + It 'can call protected internal .NET method Object.MemberwiseClone()' { + class CNetMethod { + [string]$Foo + [object]CloneIt() { return $this.MemberwiseClone() } + } + $c1 = [CNetMethod]::new() + $c1.Foo = 'bar' + $c2 = $c1.CloneIt() + $c2.Foo | Should -Be 'bar' + } + + It 'can call base ctor' -TestCases $testCases { + param($derivedType) + $derivedType::new('foo').CtorUsed | Should -Be 'C1_ctor_1args:foo' + } + + It 'can access base field' -TestCases $testCases { + param($derivedType) + $c2 = $derivedType::new() + $c2.GetInstanceField() | Should -Be 'C1_InstanceField' + $c2.SetInstanceField('foo_InstanceField') | Should -Be 'foo_InstanceField' + } + + It 'can access base property' -TestCases $testCases { + param($derivedType) + $c2 = $derivedType::new() + $c2.GetInstanceProperty() | Should -Be 'C1_InstanceProperty' + $c2.SetInstanceProperty('foo_InstanceProperty') | Should -Be 'foo_InstanceProperty' + } + + It 'can call base method' -TestCases $testCases { + param($derivedType) + $derivedType::new().CallInstanceMethod() | Should -Be 'C1_InstanceMethod' + } + + It 'can access virtual base property' -TestCases $testCases { + param($derivedType) + $c2 = $derivedType::new() + $c2.GetVirtualProperty1() | Should -Be 'C1_VirtualProperty1' + $c2.SetVirtualProperty1('foo_VirtualProperty1') | Should -Be 'foo_VirtualProperty1' + } + + It 'can call virtual base method' -TestCases $testCases { + param($derivedType) + $derivedType::new().CallVirtualMethod1() | Should -Be 'C1_VirtualMethod1' + } + } + + Context 'Derived class can override virtual base class members' { + + It 'can override virtual base property' -TestCases $testCases { + param($derivedType) + $c2 = $derivedType::new() + $c2.GetVirtualProperty2() | Should -Be 'C2_VirtualProperty2' + $c2.SetVirtualProperty2('foo_VirtualProperty2') | Should -Be 'foo_VirtualProperty2' + } + + It 'can override virtual base method' -TestCases $testCases { + param($derivedType) + $c2 = $derivedType::new() + $c2.CallVirtualMethod2Base() | Should -Be 'C1_VirtualMethod2' + $c2.CallVirtualMethod2Derived() | Should -Be 'C2_VirtualMethod2' + } + } + + Context 'Derived class can access instance base class members dynamically' { + + It 'can access base fields and properties' -TestCases $testCases { + param($derivedType) + $c2 = $derivedType::new() + $c2.GetInstanceMemberDynamic('InstanceField') | Should -Be 'C1_InstanceField' + $c2.GetInstanceMemberDynamic('InstanceProperty') | Should -Be 'C1_InstanceProperty' + $c2.GetInstanceMemberDynamic('VirtualProperty1') | Should -Be 'C1_VirtualProperty1' + $c2.SetInstanceMemberDynamic('InstanceField', 'foo1') | Should -Be 'foo1' + $c2.SetInstanceMemberDynamic('InstanceProperty', 'foo2') | Should -Be 'foo2' + $c2.SetInstanceMemberDynamic('VirtualProperty1', 'foo3') | Should -Be 'foo3' + } + + It 'can call base methods' -TestCases $testCases { + param($derivedType) + $c2 = $derivedType::new() + $c2.CallInstanceMemberDynamic('InstanceMethod') | Should -Be 'C1_InstanceMethod' + $c2.CallInstanceMemberDynamic('VirtualMethod1') | Should -Be 'C1_VirtualMethod1' + } + } + + Context 'Base class members are not accessible outside class scope' { + + BeforeAll { + $instanceTest = { + $c2 = $derivedType::new() + { $null = $c2.InstanceField } | Should -Throw -ErrorId 'PropertyNotFoundStrict' + { $null = $c2.InstanceProperty } | Should -Throw -ErrorId 'PropertyNotFoundStrict' + { $null = $c2.VirtualProperty1 } | Should -Throw -ErrorId 'PropertyNotFoundStrict' + { $c2.InstanceField = 'foo' } | Should -Throw -ErrorId 'PropertyAssignmentException' + { $c2.InstanceProperty = 'foo' } | Should -Throw -ErrorId 'PropertyAssignmentException' + { $c2.VirtualProperty1 = 'foo' } | Should -Throw -ErrorId 'PropertyAssignmentException' + { $derivedType::new().InstanceMethod() } | Should -Throw -ErrorId 'MethodNotFound' + { $derivedType::new().VirtualMethod1() } | Should -Throw -ErrorId 'MethodNotFound' + foreach ($name in @('InstanceField', 'InstanceProperty', 'VirtualProperty1')) { + { $null = $c2.$name } | Should -Throw -ErrorId 'PropertyNotFoundStrict' + { $c2.$name = 'foo' } | Should -Throw -ErrorId 'PropertyAssignmentException' + } + foreach ($name in @('InstanceMethod', 'VirtualMethod1')) { + { $c2.$name() } | Should -Throw -ErrorId 'MethodNotFound' + } + } + $c3UnrelatedType = Invoke-Expression @" + class C3Unrelated { + [void]RunInstanceTest([type]`$derivedType) { $instanceTest } + } + [C3Unrelated] +"@ + $negativeTestCases = $testCases.ForEach({ + $item = $_.Clone() + $item['scopeType'] = 'null scope' + $item['classScope'] = $null + $item + $item = $_.Clone() + $item['scopeType'] = 'unrelated class scope' + $item['classScope'] = $c3UnrelatedType + $item + }) + } + + It 'cannot access instance base members in ' -TestCases $negativeTestCases { + param($derivedType, $classScope) + if ($null -eq $classScope) { + $instanceTest.Invoke() + } + else { + $c3 = $classScope::new() + $c3.RunInstanceTest($derivedType) + } + } + } +} From ebbb97c71b26bedec3e1b33300b626474d4c9a58 Mon Sep 17 00:00:00 2001 From: PowerShell Team Bot <69177312+pwshBot@users.noreply.github.com> Date: Tue, 3 Jun 2025 13:20:38 -0700 Subject: [PATCH 128/173] [release/v7.5] Fix MSIX artifact upload, vPack template, changelog hashes, git tag command (#25633) Co-authored-by: Justin Chung <124807742+jshigetomi@users.noreply.github.com> Co-authored-by: Travis Plunk --- .pipelines/PowerShell-Release-Official.yml | 13 +--- .pipelines/PowerShell-vPack-Official.yml | 2 +- .pipelines/templates/package-create-msix.yml | 8 +- .pipelines/templates/release-githubNuget.yml | 82 ++++++++++++++------ 4 files changed, 64 insertions(+), 41 deletions(-) diff --git a/.pipelines/PowerShell-Release-Official.yml b/.pipelines/PowerShell-Release-Official.yml index 71ff540cacd..55c6ec1c486 100644 --- a/.pipelines/PowerShell-Release-Official.yml +++ b/.pipelines/PowerShell-Release-Official.yml @@ -325,17 +325,6 @@ extends: instructions: | Run PowerShell-Release-Official-Azure.yml pipeline to publish to PMC - - stage: ReleaseDocker - dependsOn: PushGitTagAndMakeDraftPublic - displayName: 'Docker Release' - jobs: - - template: /.pipelines/templates/approvalJob.yml@self - parameters: - displayName: Start Docker Release - jobName: StartDockerRelease - instructions: | - Kickoff docker release - - stage: UpdateDotnetDocker dependsOn: PushGitTagAndMakeDraftPublic displayName: Update DotNet SDK Docker images @@ -348,7 +337,7 @@ extends: Create PR for updating dotnet-docker images to use latest PowerShell version. 1. Fork and clone https://github.com/dotnet/dotnet-docker.git 2. git checkout upstream/nightly -b updatePS - 3. dotnet run --project .\eng\update-dependencies\ -- --product-version powershell= --compute-shas + 3. dotnet run --project .\eng\update-dependencies\ specific --product-version powershell= --compute-shas 4. create PR targeting nightly branch - stage: UpdateWinGet diff --git a/.pipelines/PowerShell-vPack-Official.yml b/.pipelines/PowerShell-vPack-Official.yml index 829e374e606..9a9aceed387 100644 --- a/.pipelines/PowerShell-vPack-Official.yml +++ b/.pipelines/PowerShell-vPack-Official.yml @@ -118,7 +118,7 @@ extends: ob_createvpack_verbose: true steps: - - template: ./templates/SetVersionVariables.yml + - template: .pipelines/templates/SetVersionVariables.yml@self parameters: ReleaseTagVar: $(ReleaseTagVar) CreateJson: yes diff --git a/.pipelines/templates/package-create-msix.yml b/.pipelines/templates/package-create-msix.yml index 0ab2408e6a7..c8312ad926e 100644 --- a/.pipelines/templates/package-create-msix.yml +++ b/.pipelines/templates/package-create-msix.yml @@ -99,11 +99,13 @@ jobs: $signedBundle = Get-ChildItem -Path $(BundleDir) -Filter "*.msixbundle" -File Write-Verbose -Verbose "Signed bundle: $signedBundle" - if (-not (Test-Path $(ob_outputDirectory))) { - New-Item -ItemType Directory -Path $(ob_outputDirectory) -Force + # Ensure the destination directory exists + if (-not (Test-Path -Path "$(ob_outputDirectory)")) { + Write-Verbose -Verbose "Creating destination directory: $(ob_outputDirectory)" + New-Item -Path "$(ob_outputDirectory)" -ItemType Directory -Force | Out-Null } - Copy-Item -Path $signedBundle.FullName -Destination "$(ob_outputDirectory)" -Verbose + Copy-Item -Path $signedBundle.FullName -Destination "$(ob_outputDirectory)\$($signedBundle.Name)" -Verbose Write-Verbose -Verbose "Uploaded Bundle:" Get-ChildItem -Path $(ob_outputDirectory) | Write-Verbose -Verbose diff --git a/.pipelines/templates/release-githubNuget.yml b/.pipelines/templates/release-githubNuget.yml index 8aca980eff2..ba0db845bfd 100644 --- a/.pipelines/templates/release-githubNuget.yml +++ b/.pipelines/templates/release-githubNuget.yml @@ -30,12 +30,9 @@ jobs: Get-ChildItem Env: | Out-String -Stream | Write-Verbose -Verbose displayName: 'Capture Environment Variables' - - template: release-install-pwsh.yml - - task: PowerShell@2 inputs: targetType: inline - pwsh: true script: | $Path = "$(Pipeline.Workspace)/GitHubPackages" $OutputPath = Join-Path $Path 'hashes.sha256' @@ -56,7 +53,6 @@ jobs: - task: PowerShell@2 inputs: targetType: inline - pwsh: true script: | Get-ChildItem $(Pipeline.Workspace) -recurse | Select-Object -ExpandProperty FullName displayName: List all files in the workspace @@ -64,7 +60,6 @@ jobs: - task: PowerShell@2 inputs: targetType: inline - pwsh: true script: | $releaseVersion = '$(ReleaseTag)' -replace '^v','' Write-Verbose -Verbose "Available modules: " @@ -85,6 +80,17 @@ jobs: $clContent = $changelog | Select-Object -Skip ($startLine-1) -First ($endLine - $startLine) | Out-String + $StringBuilder = [System.Text.StringBuilder]::new($clContent, $clContent.Length + 2kb) + $StringBuilder.AppendLine().AppendLine() > $null + $StringBuilder.AppendLine("### SHA256 Hashes of the release artifacts").AppendLine() > $null + Get-ChildItem -Path "$(Pipeline.Workspace)/GitHubPackages/" -File | ForEach-Object { + $PackageName = $_.Name + $SHA256 = (Get-FileHash -Path $_.FullName -Algorithm SHA256).Hash + $StringBuilder.AppendLine("- $PackageName").AppendLine(" - $SHA256") > $null + } + + $clContent = $StringBuilder.ToString() + Write-Verbose -Verbose "Selected content: `n$clContent" $releaseNotesFilePath = "$(Pipeline.Workspace)/release-notes.md" @@ -100,11 +106,32 @@ jobs: } displayName: Set variables for GitHub release task - - pwsh: | - Write-Host "ReleaseNotes content:" - Get-Content "$(Pipeline.Workspace)/release-notes.md" -Raw | Out-String -width 9999 | Write-Host + - task: PowerShell@2 + inputs: + targetType: inline + script: | + Write-Host "ReleaseNotes content:" + Get-Content "$(Pipeline.Workspace)/release-notes.md" -Raw | Out-String -width 9999 | Write-Host displayName: Verify Release Notes + - task: PowerShell@2 + inputs: + targetType: inline + script: | + $middleURL = '' + $tagString = "$(ReleaseTag)" + Write-Verbose -Verbose "Use the following command to push the tag:" + if ($tagString -match '-') { + $middleURL = "preview" + } + elseif ($tagString -match '(\d+\.\d+)') { + $middleURL = $matches[1] + } + $endURL = $tagString -replace '[v\.]','' + $message = "https://github.com/PowerShell/PowerShell/blob/master/CHANGELOG/$middleURL.md#$endURL" + Write-Verbose -Verbose "git tag -a $(ReleaseTag) $env:BUILD_SOURCEVERSION -m $message" + displayName: Git Push Tag Command + - task: GitHubRelease@1 inputs: gitHubConnection: GitHubReleasePAT @@ -113,6 +140,7 @@ jobs: assets: '$(Pipeline.Workspace)/GitHubPackages/*' tagSource: 'userSpecifiedTag' tag: '$(ReleaseTag)' + title: "$(ReleaseTag) Release of PowerShell" isDraft: true addChangeLog: false action: 'create' @@ -136,28 +164,32 @@ jobs: VERSION: $[ stageDependencies.setReleaseTagAndChangelog.SetTagAndChangelog.outputs['OutputVersion.Version'] ] steps: - - template: release-install-pwsh.yml - - - pwsh: | - Write-Verbose -Verbose "Version: $(Version)" - Get-ChildItem Env: | Out-String -width 9999 -Stream | write-Verbose -Verbose + - task: PowerShell@2 + inputs: + targetType: inline + script: | + Write-Verbose -Verbose "Version: $(Version)" + Get-ChildItem Env: | Out-String -width 9999 -Stream | write-Verbose -Verbose displayName: 'Capture Environment Variables' - - pwsh: | - #Exclude all global tool packages. Their names start with 'PowerShell.' - $null = New-Item -ItemType Directory -Path "$(Pipeline.Workspace)/release" - Copy-Item "$(Pipeline.Workspace)/NuGetPackages/*.nupkg" -Destination "$(Pipeline.Workspace)/release" -Exclude "PowerShell.*.nupkg" -Force -Verbose + - task: PowerShell@2 + inputs: + targetType: inline + script: | + #Exclude all global tool packages. Their names start with 'PowerShell.' + $null = New-Item -ItemType Directory -Path "$(Pipeline.Workspace)/release" + Copy-Item "$(Pipeline.Workspace)/NuGetPackages/*.nupkg" -Destination "$(Pipeline.Workspace)/release" -Exclude "PowerShell.*.nupkg" -Force -Verbose - $releaseVersion = '$(Version)' - $globalToolPath = "$(Pipeline.Workspace)/NuGetPackages/PowerShell.$releaseVersion.nupkg" + $releaseVersion = '$(Version)' + $globalToolPath = "$(Pipeline.Workspace)/NuGetPackages/PowerShell.$releaseVersion.nupkg" - if ($releaseVersion -notlike '*-*') { - # Copy the global tool package for stable releases - Copy-Item $globalToolPath -Destination "$(Pipeline.Workspace)/release" - } + if ($releaseVersion -notlike '*-*') { + # Copy the global tool package for stable releases + Copy-Item $globalToolPath -Destination "$(Pipeline.Workspace)/release" + } - Write-Verbose -Verbose "The .nupkgs below will be pushed:" - Get-ChildItem "$(Pipeline.Workspace)/release" -recurse + Write-Verbose -Verbose "The .nupkgs below will be pushed:" + Get-ChildItem "$(Pipeline.Workspace)/release" -recurse displayName: Download and capture nupkgs condition: and(ne('${{ parameters.skipPublish }}', 'false'), succeeded()) From 8249040f1ee1be3b76705034ea94b45b4c8e8716 Mon Sep 17 00:00:00 2001 From: PowerShell Team Bot <69177312+pwshBot@users.noreply.github.com> Date: Wed, 4 Jun 2025 15:22:16 -0700 Subject: [PATCH 129/173] [release/v7.5] Change linux packaging tests to ubuntu latest (#25639) Co-authored-by: Travis Plunk --- .vsts-ci/linux.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.vsts-ci/linux.yml b/.vsts-ci/linux.yml index 338821e37dd..b386b9c7eb3 100644 --- a/.vsts-ci/linux.yml +++ b/.vsts-ci/linux.yml @@ -67,7 +67,7 @@ stages: jobs: - template: templates/ci-build.yml parameters: - pool: ubuntu-20.04 + pool: ubuntu-latest jobName: linux_build displayName: linux Build @@ -77,4 +77,4 @@ stages: jobs: - template: linux/templates/packaging.yml parameters: - pool: ubuntu-20.04 + pool: ubuntu-latest From cd6b4d8f53f111fb27dc5fefba4af64e7d1de3c0 Mon Sep 17 00:00:00 2001 From: PowerShell Team Bot <69177312+pwshBot@users.noreply.github.com> Date: Wed, 4 Jun 2025 16:04:40 -0700 Subject: [PATCH 130/173] [release/v7.5] Set standard handles explicitly when starting a process with `-NoNewWindow` (#25324) Co-authored-by: Dongbo Wang Co-authored-by: Travis Plunk --- .../commands/management/Process.cs | 44 ++++++++++++++++--- .../Start-Process.Tests.ps1 | 14 ++++++ 2 files changed, 52 insertions(+), 6 deletions(-) diff --git a/src/Microsoft.PowerShell.Commands.Management/commands/management/Process.cs b/src/Microsoft.PowerShell.Commands.Management/commands/management/Process.cs index 73f00b5acc6..4ca7d9aaa5b 100644 --- a/src/Microsoft.PowerShell.Commands.Management/commands/management/Process.cs +++ b/src/Microsoft.PowerShell.Commands.Management/commands/management/Process.cs @@ -1677,7 +1677,7 @@ public SwitchParameter LoadUserProfile private SwitchParameter _loaduserprofile = SwitchParameter.Present; /// - /// Starts process in a new window. + /// Starts process in the current console window. /// [Parameter(ParameterSetName = "Default")] [Alias("nnw")] @@ -1965,7 +1965,9 @@ protected override void BeginProcessing() startInfo.WindowStyle = _windowstyle; - if (_nonewwindow) + // When starting a process as another user, the 'CreateNoWindow' property value is ignored and a new window is created. + // See details at https://learn.microsoft.com/dotnet/api/system.diagnostics.processstartinfo.createnowindow?view=net-9.0#remarks + if (_nonewwindow && _credential is null) { startInfo.CreateNoWindow = _nonewwindow; } @@ -2413,33 +2415,60 @@ private static byte[] ConvertEnvVarsToByteArray(StringDictionary sd) private void SetStartupInfo(ProcessStartInfo startinfo, ref ProcessNativeMethods.STARTUPINFO lpStartupInfo, ref int creationFlags) { - bool hasRedirection = false; + // If we are starting a process using the current console window, we need to set its standard handles + // explicitly when they are not redirected because otherwise they won't be set and the new process will + // fail with the "invalid handle" error. + // + // However, if we are starting a process with a new console window, we should not explicitly set those + // standard handles when they are not redirected, but instead let Windows figure out the default to use + // when creating the process. Otherwise, the standard input handles of the current window and the new + // window will get weirdly tied together and cause problems. + bool hasRedirection = startinfo.CreateNoWindow + || _redirectstandardinput is not null + || _redirectstandardoutput is not null + || _redirectstandarderror is not null; + // RedirectionStandardInput if (_redirectstandardinput != null) { - hasRedirection = true; startinfo.RedirectStandardInput = true; _redirectstandardinput = ResolveFilePath(_redirectstandardinput); lpStartupInfo.hStdInput = GetSafeFileHandleForRedirection(_redirectstandardinput, FileMode.Open); } + else if (startinfo.CreateNoWindow) + { + lpStartupInfo.hStdInput = new SafeFileHandle( + ProcessNativeMethods.GetStdHandle(-10), + ownsHandle: false); + } // RedirectionStandardOutput if (_redirectstandardoutput != null) { - hasRedirection = true; startinfo.RedirectStandardOutput = true; _redirectstandardoutput = ResolveFilePath(_redirectstandardoutput); lpStartupInfo.hStdOutput = GetSafeFileHandleForRedirection(_redirectstandardoutput, FileMode.Create); } + else if (startinfo.CreateNoWindow) + { + lpStartupInfo.hStdOutput = new SafeFileHandle( + ProcessNativeMethods.GetStdHandle(-11), + ownsHandle: false); + } // RedirectionStandardError if (_redirectstandarderror != null) { - hasRedirection = true; startinfo.RedirectStandardError = true; _redirectstandarderror = ResolveFilePath(_redirectstandarderror); lpStartupInfo.hStdError = GetSafeFileHandleForRedirection(_redirectstandarderror, FileMode.Create); } + else if (startinfo.CreateNoWindow) + { + lpStartupInfo.hStdError = new SafeFileHandle( + ProcessNativeMethods.GetStdHandle(-12), + ownsHandle: false); + } if (hasRedirection) { @@ -2881,6 +2910,9 @@ internal struct JOBOBJECT_BASIC_PROCESS_ID_LIST internal static class ProcessNativeMethods { + [DllImport(PinvokeDllNames.GetStdHandleDllName, SetLastError = true)] + public static extern IntPtr GetStdHandle(int whichHandle); + [DllImport(PinvokeDllNames.CreateProcessWithLogonWDllName, CharSet = CharSet.Unicode, SetLastError = true, ExactSpelling = true)] [return: MarshalAs(UnmanagedType.Bool)] internal static extern bool CreateProcessWithLogonW(string userName, diff --git a/test/powershell/Modules/Microsoft.PowerShell.Management/Start-Process.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Management/Start-Process.Tests.ps1 index 50cde0bae6e..65dd74e1b94 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Management/Start-Process.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Management/Start-Process.Tests.ps1 @@ -241,3 +241,17 @@ Describe "Environment Tests" -Tags "Feature" { } } } + +Describe "Bug fixes" -Tags "CI" { + + ## https://github.com/PowerShell/PowerShell/issues/24986 + It "Error redirection along with '-NoNewWindow' should work for Start-Process" -Skip:(!$IsWindows) { + $errorFile = Join-Path -Path $TestDrive -ChildPath error.txt + $out = pwsh -noprofile -c "Start-Process -Wait -NoNewWindow -RedirectStandardError $errorFile -FilePath cmd -ArgumentList '/C echo Hello'" + + ## 'Hello' should be sent to standard output; 'error.txt' file should be created but empty. + $out | Should -BeExactly "Hello" + Test-Path -Path $errorFile | Should -BeTrue + (Get-Item $errorFile).Length | Should -Be 0 + } +} From 366625448efe12351e9bda85cc3f6f545abc927b Mon Sep 17 00:00:00 2001 From: PowerShell GitHub Bot Date: Tue, 10 Jun 2025 22:11:43 +0000 Subject: [PATCH 131/173] Update .NET SDK to latest version --- DotnetRuntimeMetadata.json | 2 +- global.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/DotnetRuntimeMetadata.json b/DotnetRuntimeMetadata.json index f78f43e709b..a97818844d0 100644 --- a/DotnetRuntimeMetadata.json +++ b/DotnetRuntimeMetadata.json @@ -4,7 +4,7 @@ "quality": "daily", "qualityFallback": "preview", "packageVersionPattern": "9.0.0-preview.6", - "sdkImageVersion": "9.0.203", + "sdkImageVersion": "9.0.301", "nextChannel": "9.0.0-preview.7", "azureFeed": "", "sdkImageOverride": "" diff --git a/global.json b/global.json index e4da652c648..2808b362fea 100644 --- a/global.json +++ b/global.json @@ -1,5 +1,5 @@ { "sdk": { - "version": "9.0.203" + "version": "9.0.301" } } From b8ff7f903984d1f66741a0903fc1915a30ca63c1 Mon Sep 17 00:00:00 2001 From: PowerShell GitHub Bot Date: Tue, 10 Jun 2025 22:21:41 +0000 Subject: [PATCH 132/173] Update package references --- ...oft.PowerShell.Commands.Diagnostics.csproj | 8 +- ...soft.PowerShell.Commands.Management.csproj | 4 +- ...crosoft.PowerShell.Commands.Utility.csproj | 6 +- ...crosoft.PowerShell.CoreCLR.Eventing.csproj | 2 +- .../Microsoft.PowerShell.SDK.csproj | 100 +++++++++--------- .../Microsoft.WSMan.Management.csproj | 4 +- .../System.Management.Automation.csproj | 24 ++--- .../BenchmarkDotNet.Extensions.csproj | 2 +- .../ResultsComparer/ResultsComparer.csproj | 2 +- ...soft.PowerShell.NamedPipeConnection.csproj | 26 ++--- test/tools/TestService/TestService.csproj | 94 ++++++++-------- test/tools/WebListener/WebListener.csproj | 6 +- 12 files changed, 139 insertions(+), 139 deletions(-) diff --git a/src/Microsoft.PowerShell.Commands.Diagnostics/Microsoft.PowerShell.Commands.Diagnostics.csproj b/src/Microsoft.PowerShell.Commands.Diagnostics/Microsoft.PowerShell.Commands.Diagnostics.csproj index 4952c8f6ad4..af93c4c2bf4 100644 --- a/src/Microsoft.PowerShell.Commands.Diagnostics/Microsoft.PowerShell.Commands.Diagnostics.csproj +++ b/src/Microsoft.PowerShell.Commands.Diagnostics/Microsoft.PowerShell.Commands.Diagnostics.csproj @@ -7,11 +7,11 @@ - - - + + + - + diff --git a/src/Microsoft.PowerShell.Commands.Management/Microsoft.PowerShell.Commands.Management.csproj b/src/Microsoft.PowerShell.Commands.Management/Microsoft.PowerShell.Commands.Management.csproj index 4fe6ed61803..d4c5da64bae 100644 --- a/src/Microsoft.PowerShell.Commands.Management/Microsoft.PowerShell.Commands.Management.csproj +++ b/src/Microsoft.PowerShell.Commands.Management/Microsoft.PowerShell.Commands.Management.csproj @@ -47,8 +47,8 @@ - - + + diff --git a/src/Microsoft.PowerShell.Commands.Utility/Microsoft.PowerShell.Commands.Utility.csproj b/src/Microsoft.PowerShell.Commands.Utility/Microsoft.PowerShell.Commands.Utility.csproj index 1cc347541a2..8fe2b24b05f 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/Microsoft.PowerShell.Commands.Utility.csproj +++ b/src/Microsoft.PowerShell.Commands.Utility/Microsoft.PowerShell.Commands.Utility.csproj @@ -13,7 +13,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive all - + @@ -41,8 +41,8 @@ - - + + diff --git a/src/Microsoft.PowerShell.CoreCLR.Eventing/Microsoft.PowerShell.CoreCLR.Eventing.csproj b/src/Microsoft.PowerShell.CoreCLR.Eventing/Microsoft.PowerShell.CoreCLR.Eventing.csproj index e5f5b849645..b88db6c5e62 100644 --- a/src/Microsoft.PowerShell.CoreCLR.Eventing/Microsoft.PowerShell.CoreCLR.Eventing.csproj +++ b/src/Microsoft.PowerShell.CoreCLR.Eventing/Microsoft.PowerShell.CoreCLR.Eventing.csproj @@ -8,7 +8,7 @@ - + diff --git a/src/Microsoft.PowerShell.SDK/Microsoft.PowerShell.SDK.csproj b/src/Microsoft.PowerShell.SDK/Microsoft.PowerShell.SDK.csproj index 1d1fc2f1291..f1feac7c371 100644 --- a/src/Microsoft.PowerShell.SDK/Microsoft.PowerShell.SDK.csproj +++ b/src/Microsoft.PowerShell.SDK/Microsoft.PowerShell.SDK.csproj @@ -17,55 +17,55 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - + + + + + + + - - - - - - - - - - - - - - + + + + + + + + + + + + + + - - + + - + diff --git a/src/Microsoft.WSMan.Management/Microsoft.WSMan.Management.csproj b/src/Microsoft.WSMan.Management/Microsoft.WSMan.Management.csproj index db972fa45c8..087d4562069 100644 --- a/src/Microsoft.WSMan.Management/Microsoft.WSMan.Management.csproj +++ b/src/Microsoft.WSMan.Management/Microsoft.WSMan.Management.csproj @@ -7,11 +7,11 @@ - + - + diff --git a/src/System.Management.Automation/System.Management.Automation.csproj b/src/System.Management.Automation/System.Management.Automation.csproj index afc4c178cb3..030f6654237 100644 --- a/src/System.Management.Automation/System.Management.Automation.csproj +++ b/src/System.Management.Automation/System.Management.Automation.csproj @@ -32,25 +32,25 @@ - - - - - - + + + + + + - + - - - - + + + + - + diff --git a/test/perf/dotnet-tools/BenchmarkDotNet.Extensions/BenchmarkDotNet.Extensions.csproj b/test/perf/dotnet-tools/BenchmarkDotNet.Extensions/BenchmarkDotNet.Extensions.csproj index 6f6ef0087ab..b8568a0e373 100644 --- a/test/perf/dotnet-tools/BenchmarkDotNet.Extensions/BenchmarkDotNet.Extensions.csproj +++ b/test/perf/dotnet-tools/BenchmarkDotNet.Extensions/BenchmarkDotNet.Extensions.csproj @@ -13,7 +13,7 @@ - + diff --git a/test/perf/dotnet-tools/ResultsComparer/ResultsComparer.csproj b/test/perf/dotnet-tools/ResultsComparer/ResultsComparer.csproj index 164023a0f62..a7ec51fdcf7 100644 --- a/test/perf/dotnet-tools/ResultsComparer/ResultsComparer.csproj +++ b/test/perf/dotnet-tools/ResultsComparer/ResultsComparer.csproj @@ -13,7 +13,7 @@ - + diff --git a/test/tools/NamedPipeConnection/src/code/Microsoft.PowerShell.NamedPipeConnection.csproj b/test/tools/NamedPipeConnection/src/code/Microsoft.PowerShell.NamedPipeConnection.csproj index aa15f08cb56..a813503467c 100644 --- a/test/tools/NamedPipeConnection/src/code/Microsoft.PowerShell.NamedPipeConnection.csproj +++ b/test/tools/NamedPipeConnection/src/code/Microsoft.PowerShell.NamedPipeConnection.csproj @@ -17,21 +17,21 @@ - + - - - - - - - + + + + + + + - - - - - + + + + + diff --git a/test/tools/TestService/TestService.csproj b/test/tools/TestService/TestService.csproj index 31a95e0b875..8215dfb01d1 100644 --- a/test/tools/TestService/TestService.csproj +++ b/test/tools/TestService/TestService.csproj @@ -15,56 +15,56 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - + + + + + - - - - - - - - + + + + + + + + - + diff --git a/test/tools/WebListener/WebListener.csproj b/test/tools/WebListener/WebListener.csproj index b609555c9ad..9f6fb2ce79a 100644 --- a/test/tools/WebListener/WebListener.csproj +++ b/test/tools/WebListener/WebListener.csproj @@ -7,9 +7,9 @@ - - + + - + From eea41ea52e0bbcd2339b0fe7704221dd4eb0d8f9 Mon Sep 17 00:00:00 2001 From: PowerShell GitHub Bot Date: Tue, 10 Jun 2025 22:23:19 +0000 Subject: [PATCH 133/173] Update cgmanifest --- tools/cgmanifest.json | 116 +++++++++++++++++++----------------------- 1 file changed, 53 insertions(+), 63 deletions(-) diff --git a/tools/cgmanifest.json b/tools/cgmanifest.json index e64601d8eaf..13f35eb8dd2 100644 --- a/tools/cgmanifest.json +++ b/tools/cgmanifest.json @@ -115,7 +115,7 @@ "Type": "nuget", "Nuget": { "Name": "Microsoft.Extensions.ObjectPool", - "Version": "8.0.15" + "Version": "8.0.17" } }, "DevelopmentDependency": false @@ -155,17 +155,7 @@ "Type": "nuget", "Nuget": { "Name": "Microsoft.Win32.Registry.AccessControl", - "Version": "9.0.4" - } - }, - "DevelopmentDependency": false - }, - { - "Component": { - "Type": "nuget", - "Nuget": { - "Name": "Microsoft.Win32.Registry", - "Version": "5.0.0" + "Version": "9.0.6" } }, "DevelopmentDependency": false @@ -175,7 +165,7 @@ "Type": "nuget", "Nuget": { "Name": "Microsoft.Win32.SystemEvents", - "Version": "9.0.4" + "Version": "9.0.6" } }, "DevelopmentDependency": false @@ -185,7 +175,7 @@ "Type": "nuget", "Nuget": { "Name": "Microsoft.Windows.Compatibility", - "Version": "9.0.4" + "Version": "9.0.6" } }, "DevelopmentDependency": false @@ -205,7 +195,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.android-arm.runtime.native.System.IO.Ports", - "Version": "9.0.4" + "Version": "9.0.6" } }, "DevelopmentDependency": false @@ -215,7 +205,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.android-arm64.runtime.native.System.IO.Ports", - "Version": "9.0.4" + "Version": "9.0.6" } }, "DevelopmentDependency": false @@ -225,7 +215,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.android-x64.runtime.native.System.IO.Ports", - "Version": "9.0.4" + "Version": "9.0.6" } }, "DevelopmentDependency": false @@ -235,7 +225,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.android-x86.runtime.native.System.IO.Ports", - "Version": "9.0.4" + "Version": "9.0.6" } }, "DevelopmentDependency": false @@ -245,7 +235,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.linux-arm.runtime.native.System.IO.Ports", - "Version": "9.0.4" + "Version": "9.0.6" } }, "DevelopmentDependency": false @@ -255,7 +245,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.linux-arm64.runtime.native.System.IO.Ports", - "Version": "9.0.4" + "Version": "9.0.6" } }, "DevelopmentDependency": false @@ -265,7 +255,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.linux-bionic-arm64.runtime.native.System.IO.Ports", - "Version": "9.0.4" + "Version": "9.0.6" } }, "DevelopmentDependency": false @@ -275,7 +265,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.linux-bionic-x64.runtime.native.System.IO.Ports", - "Version": "9.0.4" + "Version": "9.0.6" } }, "DevelopmentDependency": false @@ -285,7 +275,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.linux-musl-arm.runtime.native.System.IO.Ports", - "Version": "9.0.4" + "Version": "9.0.6" } }, "DevelopmentDependency": false @@ -295,7 +285,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.linux-musl-arm64.runtime.native.System.IO.Ports", - "Version": "9.0.4" + "Version": "9.0.6" } }, "DevelopmentDependency": false @@ -305,7 +295,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.linux-musl-x64.runtime.native.System.IO.Ports", - "Version": "9.0.4" + "Version": "9.0.6" } }, "DevelopmentDependency": false @@ -315,7 +305,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.linux-x64.runtime.native.System.IO.Ports", - "Version": "9.0.4" + "Version": "9.0.6" } }, "DevelopmentDependency": false @@ -325,7 +315,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.maccatalyst-arm64.runtime.native.System.IO.Ports", - "Version": "9.0.4" + "Version": "9.0.6" } }, "DevelopmentDependency": false @@ -335,7 +325,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.maccatalyst-x64.runtime.native.System.IO.Ports", - "Version": "9.0.4" + "Version": "9.0.6" } }, "DevelopmentDependency": false @@ -345,7 +335,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.native.System.Data.SqlClient.sni", - "Version": "4.7.0" + "Version": "4.4.0" } }, "DevelopmentDependency": false @@ -355,7 +345,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.native.System.IO.Ports", - "Version": "9.0.4" + "Version": "9.0.6" } }, "DevelopmentDependency": false @@ -365,7 +355,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.osx-arm64.runtime.native.System.IO.Ports", - "Version": "9.0.4" + "Version": "9.0.6" } }, "DevelopmentDependency": false @@ -375,7 +365,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.osx-x64.runtime.native.System.IO.Ports", - "Version": "9.0.4" + "Version": "9.0.6" } }, "DevelopmentDependency": false @@ -435,7 +425,7 @@ "Type": "nuget", "Nuget": { "Name": "System.CodeDom", - "Version": "9.0.4" + "Version": "9.0.6" } }, "DevelopmentDependency": false @@ -455,7 +445,7 @@ "Type": "nuget", "Nuget": { "Name": "System.ComponentModel.Composition.Registration", - "Version": "9.0.4" + "Version": "9.0.6" } }, "DevelopmentDependency": false @@ -465,7 +455,7 @@ "Type": "nuget", "Nuget": { "Name": "System.ComponentModel.Composition", - "Version": "9.0.4" + "Version": "9.0.6" } }, "DevelopmentDependency": false @@ -475,7 +465,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Configuration.ConfigurationManager", - "Version": "9.0.4" + "Version": "9.0.6" } }, "DevelopmentDependency": false @@ -485,7 +475,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Data.Odbc", - "Version": "9.0.4" + "Version": "9.0.6" } }, "DevelopmentDependency": false @@ -495,7 +485,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Data.OleDb", - "Version": "9.0.4" + "Version": "9.0.6" } }, "DevelopmentDependency": false @@ -505,7 +495,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Data.SqlClient", - "Version": "4.8.6" + "Version": "4.9.0" } }, "DevelopmentDependency": false @@ -515,7 +505,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Diagnostics.DiagnosticSource", - "Version": "9.0.4" + "Version": "9.0.6" } }, "DevelopmentDependency": false @@ -525,7 +515,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Diagnostics.EventLog", - "Version": "9.0.4" + "Version": "9.0.6" } }, "DevelopmentDependency": false @@ -535,7 +525,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Diagnostics.PerformanceCounter", - "Version": "9.0.4" + "Version": "9.0.6" } }, "DevelopmentDependency": false @@ -545,7 +535,7 @@ "Type": "nuget", "Nuget": { "Name": "System.DirectoryServices.AccountManagement", - "Version": "9.0.4" + "Version": "9.0.6" } }, "DevelopmentDependency": false @@ -555,7 +545,7 @@ "Type": "nuget", "Nuget": { "Name": "System.DirectoryServices.Protocols", - "Version": "9.0.4" + "Version": "9.0.6" } }, "DevelopmentDependency": false @@ -565,7 +555,7 @@ "Type": "nuget", "Nuget": { "Name": "System.DirectoryServices", - "Version": "9.0.4" + "Version": "9.0.6" } }, "DevelopmentDependency": false @@ -575,7 +565,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Drawing.Common", - "Version": "9.0.4" + "Version": "9.0.6" } }, "DevelopmentDependency": false @@ -585,7 +575,7 @@ "Type": "nuget", "Nuget": { "Name": "System.IO.Packaging", - "Version": "9.0.4" + "Version": "9.0.6" } }, "DevelopmentDependency": false @@ -595,7 +585,7 @@ "Type": "nuget", "Nuget": { "Name": "System.IO.Ports", - "Version": "9.0.4" + "Version": "9.0.6" } }, "DevelopmentDependency": false @@ -605,7 +595,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Management", - "Version": "9.0.4" + "Version": "9.0.6" } }, "DevelopmentDependency": false @@ -615,7 +605,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Net.Http.WinHttpHandler", - "Version": "9.0.4" + "Version": "9.0.6" } }, "DevelopmentDependency": false @@ -645,7 +635,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Reflection.Context", - "Version": "9.0.4" + "Version": "9.0.6" } }, "DevelopmentDependency": false @@ -675,7 +665,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Runtime.Caching", - "Version": "9.0.4" + "Version": "9.0.6" } }, "DevelopmentDependency": false @@ -695,7 +685,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Security.Cryptography.Pkcs", - "Version": "9.0.4" + "Version": "9.0.6" } }, "DevelopmentDependency": false @@ -705,7 +695,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Security.Cryptography.ProtectedData", - "Version": "9.0.4" + "Version": "9.0.6" } }, "DevelopmentDependency": false @@ -715,7 +705,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Security.Cryptography.Xml", - "Version": "9.0.4" + "Version": "9.0.6" } }, "DevelopmentDependency": false @@ -725,7 +715,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Security.Permissions", - "Version": "9.0.4" + "Version": "9.0.6" } }, "DevelopmentDependency": false @@ -795,7 +785,7 @@ "Type": "nuget", "Nuget": { "Name": "System.ServiceModel.Syndication", - "Version": "9.0.4" + "Version": "9.0.6" } }, "DevelopmentDependency": false @@ -805,7 +795,7 @@ "Type": "nuget", "Nuget": { "Name": "System.ServiceProcess.ServiceController", - "Version": "9.0.4" + "Version": "9.0.6" } }, "DevelopmentDependency": false @@ -815,7 +805,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Speech", - "Version": "9.0.4" + "Version": "9.0.6" } }, "DevelopmentDependency": false @@ -825,7 +815,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Text.Encoding.CodePages", - "Version": "9.0.4" + "Version": "9.0.6" } }, "DevelopmentDependency": false @@ -835,7 +825,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Text.Encodings.Web", - "Version": "9.0.4" + "Version": "9.0.6" } }, "DevelopmentDependency": false @@ -845,7 +835,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Threading.AccessControl", - "Version": "9.0.4" + "Version": "9.0.6" } }, "DevelopmentDependency": false @@ -865,7 +855,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Windows.Extensions", - "Version": "9.0.4" + "Version": "9.0.6" } }, "DevelopmentDependency": false From ff78f2582d3d107a0ea09b97f2b637848434d1a0 Mon Sep 17 00:00:00 2001 From: Patrick Meinecke Date: Tue, 10 Jun 2025 19:09:24 -0400 Subject: [PATCH 134/173] Manually update SqlClient in TestService The version bump from 4.8.6 to 4.9.0 is required for Microsoft.Windows.Compatibility 9.0.6 --- test/tools/TestService/TestService.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/tools/TestService/TestService.csproj b/test/tools/TestService/TestService.csproj index 8215dfb01d1..cae146e8f5e 100644 --- a/test/tools/TestService/TestService.csproj +++ b/test/tools/TestService/TestService.csproj @@ -48,7 +48,7 @@ - + From 63cccc6ca24e07aa598930f02d51af780f57201c Mon Sep 17 00:00:00 2001 From: Patrick Meinecke Date: Mon, 16 Jun 2025 12:15:39 -0400 Subject: [PATCH 135/173] Update ThirdPartyNotices for v7.5.2 (#25658) --- ThirdPartyNotices.txt | 246 ++++++++++++------------------------------ 1 file changed, 66 insertions(+), 180 deletions(-) diff --git a/ThirdPartyNotices.txt b/ThirdPartyNotices.txt index d48be300df3..c97524423aa 100644 --- a/ThirdPartyNotices.txt +++ b/ThirdPartyNotices.txt @@ -284,7 +284,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI --------------------------------------------------------- -Microsoft.Extensions.ObjectPool 8.0.15 - MIT +Microsoft.Extensions.ObjectPool 8.0.17 - MIT Copyright Jorn Zaefferer @@ -374,79 +374,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI --------------------------------------------------------- -Microsoft.Win32.Registry 5.0.0 - MIT - - -(c) Microsoft Corporation -Copyright (c) Andrew Arnott -Copyright 2018 Daniel Lemire -Copyright (c) .NET Foundation -Copyright (c) 2011, Google Inc. -Copyright (c) 2020 Dan Shechter -(c) 1997-2005 Sean Eron Anderson -Copyright (c) 1998 Microsoft. To -Copyright (c) 2017 Yoshifumi Kawai -Copyright (c) Microsoft Corporation -Copyright (c) 2007 James Newton-King -Copyright (c) 2012-2014, Yann Collet -Copyright (c) 1991-2020 Unicode, Inc. -Copyright (c) 2013-2017, Alfred Klomp -Copyright 2012 the V8 project authors -Copyright (c) 2011-2020 Microsoft Corp -Copyright (c) 2015-2017, Wojciech Mula -Copyright (c) 2005-2007, Nick Galbreath -Copyright (c) 2015 The Chromium Authors -Copyright (c) 2018 Alexander Chermyanin -Copyright (c) The Internet Society 1997 -Portions (c) International Organization -Copyright (c) 2004-2006 Intel Corporation -Copyright (c) 2013-2017, Milosz Krajewski -Copyright (c) 2016-2017, Matthieu Darbois -Copyright (c) The Internet Society (2003) -Copyright (c) .NET Foundation Contributors -Copyright (c) .NET Foundation and Contributors -Copyright (c) 2011 Novell, Inc (http://www.novell.com) -Copyright (c) 1995-2017 Jean-loup Gailly and Mark Adler -Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com) -Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors -Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com -Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc. -Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers -Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip -Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California -Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass -Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass. To - -The MIT License (MIT) - -Copyright (c) .NET Foundation and Contributors - -All rights reserved. - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - - ---------------------------------------------------------- - ---------------------------------------------------------- - -Microsoft.Win32.Registry.AccessControl 9.0.4 - MIT +Microsoft.Win32.Registry.AccessControl 9.0.6 - MIT Copyright (c) 2021 @@ -536,7 +464,7 @@ SOFTWARE. --------------------------------------------------------- -Microsoft.Win32.SystemEvents 9.0.4 - MIT +Microsoft.Win32.SystemEvents 9.0.6 - MIT Copyright (c) 2021 @@ -626,7 +554,7 @@ SOFTWARE. --------------------------------------------------------- -Microsoft.Windows.Compatibility 9.0.4 - MIT +Microsoft.Windows.Compatibility 9.0.6 - MIT (c) Microsoft Corporation @@ -679,7 +607,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. --------------------------------------------------------- -runtime.android-arm.runtime.native.System.IO.Ports 9.0.4 - MIT +runtime.android-arm.runtime.native.System.IO.Ports 9.0.6 - MIT Copyright (c) 2021 @@ -769,7 +697,7 @@ SOFTWARE. --------------------------------------------------------- -runtime.android-arm64.runtime.native.System.IO.Ports 9.0.4 - MIT +runtime.android-arm64.runtime.native.System.IO.Ports 9.0.6 - MIT Copyright (c) 2021 @@ -859,7 +787,7 @@ SOFTWARE. --------------------------------------------------------- -runtime.android-x64.runtime.native.System.IO.Ports 9.0.4 - MIT +runtime.android-x64.runtime.native.System.IO.Ports 9.0.6 - MIT Copyright (c) 2021 @@ -949,7 +877,7 @@ SOFTWARE. --------------------------------------------------------- -runtime.android-x86.runtime.native.System.IO.Ports 9.0.4 - MIT +runtime.android-x86.runtime.native.System.IO.Ports 9.0.6 - MIT Copyright (c) 2021 @@ -1039,7 +967,7 @@ SOFTWARE. --------------------------------------------------------- -runtime.linux-arm.runtime.native.System.IO.Ports 9.0.4 - MIT +runtime.linux-arm.runtime.native.System.IO.Ports 9.0.6 - MIT Copyright (c) 2021 @@ -1129,7 +1057,7 @@ SOFTWARE. --------------------------------------------------------- -runtime.linux-arm64.runtime.native.System.IO.Ports 9.0.4 - MIT +runtime.linux-arm64.runtime.native.System.IO.Ports 9.0.6 - MIT Copyright (c) 2021 @@ -1219,7 +1147,7 @@ SOFTWARE. --------------------------------------------------------- -runtime.linux-bionic-arm64.runtime.native.System.IO.Ports 9.0.4 - MIT +runtime.linux-bionic-arm64.runtime.native.System.IO.Ports 9.0.6 - MIT Copyright (c) 2021 @@ -1309,7 +1237,7 @@ SOFTWARE. --------------------------------------------------------- -runtime.linux-bionic-x64.runtime.native.System.IO.Ports 9.0.4 - MIT +runtime.linux-bionic-x64.runtime.native.System.IO.Ports 9.0.6 - MIT Copyright (c) 2021 @@ -1399,7 +1327,7 @@ SOFTWARE. --------------------------------------------------------- -runtime.linux-musl-arm.runtime.native.System.IO.Ports 9.0.4 - MIT +runtime.linux-musl-arm.runtime.native.System.IO.Ports 9.0.6 - MIT Copyright (c) 2021 @@ -1489,7 +1417,7 @@ SOFTWARE. --------------------------------------------------------- -runtime.linux-musl-arm64.runtime.native.System.IO.Ports 9.0.4 - MIT +runtime.linux-musl-arm64.runtime.native.System.IO.Ports 9.0.6 - MIT Copyright (c) 2021 @@ -1579,7 +1507,7 @@ SOFTWARE. --------------------------------------------------------- -runtime.linux-musl-x64.runtime.native.System.IO.Ports 9.0.4 - MIT +runtime.linux-musl-x64.runtime.native.System.IO.Ports 9.0.6 - MIT Copyright (c) 2021 @@ -1669,7 +1597,7 @@ SOFTWARE. --------------------------------------------------------- -runtime.linux-x64.runtime.native.System.IO.Ports 9.0.4 - MIT +runtime.linux-x64.runtime.native.System.IO.Ports 9.0.6 - MIT Copyright (c) 2021 @@ -1759,7 +1687,7 @@ SOFTWARE. --------------------------------------------------------- -runtime.maccatalyst-arm64.runtime.native.System.IO.Ports 9.0.4 - MIT +runtime.maccatalyst-arm64.runtime.native.System.IO.Ports 9.0.6 - MIT Copyright (c) 2021 @@ -1849,7 +1777,7 @@ SOFTWARE. --------------------------------------------------------- -runtime.maccatalyst-x64.runtime.native.System.IO.Ports 9.0.4 - MIT +runtime.maccatalyst-x64.runtime.native.System.IO.Ports 9.0.6 - MIT Copyright (c) 2021 @@ -1939,29 +1867,21 @@ SOFTWARE. --------------------------------------------------------- -runtime.native.System.Data.SqlClient.sni 4.7.0 - MIT +runtime.native.System.Data.SqlClient.sni 4.4.0 - MIT -(c) Microsoft Corporation. -Copyright (c) .NET Foundation. -Copyright (c) 2011, Google Inc. -(c) 1997-2005 Sean Eron Anderson. -Copyright (c) 2007 James Newton-King +(c) 2022 GitHub, Inc. +(c) Microsoft Corporation +(c) 1997-2005 Sean Eron Anderson Copyright (c) 1991-2017 Unicode, Inc. -Copyright (c) 2013-2017, Alfred Klomp -Copyright (c) 2015-2017, Wojciech Mula -Copyright (c) 2005-2007, Nick Galbreath Portions (c) International Organization -Copyright (c) 2015 The Chromium Authors. Copyright (c) 2004-2006 Intel Corporation -Copyright (c) 2016-2017, Matthieu Darbois Copyright (c) .NET Foundation Contributors Copyright (c) .NET Foundation and Contributors Copyright (c) 2011 Novell, Inc (http://www.novell.com) Copyright (c) 1995-2017 Jean-loup Gailly and Mark Adler Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com) -Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors. -Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers THIS WORK IS PROVIDED AS +Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers The MIT License (MIT) @@ -1992,7 +1912,7 @@ SOFTWARE. --------------------------------------------------------- -runtime.native.System.IO.Ports 9.0.4 - MIT +runtime.native.System.IO.Ports 9.0.6 - MIT Copyright (c) 2021 @@ -2082,7 +2002,7 @@ SOFTWARE. --------------------------------------------------------- -runtime.osx-arm64.runtime.native.System.IO.Ports 9.0.4 - MIT +runtime.osx-arm64.runtime.native.System.IO.Ports 9.0.6 - MIT Copyright (c) 2021 @@ -2172,7 +2092,7 @@ SOFTWARE. --------------------------------------------------------- -runtime.osx-x64.runtime.native.System.IO.Ports 9.0.4 - MIT +runtime.osx-x64.runtime.native.System.IO.Ports 9.0.6 - MIT Copyright (c) 2021 @@ -2262,7 +2182,7 @@ SOFTWARE. --------------------------------------------------------- -System.CodeDom 9.0.4 - MIT +System.CodeDom 9.0.6 - MIT Copyright (c) 2021 @@ -2355,16 +2275,17 @@ SOFTWARE. System.Collections.Immutable 8.0.0 - MIT +Copyright (c) 2021 Copyright (c) Six Labors (c) Microsoft Corporation Copyright (c) Andrew Arnott Copyright 2019 LLVM Project +Copyright (c) 1998 Microsoft Copyright 2018 Daniel Lemire Copyright (c) .NET Foundation Copyright (c) 2011, Google Inc. Copyright (c) 2020 Dan Shechter (c) 1997-2005 Sean Eron Anderson -Copyright (c) 1998 Microsoft. To Copyright (c) 2022, Wojciech Mula Copyright (c) 2017 Yoshifumi Kawai Copyright (c) 2022, Geoff Langdale @@ -2379,12 +2300,10 @@ Copyright (c) 1999 Lucent Technologies Copyright (c) 2008-2016, Wojciech Mula Copyright (c) 2011-2020 Microsoft Corp Copyright (c) 2015-2017, Wojciech Mula -Copyright (c) 2021 csFastFloat authors Copyright (c) 2005-2007, Nick Galbreath Copyright (c) 2015 The Chromium Authors Copyright (c) 2018 Alexander Chermyanin Copyright (c) The Internet Society 1997 -Portions (c) International Organization Copyright (c) 2004-2006 Intel Corporation Copyright (c) 2011-2015 Intel Corporation Copyright (c) 2013-2017, Milosz Krajewski @@ -2403,7 +2322,8 @@ Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com) Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc. -Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers +Portions (c) International Organization for Standardization 1986 +Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip Copyright (c) 1980, 1986, 1993 The Regents of the University of California Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California @@ -2438,7 +2358,7 @@ SOFTWARE. --------------------------------------------------------- -System.ComponentModel.Composition 9.0.4 - MIT +System.ComponentModel.Composition 9.0.6 - MIT Copyright (c) 2021 @@ -2528,7 +2448,7 @@ SOFTWARE. --------------------------------------------------------- -System.ComponentModel.Composition.Registration 9.0.4 - MIT +System.ComponentModel.Composition.Registration 9.0.6 - MIT Copyright (c) 2021 @@ -2618,7 +2538,7 @@ SOFTWARE. --------------------------------------------------------- -System.Configuration.ConfigurationManager 9.0.4 - MIT +System.Configuration.ConfigurationManager 9.0.6 - MIT Copyright (c) 2021 @@ -2708,7 +2628,7 @@ SOFTWARE. --------------------------------------------------------- -System.Data.Odbc 9.0.4 - MIT +System.Data.Odbc 9.0.6 - MIT Copyright (c) 2021 @@ -2798,7 +2718,7 @@ SOFTWARE. --------------------------------------------------------- -System.Data.OleDb 9.0.4 - MIT +System.Data.OleDb 9.0.6 - MIT Copyright (c) 2021 @@ -2888,60 +2808,26 @@ SOFTWARE. --------------------------------------------------------- -System.Data.SqlClient 4.8.6 - MIT +System.Data.SqlClient 4.9.0 - MIT (c) Microsoft Corporation -Copyright (c) .NET Foundation -Copyright (c) 2011, Google Inc. -(c) 1997-2005 Sean Eron Anderson -Copyright (c) 2007 James Newton-King -Copyright (c) 1991-2017 Unicode, Inc. -Copyright (c) 2013-2017, Alfred Klomp -Copyright (c) 2015-2017, Wojciech Mula -Copyright (c) 2005-2007, Nick Galbreath -Copyright (c) 2015 The Chromium Authors -Portions (c) International Organization -Copyright (c) 2004-2006 Intel Corporation -Copyright (c) 2016-2017, Matthieu Darbois -Copyright (c) .NET Foundation Contributors -Copyright (c) .NET Foundation and Contributors -Copyright (c) 2011 Novell, Inc (http://www.novell.com) -Copyright (c) 1995-2017 Jean-loup Gailly and Mark Adler -Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com) -Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors -Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers -The MIT License (MIT) - -Copyright (c) .NET Foundation and Contributors - -All rights reserved. +MIT License -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: +Copyright (c) -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. --------------------------------------------------------- --------------------------------------------------------- -System.Diagnostics.DiagnosticSource 9.0.4 - MIT +System.Diagnostics.DiagnosticSource 9.0.6 - MIT Copyright (c) 2021 @@ -3031,7 +2917,7 @@ SOFTWARE. --------------------------------------------------------- -System.Diagnostics.EventLog 9.0.4 - MIT +System.Diagnostics.EventLog 9.0.6 - MIT Copyright (c) 2021 @@ -3121,7 +3007,7 @@ SOFTWARE. --------------------------------------------------------- -System.Diagnostics.PerformanceCounter 9.0.4 - MIT +System.Diagnostics.PerformanceCounter 9.0.6 - MIT Copyright (c) 2021 @@ -3211,7 +3097,7 @@ SOFTWARE. --------------------------------------------------------- -System.DirectoryServices 9.0.4 - MIT +System.DirectoryServices 9.0.6 - MIT Copyright (c) 2021 @@ -3301,7 +3187,7 @@ SOFTWARE. --------------------------------------------------------- -System.DirectoryServices.AccountManagement 9.0.4 - MIT +System.DirectoryServices.AccountManagement 9.0.6 - MIT Copyright (c) 2021 @@ -3391,7 +3277,7 @@ SOFTWARE. --------------------------------------------------------- -System.DirectoryServices.Protocols 9.0.4 - MIT +System.DirectoryServices.Protocols 9.0.6 - MIT Copyright (c) 2021 @@ -3481,7 +3367,7 @@ SOFTWARE. --------------------------------------------------------- -System.Drawing.Common 9.0.4 - MIT +System.Drawing.Common 9.0.6 - MIT (c) Microsoft Corporation @@ -3516,7 +3402,7 @@ SOFTWARE. --------------------------------------------------------- -System.IO.Packaging 9.0.4 - MIT +System.IO.Packaging 9.0.6 - MIT Copyright (c) 2021 @@ -3606,7 +3492,7 @@ SOFTWARE. --------------------------------------------------------- -System.IO.Ports 9.0.4 - MIT +System.IO.Ports 9.0.6 - MIT Copyright (c) 2021 @@ -3696,7 +3582,7 @@ SOFTWARE. --------------------------------------------------------- -System.Management 9.0.4 - MIT +System.Management 9.0.6 - MIT Copyright (c) 2021 @@ -3786,7 +3672,7 @@ SOFTWARE. --------------------------------------------------------- -System.Net.Http.WinHttpHandler 9.0.4 - MIT +System.Net.Http.WinHttpHandler 9.0.6 - MIT Copyright (c) 2021 @@ -3961,7 +3847,7 @@ SOFTWARE. --------------------------------------------------------- -System.Reflection.Context 9.0.4 - MIT +System.Reflection.Context 9.0.6 - MIT Copyright (c) 2021 @@ -4191,7 +4077,7 @@ SOFTWARE. --------------------------------------------------------- -System.Runtime.Caching 9.0.4 - MIT +System.Runtime.Caching 9.0.6 - MIT Copyright (c) 2021 @@ -4356,7 +4242,7 @@ SOFTWARE. --------------------------------------------------------- -System.Security.Cryptography.Pkcs 9.0.4 - MIT +System.Security.Cryptography.Pkcs 9.0.6 - MIT Copyright (c) 2021 @@ -4446,7 +4332,7 @@ SOFTWARE. --------------------------------------------------------- -System.Security.Cryptography.ProtectedData 9.0.4 - MIT +System.Security.Cryptography.ProtectedData 9.0.6 - MIT Copyright (c) 2021 @@ -4536,7 +4422,7 @@ SOFTWARE. --------------------------------------------------------- -System.Security.Cryptography.Xml 9.0.4 - MIT +System.Security.Cryptography.Xml 9.0.6 - MIT Copyright (c) 2021 @@ -4626,7 +4512,7 @@ SOFTWARE. --------------------------------------------------------- -System.Security.Permissions 9.0.4 - MIT +System.Security.Permissions 9.0.6 - MIT Copyright (c) 2021 @@ -4965,7 +4851,7 @@ SOFTWARE. --------------------------------------------------------- -System.ServiceModel.Syndication 9.0.4 - MIT +System.ServiceModel.Syndication 9.0.6 - MIT Copyright (c) 2021 @@ -5055,7 +4941,7 @@ SOFTWARE. --------------------------------------------------------- -System.ServiceProcess.ServiceController 9.0.4 - MIT +System.ServiceProcess.ServiceController 9.0.6 - MIT Copyright (c) 2021 @@ -5145,7 +5031,7 @@ SOFTWARE. --------------------------------------------------------- -System.Speech 9.0.4 - MIT +System.Speech 9.0.6 - MIT Copyright (c) 2021 @@ -5235,7 +5121,7 @@ SOFTWARE. --------------------------------------------------------- -System.Text.Encoding.CodePages 9.0.4 - MIT +System.Text.Encoding.CodePages 9.0.6 - MIT Copyright (c) 2021 @@ -5325,7 +5211,7 @@ SOFTWARE. --------------------------------------------------------- -System.Text.Encodings.Web 9.0.4 - MIT +System.Text.Encodings.Web 9.0.6 - MIT Copyright (c) 2021 @@ -5415,7 +5301,7 @@ SOFTWARE. --------------------------------------------------------- -System.Threading.AccessControl 9.0.4 - MIT +System.Threading.AccessControl 9.0.6 - MIT Copyright (c) 2021 @@ -5541,7 +5427,7 @@ SOFTWARE. --------------------------------------------------------- -System.Windows.Extensions 9.0.4 - MIT +System.Windows.Extensions 9.0.6 - MIT Copyright (c) 2021 From 74af3bfef50d03b1bc41932b54faeff954ef4d52 Mon Sep 17 00:00:00 2001 From: PowerShell Team Bot <69177312+pwshBot@users.noreply.github.com> Date: Mon, 16 Jun 2025 10:39:35 -0700 Subject: [PATCH 136/173] [release/v7.5] Publish `.msixbundle` package as a VPack (#25621) Co-authored-by: Dongbo Wang Co-authored-by: Travis Plunk --- .pipelines/MSIXBundle-vPack-Official.yml | 147 +++++++++++++++++++ .pipelines/PowerShell-Release-Official.yml | 5 +- .pipelines/templates/SetVersionVariables.yml | 6 +- assets/AppxManifest.xml | 1 + tools/packaging/packaging.psm1 | 18 ++- 5 files changed, 171 insertions(+), 6 deletions(-) create mode 100644 .pipelines/MSIXBundle-vPack-Official.yml diff --git a/.pipelines/MSIXBundle-vPack-Official.yml b/.pipelines/MSIXBundle-vPack-Official.yml new file mode 100644 index 00000000000..f20e8a31114 --- /dev/null +++ b/.pipelines/MSIXBundle-vPack-Official.yml @@ -0,0 +1,147 @@ +trigger: none + +parameters: # parameters are shown up in ADO UI in a build queue time +- name: 'createVPack' + displayName: 'Create and Submit VPack' + type: boolean + default: true +- name: 'debug' + displayName: 'Enable debug output' + type: boolean + default: false +- name: 'ReleaseTagVar' + type: string + displayName: 'Release Tag Var:' + default: 'fromBranch' + +name: msixbundle_vPack_$(date:yyMM).$(date:dd)$(rev:rrr) + +variables: + CDP_DEFINITION_BUILD_COUNT: $[counter('', 0)] + system.debug: ${{ parameters.debug }} + BuildSolution: $(Build.SourcesDirectory)\dirs.proj + ReleaseTagVar: ${{ parameters.ReleaseTagVar }} + BuildConfiguration: Release + WindowsContainerImage: 'onebranch.azurecr.io/windows/ltsc2019/vse2022:latest' + Codeql.Enabled: false # pipeline is not building artifacts; it repackages existing artifacts into a vpack + DOTNET_CLI_TELEMETRY_OPTOUT: 1 + POWERSHELL_TELEMETRY_OPTOUT: 1 + +resources: + repositories: + - repository: templates + type: git + name: OneBranch.Pipelines/GovernedTemplates + ref: refs/heads/main + + pipelines: + - pipeline: PSPackagesOfficial + source: 'PowerShell-Packages-Official' + trigger: + branches: + include: + - master + - releases/* + +extends: + template: v2/Microsoft.Official.yml@templates + parameters: + platform: + name: 'windows_undocked' # windows undocked + + cloudvault: + enabled: false + + globalSdl: + useCustomPolicy: true # for signing code + disableLegacyManifest: true + # disabled Armory as we dont have any ARM templates to scan. It fails on some sample ARM templates. + armory: + enabled: false + sbom: + enabled: true + compiled: + enabled: false + credscan: + enabled: true + scanFolder: $(Build.SourcesDirectory) + suppressionsFile: $(Build.SourcesDirectory)\.config\suppress.json + binskim: + enabled: false + # APIScan requires a non-Ready-To-Run build + apiscan: + enabled: false + asyncSDL: + enabled: false + tsaOptionsFile: .config/tsaoptions.json + + stages: + - stage: build + jobs: + - job: main + pool: + type: windows + + variables: + ob_outputDirectory: '$(BUILD.SOURCESDIRECTORY)\out' + ob_createvpack_enabled: ${{ parameters.createVPack }} + ob_createvpack_packagename: 'PowerShell.app' + ob_createvpack_owneralias: 'dongbow' + ob_createvpack_description: 'VPack for the PowerShell Application' + ob_createvpack_targetDestinationDirectory: '$(Destination)' + ob_createvpack_propsFile: false + ob_createvpack_provData: true + ob_createvpack_metadata: '$(Build.SourceVersion)' + ob_createvpack_versionAs: string + ob_createvpack_version: '$(version)' + ob_createvpack_verbose: true + + steps: + - template: .pipelines/templates/SetVersionVariables.yml@self + parameters: + ReleaseTagVar: $(ReleaseTagVar) + UseJson: no + + - pwsh: | + Write-Verbose -Verbose 'PowerShell Version: $(version)' + if('$(version)' -match '-') { + throw "Don't release a preview build msixbundle package" + } + displayName: Stop any preview release + + - download: PSPackagesOfficial + artifact: 'drop_msixbundle_CreateMSIXBundle' + displayName: Download package + + - pwsh: | + $payloadDir = '$(Pipeline.Workspace)\PSPackagesOfficial\drop_msixbundle_CreateMSIXBundle' + Get-ChildItem $payloadDir -Recurse | Out-String -Width 150 + $vstsCommandString = "vso[task.setvariable variable=PayloadDir]$payloadDir" + Write-Host "sending " + $vstsCommandString + Write-Host "##$vstsCommandString" + displayName: 'Capture Artifact Listing' + + - pwsh: | + $bundlePackage = Get-ChildItem '$(PayloadDir)\*.msixbundle' + Write-Verbose -Verbose ("MSIX bundle package: " + $bundlePackage.FullName -join ', ') + if ($bundlePackage.Count -ne 1) { + throw "Expected to find 1 MSIX bundle package, but found $($bundlePackage.Count)" + } + + if (-not (Test-Path '$(ob_outputDirectory)' -PathType Container)) { + $null = New-Item '$(ob_outputDirectory)' -ItemType Directory -ErrorAction Stop + } + + $targetPath = Join-Path '$(ob_outputDirectory)' 'Microsoft.PowerShell_8wekyb3d8bbwe.msixbundle' + Copy-Item -Verbose -Path $bundlePackage.FullName -Destination $targetPath + displayName: 'Stage msixbundle for vpack' + + - pwsh: | + Write-Verbose "VPack Version: $(ob_createvpack_version)" -Verbose + $vpackFiles = Get-ChildItem -Path $(ob_outputDirectory)\* -Recurse + if($vpackFiles.Count -eq 0) { + throw "No files found in $(ob_outputDirectory)" + } + $vpackFiles | Out-String -Width 150 + displayName: Debug Output Directory and Version + condition: succeededOrFailed() diff --git a/.pipelines/PowerShell-Release-Official.yml b/.pipelines/PowerShell-Release-Official.yml index 55c6ec1c486..c073b9e1223 100644 --- a/.pipelines/PowerShell-Release-Official.yml +++ b/.pipelines/PowerShell-Release-Official.yml @@ -368,10 +368,11 @@ extends: jobs: - template: /.pipelines/templates/approvalJob.yml@self parameters: - displayName: Start vPack Release pipeline + displayName: Start 2 vPack Release pipelines jobName: PublishVPack instructions: | - Kick off vPack release pipeline + 1. Kick off PowerShell-vPack-Official pipeline + 2. Kick off PowerShell-MSIXBundle-VPack pipeline # Need to verify if the Az PS / CLI team still uses this. Skippinng for this release. # - stage: ReleaseDeps diff --git a/.pipelines/templates/SetVersionVariables.yml b/.pipelines/templates/SetVersionVariables.yml index 9894f9d53f6..9f692373f6c 100644 --- a/.pipelines/templates/SetVersionVariables.yml +++ b/.pipelines/templates/SetVersionVariables.yml @@ -23,7 +23,7 @@ steps: } if(Test-Path -Path $path) { - Write-Verbose "reporoot detect at: ." -Verbose + Write-Verbose "reporoot detected at: ." -Verbose $repoRoot = '.' } else{ @@ -51,7 +51,7 @@ steps: $REPOROOT = $env:REPOROOT if (-not (Test-Path $REPOROOT/tools/releaseBuild/setReleaseTag.ps1)) { - if ((Test-Path "$REPOROOT/PowerShell/tools/releaseBuild/setReleaseTag.ps1")) { + if (Test-Path "$REPOROOT/PowerShell/tools/releaseBuild/setReleaseTag.ps1") { $REPOROOT = "$REPOROOT/PowerShell" } else { throw "Could not find setReleaseTag.ps1 in $REPOROOT/tools/releaseBuild or $REPOROOT/PowerShell/tools/releaseBuild" @@ -72,7 +72,7 @@ steps: ob_restore_phase: true # This ensures this done in restore phase to workaround signing issue - powershell: | - Get-ChildItem -Path env: + Get-ChildItem -Path Env: | Out-String -Width 150 displayName: Capture environment condition: succeededOrFailed() env: diff --git a/assets/AppxManifest.xml b/assets/AppxManifest.xml index c646bcdf94b..50a8c7af45d 100644 --- a/assets/AppxManifest.xml +++ b/assets/AppxManifest.xml @@ -48,4 +48,5 @@ + diff --git a/tools/packaging/packaging.psm1 b/tools/packaging/packaging.psm1 index 43a8d5d8dd4..782a4ecadc8 100644 --- a/tools/packaging/packaging.psm1 +++ b/tools/packaging/packaging.psm1 @@ -3702,8 +3702,17 @@ function New-MSIXPackage $ProductVersion = Get-WindowsVersion -PackageName $packageName + # Any app that is submitted to the Store must have a PhoneIdentity in its appxmanifest. + # If you submit a package without this information to the Store, the Store will silently modify your package to include it. + # To find the PhoneProductId value, you need to run a package through the Store certification process, + # and use the PhoneProductId value from the Store certified package to update the manifest in your source code. + # This is the PhoneProductId for the "Microsoft.PowerShell" package. + $PhoneProductId = "5b3ae196-2df7-446e-8060-94b4ad878387" + $isPreview = Test-IsPreview -Version $ProductSemanticVersion if ($isPreview) { + # This is the PhoneProductId for the "Microsoft.PowerShellPreview" package. + $PhoneProductId = "67859fd2-b02a-45be-8fb5-62c569a3e8bf" Write-Verbose "Using Preview assets" -Verbose } @@ -3713,7 +3722,14 @@ function New-MSIXPackage $releasePublisher = 'CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US' $appxManifest = Get-Content "$RepoRoot\assets\AppxManifest.xml" -Raw - $appxManifest = $appxManifest.Replace('$VERSION$', $ProductVersion).Replace('$ARCH$', $Architecture).Replace('$PRODUCTNAME$', $productName).Replace('$DISPLAYNAME$', $displayName).Replace('$PUBLISHER$', $releasePublisher) + $appxManifest = $appxManifest. + Replace('$VERSION$', $ProductVersion). + Replace('$ARCH$', $Architecture). + Replace('$PRODUCTNAME$', $productName). + Replace('$DISPLAYNAME$', $displayName). + Replace('$PUBLISHER$', $releasePublisher). + Replace('$PHONEPRODUCTID$', $PhoneProductId) + $xml = [xml]$appxManifest if ($isPreview) { Write-Verbose -Verbose "Adding pwsh-preview.exe alias" From d1a57af02c719f2f1695425f5124bbbf218dbf77 Mon Sep 17 00:00:00 2001 From: PowerShell Team Bot <69177312+pwshBot@users.noreply.github.com> Date: Tue, 17 Jun 2025 09:46:11 -0700 Subject: [PATCH 137/173] [release/v7.5] Correct Capitalization Referencing Templates (#25673) Co-authored-by: Justin Chung <124807742+jshigetomi@users.noreply.github.com> --- .pipelines/templates/release-symbols.yml | 2 +- .pipelines/templates/release-upload-buildinfo.yml | 2 +- .pipelines/templates/release-validate-packagenames.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.pipelines/templates/release-symbols.yml b/.pipelines/templates/release-symbols.yml index 6b728a75b02..68b8dd4324d 100644 --- a/.pipelines/templates/release-symbols.yml +++ b/.pipelines/templates/release-symbols.yml @@ -33,7 +33,7 @@ jobs: env: ob_restore_phase: true # This ensures checkout is done at the beginning of the restore phase - - template: release-SetReleaseTagAndContainerName.yml + - template: release-SetReleaseTagandContainerName.yml - pwsh: | Get-ChildItem Env: diff --git a/.pipelines/templates/release-upload-buildinfo.yml b/.pipelines/templates/release-upload-buildinfo.yml index d35630168a0..1134e1cc016 100644 --- a/.pipelines/templates/release-upload-buildinfo.yml +++ b/.pipelines/templates/release-upload-buildinfo.yml @@ -38,7 +38,7 @@ jobs: env: ob_restore_phase: true # This ensures checkout is done at the beginning of the restore phase - - template: release-SetReleaseTagAndContainerName.yml + - template: release-SetReleaseTagandContainerName.yml - pwsh: | Get-ChildItem Env: diff --git a/.pipelines/templates/release-validate-packagenames.yml b/.pipelines/templates/release-validate-packagenames.yml index 1eaf9c070ee..dbbd5c9f742 100644 --- a/.pipelines/templates/release-validate-packagenames.yml +++ b/.pipelines/templates/release-validate-packagenames.yml @@ -16,7 +16,7 @@ jobs: - checkout: self clean: true - - template: release-SetReleaseTagAndContainerName.yml + - template: release-SetReleaseTagandContainerName.yml - pwsh: | Get-ChildItem ENV: From ee140c433c5b0319c3522ca1263ba18045dfbd2f Mon Sep 17 00:00:00 2001 From: PowerShell Team Bot <69177312+pwshBot@users.noreply.github.com> Date: Tue, 24 Jun 2025 09:54:30 -0700 Subject: [PATCH 138/173] [release/v7.5] Update CHANGELOG for v7.5.2 (#25686) Co-authored-by: Patrick Meinecke --- CHANGELOG/7.5.md | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/CHANGELOG/7.5.md b/CHANGELOG/7.5.md index 37aa3e27995..8cf3dba6282 100644 --- a/CHANGELOG/7.5.md +++ b/CHANGELOG/7.5.md @@ -1,5 +1,47 @@ # 7.5 Changelog +## [7.5.2] - 2025-06-24 + +### Engine Updates and Fixes + +- Move .NET method invocation logging to after the needed type conversion is done for method arguments (#25357) + +### General Cmdlet Updates and Fixes + +- Set standard handles explicitly when starting a process with `-NoNewWindow` (#25324) +- Make inherited protected internal instance members accessible in class scope. (#25547) (Thanks @mawosoft!) +- Remove the old fuzzy suggestion and fix the local script file name suggestion (#25330) +- Fix `PSMethodInvocationConstraints.GetHashCode` method (#25306) (Thanks @crazyjncsu!) + +### Build and Packaging Improvements + +
+ + + +

Update to .NET SDK 9.0.301

+ +
+ +
    +
  • Correct Capitalization Referencing Templates (#25673)
  • +
  • Publish .msixbundle package as a VPack (#25621)
  • +
  • Update ThirdPartyNotices for v7.5.2 (#25658)
  • +
  • Manually update SqlClient in TestService
  • +
  • Update cgmanifest
  • +
  • Update package references
  • +
  • Update .NET SDK to latest version
  • +
  • Change linux packaging tests to ubuntu latest (#25639)
  • +
  • Fix MSIX artifact upload, vPack template, changelog hashes, git tag command (#25633)
  • +
  • Move MSIXBundle to Packages and Release to GitHub (#25517)
  • +
  • Use new variables template for vPack (#25435)
  • +
+ +
+ +[7.5.2]: https://github.com/PowerShell/PowerShell/compare/v7.5.1...v7.5.2 + + ## [7.5.1] ### Engine Updates and Fixes From 411d5fee10110d9881a909804f9d4eb1a06052ea Mon Sep 17 00:00:00 2001 From: PowerShell Team Bot <69177312+pwshBot@users.noreply.github.com> Date: Tue, 24 Jun 2025 13:20:39 -0700 Subject: [PATCH 139/173] [release/v7.5] Fix Conditional Parameter to Skip NuGet Publish (#25688) Co-authored-by: Justin Chung <124807742+jshigetomi@users.noreply.github.com> --- .pipelines/PowerShell-Release-Official.yml | 2 +- .pipelines/templates/release-githubNuget.yml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.pipelines/PowerShell-Release-Official.yml b/.pipelines/PowerShell-Release-Official.yml index c073b9e1223..bfc475785aa 100644 --- a/.pipelines/PowerShell-Release-Official.yml +++ b/.pipelines/PowerShell-Release-Official.yml @@ -18,7 +18,7 @@ parameters: # parameters are shown up in ADO UI in a build queue time type: string default: 'NO' - name: SkipPublish - displayName: Skip Publishing to GitHub and Nuget + displayName: Skip Publishing to Nuget type: boolean default: false - name: SkipPSInfraInstallers diff --git a/.pipelines/templates/release-githubNuget.yml b/.pipelines/templates/release-githubNuget.yml index ba0db845bfd..5a053514d6b 100644 --- a/.pipelines/templates/release-githubNuget.yml +++ b/.pipelines/templates/release-githubNuget.yml @@ -191,11 +191,11 @@ jobs: Write-Verbose -Verbose "The .nupkgs below will be pushed:" Get-ChildItem "$(Pipeline.Workspace)/release" -recurse displayName: Download and capture nupkgs - condition: and(ne('${{ parameters.skipPublish }}', 'false'), succeeded()) + condition: and(ne('${{ parameters.skipPublish }}', 'true'), succeeded()) - task: NuGetCommand@2 displayName: 'NuGet push' - condition: and(ne('${{ parameters.skipPublish }}', 'false'), succeeded()) + condition: and(ne('${{ parameters.skipPublish }}', 'true'), succeeded()) inputs: command: push packagesToPush: '$(Pipeline.Workspace)/release/*.nupkg' From 0bc793fc1341a5930e2a0efd4a66c200a9f2a4ab Mon Sep 17 00:00:00 2001 From: PowerShell Team Bot <69177312+pwshBot@users.noreply.github.com> Date: Wed, 6 Aug 2025 14:25:19 -0700 Subject: [PATCH 140/173] [release/v7.5] Fix Out-GridView by replacing use of obsolete BinaryFormatter with custom implementation. (#25559) Co-authored-by: Matthias Wolf <78562192+mawosoft@users.noreply.github.com> Co-authored-by: Travis Plunk --- .../FilterRules/ComparableValueFilterRule.cs | 17 +++++++++ .../FilterRules/DoesNotEqualFilterRule.cs | 11 +++++- .../FilterRules/EqualsFilterRule.cs | 11 +++++- .../FilterCore/FilterRules/FilterRule.cs | 20 +++++++++- .../FilterRules/FilterRuleExtensions.cs | 28 +------------- .../FilterRules/IsBetweenFilterRule.cs | 16 +++++++- .../FilterRules/IsEmptyFilterRule.cs | 11 +++++- .../FilterRules/IsGreaterThanFilterRule.cs | 11 +++++- .../FilterRules/IsLessThanFilterRule.cs | 11 +++++- .../FilterRules/IsNotEmptyFilterRule.cs | 11 +++++- .../FilterRules/IsNotEmptyValidationRule.cs | 8 ++++ .../PropertiesTextContainsFilterRule.cs | 11 ++++++ .../PropertyValueSelectorFilterRule.cs | 11 ++++++ .../FilterRules/SelectorFilterRule.cs | 16 +++++++- .../SingleValueComparableValueFilterRule.cs | 13 ++++++- .../FilterRules/TextContainsFilterRule.cs | 11 +++++- .../TextDoesNotContainFilterRule.cs | 11 +++++- .../FilterRules/TextDoesNotEqualFilterRule.cs | 11 +++++- .../FilterRules/TextEndsWithFilterRule.cs | 11 +++++- .../FilterRules/TextEqualsFilterRule.cs | 11 +++++- .../FilterCore/FilterRules/TextFilterRule.cs | 13 ++++++- .../FilterRules/TextStartsWithFilterRule.cs | 11 +++++- .../FilterCore/IDeepCloneable.cs | 18 +++++++++ .../FilterCore/ValidatingSelectorValue.cs | 37 +++++++++++++++++++ .../FilterCore/ValidatingValue.cs | 23 ++++++++++++ .../FilterCore/ValidatingValueBase.cs | 26 ++++++++++++- .../DataErrorInfoValidationRule.cs | 5 ++- 27 files changed, 346 insertions(+), 48 deletions(-) create mode 100644 src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/IDeepCloneable.cs diff --git a/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/ComparableValueFilterRule.cs b/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/ComparableValueFilterRule.cs index e7ef648e3fe..dca6c08d535 100644 --- a/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/ComparableValueFilterRule.cs +++ b/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/ComparableValueFilterRule.cs @@ -16,6 +16,23 @@ namespace Microsoft.Management.UI.Internal [Serializable] public abstract class ComparableValueFilterRule : FilterRule where T : IComparable { + /// + /// Initializes a new instance of the class. + /// + protected ComparableValueFilterRule() + { + } + + /// + /// Initializes a new instance of the class. + /// + /// The source to initialize from. + protected ComparableValueFilterRule(ComparableValueFilterRule source) + : base(source) + { + this.DefaultNullValueEvaluation = source.DefaultNullValueEvaluation; + } + #region Properties /// diff --git a/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/DoesNotEqualFilterRule.cs b/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/DoesNotEqualFilterRule.cs index ae209d0e60f..94451623c3a 100644 --- a/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/DoesNotEqualFilterRule.cs +++ b/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/DoesNotEqualFilterRule.cs @@ -17,7 +17,7 @@ namespace Microsoft.Management.UI.Internal public class DoesNotEqualFilterRule : EqualsFilterRule where T : IComparable { /// - /// Initializes a new instance of the DoesNotEqualFilterRule class. + /// Initializes a new instance of the class. /// public DoesNotEqualFilterRule() { @@ -25,6 +25,15 @@ public DoesNotEqualFilterRule() this.DefaultNullValueEvaluation = true; } + /// + /// Initializes a new instance of the class. + /// + /// The source to initialize from. + public DoesNotEqualFilterRule(DoesNotEqualFilterRule source) + : base(source) + { + } + /// /// Determines if item is not equal to Value. /// diff --git a/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/EqualsFilterRule.cs b/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/EqualsFilterRule.cs index 7bafd53e411..eaf647f0030 100644 --- a/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/EqualsFilterRule.cs +++ b/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/EqualsFilterRule.cs @@ -18,13 +18,22 @@ namespace Microsoft.Management.UI.Internal public class EqualsFilterRule : SingleValueComparableValueFilterRule where T : IComparable { /// - /// Initializes a new instance of the EqualsFilterRule class. + /// Initializes a new instance of the class. /// public EqualsFilterRule() { this.DisplayName = UICultureResources.FilterRule_Equals; } + /// + /// Initializes a new instance of the class. + /// + /// The source to initialize from. + public EqualsFilterRule(EqualsFilterRule source) + : base(source) + { + } + /// /// Determines if item is equal to Value. /// diff --git a/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/FilterRule.cs b/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/FilterRule.cs index 800812cdba5..7f72f33eb2d 100644 --- a/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/FilterRule.cs +++ b/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/FilterRule.cs @@ -10,7 +10,7 @@ namespace Microsoft.Management.UI.Internal /// [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.MSInternal", "CA903:InternalNamespaceShouldNotContainPublicTypes")] [Serializable] - public abstract class FilterRule : IEvaluate + public abstract class FilterRule : IEvaluate, IDeepCloneable { /// /// Gets a value indicating whether the FilterRule can be @@ -34,12 +34,28 @@ public string DisplayName } /// - /// Initializes a new instance of the FilterRule class. + /// Initializes a new instance of the class. /// protected FilterRule() { } + /// + /// Initializes a new instance of the class. + /// + /// The source to initialize from. + protected FilterRule(FilterRule source) + { + ArgumentNullException.ThrowIfNull(source); + this.DisplayName = source.DisplayName; + } + + /// + public object DeepClone() + { + return Activator.CreateInstance(this.GetType(), new object[] { this }); + } + /// /// Gets a value indicating whether the supplied item meets the /// criteria specified by this rule. diff --git a/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/FilterRuleExtensions.cs b/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/FilterRuleExtensions.cs index bc8e0b02ca6..4a3f8dc2975 100644 --- a/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/FilterRuleExtensions.cs +++ b/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/FilterRuleExtensions.cs @@ -2,10 +2,6 @@ // Licensed under the MIT License. using System; -using System.Diagnostics; -using System.IO; -using System.Runtime.Serialization; -using System.Runtime.Serialization.Formatters.Binary; namespace Microsoft.Management.UI.Internal { @@ -28,29 +24,7 @@ public static class FilterRuleExtensions public static FilterRule DeepCopy(this FilterRule rule) { ArgumentNullException.ThrowIfNull(rule); - -#pragma warning disable SYSLIB0050 - Debug.Assert(rule.GetType().IsSerializable, "rule is serializable"); -#pragma warning disable SYSLIB0011 - BinaryFormatter formatter = new BinaryFormatter(null, new StreamingContext(StreamingContextStates.Clone)); -#pragma warning restore SYSLIB0011 - MemoryStream ms = new MemoryStream(); - - FilterRule copy = null; - try - { - formatter.Serialize(ms, rule); - - ms.Position = 0; - copy = (FilterRule)formatter.Deserialize(ms); -#pragma warning restore SYSLIB0050 - } - finally - { - ms.Close(); - } - - return copy; + return (FilterRule)rule.DeepClone(); } } } diff --git a/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/IsBetweenFilterRule.cs b/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/IsBetweenFilterRule.cs index cbe4a875dd0..d8c4a263c61 100644 --- a/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/IsBetweenFilterRule.cs +++ b/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/IsBetweenFilterRule.cs @@ -56,7 +56,7 @@ public ValidatingValue EndValue #region Ctor /// - /// Initializes a new instance of the IsBetweenFilterRule class. + /// Initializes a new instance of the class. /// public IsBetweenFilterRule() { @@ -69,6 +69,20 @@ public IsBetweenFilterRule() this.EndValue.PropertyChanged += this.Value_PropertyChanged; } + /// + /// Initializes a new instance of the class. + /// + /// The source to initialize from. + public IsBetweenFilterRule(IsBetweenFilterRule source) + : base(source) + { + this.StartValue = (ValidatingValue)source.StartValue.DeepClone(); + this.StartValue.PropertyChanged += this.Value_PropertyChanged; + + this.EndValue = (ValidatingValue)source.EndValue.DeepClone(); + this.EndValue.PropertyChanged += this.Value_PropertyChanged; + } + #endregion Ctor #region Public Methods diff --git a/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/IsEmptyFilterRule.cs b/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/IsEmptyFilterRule.cs index 5ad2ae1247e..a3add25eae5 100644 --- a/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/IsEmptyFilterRule.cs +++ b/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/IsEmptyFilterRule.cs @@ -14,13 +14,22 @@ namespace Microsoft.Management.UI.Internal public class IsEmptyFilterRule : FilterRule { /// - /// Initializes a new instance of the IsEmptyFilterRule class. + /// Initializes a new instance of the class. /// public IsEmptyFilterRule() { this.DisplayName = UICultureResources.FilterRule_IsEmpty; } + /// + /// Initializes a new instance of the class. + /// + /// The source to initialize from. + public IsEmptyFilterRule(IsEmptyFilterRule source) + : base(source) + { + } + /// /// Gets a values indicating whether the supplied item is empty. /// diff --git a/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/IsGreaterThanFilterRule.cs b/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/IsGreaterThanFilterRule.cs index d098d2a9383..c6d9ef762b4 100644 --- a/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/IsGreaterThanFilterRule.cs +++ b/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/IsGreaterThanFilterRule.cs @@ -18,13 +18,22 @@ namespace Microsoft.Management.UI.Internal public class IsGreaterThanFilterRule : SingleValueComparableValueFilterRule where T : IComparable { /// - /// Initializes a new instance of the IsGreaterThanFilterRule class. + /// Initializes a new instance of the class. /// public IsGreaterThanFilterRule() { this.DisplayName = UICultureResources.FilterRule_GreaterThanOrEqual; } + /// + /// Initializes a new instance of the class. + /// + /// The source to initialize from. + public IsGreaterThanFilterRule(IsGreaterThanFilterRule source) + : base(source) + { + } + /// /// Determines if item is greater than Value. /// diff --git a/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/IsLessThanFilterRule.cs b/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/IsLessThanFilterRule.cs index 8539d6edf0e..a90dcdc8a82 100644 --- a/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/IsLessThanFilterRule.cs +++ b/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/IsLessThanFilterRule.cs @@ -18,13 +18,22 @@ namespace Microsoft.Management.UI.Internal public class IsLessThanFilterRule : SingleValueComparableValueFilterRule where T : IComparable { /// - /// Initializes a new instance of the IsLessThanFilterRule class. + /// Initializes a new instance of the class. /// public IsLessThanFilterRule() { this.DisplayName = UICultureResources.FilterRule_LessThanOrEqual; } + /// + /// Initializes a new instance of the class. + /// + /// The source to initialize from. + public IsLessThanFilterRule(IsLessThanFilterRule source) + : base(source) + { + } + /// /// Determines if item is less than Value. /// diff --git a/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/IsNotEmptyFilterRule.cs b/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/IsNotEmptyFilterRule.cs index 68e501d1f68..450a1237a97 100644 --- a/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/IsNotEmptyFilterRule.cs +++ b/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/IsNotEmptyFilterRule.cs @@ -14,13 +14,22 @@ namespace Microsoft.Management.UI.Internal public class IsNotEmptyFilterRule : IsEmptyFilterRule { /// - /// Initializes a new instance of the IsNotEmptyFilterRule class. + /// Initializes a new instance of the class. /// public IsNotEmptyFilterRule() { this.DisplayName = UICultureResources.FilterRule_IsNotEmpty; } + /// + /// Initializes a new instance of the class. + /// + /// The source to initialize from. + public IsNotEmptyFilterRule(IsNotEmptyFilterRule source) + : base(source) + { + } + /// /// Gets a values indicating whether the supplied item is not empty. /// diff --git a/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/IsNotEmptyValidationRule.cs b/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/IsNotEmptyValidationRule.cs index 31722bfe1f7..98534aca0ad 100644 --- a/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/IsNotEmptyValidationRule.cs +++ b/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/IsNotEmptyValidationRule.cs @@ -51,6 +51,14 @@ public override DataErrorInfoValidationResult Validate(object value, System.Glob } } + /// + public override object DeepClone() + { + // Instance is stateless. + // return this; + return new IsNotEmptyValidationRule(); + } + #endregion Public Methods internal static bool IsStringNotEmpty(string value) diff --git a/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/PropertiesTextContainsFilterRule.cs b/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/PropertiesTextContainsFilterRule.cs index 2a1cc576b39..54532335835 100644 --- a/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/PropertiesTextContainsFilterRule.cs +++ b/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/PropertiesTextContainsFilterRule.cs @@ -29,6 +29,17 @@ public PropertiesTextContainsFilterRule() this.EvaluationResultInvalidated += this.PropertiesTextContainsFilterRule_EvaluationResultInvalidated; } + /// + /// Initializes a new instance of the class. + /// + /// The source to initialize from. + public PropertiesTextContainsFilterRule(PropertiesTextContainsFilterRule source) + : base(source) + { + this.PropertyNames = new List(source.PropertyNames); + this.EvaluationResultInvalidated += this.PropertiesTextContainsFilterRule_EvaluationResultInvalidated; + } + /// /// Gets a collection of the names of properties to search in. /// diff --git a/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/PropertyValueSelectorFilterRule.cs b/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/PropertyValueSelectorFilterRule.cs index 158ab4e0229..6699cb0e698 100644 --- a/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/PropertyValueSelectorFilterRule.cs +++ b/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/PropertyValueSelectorFilterRule.cs @@ -82,6 +82,17 @@ public PropertyValueSelectorFilterRule(string propertyName, string propertyDispl this.AvailableRules.DisplayNameConverter = new FilterRuleToDisplayNameConverter(); } + /// + /// Initializes a new instance of the class. + /// + /// The source to initialize from. + public PropertyValueSelectorFilterRule(PropertyValueSelectorFilterRule source) + : base(source) + { + this.PropertyName = source.PropertyName; + this.AvailableRules.DisplayNameConverter = new FilterRuleToDisplayNameConverter(); + } + #endregion Ctor #region Public Methods diff --git a/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/SelectorFilterRule.cs b/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/SelectorFilterRule.cs index da4a62b6f66..d7451bbd21f 100644 --- a/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/SelectorFilterRule.cs +++ b/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/SelectorFilterRule.cs @@ -40,7 +40,7 @@ public ValidatingSelectorValue AvailableRules #region Ctor /// - /// Creates a new SelectorFilterRule instance. + /// Initializes a new instance of the class. /// public SelectorFilterRule() { @@ -48,6 +48,18 @@ public SelectorFilterRule() this.AvailableRules.SelectedValueChanged += this.AvailableRules_SelectedValueChanged; } + /// + /// Initializes a new instance of the class. + /// + /// The source to initialize from. + public SelectorFilterRule(SelectorFilterRule source) + : base(source) + { + this.AvailableRules = (ValidatingSelectorValue)source.AvailableRules.DeepClone(); + this.AvailableRules.SelectedValueChanged += this.AvailableRules_SelectedValueChanged; + this.AvailableRules.SelectedValue.EvaluationResultInvalidated += this.SelectedValue_EvaluationResultInvalidated; + } + #endregion Ctor #region Public Methods @@ -86,8 +98,8 @@ protected void OnSelectedValueChanged(FilterRule oldValue, FilterRule newValue) FilterRuleCustomizationFactory.FactoryInstance.TransferValues(oldValue, newValue); FilterRuleCustomizationFactory.FactoryInstance.ClearValues(oldValue); - newValue.EvaluationResultInvalidated += this.SelectedValue_EvaluationResultInvalidated; oldValue.EvaluationResultInvalidated -= this.SelectedValue_EvaluationResultInvalidated; + newValue.EvaluationResultInvalidated += this.SelectedValue_EvaluationResultInvalidated; this.NotifyEvaluationResultInvalidated(); } diff --git a/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/SingleValueComparableValueFilterRule.cs b/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/SingleValueComparableValueFilterRule.cs index 9486a126820..a34288a6530 100644 --- a/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/SingleValueComparableValueFilterRule.cs +++ b/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/SingleValueComparableValueFilterRule.cs @@ -44,7 +44,7 @@ public override bool IsValid #region Ctor /// - /// Initializes a new instance of the SingleValueComparableValueFilterRule class. + /// Initializes a new instance of the class. /// protected SingleValueComparableValueFilterRule() { @@ -52,6 +52,17 @@ protected SingleValueComparableValueFilterRule() this.Value.PropertyChanged += this.Value_PropertyChanged; } + /// + /// Initializes a new instance of the class. + /// + /// The source to initialize from. + protected SingleValueComparableValueFilterRule(SingleValueComparableValueFilterRule source) + : base(source) + { + this.Value = (ValidatingValue)source.Value.DeepClone(); + this.Value.PropertyChanged += this.Value_PropertyChanged; + } + #endregion Ctor private void Value_PropertyChanged(object sender, PropertyChangedEventArgs e) diff --git a/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/TextContainsFilterRule.cs b/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/TextContainsFilterRule.cs index fe581ca2031..acd52555498 100644 --- a/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/TextContainsFilterRule.cs +++ b/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/TextContainsFilterRule.cs @@ -18,13 +18,22 @@ public class TextContainsFilterRule : TextFilterRule private static readonly string TextContainsWordsRegexPattern = WordBoundaryRegexPattern + TextContainsCharactersRegexPattern + WordBoundaryRegexPattern; /// - /// Initializes a new instance of the TextContainsFilterRule class. + /// Initializes a new instance of the class. /// public TextContainsFilterRule() { this.DisplayName = UICultureResources.FilterRule_Contains; } + /// + /// Initializes a new instance of the class. + /// + /// The source to initialize from. + public TextContainsFilterRule(TextContainsFilterRule source) + : base(source) + { + } + /// /// Determines if Value is contained within data. /// diff --git a/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/TextDoesNotContainFilterRule.cs b/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/TextDoesNotContainFilterRule.cs index 29bec9b4bbf..f85ca1bd125 100644 --- a/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/TextDoesNotContainFilterRule.cs +++ b/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/TextDoesNotContainFilterRule.cs @@ -14,7 +14,7 @@ namespace Microsoft.Management.UI.Internal public class TextDoesNotContainFilterRule : TextContainsFilterRule { /// - /// Initializes a new instance of the TextDoesNotContainFilterRule class. + /// Initializes a new instance of the class. /// public TextDoesNotContainFilterRule() { @@ -22,6 +22,15 @@ public TextDoesNotContainFilterRule() this.DefaultNullValueEvaluation = true; } + /// + /// Initializes a new instance of the class. + /// + /// The source to initialize from. + public TextDoesNotContainFilterRule(TextDoesNotContainFilterRule source) + : base(source) + { + } + /// /// Determines if Value is not contained within data. /// diff --git a/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/TextDoesNotEqualFilterRule.cs b/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/TextDoesNotEqualFilterRule.cs index 4e72fe16e67..0c7bb96532c 100644 --- a/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/TextDoesNotEqualFilterRule.cs +++ b/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/TextDoesNotEqualFilterRule.cs @@ -14,7 +14,7 @@ namespace Microsoft.Management.UI.Internal public class TextDoesNotEqualFilterRule : TextEqualsFilterRule { /// - /// Initializes a new instance of the TextDoesNotEqualFilterRule class. + /// Initializes a new instance of the class. /// public TextDoesNotEqualFilterRule() { @@ -22,6 +22,15 @@ public TextDoesNotEqualFilterRule() this.DefaultNullValueEvaluation = true; } + /// + /// Initializes a new instance of the class. + /// + /// The source to initialize from. + public TextDoesNotEqualFilterRule(TextDoesNotEqualFilterRule source) + : base(source) + { + } + /// /// Determines if data is not equal to Value. /// diff --git a/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/TextEndsWithFilterRule.cs b/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/TextEndsWithFilterRule.cs index baca67801bf..2d4febe058d 100644 --- a/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/TextEndsWithFilterRule.cs +++ b/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/TextEndsWithFilterRule.cs @@ -18,13 +18,22 @@ public class TextEndsWithFilterRule : TextFilterRule private static readonly string TextEndsWithWordsRegexPattern = WordBoundaryRegexPattern + TextEndsWithCharactersRegexPattern; /// - /// Initializes a new instance of the TextEndsWithFilterRule class. + /// Initializes a new instance of the class. /// public TextEndsWithFilterRule() { this.DisplayName = UICultureResources.FilterRule_TextEndsWith; } + /// + /// Initializes a new instance of the class. + /// + /// The source to initialize from. + public TextEndsWithFilterRule(TextEndsWithFilterRule source) + : base(source) + { + } + /// /// Determines if data ends with Value. /// diff --git a/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/TextEqualsFilterRule.cs b/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/TextEqualsFilterRule.cs index e49dd9b4a0d..a6e74dca622 100644 --- a/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/TextEqualsFilterRule.cs +++ b/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/TextEqualsFilterRule.cs @@ -17,13 +17,22 @@ public class TextEqualsFilterRule : TextFilterRule private static readonly string TextEqualsCharactersRegexPattern = "^{0}$"; /// - /// Initializes a new instance of the TextEqualsFilterRule class. + /// Initializes a new instance of the class. /// public TextEqualsFilterRule() { this.DisplayName = UICultureResources.FilterRule_Equals; } + /// + /// Initializes a new instance of the class. + /// + /// The source to initialize from. + public TextEqualsFilterRule(TextEqualsFilterRule source) + : base(source) + { + } + /// /// Determines if data is equal to Value. /// diff --git a/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/TextFilterRule.cs b/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/TextFilterRule.cs index 0dc75cf24e4..c4cd5dba9f7 100644 --- a/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/TextFilterRule.cs +++ b/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/TextFilterRule.cs @@ -62,7 +62,7 @@ public bool CultureInvariant } /// - /// Initializes a new instance of the TextFilterRule class. + /// Initializes a new instance of the class. /// protected TextFilterRule() { @@ -70,6 +70,17 @@ protected TextFilterRule() this.CultureInvariant = false; } + /// + /// Initializes a new instance of the class. + /// + /// The source to initialize from. + protected TextFilterRule(TextFilterRule source) + : base(source) + { + this.IgnoreCase = source.IgnoreCase; + this.CultureInvariant = source.CultureInvariant; + } + /// /// Gets the current value and determines whether it should be evaluated as an exact match. /// diff --git a/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/TextStartsWithFilterRule.cs b/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/TextStartsWithFilterRule.cs index e97deb0fd46..3b39d0f5660 100644 --- a/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/TextStartsWithFilterRule.cs +++ b/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/TextStartsWithFilterRule.cs @@ -18,13 +18,22 @@ public class TextStartsWithFilterRule : TextFilterRule private static readonly string TextStartsWithWordsRegexPattern = TextStartsWithCharactersRegexPattern + WordBoundaryRegexPattern; /// - /// Initializes a new instance of the TextStartsWithFilterRule class. + /// Initializes a new instance of the class. /// public TextStartsWithFilterRule() { this.DisplayName = UICultureResources.FilterRule_TextStartsWith; } + /// + /// Initializes a new instance of the class. + /// + /// The source to initialize from. + public TextStartsWithFilterRule(TextStartsWithFilterRule source) + : base(source) + { + } + /// /// Determines if data starts with Value. /// diff --git a/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/IDeepCloneable.cs b/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/IDeepCloneable.cs new file mode 100644 index 00000000000..3090f93a95c --- /dev/null +++ b/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/IDeepCloneable.cs @@ -0,0 +1,18 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +namespace Microsoft.Management.UI.Internal +{ + /// + /// Defines a generalized method for creating a deep copy of an instance. + /// + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.MSInternal", "CA903:InternalNamespaceShouldNotContainPublicTypes")] + public interface IDeepCloneable + { + /// + /// Creates a deep copy of the current instance. + /// + /// A new object that is a deep copy of the current instance. + object DeepClone(); + } +} diff --git a/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/ValidatingSelectorValue.cs b/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/ValidatingSelectorValue.cs index 30b2fe8fac1..ff981a74751 100644 --- a/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/ValidatingSelectorValue.cs +++ b/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/ValidatingSelectorValue.cs @@ -19,6 +19,37 @@ namespace Microsoft.Management.UI.Internal [Serializable] public class ValidatingSelectorValue : ValidatingValueBase { + /// + /// Initializes a new instance of the class. + /// + public ValidatingSelectorValue() + { + } + + /// + /// Initializes a new instance of the class. + /// + /// The source to initialize from. + public ValidatingSelectorValue(ValidatingSelectorValue source) + : base(source) + { + availableValues.EnsureCapacity(source.availableValues.Count); + if (typeof(IDeepCloneable).IsAssignableFrom(typeof(T))) + { + foreach (var value in source.availableValues) + { + availableValues.Add((T)((IDeepCloneable)value).DeepClone()); + } + } + else + { + availableValues.AddRange(source.availableValues); + } + + selectedIndex = source.selectedIndex; + displayNameConverter = source.displayNameConverter; + } + #region Properties #region Consts @@ -150,6 +181,12 @@ public IValueConverter DisplayNameConverter #region Public Methods + /// + public override object DeepClone() + { + return new ValidatingSelectorValue(this); + } + #region Validate /// diff --git a/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/ValidatingValue.cs b/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/ValidatingValue.cs index fe21d2fee37..eee8ebc6e4a 100644 --- a/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/ValidatingValue.cs +++ b/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/ValidatingValue.cs @@ -18,6 +18,23 @@ namespace Microsoft.Management.UI.Internal [Serializable] public class ValidatingValue : ValidatingValueBase { + /// + /// Initializes a new instance of the class. + /// + public ValidatingValue() + { + } + + /// + /// Initializes a new instance of the class. + /// + /// The source to initialize from. + public ValidatingValue(ValidatingValue source) + : base(source) + { + value = source.Value is IDeepCloneable deepClone ? deepClone.DeepClone() : source.Value; + } + #region Properties #region Value @@ -50,6 +67,12 @@ public object Value #region Public Methods + /// + public override object DeepClone() + { + return new ValidatingValue(this); + } + /// /// Gets the raw value cast/transformed into /// type T. diff --git a/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/ValidatingValueBase.cs b/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/ValidatingValueBase.cs index d1c349dc32c..6b4c2daa10d 100644 --- a/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/ValidatingValueBase.cs +++ b/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/ValidatingValueBase.cs @@ -16,8 +16,29 @@ namespace Microsoft.Management.UI.Internal /// [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.MSInternal", "CA903:InternalNamespaceShouldNotContainPublicTypes")] [Serializable] - public abstract class ValidatingValueBase : IDataErrorInfo, INotifyPropertyChanged + public abstract class ValidatingValueBase : IDataErrorInfo, INotifyPropertyChanged, IDeepCloneable { + /// + /// Initializes a new instance of the class. + /// + protected ValidatingValueBase() + { + } + + /// + /// Initializes a new instance of the class. + /// + /// The source to initialize from. + protected ValidatingValueBase(ValidatingValueBase source) + { + ArgumentNullException.ThrowIfNull(source); + validationRules.EnsureCapacity(source.validationRules.Count); + foreach (var rule in source.validationRules) + { + validationRules.Add((DataErrorInfoValidationRule)rule.DeepClone()); + } + } + #region Properties #region ValidationRules @@ -129,6 +150,9 @@ public string Error #region Public Methods + /// + public abstract object DeepClone(); + #region AddValidationRule /// diff --git a/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/ValidationRules/DataErrorInfoValidationRule.cs b/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/ValidationRules/DataErrorInfoValidationRule.cs index 652592aec04..78b54a9c045 100644 --- a/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/ValidationRules/DataErrorInfoValidationRule.cs +++ b/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/ValidationRules/DataErrorInfoValidationRule.cs @@ -10,7 +10,7 @@ namespace Microsoft.Management.UI.Internal /// [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.MSInternal", "CA903:InternalNamespaceShouldNotContainPublicTypes")] [Serializable] - public abstract class DataErrorInfoValidationRule + public abstract class DataErrorInfoValidationRule : IDeepCloneable { /// /// When overridden in a derived class, performs validation checks on a value. @@ -25,5 +25,8 @@ public abstract class DataErrorInfoValidationRule /// A DataErrorInfoValidationResult object. /// public abstract DataErrorInfoValidationResult Validate(object value, System.Globalization.CultureInfo cultureInfo); + + /// + public abstract object DeepClone(); } } From b69a4798068fe64bd2aac654b07c41f2999fca50 Mon Sep 17 00:00:00 2001 From: PowerShell Team Bot <69177312+pwshBot@users.noreply.github.com> Date: Fri, 29 Aug 2025 16:47:05 -0700 Subject: [PATCH 141/173] [release/v7.5] Fix updatable help test for new content (#25944) Co-authored-by: Aditya Patwardhan --- .../engine/Help/UpdatableHelpSystem.Tests.ps1 | 6 +++--- ...3e-98dc-74d7b4d63d59_en-US_helpcontent.cab | Bin 202345 -> 198346 bytes ...3e-98dc-74d7b4d63d59_en-US_helpcontent.zip | Bin 203864 -> 198989 bytes 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/test/powershell/engine/Help/UpdatableHelpSystem.Tests.ps1 b/test/powershell/engine/Help/UpdatableHelpSystem.Tests.ps1 index 439dc3be989..d4cbb420066 100644 --- a/test/powershell/engine/Help/UpdatableHelpSystem.Tests.ps1 +++ b/test/powershell/engine/Help/UpdatableHelpSystem.Tests.ps1 @@ -47,7 +47,7 @@ else } # default values for system modules -[string] $myUICulture = 'en-US' +[string] $myUICulture = 'en-US' [string] $HelpInstallationPath = Join-Path $PSHOME $myUICulture [string] $HelpInstallationPathHome = Join-Path $userHelpRoot $myUICulture @@ -118,7 +118,7 @@ else } "Microsoft.PowerShell.Utility" = @{ - HelpFiles = "Microsoft.PowerShell.Commands.Utility.dll-Help.xml", "Microsoft.PowerShell.Utility-help.xml" + HelpFiles = "Microsoft.PowerShell.Commands.Utility.dll-Help.xml" HelpInfoFiles = "Microsoft.PowerShell.Utility_1da87e53-152b-403e-98dc-74d7b4d63d59_HelpInfo.xml" CompressedFiles = "Microsoft.PowerShell.Utility_1da87e53-152b-403e-98dc-74d7b4d63d59_en-US_helpcontent$extension" HelpInstallationPath = $HelpInstallationPath @@ -216,7 +216,7 @@ function RunUpdateHelpTests # Delete the whole help directory Remove-Item ($moduleHelpPath) -Recurse - + [hashtable] $UICultureParam = $(if ((Get-UICulture).Name -ne $myUICulture) { @{ UICulture = $myUICulture } } else { @{} }) [hashtable] $sourcePathParam = $(if ($useSourcePath) { @{ SourcePath = Join-Path $PSScriptRoot assets } } else { @{} }) Update-Help -Module:$moduleName -Force @UICultureParam @sourcePathParam -Scope:$updateScope diff --git a/test/powershell/engine/Help/assets/Microsoft.PowerShell.Utility_1da87e53-152b-403e-98dc-74d7b4d63d59_en-US_helpcontent.cab b/test/powershell/engine/Help/assets/Microsoft.PowerShell.Utility_1da87e53-152b-403e-98dc-74d7b4d63d59_en-US_helpcontent.cab index 949471140cebe33bf9c372e4ee2b261f131d81f1..ec0d3294f798823316d9c9d11643763c0b29a5c9 100644 GIT binary patch delta 923 zcmV;M17!T^tPIMH3@J@hLq-4q007Dc0{{R3001li00000000940RRC200000003_Q z0029YDMo>%g{1+7r2@630|x_tt)_r-OamhpLrd*l!EW0y480fVKL|by>*jR`(35v4 zd|GqqVI5EeK@P5KYzERKh?V8ij~_`%wB#s~oi*DK;ymcD zVT49~#aQku*CQ)&+Z%c{!ktj4uh!yS2x?BK2fgkKXYET& zH|$Iv^KbX#`>&Y@QagHoXUJkFKarBaU3 zW8n=uNmeqdy=-uJJK$5RM_WyVEg&@lde}y~ya@eUglMDKbwN{q4>H|%9_@RsxO&OT zG2%1UAW)T z*sg&PpM_OeVr27wTI8r{)zO-^SLSv0Ve0b~+z6{H18i7?miK6=QQ})Qh@+|JYk2vq z2ZvSu0Mi)O+mh&RR6Dp~t=D}AWHVw^q5L-%FWlm*5JO^-=@2_2w;&u%x!<(P-NkZR z@AxpqK16+qPcH58g51!ER^#tWCkAY^7whPt(jYoc`5MxHTY*KslbM)+fQV_XegTD* zgKiVkyP3EvU^^O(D5eiH@vvzSGJ`*E;osGKCElBD3qvQ9UCjnAuaEt$C`eDGf#-We)^-_Mj0?ls`7?%HF*Jft{04sFw_N}L delta 4946 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 diff --git a/test/powershell/engine/Help/assets/Microsoft.PowerShell.Utility_1da87e53-152b-403e-98dc-74d7b4d63d59_en-US_helpcontent.zip b/test/powershell/engine/Help/assets/Microsoft.PowerShell.Utility_1da87e53-152b-403e-98dc-74d7b4d63d59_en-US_helpcontent.zip index 47643e90de6000705f6ecb69f4a032253a19e6f9..480f920114fcee4f8339fe5d781f50f1d418b152 100644 GIT binary patch delta 41 rcmcbygXiodo`x327N#xCH#w$Hlx9v4VP#_g0!AQA0Mgevn1Lh!45SG( delta 4952 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 From add10d83e520326b210f6eb1fdb84446b7dfa106 Mon Sep 17 00:00:00 2001 From: PowerShell Team Bot <69177312+pwshBot@users.noreply.github.com> Date: Tue, 2 Sep 2025 14:10:17 -0700 Subject: [PATCH 142/173] [release/v7.5] Update branch for release (#25942) Co-authored-by: Travis Plunk --- DotnetRuntimeMetadata.json | 2 +- global.json | 2 +- ...oft.PowerShell.Commands.Diagnostics.csproj | 8 +- ...soft.PowerShell.Commands.Management.csproj | 4 +- ...crosoft.PowerShell.Commands.Utility.csproj | 6 +- ...crosoft.PowerShell.CoreCLR.Eventing.csproj | 2 +- .../Microsoft.PowerShell.SDK.csproj | 98 ++++++++--------- .../Microsoft.WSMan.Management.csproj | 4 +- .../System.Management.Automation.csproj | 24 ++--- .../BenchmarkDotNet.Extensions.csproj | 3 +- .../ResultsComparer/ResultsComparer.csproj | 3 +- ...soft.PowerShell.NamedPipeConnection.csproj | 26 ++--- test/tools/TestService/TestService.csproj | 94 ++++++++-------- test/tools/WebListener/WebListener.csproj | 6 +- tools/cgmanifest.json | 102 +++++++++--------- 15 files changed, 193 insertions(+), 191 deletions(-) diff --git a/DotnetRuntimeMetadata.json b/DotnetRuntimeMetadata.json index a97818844d0..eb802bfec36 100644 --- a/DotnetRuntimeMetadata.json +++ b/DotnetRuntimeMetadata.json @@ -4,7 +4,7 @@ "quality": "daily", "qualityFallback": "preview", "packageVersionPattern": "9.0.0-preview.6", - "sdkImageVersion": "9.0.301", + "sdkImageVersion": "9.0.304", "nextChannel": "9.0.0-preview.7", "azureFeed": "", "sdkImageOverride": "" diff --git a/global.json b/global.json index 2808b362fea..4c6e2601f69 100644 --- a/global.json +++ b/global.json @@ -1,5 +1,5 @@ { "sdk": { - "version": "9.0.301" + "version": "9.0.304" } } diff --git a/src/Microsoft.PowerShell.Commands.Diagnostics/Microsoft.PowerShell.Commands.Diagnostics.csproj b/src/Microsoft.PowerShell.Commands.Diagnostics/Microsoft.PowerShell.Commands.Diagnostics.csproj index af93c4c2bf4..0b8a4c35cfc 100644 --- a/src/Microsoft.PowerShell.Commands.Diagnostics/Microsoft.PowerShell.Commands.Diagnostics.csproj +++ b/src/Microsoft.PowerShell.Commands.Diagnostics/Microsoft.PowerShell.Commands.Diagnostics.csproj @@ -7,11 +7,11 @@ - - - + + + - + diff --git a/src/Microsoft.PowerShell.Commands.Management/Microsoft.PowerShell.Commands.Management.csproj b/src/Microsoft.PowerShell.Commands.Management/Microsoft.PowerShell.Commands.Management.csproj index d4c5da64bae..d9f8e52e762 100644 --- a/src/Microsoft.PowerShell.Commands.Management/Microsoft.PowerShell.Commands.Management.csproj +++ b/src/Microsoft.PowerShell.Commands.Management/Microsoft.PowerShell.Commands.Management.csproj @@ -47,8 +47,8 @@ - - + + diff --git a/src/Microsoft.PowerShell.Commands.Utility/Microsoft.PowerShell.Commands.Utility.csproj b/src/Microsoft.PowerShell.Commands.Utility/Microsoft.PowerShell.Commands.Utility.csproj index 8fe2b24b05f..3e270da4164 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/Microsoft.PowerShell.Commands.Utility.csproj +++ b/src/Microsoft.PowerShell.Commands.Utility/Microsoft.PowerShell.Commands.Utility.csproj @@ -13,7 +13,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive all - + @@ -41,8 +41,8 @@ - - + + diff --git a/src/Microsoft.PowerShell.CoreCLR.Eventing/Microsoft.PowerShell.CoreCLR.Eventing.csproj b/src/Microsoft.PowerShell.CoreCLR.Eventing/Microsoft.PowerShell.CoreCLR.Eventing.csproj index b88db6c5e62..a02a0637693 100644 --- a/src/Microsoft.PowerShell.CoreCLR.Eventing/Microsoft.PowerShell.CoreCLR.Eventing.csproj +++ b/src/Microsoft.PowerShell.CoreCLR.Eventing/Microsoft.PowerShell.CoreCLR.Eventing.csproj @@ -8,7 +8,7 @@ - + diff --git a/src/Microsoft.PowerShell.SDK/Microsoft.PowerShell.SDK.csproj b/src/Microsoft.PowerShell.SDK/Microsoft.PowerShell.SDK.csproj index f1feac7c371..e951707c28b 100644 --- a/src/Microsoft.PowerShell.SDK/Microsoft.PowerShell.SDK.csproj +++ b/src/Microsoft.PowerShell.SDK/Microsoft.PowerShell.SDK.csproj @@ -17,55 +17,55 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - + + + + + + - - - - - - - - - - - - - - + + + + + + + + + + + + + + - - + + - + diff --git a/src/Microsoft.WSMan.Management/Microsoft.WSMan.Management.csproj b/src/Microsoft.WSMan.Management/Microsoft.WSMan.Management.csproj index 087d4562069..c820e3f235b 100644 --- a/src/Microsoft.WSMan.Management/Microsoft.WSMan.Management.csproj +++ b/src/Microsoft.WSMan.Management/Microsoft.WSMan.Management.csproj @@ -7,11 +7,11 @@ - + - + diff --git a/src/System.Management.Automation/System.Management.Automation.csproj b/src/System.Management.Automation/System.Management.Automation.csproj index 030f6654237..f3b62eafb49 100644 --- a/src/System.Management.Automation/System.Management.Automation.csproj +++ b/src/System.Management.Automation/System.Management.Automation.csproj @@ -32,25 +32,25 @@ - - - - - - + + + + + + - + - - - - + + + + - + diff --git a/test/perf/dotnet-tools/BenchmarkDotNet.Extensions/BenchmarkDotNet.Extensions.csproj b/test/perf/dotnet-tools/BenchmarkDotNet.Extensions/BenchmarkDotNet.Extensions.csproj index b8568a0e373..9b5fb753394 100644 --- a/test/perf/dotnet-tools/BenchmarkDotNet.Extensions/BenchmarkDotNet.Extensions.csproj +++ b/test/perf/dotnet-tools/BenchmarkDotNet.Extensions/BenchmarkDotNet.Extensions.csproj @@ -13,10 +13,11 @@ - + + diff --git a/test/perf/dotnet-tools/ResultsComparer/ResultsComparer.csproj b/test/perf/dotnet-tools/ResultsComparer/ResultsComparer.csproj index a7ec51fdcf7..3eacb22eb51 100644 --- a/test/perf/dotnet-tools/ResultsComparer/ResultsComparer.csproj +++ b/test/perf/dotnet-tools/ResultsComparer/ResultsComparer.csproj @@ -13,11 +13,12 @@ - + + diff --git a/test/tools/NamedPipeConnection/src/code/Microsoft.PowerShell.NamedPipeConnection.csproj b/test/tools/NamedPipeConnection/src/code/Microsoft.PowerShell.NamedPipeConnection.csproj index a813503467c..7fa3f53c83d 100644 --- a/test/tools/NamedPipeConnection/src/code/Microsoft.PowerShell.NamedPipeConnection.csproj +++ b/test/tools/NamedPipeConnection/src/code/Microsoft.PowerShell.NamedPipeConnection.csproj @@ -17,21 +17,21 @@ - + - - - - - - - + + + + + + + - - - - - + + + + + diff --git a/test/tools/TestService/TestService.csproj b/test/tools/TestService/TestService.csproj index cae146e8f5e..5508aa6cd9b 100644 --- a/test/tools/TestService/TestService.csproj +++ b/test/tools/TestService/TestService.csproj @@ -15,56 +15,56 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - + + + + + - - - - - - - - + + + + + + + + - + diff --git a/test/tools/WebListener/WebListener.csproj b/test/tools/WebListener/WebListener.csproj index 9f6fb2ce79a..c65c90a3ff7 100644 --- a/test/tools/WebListener/WebListener.csproj +++ b/test/tools/WebListener/WebListener.csproj @@ -7,9 +7,9 @@ - - + + - + diff --git a/tools/cgmanifest.json b/tools/cgmanifest.json index 13f35eb8dd2..9b00c6ac230 100644 --- a/tools/cgmanifest.json +++ b/tools/cgmanifest.json @@ -115,7 +115,7 @@ "Type": "nuget", "Nuget": { "Name": "Microsoft.Extensions.ObjectPool", - "Version": "8.0.17" + "Version": "8.0.19" } }, "DevelopmentDependency": false @@ -155,7 +155,7 @@ "Type": "nuget", "Nuget": { "Name": "Microsoft.Win32.Registry.AccessControl", - "Version": "9.0.6" + "Version": "9.0.8" } }, "DevelopmentDependency": false @@ -165,7 +165,7 @@ "Type": "nuget", "Nuget": { "Name": "Microsoft.Win32.SystemEvents", - "Version": "9.0.6" + "Version": "9.0.8" } }, "DevelopmentDependency": false @@ -175,7 +175,7 @@ "Type": "nuget", "Nuget": { "Name": "Microsoft.Windows.Compatibility", - "Version": "9.0.6" + "Version": "9.0.8" } }, "DevelopmentDependency": false @@ -195,7 +195,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.android-arm.runtime.native.System.IO.Ports", - "Version": "9.0.6" + "Version": "9.0.8" } }, "DevelopmentDependency": false @@ -205,7 +205,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.android-arm64.runtime.native.System.IO.Ports", - "Version": "9.0.6" + "Version": "9.0.8" } }, "DevelopmentDependency": false @@ -215,7 +215,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.android-x64.runtime.native.System.IO.Ports", - "Version": "9.0.6" + "Version": "9.0.8" } }, "DevelopmentDependency": false @@ -225,7 +225,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.android-x86.runtime.native.System.IO.Ports", - "Version": "9.0.6" + "Version": "9.0.8" } }, "DevelopmentDependency": false @@ -235,7 +235,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.linux-arm.runtime.native.System.IO.Ports", - "Version": "9.0.6" + "Version": "9.0.8" } }, "DevelopmentDependency": false @@ -245,7 +245,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.linux-arm64.runtime.native.System.IO.Ports", - "Version": "9.0.6" + "Version": "9.0.8" } }, "DevelopmentDependency": false @@ -255,7 +255,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.linux-bionic-arm64.runtime.native.System.IO.Ports", - "Version": "9.0.6" + "Version": "9.0.8" } }, "DevelopmentDependency": false @@ -265,7 +265,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.linux-bionic-x64.runtime.native.System.IO.Ports", - "Version": "9.0.6" + "Version": "9.0.8" } }, "DevelopmentDependency": false @@ -275,7 +275,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.linux-musl-arm.runtime.native.System.IO.Ports", - "Version": "9.0.6" + "Version": "9.0.8" } }, "DevelopmentDependency": false @@ -285,7 +285,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.linux-musl-arm64.runtime.native.System.IO.Ports", - "Version": "9.0.6" + "Version": "9.0.8" } }, "DevelopmentDependency": false @@ -295,7 +295,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.linux-musl-x64.runtime.native.System.IO.Ports", - "Version": "9.0.6" + "Version": "9.0.8" } }, "DevelopmentDependency": false @@ -305,7 +305,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.linux-x64.runtime.native.System.IO.Ports", - "Version": "9.0.6" + "Version": "9.0.8" } }, "DevelopmentDependency": false @@ -315,7 +315,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.maccatalyst-arm64.runtime.native.System.IO.Ports", - "Version": "9.0.6" + "Version": "9.0.8" } }, "DevelopmentDependency": false @@ -325,7 +325,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.maccatalyst-x64.runtime.native.System.IO.Ports", - "Version": "9.0.6" + "Version": "9.0.8" } }, "DevelopmentDependency": false @@ -345,7 +345,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.native.System.IO.Ports", - "Version": "9.0.6" + "Version": "9.0.8" } }, "DevelopmentDependency": false @@ -355,7 +355,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.osx-arm64.runtime.native.System.IO.Ports", - "Version": "9.0.6" + "Version": "9.0.8" } }, "DevelopmentDependency": false @@ -365,7 +365,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.osx-x64.runtime.native.System.IO.Ports", - "Version": "9.0.6" + "Version": "9.0.8" } }, "DevelopmentDependency": false @@ -425,7 +425,7 @@ "Type": "nuget", "Nuget": { "Name": "System.CodeDom", - "Version": "9.0.6" + "Version": "9.0.8" } }, "DevelopmentDependency": false @@ -445,7 +445,7 @@ "Type": "nuget", "Nuget": { "Name": "System.ComponentModel.Composition.Registration", - "Version": "9.0.6" + "Version": "9.0.8" } }, "DevelopmentDependency": false @@ -455,7 +455,7 @@ "Type": "nuget", "Nuget": { "Name": "System.ComponentModel.Composition", - "Version": "9.0.6" + "Version": "9.0.8" } }, "DevelopmentDependency": false @@ -465,7 +465,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Configuration.ConfigurationManager", - "Version": "9.0.6" + "Version": "9.0.8" } }, "DevelopmentDependency": false @@ -475,7 +475,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Data.Odbc", - "Version": "9.0.6" + "Version": "9.0.8" } }, "DevelopmentDependency": false @@ -485,7 +485,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Data.OleDb", - "Version": "9.0.6" + "Version": "9.0.8" } }, "DevelopmentDependency": false @@ -505,7 +505,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Diagnostics.DiagnosticSource", - "Version": "9.0.6" + "Version": "9.0.8" } }, "DevelopmentDependency": false @@ -515,7 +515,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Diagnostics.EventLog", - "Version": "9.0.6" + "Version": "9.0.8" } }, "DevelopmentDependency": false @@ -525,7 +525,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Diagnostics.PerformanceCounter", - "Version": "9.0.6" + "Version": "9.0.8" } }, "DevelopmentDependency": false @@ -535,7 +535,7 @@ "Type": "nuget", "Nuget": { "Name": "System.DirectoryServices.AccountManagement", - "Version": "9.0.6" + "Version": "9.0.8" } }, "DevelopmentDependency": false @@ -545,7 +545,7 @@ "Type": "nuget", "Nuget": { "Name": "System.DirectoryServices.Protocols", - "Version": "9.0.6" + "Version": "9.0.8" } }, "DevelopmentDependency": false @@ -555,7 +555,7 @@ "Type": "nuget", "Nuget": { "Name": "System.DirectoryServices", - "Version": "9.0.6" + "Version": "9.0.8" } }, "DevelopmentDependency": false @@ -565,7 +565,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Drawing.Common", - "Version": "9.0.6" + "Version": "9.0.8" } }, "DevelopmentDependency": false @@ -575,7 +575,7 @@ "Type": "nuget", "Nuget": { "Name": "System.IO.Packaging", - "Version": "9.0.6" + "Version": "9.0.8" } }, "DevelopmentDependency": false @@ -585,7 +585,7 @@ "Type": "nuget", "Nuget": { "Name": "System.IO.Ports", - "Version": "9.0.6" + "Version": "9.0.8" } }, "DevelopmentDependency": false @@ -595,7 +595,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Management", - "Version": "9.0.6" + "Version": "9.0.8" } }, "DevelopmentDependency": false @@ -605,7 +605,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Net.Http.WinHttpHandler", - "Version": "9.0.6" + "Version": "9.0.8" } }, "DevelopmentDependency": false @@ -635,7 +635,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Reflection.Context", - "Version": "9.0.6" + "Version": "9.0.8" } }, "DevelopmentDependency": false @@ -665,7 +665,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Runtime.Caching", - "Version": "9.0.6" + "Version": "9.0.8" } }, "DevelopmentDependency": false @@ -685,7 +685,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Security.Cryptography.Pkcs", - "Version": "9.0.6" + "Version": "9.0.8" } }, "DevelopmentDependency": false @@ -695,7 +695,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Security.Cryptography.ProtectedData", - "Version": "9.0.6" + "Version": "9.0.8" } }, "DevelopmentDependency": false @@ -705,7 +705,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Security.Cryptography.Xml", - "Version": "9.0.6" + "Version": "9.0.8" } }, "DevelopmentDependency": false @@ -715,7 +715,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Security.Permissions", - "Version": "9.0.6" + "Version": "9.0.8" } }, "DevelopmentDependency": false @@ -785,7 +785,7 @@ "Type": "nuget", "Nuget": { "Name": "System.ServiceModel.Syndication", - "Version": "9.0.6" + "Version": "9.0.8" } }, "DevelopmentDependency": false @@ -795,7 +795,7 @@ "Type": "nuget", "Nuget": { "Name": "System.ServiceProcess.ServiceController", - "Version": "9.0.6" + "Version": "9.0.8" } }, "DevelopmentDependency": false @@ -805,7 +805,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Speech", - "Version": "9.0.6" + "Version": "9.0.8" } }, "DevelopmentDependency": false @@ -815,7 +815,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Text.Encoding.CodePages", - "Version": "9.0.6" + "Version": "9.0.8" } }, "DevelopmentDependency": false @@ -825,7 +825,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Text.Encodings.Web", - "Version": "9.0.6" + "Version": "9.0.8" } }, "DevelopmentDependency": false @@ -835,7 +835,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Threading.AccessControl", - "Version": "9.0.6" + "Version": "9.0.8" } }, "DevelopmentDependency": false @@ -855,7 +855,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Windows.Extensions", - "Version": "9.0.6" + "Version": "9.0.8" } }, "DevelopmentDependency": false From 18fa315361602d5a97a13b919a9c70bdd721366f Mon Sep 17 00:00:00 2001 From: PowerShell Team Bot <69177312+pwshBot@users.noreply.github.com> Date: Tue, 2 Sep 2025 14:31:44 -0700 Subject: [PATCH 143/173] [release/v7.5] Fix typo in CHANGELOG for script filename suggestion (#25963) Co-authored-by: Travis Plunk --- CHANGELOG/7.5.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG/7.5.md b/CHANGELOG/7.5.md index 8cf3dba6282..d2071727790 100644 --- a/CHANGELOG/7.5.md +++ b/CHANGELOG/7.5.md @@ -10,7 +10,7 @@ - Set standard handles explicitly when starting a process with `-NoNewWindow` (#25324) - Make inherited protected internal instance members accessible in class scope. (#25547) (Thanks @mawosoft!) -- Remove the old fuzzy suggestion and fix the local script file name suggestion (#25330) +- Remove the old fuzzy suggestion and fix the local script filename suggestion (#25330) - Fix `PSMethodInvocationConstraints.GetHashCode` method (#25306) (Thanks @crazyjncsu!) ### Build and Packaging Improvements From 964a77b46f52c6b35308bbee83db7f878a816fec Mon Sep 17 00:00:00 2001 From: PowerShell Team Bot <69177312+pwshBot@users.noreply.github.com> Date: Tue, 2 Sep 2025 14:51:58 -0700 Subject: [PATCH 144/173] [release/v7.5] Remove AsyncSDL from Pipelines Toggle Official/NonOfficial Runs (#25964) Co-authored-by: Justin Chung <124807742+jshigetomi@users.noreply.github.com> Co-authored-by: Travis Plunk --- .pipelines/MSIXBundle-vPack-Official.yml | 3 +- ...werShell-Coordinated_Packages-Official.yml | 35 +++++++++++-------- .pipelines/PowerShell-Packages-Official.yml | 31 ++++++++-------- .../PowerShell-Release-Official-Azure.yml | 13 ++++--- .pipelines/PowerShell-Release-Official.yml | 19 +++++++--- .pipelines/PowerShell-vPack-Official.yml | 3 +- 6 files changed, 62 insertions(+), 42 deletions(-) diff --git a/.pipelines/MSIXBundle-vPack-Official.yml b/.pipelines/MSIXBundle-vPack-Official.yml index f20e8a31114..ef96f63f045 100644 --- a/.pipelines/MSIXBundle-vPack-Official.yml +++ b/.pipelines/MSIXBundle-vPack-Official.yml @@ -68,11 +68,10 @@ extends: suppressionsFile: $(Build.SourcesDirectory)\.config\suppress.json binskim: enabled: false + exactToolVersion: 4.4.2 # APIScan requires a non-Ready-To-Run build apiscan: enabled: false - asyncSDL: - enabled: false tsaOptionsFile: .config/tsaoptions.json stages: diff --git a/.pipelines/PowerShell-Coordinated_Packages-Official.yml b/.pipelines/PowerShell-Coordinated_Packages-Official.yml index 11215302e46..8de89b0c508 100644 --- a/.pipelines/PowerShell-Coordinated_Packages-Official.yml +++ b/.pipelines/PowerShell-Coordinated_Packages-Official.yml @@ -26,6 +26,10 @@ parameters: displayName: Enable MSBuild Binary Logs type: boolean default: false + - name: OfficialBuild + type: boolean + default: false + resources: repositories: @@ -74,9 +78,17 @@ variables: - group: mscodehub-feed-read-akv - name: ENABLE_MSBUILD_BINLOGS value: ${{ parameters.ENABLE_MSBUILD_BINLOGS }} + - name: templateFile + value: ${{ iif ( parameters.OfficialBuild, 'v2/OneBranch.Official.CrossPlat.yml@onebranchTemplates', 'v2/OneBranch.NonOfficial.CrossPlat.yml@onebranchTemplates' ) }} + # Fix for BinSkim ICU package error in Linux containers + - name: DOTNET_SYSTEM_GLOBALIZATION_INVARIANT + value: true + # Disable BinSkim at job level to override NonOfficial template defaults + - name: ob_sdl_binskim_enabled + value: false extends: - template: v2/OneBranch.Official.CrossPlat.yml@onebranchTemplates + template: ${{ variables.templateFile }} parameters: customTags: 'ES365AIMigrationTooling' featureFlags: @@ -84,6 +96,7 @@ extends: Network: KS3 WindowsHostVersion: Network: KS3 + incrementalSDLBinaryAnalysis: true globalSdl: disableLegacyManifest: true # disabled Armorty as we dont have any ARM templates to scan. It fails on some sample ARM templates. @@ -103,19 +116,13 @@ extends: cg: enabled: true ignoreDirectories: '.devcontainer,demos,docker,docs,src,test,tools/packaging' - asyncSdl: - enabled: true - forStages: [prep, macos, linux, windows, SignFiles, test_and_release_artifacts] - credscan: - enabled: true - scanFolder: $(Build.SourcesDirectory) - suppressionsFile: $(Build.SourcesDirectory)\PowerShell\.config\suppress.json - binskim: - enabled: false - # APIScan requires a non-Ready-To-Run build - apiscan: - enabled: false - tsaOptionsFile: .config\tsaoptions.json + binskim: + enabled: false + exactToolVersion: 4.4.2 + # APIScan requires a non-Ready-To-Run build + apiscan: + enabled: false + tsaOptionsFile: .config\tsaoptions.json stages: - stage: prep diff --git a/.pipelines/PowerShell-Packages-Official.yml b/.pipelines/PowerShell-Packages-Official.yml index 487e8cb9c6a..f0d428bf1d6 100644 --- a/.pipelines/PowerShell-Packages-Official.yml +++ b/.pipelines/PowerShell-Packages-Official.yml @@ -24,7 +24,10 @@ parameters: # parameters are shown up in ADO UI in a build queue time displayName: Skip Signing type: string default: 'NO' - + - name: OfficialBuild + type: boolean + default: false + name: pkgs-$(BUILD.SOURCEBRANCHNAME)-$(Build.BuildId) variables: @@ -61,6 +64,9 @@ variables: - name: branchCounter value: $[counter(variables['branchCounterKey'], 1)] - group: MSIXSigningProfile + - name: templateFile + value: ${{ iif ( parameters.OfficialBuild, 'v2/OneBranch.Official.CrossPlat.yml@onebranchTemplates', 'v2/OneBranch.NonOfficial.CrossPlat.yml@onebranchTemplates' ) }} + resources: pipelines: @@ -79,7 +85,7 @@ resources: ref: refs/heads/main extends: - template: v2/OneBranch.Official.CrossPlat.yml@templates + template: ${{ variables.templateFile }} parameters: cloudvault: enabled: false @@ -88,6 +94,7 @@ extends: Version: 2022 Network: KS3 linuxEsrpSigning: true + incrementalSDLBinaryAnalysis: true globalSdl: disableLegacyManifest: true # disabled Armorty as we dont have any ARM templates to scan. It fails on some sample ARM templates. @@ -104,19 +111,13 @@ extends: cg: enabled: true ignoreDirectories: '.devcontainer,demos,docker,docs,src,test,tools/packaging' - asyncSdl: - enabled: true - forStages: ['build'] - credscan: - enabled: true - scanFolder: $(Build.SourcesDirectory) - suppressionsFile: $(Build.SourcesDirectory)\PowerShell\.config\suppress.json - binskim: - enabled: false - # APIScan requires a non-Ready-To-Run build - apiscan: - enabled: false - tsaOptionsFile: .config\tsaoptions.json + binskim: + enabled: false + exactToolVersion: 4.4.2 + # APIScan requires a non-Ready-To-Run build + apiscan: + enabled: false + tsaOptionsFile: .config\tsaoptions.json stages: - stage: prep jobs: diff --git a/.pipelines/PowerShell-Release-Official-Azure.yml b/.pipelines/PowerShell-Release-Official-Azure.yml index 2d644c7a5dd..8e144f1ee55 100644 --- a/.pipelines/PowerShell-Release-Official-Azure.yml +++ b/.pipelines/PowerShell-Release-Official-Azure.yml @@ -13,6 +13,9 @@ parameters: # parameters are shown up in ADO UI in a build queue time displayName: Skip Signing type: string default: 'NO' + - name: OfficialBuild + type: boolean + default: false name: ev2-$(BUILD.SOURCEBRANCHNAME)-$(Build.BuildId) @@ -46,6 +49,9 @@ variables: - name: LinuxContainerImage value: mcr.microsoft.com/onebranch/cbl-mariner/build:2.0 - group: PoolNames + - name: templateFile + value: ${{ iif ( parameters.OfficialBuild, 'v2/OneBranch.Official.CrossPlat.yml@onebranchTemplates', 'v2/OneBranch.NonOfficial.CrossPlat.yml@onebranchTemplates' ) }} + resources: repositories: @@ -67,13 +73,14 @@ resources: - releases/* extends: - template: v2/OneBranch.Official.CrossPlat.yml@templates + template: ${{ variables.templateFile }} parameters: featureFlags: WindowsHostVersion: Version: 2022 Network: Netlock linuxEsrpSigning: true + incrementalSDLBinaryAnalysis: true cloudvault: enabled: false globalSdl: @@ -81,9 +88,6 @@ extends: # disabled Armory as we dont have any ARM templates to scan. It fails on some sample ARM templates. armory: enabled: false - asyncSdl: - enabled: true - tsaOptionsFile: .config/tsaoptions.json tsa: enabled: true credscan: @@ -92,6 +96,7 @@ extends: suppressionsFile: $(Build.SourcesDirectory)\.config\suppress.json binskim: break: false # always break the build on binskim issues in addition to TSA upload + exactToolVersion: 4.4.2 policheck: break: true # always break the build on policheck issues. You can disable it by setting to 'false' tsaOptionsFile: .config\tsaoptions.json diff --git a/.pipelines/PowerShell-Release-Official.yml b/.pipelines/PowerShell-Release-Official.yml index bfc475785aa..9d543eae3a9 100644 --- a/.pipelines/PowerShell-Release-Official.yml +++ b/.pipelines/PowerShell-Release-Official.yml @@ -25,6 +25,9 @@ parameters: # parameters are shown up in ADO UI in a build queue time displayName: Skip Copying Archives and Installers to PSInfrastructure Public Location type: boolean default: false + - name: OfficialBuild + type: boolean + default: false name: release-$(BUILD.SOURCEBRANCHNAME)-$(Build.BuildId) @@ -58,6 +61,13 @@ variables: - name: ReleaseTagVar value: ${{ parameters.ReleaseTagVar }} - group: PoolNames + - name: templateFile + value: ${{ iif ( parameters.OfficialBuild, 'v2/OneBranch.Official.CrossPlat.yml@onebranchTemplates', 'v2/OneBranch.NonOfficial.CrossPlat.yml@onebranchTemplates' ) }} + - name: releaseEnvironment + value: ${{ iif ( parameters.OfficialBuild, 'Production', 'Test' ) }} + # Fix for BinSkim ICU package error in Linux containers + - name: DOTNET_SYSTEM_GLOBALIZATION_INVARIANT + value: true resources: repositories: @@ -83,7 +93,7 @@ resources: - releases/* extends: - template: v2/OneBranch.Official.CrossPlat.yml@templates + template: ${{ variables.templateFile }} parameters: release: category: NonAzure @@ -91,6 +101,7 @@ extends: WindowsHostVersion: Version: 2022 Network: KS3 + incrementalSDLBinaryAnalysis: true cloudvault: enabled: false globalSdl: @@ -98,9 +109,6 @@ extends: # disabled Armory as we dont have any ARM templates to scan. It fails on some sample ARM templates. armory: enabled: false - asyncSdl: - enabled: true - tsaOptionsFile: .config/tsaoptions.json tsa: enabled: true credscan: @@ -109,6 +117,7 @@ extends: suppressionsFile: $(Build.SourcesDirectory)\.config\suppress.json binskim: break: false # always break the build on binskim issues in addition to TSA upload + exactToolVersion: 4.4.2 policheck: break: true # always break the build on policheck issues. You can disable it by setting to 'false' # suppression: @@ -279,7 +288,7 @@ extends: - setReleaseTagAndChangelog - UpdateChangeLog variables: - ob_release_environment: Production + ob_release_environment: ${{ parameters.releaseEnvironment }} jobs: - template: /.pipelines/templates/release-githubNuget.yml@self parameters: diff --git a/.pipelines/PowerShell-vPack-Official.yml b/.pipelines/PowerShell-vPack-Official.yml index 9a9aceed387..05a8fefbb0f 100644 --- a/.pipelines/PowerShell-vPack-Official.yml +++ b/.pipelines/PowerShell-vPack-Official.yml @@ -93,11 +93,10 @@ extends: suppressionsFile: $(Build.SourcesDirectory)\.config\suppress.json binskim: enabled: false + exactToolVersion: 4.4.2 # APIScan requires a non-Ready-To-Run build apiscan: enabled: false - asyncSDL: - enabled: false tsaOptionsFile: .config/tsaoptions.json stages: - stage: main From 8fb0da460ddfe48fb43a1463441cd2d59b53943f Mon Sep 17 00:00:00 2001 From: PowerShell Team Bot <69177312+pwshBot@users.noreply.github.com> Date: Tue, 2 Sep 2025 16:45:51 -0700 Subject: [PATCH 145/173] [release/v7.5] Make the interface `IDeepCloneable` internal (#25830) Co-authored-by: Dongbo Wang Co-authored-by: Travis Plunk --- .../ManagementList/FilterCore/IDeepCloneable.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/IDeepCloneable.cs b/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/IDeepCloneable.cs index 3090f93a95c..841a2424b51 100644 --- a/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/IDeepCloneable.cs +++ b/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/IDeepCloneable.cs @@ -6,8 +6,7 @@ namespace Microsoft.Management.UI.Internal /// /// Defines a generalized method for creating a deep copy of an instance. /// - [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.MSInternal", "CA903:InternalNamespaceShouldNotContainPublicTypes")] - public interface IDeepCloneable + internal interface IDeepCloneable { /// /// Creates a deep copy of the current instance. From d03f8071174c0c0114113fe4b8f14e411e706ec3 Mon Sep 17 00:00:00 2001 From: PowerShell Team Bot <69177312+pwshBot@users.noreply.github.com> Date: Tue, 2 Sep 2025 17:12:48 -0700 Subject: [PATCH 146/173] [release/v7.5] Remove `OnDeserialized` and `Serializable` attributes from `Microsoft.Management.UI.Internal` project (#25831) Co-authored-by: Dongbo Wang Co-authored-by: Travis Plunk --- .../FilterCore/FilterRules/ComparableValueFilterRule.cs | 1 - .../FilterCore/FilterRules/DoesNotEqualFilterRule.cs | 1 - .../FilterCore/FilterRules/EqualsFilterRule.cs | 1 - .../ManagementList/FilterCore/FilterRules/FilterRule.cs | 2 -- .../FilterCore/FilterRules/IsBetweenFilterRule.cs | 8 -------- .../FilterCore/FilterRules/IsEmptyFilterRule.cs | 1 - .../FilterCore/FilterRules/IsGreaterThanFilterRule.cs | 1 - .../FilterCore/FilterRules/IsLessThanFilterRule.cs | 1 - .../FilterCore/FilterRules/IsNotEmptyFilterRule.cs | 1 - .../FilterCore/FilterRules/IsNotEmptyValidationRule.cs | 1 - .../FilterRules/PropertiesTextContainsFilterRule.cs | 7 ------- .../FilterRules/PropertyValueSelectorFilterRule.cs | 1 - .../FilterCore/FilterRules/SelectorFilterRule.cs | 8 -------- .../FilterRules/SingleValueComparableValueFilterRule.cs | 7 ------- .../FilterCore/FilterRules/TextContainsFilterRule.cs | 1 - .../FilterRules/TextDoesNotContainFilterRule.cs | 1 - .../FilterCore/FilterRules/TextDoesNotEqualFilterRule.cs | 1 - .../FilterCore/FilterRules/TextEndsWithFilterRule.cs | 1 - .../FilterCore/FilterRules/TextEqualsFilterRule.cs | 1 - .../FilterCore/FilterRules/TextFilterRule.cs | 1 - .../FilterCore/FilterRules/TextStartsWithFilterRule.cs | 1 - .../ManagementList/FilterCore/ValidatingSelectorValue.cs | 2 -- .../ManagementList/FilterCore/ValidatingValue.cs | 1 - .../ManagementList/FilterCore/ValidatingValueBase.cs | 3 --- .../ValidationRules/DataErrorInfoValidationRule.cs | 1 - .../FilterProviders/FilterRuleToDisplayNameConverter.cs | 1 - .../ManagementList/ManagementListStateDescriptor.cs | 1 - src/powershell-win-core/powershell-win-core.csproj | 1 - 28 files changed, 58 deletions(-) diff --git a/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/ComparableValueFilterRule.cs b/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/ComparableValueFilterRule.cs index dca6c08d535..8362a035156 100644 --- a/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/ComparableValueFilterRule.cs +++ b/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/ComparableValueFilterRule.cs @@ -13,7 +13,6 @@ namespace Microsoft.Management.UI.Internal /// The generic parameter. /// [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.MSInternal", "CA903:InternalNamespaceShouldNotContainPublicTypes")] - [Serializable] public abstract class ComparableValueFilterRule : FilterRule where T : IComparable { /// diff --git a/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/DoesNotEqualFilterRule.cs b/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/DoesNotEqualFilterRule.cs index 94451623c3a..c5d4f36fe55 100644 --- a/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/DoesNotEqualFilterRule.cs +++ b/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/DoesNotEqualFilterRule.cs @@ -13,7 +13,6 @@ namespace Microsoft.Management.UI.Internal /// The generic parameter. /// [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.MSInternal", "CA903:InternalNamespaceShouldNotContainPublicTypes")] - [Serializable] public class DoesNotEqualFilterRule : EqualsFilterRule where T : IComparable { /// diff --git a/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/EqualsFilterRule.cs b/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/EqualsFilterRule.cs index eaf647f0030..34a1ecb722d 100644 --- a/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/EqualsFilterRule.cs +++ b/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/EqualsFilterRule.cs @@ -14,7 +14,6 @@ namespace Microsoft.Management.UI.Internal /// The generic parameter. /// [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.MSInternal", "CA903:InternalNamespaceShouldNotContainPublicTypes")] - [Serializable] public class EqualsFilterRule : SingleValueComparableValueFilterRule where T : IComparable { /// diff --git a/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/FilterRule.cs b/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/FilterRule.cs index 7f72f33eb2d..f18c89addf9 100644 --- a/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/FilterRule.cs +++ b/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/FilterRule.cs @@ -9,7 +9,6 @@ namespace Microsoft.Management.UI.Internal /// The base class for all filtering rules. /// [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.MSInternal", "CA903:InternalNamespaceShouldNotContainPublicTypes")] - [Serializable] public abstract class FilterRule : IEvaluate, IDeepCloneable { /// @@ -69,7 +68,6 @@ public object DeepClone() /// /// Occurs when the values of this rule changes. /// - [field: NonSerialized] public event EventHandler EvaluationResultInvalidated; /// diff --git a/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/IsBetweenFilterRule.cs b/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/IsBetweenFilterRule.cs index d8c4a263c61..f51093510ec 100644 --- a/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/IsBetweenFilterRule.cs +++ b/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/IsBetweenFilterRule.cs @@ -16,7 +16,6 @@ namespace Microsoft.Management.UI.Internal /// The generic parameter. /// [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.MSInternal", "CA903:InternalNamespaceShouldNotContainPublicTypes")] - [Serializable] public class IsBetweenFilterRule : ComparableValueFilterRule where T : IComparable { #region Properties @@ -122,13 +121,6 @@ private void Value_PropertyChanged(object sender, PropertyChangedEventArgs e) } } - [OnDeserialized] - private void Initialize(StreamingContext context) - { - this.StartValue.PropertyChanged += this.Value_PropertyChanged; - this.EndValue.PropertyChanged += this.Value_PropertyChanged; - } - #endregion Value Change Handlers } } diff --git a/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/IsEmptyFilterRule.cs b/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/IsEmptyFilterRule.cs index a3add25eae5..71bb7e23e7c 100644 --- a/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/IsEmptyFilterRule.cs +++ b/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/IsEmptyFilterRule.cs @@ -10,7 +10,6 @@ namespace Microsoft.Management.UI.Internal /// is empty or not. /// [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.MSInternal", "CA903:InternalNamespaceShouldNotContainPublicTypes")] - [Serializable] public class IsEmptyFilterRule : FilterRule { /// diff --git a/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/IsGreaterThanFilterRule.cs b/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/IsGreaterThanFilterRule.cs index c6d9ef762b4..6c7d16f312a 100644 --- a/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/IsGreaterThanFilterRule.cs +++ b/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/IsGreaterThanFilterRule.cs @@ -14,7 +14,6 @@ namespace Microsoft.Management.UI.Internal /// The generic parameter. /// [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.MSInternal", "CA903:InternalNamespaceShouldNotContainPublicTypes")] - [Serializable] public class IsGreaterThanFilterRule : SingleValueComparableValueFilterRule where T : IComparable { /// diff --git a/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/IsLessThanFilterRule.cs b/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/IsLessThanFilterRule.cs index a90dcdc8a82..e1dc3268cc5 100644 --- a/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/IsLessThanFilterRule.cs +++ b/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/IsLessThanFilterRule.cs @@ -14,7 +14,6 @@ namespace Microsoft.Management.UI.Internal /// The generic parameter. /// [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.MSInternal", "CA903:InternalNamespaceShouldNotContainPublicTypes")] - [Serializable] public class IsLessThanFilterRule : SingleValueComparableValueFilterRule where T : IComparable { /// diff --git a/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/IsNotEmptyFilterRule.cs b/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/IsNotEmptyFilterRule.cs index 450a1237a97..711caee9874 100644 --- a/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/IsNotEmptyFilterRule.cs +++ b/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/IsNotEmptyFilterRule.cs @@ -10,7 +10,6 @@ namespace Microsoft.Management.UI.Internal /// is empty or not. /// [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.MSInternal", "CA903:InternalNamespaceShouldNotContainPublicTypes")] - [Serializable] public class IsNotEmptyFilterRule : IsEmptyFilterRule { /// diff --git a/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/IsNotEmptyValidationRule.cs b/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/IsNotEmptyValidationRule.cs index 98534aca0ad..cb6eacaaff3 100644 --- a/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/IsNotEmptyValidationRule.cs +++ b/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/IsNotEmptyValidationRule.cs @@ -9,7 +9,6 @@ namespace Microsoft.Management.UI.Internal /// The IsNotEmptyValidationRule checks a value to see if a value is not empty. /// [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.MSInternal", "CA903:InternalNamespaceShouldNotContainPublicTypes")] - [Serializable] public class IsNotEmptyValidationRule : DataErrorInfoValidationRule { #region Properties diff --git a/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/PropertiesTextContainsFilterRule.cs b/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/PropertiesTextContainsFilterRule.cs index 54532335835..8c32530be8c 100644 --- a/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/PropertiesTextContainsFilterRule.cs +++ b/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/PropertiesTextContainsFilterRule.cs @@ -12,7 +12,6 @@ namespace Microsoft.Management.UI.Internal /// Represents a filter rule that searches for text within properties on an object. /// [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.MSInternal", "CA903:InternalNamespaceShouldNotContainPublicTypes")] - [Serializable] public class PropertiesTextContainsFilterRule : TextFilterRule { private static readonly string TextContainsCharactersRegexPattern = "{0}"; @@ -131,11 +130,5 @@ private void PropertiesTextContainsFilterRule_EvaluationResultInvalidated(object { this.OnEvaluationResultInvalidated(); } - - [OnDeserialized] - private void Initialize(StreamingContext context) - { - this.EvaluationResultInvalidated += this.PropertiesTextContainsFilterRule_EvaluationResultInvalidated; - } } } diff --git a/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/PropertyValueSelectorFilterRule.cs b/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/PropertyValueSelectorFilterRule.cs index 6699cb0e698..09c732970b0 100644 --- a/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/PropertyValueSelectorFilterRule.cs +++ b/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/PropertyValueSelectorFilterRule.cs @@ -16,7 +16,6 @@ namespace Microsoft.Management.UI.Internal /// The generic parameter. /// [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.MSInternal", "CA903:InternalNamespaceShouldNotContainPublicTypes")] - [Serializable] public class PropertyValueSelectorFilterRule : SelectorFilterRule where T : IComparable { #region Properties diff --git a/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/SelectorFilterRule.cs b/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/SelectorFilterRule.cs index d7451bbd21f..d1627ee2281 100644 --- a/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/SelectorFilterRule.cs +++ b/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/SelectorFilterRule.cs @@ -10,7 +10,6 @@ namespace Microsoft.Management.UI.Internal /// The SelectorFilterRule represents a rule composed of other rules. /// [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.MSInternal", "CA903:InternalNamespaceShouldNotContainPublicTypes")] - [Serializable] public class SelectorFilterRule : FilterRule { #region Properties @@ -113,13 +112,6 @@ private void SelectedValue_EvaluationResultInvalidated(object sender, EventArgs #region Private Methods - [OnDeserialized] - private void Initialize(StreamingContext context) - { - this.AvailableRules.SelectedValueChanged += this.AvailableRules_SelectedValueChanged; - this.AvailableRules.SelectedValue.EvaluationResultInvalidated += this.SelectedValue_EvaluationResultInvalidated; - } - private void AvailableRules_SelectedValueChanged(object sender, PropertyChangedEventArgs e) { this.OnSelectedValueChanged(e.OldValue, e.NewValue); diff --git a/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/SingleValueComparableValueFilterRule.cs b/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/SingleValueComparableValueFilterRule.cs index a34288a6530..b26531943fc 100644 --- a/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/SingleValueComparableValueFilterRule.cs +++ b/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/SingleValueComparableValueFilterRule.cs @@ -13,7 +13,6 @@ namespace Microsoft.Management.UI.Internal /// /// The generic parameter. [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.MSInternal", "CA903:InternalNamespaceShouldNotContainPublicTypes")] - [Serializable] public abstract class SingleValueComparableValueFilterRule : ComparableValueFilterRule where T : IComparable { #region Properties @@ -72,11 +71,5 @@ private void Value_PropertyChanged(object sender, PropertyChangedEventArgs e) this.NotifyEvaluationResultInvalidated(); } } - - [OnDeserialized] - private void Initialize(StreamingContext context) - { - this.Value.PropertyChanged += this.Value_PropertyChanged; - } } } diff --git a/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/TextContainsFilterRule.cs b/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/TextContainsFilterRule.cs index acd52555498..beb4a29d23f 100644 --- a/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/TextContainsFilterRule.cs +++ b/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/TextContainsFilterRule.cs @@ -11,7 +11,6 @@ namespace Microsoft.Management.UI.Internal /// check if it is contains the rule's value within it. /// [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.MSInternal", "CA903:InternalNamespaceShouldNotContainPublicTypes")] - [Serializable] public class TextContainsFilterRule : TextFilterRule { private static readonly string TextContainsCharactersRegexPattern = "{0}"; diff --git a/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/TextDoesNotContainFilterRule.cs b/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/TextDoesNotContainFilterRule.cs index f85ca1bd125..2cdbf1efcef 100644 --- a/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/TextDoesNotContainFilterRule.cs +++ b/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/TextDoesNotContainFilterRule.cs @@ -10,7 +10,6 @@ namespace Microsoft.Management.UI.Internal /// check if it is does not contain the rule's value within it. /// [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.MSInternal", "CA903:InternalNamespaceShouldNotContainPublicTypes")] - [Serializable] public class TextDoesNotContainFilterRule : TextContainsFilterRule { /// diff --git a/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/TextDoesNotEqualFilterRule.cs b/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/TextDoesNotEqualFilterRule.cs index 0c7bb96532c..e74b371a7a6 100644 --- a/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/TextDoesNotEqualFilterRule.cs +++ b/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/TextDoesNotEqualFilterRule.cs @@ -10,7 +10,6 @@ namespace Microsoft.Management.UI.Internal /// check if it is not equal to the rule's value. /// [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.MSInternal", "CA903:InternalNamespaceShouldNotContainPublicTypes")] - [Serializable] public class TextDoesNotEqualFilterRule : TextEqualsFilterRule { /// diff --git a/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/TextEndsWithFilterRule.cs b/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/TextEndsWithFilterRule.cs index 2d4febe058d..d7f7e05c4b8 100644 --- a/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/TextEndsWithFilterRule.cs +++ b/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/TextEndsWithFilterRule.cs @@ -11,7 +11,6 @@ namespace Microsoft.Management.UI.Internal /// check if it ends with the rule's value. /// [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.MSInternal", "CA903:InternalNamespaceShouldNotContainPublicTypes")] - [Serializable] public class TextEndsWithFilterRule : TextFilterRule { private static readonly string TextEndsWithCharactersRegexPattern = "{0}$"; diff --git a/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/TextEqualsFilterRule.cs b/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/TextEqualsFilterRule.cs index a6e74dca622..a357575c6ab 100644 --- a/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/TextEqualsFilterRule.cs +++ b/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/TextEqualsFilterRule.cs @@ -11,7 +11,6 @@ namespace Microsoft.Management.UI.Internal /// check if it is equal to the rule's value. /// [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.MSInternal", "CA903:InternalNamespaceShouldNotContainPublicTypes")] - [Serializable] public class TextEqualsFilterRule : TextFilterRule { private static readonly string TextEqualsCharactersRegexPattern = "^{0}$"; diff --git a/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/TextFilterRule.cs b/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/TextFilterRule.cs index c4cd5dba9f7..eacbcb8d256 100644 --- a/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/TextFilterRule.cs +++ b/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/TextFilterRule.cs @@ -14,7 +14,6 @@ namespace Microsoft.Management.UI.Internal /// evaluating string operations. /// [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.MSInternal", "CA903:InternalNamespaceShouldNotContainPublicTypes")] - [Serializable] public abstract class TextFilterRule : SingleValueComparableValueFilterRule { /// diff --git a/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/TextStartsWithFilterRule.cs b/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/TextStartsWithFilterRule.cs index 3b39d0f5660..98eac2b9a41 100644 --- a/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/TextStartsWithFilterRule.cs +++ b/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/FilterRules/TextStartsWithFilterRule.cs @@ -11,7 +11,6 @@ namespace Microsoft.Management.UI.Internal /// check if it starts with the rule's value. /// [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.MSInternal", "CA903:InternalNamespaceShouldNotContainPublicTypes")] - [Serializable] public class TextStartsWithFilterRule : TextFilterRule { private static readonly string TextStartsWithCharactersRegexPattern = "^{0}"; diff --git a/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/ValidatingSelectorValue.cs b/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/ValidatingSelectorValue.cs index ff981a74751..0fed0c42e65 100644 --- a/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/ValidatingSelectorValue.cs +++ b/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/ValidatingSelectorValue.cs @@ -16,7 +16,6 @@ namespace Microsoft.Management.UI.Internal /// The generic parameter. /// [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.MSInternal", "CA903:InternalNamespaceShouldNotContainPublicTypes")] - [Serializable] public class ValidatingSelectorValue : ValidatingValueBase { /// @@ -174,7 +173,6 @@ public IValueConverter DisplayNameConverter /// /// Notifies listeners that the selected value has changed. /// - [field: NonSerialized] public event EventHandler> SelectedValueChanged; #endregion Events diff --git a/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/ValidatingValue.cs b/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/ValidatingValue.cs index eee8ebc6e4a..437cb3be50e 100644 --- a/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/ValidatingValue.cs +++ b/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/ValidatingValue.cs @@ -15,7 +15,6 @@ namespace Microsoft.Management.UI.Internal /// The generic parameter. /// [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.MSInternal", "CA903:InternalNamespaceShouldNotContainPublicTypes")] - [Serializable] public class ValidatingValue : ValidatingValueBase { /// diff --git a/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/ValidatingValueBase.cs b/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/ValidatingValueBase.cs index 6b4c2daa10d..a4ffb1af77c 100644 --- a/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/ValidatingValueBase.cs +++ b/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/ValidatingValueBase.cs @@ -15,7 +15,6 @@ namespace Microsoft.Management.UI.Internal /// classes to support validation via the IDataErrorInfo interface. /// [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.MSInternal", "CA903:InternalNamespaceShouldNotContainPublicTypes")] - [Serializable] public abstract class ValidatingValueBase : IDataErrorInfo, INotifyPropertyChanged, IDeepCloneable { /// @@ -47,7 +46,6 @@ protected ValidatingValueBase(ValidatingValueBase source) private ReadOnlyCollection readonlyValidationRules; private bool isValidationRulesCollectionDirty = true; - [field: NonSerialized] private DataErrorInfoValidationResult cachedValidationResult; /// @@ -141,7 +139,6 @@ public string Error /// /// The listeners attached to this event are not serialized. /// - [field: NonSerialized] public event PropertyChangedEventHandler PropertyChanged; #endregion PropertyChanged diff --git a/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/ValidationRules/DataErrorInfoValidationRule.cs b/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/ValidationRules/DataErrorInfoValidationRule.cs index 78b54a9c045..a92916c0717 100644 --- a/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/ValidationRules/DataErrorInfoValidationRule.cs +++ b/src/Microsoft.Management.UI.Internal/ManagementList/FilterCore/ValidationRules/DataErrorInfoValidationRule.cs @@ -9,7 +9,6 @@ namespace Microsoft.Management.UI.Internal /// Provides a way to create a custom rule in order to check the validity of user input. /// [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.MSInternal", "CA903:InternalNamespaceShouldNotContainPublicTypes")] - [Serializable] public abstract class DataErrorInfoValidationRule : IDeepCloneable { /// diff --git a/src/Microsoft.Management.UI.Internal/ManagementList/FilterProviders/FilterRuleToDisplayNameConverter.cs b/src/Microsoft.Management.UI.Internal/ManagementList/FilterProviders/FilterRuleToDisplayNameConverter.cs index aaca30ff321..972c19080e0 100644 --- a/src/Microsoft.Management.UI.Internal/ManagementList/FilterProviders/FilterRuleToDisplayNameConverter.cs +++ b/src/Microsoft.Management.UI.Internal/ManagementList/FilterProviders/FilterRuleToDisplayNameConverter.cs @@ -12,7 +12,6 @@ namespace Microsoft.Management.UI.Internal /// a FilterRule value to its DisplayName. /// [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.MSInternal", "CA903:InternalNamespaceShouldNotContainPublicTypes")] - [Serializable] public class FilterRuleToDisplayNameConverter : IValueConverter { /// diff --git a/src/Microsoft.Management.UI.Internal/ManagementList/ManagementList/ManagementListStateDescriptor.cs b/src/Microsoft.Management.UI.Internal/ManagementList/ManagementList/ManagementListStateDescriptor.cs index 668118a5b7f..bbfd3d8603c 100644 --- a/src/Microsoft.Management.UI.Internal/ManagementList/ManagementList/ManagementListStateDescriptor.cs +++ b/src/Microsoft.Management.UI.Internal/ManagementList/ManagementList/ManagementListStateDescriptor.cs @@ -16,7 +16,6 @@ namespace Microsoft.Management.UI.Internal /// Allows the state of the ManagementList to be saved and restored. /// [SuppressMessage("Microsoft.MSInternal", "CA903:InternalNamespaceShouldNotContainPublicTypes")] - [Serializable] public class ManagementListStateDescriptor : StateDescriptor { #region Fields diff --git a/src/powershell-win-core/powershell-win-core.csproj b/src/powershell-win-core/powershell-win-core.csproj index 73c55497c5b..5368518dd3c 100644 --- a/src/powershell-win-core/powershell-win-core.csproj +++ b/src/powershell-win-core/powershell-win-core.csproj @@ -13,7 +13,6 @@ ..\..\assets\pwsh.manifest Windows 8.0 - true From 434f880bcdf6cfe8ab7ccc2dbdca4f606d027762 Mon Sep 17 00:00:00 2001 From: PowerShell Team Bot <69177312+pwshBot@users.noreply.github.com> Date: Wed, 3 Sep 2025 14:32:16 -0700 Subject: [PATCH 147/173] [release/v7.5] Add Codeql Suppressions (#25972) Co-authored-by: Anam Navied Co-authored-by: Travis Plunk --- .../commands/management/Process.cs | 1 + .../utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs | 1 + .../engine/NativeCommandProcessor.cs | 1 + .../engine/remoting/common/RunspaceConnectionInfo.cs | 1 + .../namespaces/FileSystemProvider.cs | 1 + 5 files changed, 5 insertions(+) diff --git a/src/Microsoft.PowerShell.Commands.Management/commands/management/Process.cs b/src/Microsoft.PowerShell.Commands.Management/commands/management/Process.cs index 4ca7d9aaa5b..a1f9dbf1e0f 100644 --- a/src/Microsoft.PowerShell.Commands.Management/commands/management/Process.cs +++ b/src/Microsoft.PowerShell.Commands.Management/commands/management/Process.cs @@ -1904,6 +1904,7 @@ protected override void BeginProcessing() } catch (CommandNotFoundException) { + // codeql[cs/microsoft/command-line-injection-shell-execution] - This is expected Poweshell behavior where user inputted paths are supported for the context of this method. The user assumes trust for the file path they are specifying and the process is on the user's system except for remoting in which case restricted remoting security guidelines should be used. startInfo.FileName = FilePath; #if UNIX // Arguments are passed incorrectly to the executable used for ShellExecute and not to filename https://github.com/dotnet/corefx/issues/30718 diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs index 810b54a8391..d7c0931c786 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs @@ -1296,6 +1296,7 @@ internal virtual HttpResponseMessage GetResponse(HttpClient client, HttpRequestM _cancelToken = new CancellationTokenSource(); try { + // codeql[cs/ssrf] - This is expected Poweshell behavior where user inputted Uri is supported for the context of this method. The user assumes trust for the Uri and invocation is done on the user's machine, not a web application. If there is concern for remoting, they should use restricted remoting. response = client.SendAsync(currentRequest, HttpCompletionOption.ResponseHeadersRead, _cancelToken.Token).GetAwaiter().GetResult(); } catch (TaskCanceledException ex) diff --git a/src/System.Management.Automation/engine/NativeCommandProcessor.cs b/src/System.Management.Automation/engine/NativeCommandProcessor.cs index 371e1ff00ff..43113d07425 100644 --- a/src/System.Management.Automation/engine/NativeCommandProcessor.cs +++ b/src/System.Management.Automation/engine/NativeCommandProcessor.cs @@ -1396,6 +1396,7 @@ private ProcessStartInfo GetProcessStartInfo( { var startInfo = new ProcessStartInfo { + // codeql[cs/microsoft/command-line-injection-shell-execution] - This is expected Poweshell behavior where user inputted paths are supported for the context of this method. The user assumes trust for the file path specified on the user's system to retrieve process info for, and in the case of remoting, restricted remoting security guidelines should be used. FileName = this.Path }; diff --git a/src/System.Management.Automation/engine/remoting/common/RunspaceConnectionInfo.cs b/src/System.Management.Automation/engine/remoting/common/RunspaceConnectionInfo.cs index 9c221f01dbb..d18eb249cb7 100644 --- a/src/System.Management.Automation/engine/remoting/common/RunspaceConnectionInfo.cs +++ b/src/System.Management.Automation/engine/remoting/common/RunspaceConnectionInfo.cs @@ -2230,6 +2230,7 @@ internal int StartSSHProcess( // linux|macos: // Subsystem powershell /usr/local/bin/pwsh -SSHServerMode -NoLogo -NoProfile + // codeql[cs/microsoft/command-line-injection-shell-execution] - This is expected Poweshell behavior where user inputted paths are supported for the context of this method. The user assumes trust for the file path specified, so any file executed in the runspace would be in the user's local system/process or a system they have access to in which case restricted remoting security guidelines should be used. System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo(filePath); // pass "-i identity_file" command line argument to ssh if KeyFilePath is set diff --git a/src/System.Management.Automation/namespaces/FileSystemProvider.cs b/src/System.Management.Automation/namespaces/FileSystemProvider.cs index aefa2d499b6..dee701296e4 100644 --- a/src/System.Management.Automation/namespaces/FileSystemProvider.cs +++ b/src/System.Management.Automation/namespaces/FileSystemProvider.cs @@ -1325,6 +1325,7 @@ protected override void InvokeDefaultAction(string path) if (ShouldProcess(resource, action)) { var invokeProcess = new System.Diagnostics.Process(); + // codeql[cs/microsoft/command-line-injection-shell-execution] - This is expected Poweshell behavior where user inputted paths are supported for the context of this method. The user assumes trust for the file path they are specifying. If there is concern for remoting, restricted remoting guidelines should be used. invokeProcess.StartInfo.FileName = path; #if UNIX bool useShellExecute = false; From 0091d13c5b8f4541dfd70da25a5300cfc0fa8194 Mon Sep 17 00:00:00 2001 From: PowerShell Team Bot <69177312+pwshBot@users.noreply.github.com> Date: Wed, 3 Sep 2025 14:53:57 -0700 Subject: [PATCH 148/173] [release/v7.5] Add build to vPack Pipeline (#25975) Co-authored-by: Justin Chung <124807742+jshigetomi@users.noreply.github.com> Co-authored-by: Travis Plunk --- .pipelines/PowerShell-vPack-Official.yml | 285 +++++++++++++++------- .pipelines/templates/obp-file-signing.yml | 25 +- tools/packaging/packaging.psm1 | 18 +- 3 files changed, 230 insertions(+), 98 deletions(-) diff --git a/.pipelines/PowerShell-vPack-Official.yml b/.pipelines/PowerShell-vPack-Official.yml index 05a8fefbb0f..5783785cfd6 100644 --- a/.pipelines/PowerShell-vPack-Official.yml +++ b/.pipelines/PowerShell-vPack-Official.yml @@ -1,32 +1,30 @@ trigger: none parameters: # parameters are shown up in ADO UI in a build queue time +- name: OfficialBuild + type: boolean + default: true - name: 'createVPack' displayName: 'Create and Submit VPack' type: boolean default: true -- name: 'debug' - displayName: 'Enable debug output' - type: boolean - default: false -- name: 'architecture' +- name: vPackName type: string - displayName: 'Select the vpack architecture:' + displayName: 'VPack Name:' + default: 'PowerShell' values: - - x64 - - x86 - - arm64 - default: x64 -- name: 'VPackPublishOverride' - type: string - displayName: 'VPack Publish Override Version (can leave blank):' - default: ' ' + - PowerShell + - PowerShellDoNotUse - name: 'ReleaseTagVar' type: string displayName: 'Release Tag Var:' default: 'fromBranch' +- name: 'debug' + displayName: 'Enable debug output' + type: boolean + default: false -name: vPack_${{ parameters.architecture }}_$(date:yyMM).$(date:dd)$(rev:rrr) +name: vPack_$(Build.SourceBranchName)_Prod.${{ parameters.OfficialBuild }}_Create.${{ parameters.createVPack }}_Name.${{ parameters.vPackName}}_$(date:yyyyMMdd).$(rev:rr) variables: - name: CDP_DEFINITION_BUILD_COUNT @@ -51,6 +49,12 @@ variables: value: ${{ parameters.ReleaseTagVar }} - group: Azure Blob variable group - group: certificate_logical_to_actual # used within signing task + - name: templateFile + value: ${{ iif ( parameters.OfficialBuild, 'v2/Microsoft.Official.yml@templates', 'v2/Microsoft.NonOfficial.yml@templates' ) }} + - group: DotNetPrivateBuildAccess + - group: certificate_logical_to_actual +# We shouldn't be using PATs anymore +# - group: mscodehub-feed-read-general resources: repositories: @@ -59,17 +63,8 @@ resources: name: OneBranch.Pipelines/GovernedTemplates ref: refs/heads/main - pipelines: - - pipeline: PSPackagesOfficial - source: 'PowerShell-Packages-Official' - trigger: - branches: - include: - - master - - releases/* - extends: - template: v2/Microsoft.Official.yml@templates + template: ${{ variables.templateFile }} parameters: platform: name: 'windows_undocked' # windows undocked @@ -99,35 +94,116 @@ extends: enabled: false tsaOptionsFile: .config/tsaoptions.json stages: - - stage: main + - stage: BuildStage jobs: - - job: main + - job: BuildJob pool: type: windows + strategy: + matrix: + x86: + architecture: x86 + + x64: + architecture: x64 + + arm64: + architecture: arm64 + variables: + ArtifactPlatform: 'windows' + ob_artifactBaseName: drop_build_$(architecture) ob_outputDirectory: '$(BUILD.SOURCESDIRECTORY)\out' ob_createvpack_enabled: ${{ parameters.createVPack }} - ob_createvpack_packagename: 'PowerShell.${{ parameters.architecture }}' - ob_createvpack_description: PowerShell ${{ parameters.architecture }} $(version) ob_createvpack_owneralias: tplunk - ob_createvpack_versionAs: string - ob_createvpack_version: '$(version)' + ob_createvpack_versionAs: parts ob_createvpack_propsFile: true ob_createvpack_verbose: true + ob_createvpack_packagename: '${{ parameters.vPackName }}.$(architecture)' + ob_createvpack_description: PowerShell $(architecture) $(version) + # I think the variables reload after we transition back to the host so this works. 🤷‍♂️ + ob_createvpack_majorVer: $(pwshMajorVersion) + ob_createvpack_minorVer: $(pwshMinorVersion) + ob_createvpack_patchVer: $(pwshPatchVersion) + ${{ if ne(variables['pwshPrereleaseVersion'], '') }}: + ob_createvpack_prereleaseVer: $(pwshPrereleaseVersion) + ${{ else }}: + ob_createvpack_prereleaseVer: $(Build.SourceVersion) steps: + - checkout: self + displayName: Checkout source code - during restore + clean: true + path: s + env: + ob_restore_phase: true + - template: .pipelines/templates/SetVersionVariables.yml@self parameters: ReleaseTagVar: $(ReleaseTagVar) CreateJson: yes UseJson: no + - pwsh: | + $version = '$(Version)' + Write-Verbose -Verbose "Version: $version" + if(!$version) { + throw "Version is not set." + } + + $mainVersionParts = $version -split '-' + + Write-Verbose -Verbose "mainVersionParts: $($mainVersionParts[0]) ; $($mainVersionParts[1])" + $versionParts = $mainVersionParts[0] -split '[.]'; + $major = $versionParts[0] + $minor = $versionParts[1] + $patch = $versionParts[2] + + $previewPart = $mainVersionParts[1] + Write-Verbose -Verbose "previewPart: $previewPart" + + Write-Host "major: $major; minor: $minor; patch: $patch;" + + $vstsCommandString = "vso[task.setvariable variable=pwshMajorVersion]$major" + Write-Host ("sending " + $vstsCommandString) + Write-Host "##$vstsCommandString" + + $vstsCommandString = "vso[task.setvariable variable=pwshMinorVersion]$minor" + Write-Host ("sending " + $vstsCommandString) + Write-Host "##$vstsCommandString" + + $vstsCommandString = "vso[task.setvariable variable=pwshPatchVersion]$patch" + Write-Host ("sending " + $vstsCommandString) + Write-Host "##$vstsCommandString" + if($previewPart) { + $vstsCommandString = "vso[task.setvariable variable=pwshPrereleaseVersion]$previewPart" + } else { + Write-Verbose -Verbose "No prerelease part found in version string." + } + displayName: Set ob_createvpack_*Ver + env: + ob_restore_phase: true + + # Validate pwsh*Version variables + - pwsh: | + $variables = @("pwshMajorVersion", "pwshMinorVersion", "pwshPatchVersion") + foreach ($var in $variables) { + if (-not (get-item "Env:\$var" -ErrorAction SilentlyContinue).value) { + throw "Required variable '`$env:$var' is not set." + } + } + displayName: Validate pwsh*Version variables + env: + ob_restore_phase: true + - pwsh: | if($env:RELEASETAGVAR -match '-') { throw "Don't release a preview build without coordinating with Windows Engineering Build Tools Team" } displayName: Stop any preview release + env: + ob_restore_phase: true - task: UseDotNet@2 displayName: 'Use .NET Core sdk' @@ -136,88 +212,115 @@ extends: version: 3.1.x installationPath: $(Agent.ToolsDirectory)/dotnet + ### BUILD ### + + - template: /.pipelines/templates/insert-nuget-config-azfeed.yml@self + parameters: + repoRoot: $(repoRoot) + + - task: CodeQL3000Init@0 # Add CodeQL Init task right before your 'Build' step. + env: + ob_restore_phase: true # Set ob_restore_phase to run this step before '🔒 Setup Signing' step. + inputs: + Enabled: true + AnalyzeInPipeline: false # Do not upload results + Language: csharp + + - task: UseDotNet@2 + displayName: 'Install .NET based on global.json' + inputs: + useGlobalJson: true + workingDirectory: $(repoRoot) + env: + ob_restore_phase: true + - pwsh: | - $packageArtifactName = 'drop_windows_package_package_win_${{ parameters.architecture }}' - $vstsCommandString = "vso[task.setvariable variable=PackageArtifactName]$packageArtifactName" - Write-Host "sending " + $vstsCommandString + # Need to set PowerShellRoot variable for obp-file-signing template + $vstsCommandString = "vso[task.setvariable variable=PowerShellRoot]$(repoRoot)" + Write-Host ("sending " + $vstsCommandString) Write-Host "##$vstsCommandString" - $packageArtifactPath = '$(Pipeline.Workspace)\PSPackagesOfficial' - $vstsCommandString = "vso[task.setvariable variable=PackageArtifactPath]$packageArtifactPath" - Write-Host "sending " + $vstsCommandString + $Architecture = '$(Architecture)' + $runtime = switch ($Architecture) + { + "x64" { "win7-x64" } + "x86" { "win7-x86" } + "arm64" { "win-arm64" } + } + + $params = @{} + if ($env:BuildConfiguration -eq 'minSize') { + $params['ForMinimalSize'] = $true + } + + $vstsCommandString = "vso[task.setvariable variable=Runtime]$runtime" + Write-Host ("sending " + $vstsCommandString) Write-Host "##$vstsCommandString" - displayName: 'Set package artifact variables' - - download: PSPackagesOfficial - artifact: $(PackageArtifactName) - displayName: Download package + Write-Verbose -Message "Building PowerShell with Runtime: $runtime for '$env:BuildConfiguration' configuration" + Import-Module -Name $(repoRoot)/build.psm1 -Force + $buildWithSymbolsPath = New-Item -ItemType Directory -Path "$(Pipeline.Workspace)/Symbols_$Architecture" -Force - - pwsh: 'Get-ChildItem $(PackageArtifactPath)\* -recurse | Select-Object -ExpandProperty Name' - displayName: 'Capture Artifact Listing' + Start-PSBootstrap -Scenario Package + $null = New-Item -ItemType Directory -Path $buildWithSymbolsPath -Force -Verbose - - pwsh: | - $message = @() - $packages = Get-ChildItem $(PackageArtifactPath)\* -recurse -include *.zip, *.msi - - if($packages.count -eq 0) {throw "No packages found in $(PackageArtifactPath)"} - - $packages | ForEach-Object { - if($_.Name -notmatch 'PowerShell-\d+\.\d+\.\d+\-([a-z]*.\d+\-)?win\-(fxdependent|x64|arm64|x86|fxdependentWinDesktop)\.(msi|zip){1}') - { - $messageInstance = "$($_.Name) is not a valid package name" - $message += $messageInstance - Write-Warning $messageInstance - } + $ReleaseTagParam = @{} + + if ($env:RELEASETAGVAR) { + $ReleaseTagParam['ReleaseTag'] = $env:RELEASETAGVAR } - if($message.count -gt 0){throw ($message | out-string)} - displayName: 'Validate Zip and MSI Package Names' + Start-PSBuild -Runtime $runtime -Configuration Release -Output $buildWithSymbolsPath -Clean -PSModuleRestore @params @ReleaseTagParam - - pwsh: | - Get-ChildItem $(PackageArtifactPath)\* -recurse -include *.zip | ForEach-Object { - if($_.Name -match 'PowerShell-\d+\.\d+\.\d+\-([a-z]*.\d+\-)?win\-(${{ parameters.architecture }})\.(zip){1}') - { - Expand-Archive -Path $_.FullName -DestinationPath $(ob_outputDirectory) - } - } - displayName: 'Extract Zip to ob_outputDirectory' + $refFolderPath = Join-Path $buildWithSymbolsPath 'ref' + Write-Verbose -Verbose "refFolderPath: $refFolderPath" + $outputPath = Join-Path '$(ob_outputDirectory)' 'psoptions' + $null = New-Item -ItemType Directory -Path $outputPath -Force + $psOptPath = "$outputPath/psoptions.json" + Save-PSOptions -PSOptionsPath $psOptPath + + Write-Verbose -Verbose "Completed building PowerShell for '$env:BuildConfiguration' configuration" + displayName: Build Windows Universal - $(Architecture) -$(BuildConfiguration) Symbols folder + env: + __DOTNET_RUNTIME_FEED_KEY: $(RUNTIME_SOURCEFEED_KEY) + ob_restore_phase: true # Set ob_restore_phase to run this step before '🔒 Setup Signing' step. + + - task: CodeQL3000Finalize@0 # Add CodeQL Finalize task right after your 'Build' step. + env: + ob_restore_phase: true # Set ob_restore_phase to run this step before '🔒 Setup Signing' step. + + - task: ms.vss-governance-buildtask.governance-build-task-component-detection.ComponentGovernanceComponentDetection@0 + displayName: 'Component Detection' + inputs: + sourceScanPath: '$(repoRoot)\src' + ob_restore_phase: true + + - template: /.pipelines/templates/obp-file-signing.yml@self + parameters: + binPath: '$(Pipeline.Workspace)/Symbols_$(Architecture)' + SigningProfile: $(windows_build_tools_cert_id) + OfficialBuild: false + vPackScenario: true + + ### END OF BUILD ### - pwsh: | - Write-Verbose "VPack Version: $(ob_createvpack_version)" -Verbose - Get-ChildItem -Path $(ob_outputDirectory)\* -Recurse - Get-Content $(ob_outputdirectory)\preview.json -ErrorAction SilentlyContinue | Write-Host + Get-ChildItem env:/ob_createvpack_*Ver + Get-ChildItem -Path "$(Pipeline.Workspace)\Symbols_$(Architecture)\*" -Recurse + Get-Content "$(Pipeline.Workspace)\PowerShell\preview.json" -ErrorAction SilentlyContinue | Write-Host displayName: Debug Output Directory and Version condition: succeededOrFailed() - pwsh: | - Write-Host "Using VPackPublishOverride variable" - $vpackVersion = '${{ parameters.VPackPublishOverride }}' - $vstsCommandString = "vso[task.setvariable variable=ob_createvpack_version]$vpackVersion" - Write-Host "sending " + $vstsCommandString - Write-Host "##$vstsCommandString" - condition: ne('${{ parameters.VPackPublishOverride }}', ' ') - displayName: 'Set ob_createvpack_version with VPackPublishOverride' - - - pwsh: | - Get-ChildItem -Path env: + Get-ChildItem -Path env: | Out-String -width 9999 -Stream | write-Verbose -Verbose displayName: Capture Environment condition: succeededOrFailed() - pwsh: | - Write-Verbose "VPack Version: $(ob_createvpack_version)" -Verbose - $vpackFiles = Get-ChildItem -Path $(ob_outputDirectory)\* -Recurse + $vpackFiles = Get-ChildItem -Path "$(Pipeline.Workspace)\Symbols_$(Architecture)\*" -Recurse if($vpackFiles.Count -eq 0) { - throw "No files found in $(ob_outputDirectory)" + throw "No files found in $(Pipeline.Workspace)\Symbols_$(Architecture)" } $vpackFiles displayName: Debug Output Directory and Version condition: succeededOrFailed() - - - task: onebranch.pipeline.signing@1 - displayName: 'Onebranch Signing' - inputs: - command: 'sign' - signing_environment: 'azure-ado' - cp_code: $(windows_build_tools_cert_id) - files_to_sign: '**/*.exe;**/System.Management.Automation.dll' - search_root: $(ob_outputDirectory) diff --git a/.pipelines/templates/obp-file-signing.yml b/.pipelines/templates/obp-file-signing.yml index ba761633b29..7c6ce7c6375 100644 --- a/.pipelines/templates/obp-file-signing.yml +++ b/.pipelines/templates/obp-file-signing.yml @@ -1,6 +1,9 @@ parameters: binPath: '$(ob_outputDirectory)' globalTool: 'false' + SigningProfile: 'external_distribution' + OfficialBuild: true + vPackScenario: false steps: - pwsh: | @@ -80,7 +83,7 @@ steps: displayName: Sign 1st party files inputs: command: 'sign' - signing_profile: external_distribution + signing_profile: ${{ parameters.SigningProfile }} files_to_sign: '**\*.psd1;**\*.psm1;**\*.ps1xml;**\*.ps1;**\*.dll;**\*.exe;**\pwsh' search_root: $(Pipeline.Workspace)/toBeSigned @@ -95,12 +98,15 @@ steps: $BuildPath = (Get-Item '${{ parameters.binPath }}').FullName Write-Verbose -Verbose -Message "BuildPath: $BuildPath" + $officialBuild = [System.Convert]::ToBoolean('${{ parameters.OfficialBuild }}') ## copy all files to be signed to build folder - Update-PSSignedBuildFolder -BuildPath $BuildPath -SignedFilesPath '$(Pipeline.Workspace)/toBeSigned' + Update-PSSignedBuildFolder -BuildPath $BuildPath -SignedFilesPath '$(Pipeline.Workspace)/toBeSigned' -OfficialBuild $officialBuild $dlls = Get-ChildItem $BuildPath/*.dll, $BuildPath/*.exe -Recurse $signatures = $dlls | Get-AuthenticodeSignature - $missingSignatures = $signatures | Where-Object { $_.status -eq 'notsigned' -or $_.SignerCertificate.Issuer -notmatch '^CN=Microsoft.*'}| select-object -ExpandProperty Path + $officialIssuerPattern = '^CN=(Microsoft Code Signing PCA|Microsoft Root Certificate Authority|Microsoft Corporation).*' + $testCert = '^CN=(Microsoft|TestAzureEngBuildCodeSign).*' + $missingSignatures = $signatures | Where-Object { $_.status -eq 'notsigned' -or $_.SignerCertificate.Issuer -notmatch $testCert -or $_.SignerCertificate.Issuer -notmatch $officialIssuerPattern} | select-object -ExpandProperty Path Write-Verbose -verbose "to be signed:`r`n $($missingSignatures | Out-String)" @@ -137,11 +143,20 @@ steps: displayName: Capture ThirdParty Signed files - pwsh: | + $officialBuild = [System.Convert]::ToBoolean('${{ parameters.OfficialBuild }}') + $vPackScenario = [System.Convert]::ToBoolean('${{ parameters.vPackScenario }}') Import-Module '$(PowerShellRoot)/build.psm1' -Force Import-Module '$(PowerShellRoot)/tools/packaging' -Force $isGlobalTool = '${{ parameters.globalTool }}' -eq 'true' - if (-not $isGlobalTool) { + if ($vPackScenario) { + Write-Verbose -Verbose -Message "vPackScenario is true, copying to $(ob_outputDirectory)" + $pathForUpload = New-Item -ItemType Directory -Path '$(ob_outputDirectory)' -Force + Write-Verbose -Verbose -Message "pathForUpload: $pathForUpload" + Copy-Item -Path '${{ parameters.binPath }}\*' -Destination $pathForUpload -Recurse -Force -Verbose + Write-Verbose -Verbose -Message "Files copied to $pathForUpload" + } + elseif (-not $isGlobalTool) { $pathForUpload = New-Item -ItemType Directory -Path '$(ob_outputDirectory)/Signed-$(Runtime)' -Force Write-Verbose -Verbose -Message "pathForUpload: $pathForUpload" Copy-Item -Path '${{ parameters.binPath }}\*' -Destination $pathForUpload -Recurse -Force -Verbose @@ -153,7 +168,7 @@ steps: Write-Verbose "Copying third party signed files to the build folder" $thirdPartySignedFilesPath = (Get-Item '$(Pipeline.Workspace)/thirdPartyToBeSigned').FullName - Update-PSSignedBuildFolder -BuildPath $pathForUpload -SignedFilesPath $thirdPartySignedFilesPath + Update-PSSignedBuildFolder -BuildPath $pathForUpload -SignedFilesPath $thirdPartySignedFilesPath -OfficialBuild $officialBuild displayName: 'Copy signed files for upload' diff --git a/tools/packaging/packaging.psm1 b/tools/packaging/packaging.psm1 index 782a4ecadc8..560a985283b 100644 --- a/tools/packaging/packaging.psm1 +++ b/tools/packaging/packaging.psm1 @@ -887,7 +887,8 @@ function Update-PSSignedBuildFolder [string]$BuildPath, [Parameter(Mandatory)] [string]$SignedFilesPath, - [string[]] $RemoveFilter = ('*.pdb', '*.zip', '*.r2rmap') + [string[]] $RemoveFilter = ('*.pdb', '*.zip', '*.r2rmap'), + [bool]$OfficialBuild = $true ) $BuildPathNormalized = (Get-Item $BuildPath).FullName @@ -943,8 +944,21 @@ function Update-PSSignedBuildFolder if ($IsWindows) { $signature = Get-AuthenticodeSignature -FilePath $signedFilePath - if ($signature.Status -ne 'Valid') { + + if ($signature.Status -ne 'Valid' -and $OfficialBuild) { + Write-Host "Certificate Issuer: $($signature.SignerCertificate.Issuer)" + Write-Host "Certificate Subject: $($signature.SignerCertificate.Subject)" Write-Error "Invalid signature for $signedFilePath" + } elseif ($OfficialBuild -eq $false) { + if ($signature.Status -eq 'NotSigned') { + Write-Warning "File is not signed: $signedFilePath" + } elseif ($signature.SignerCertificate.Issuer -notmatch '^CN=(Microsoft|TestAzureEngBuildCodeSign|Windows Internal Build Tools).*') { + Write-Warning "File signed with test certificate: $signedFilePath" + Write-Host "Certificate Issuer: $($signature.SignerCertificate.Issuer)" + Write-Host "Certificate Subject: $($signature.SignerCertificate.Subject)" + } else { + Write-Verbose -Verbose "File properly signed: $signedFilePath" + } } } else From cbfecf7ae155fa310ee78fd1ff42f0fcf1d13a71 Mon Sep 17 00:00:00 2001 From: Travis Plunk Date: Fri, 5 Sep 2025 11:11:07 -0700 Subject: [PATCH 149/173] [release/v7.5] Update container images to use mcr.microsoft.com for Linux and Azure Linux (#25986) --- .../PowerShell-Coordinated_Packages-Official.yml | 6 ++++-- .pipelines/PowerShell-Packages-Official.yml | 3 +-- .pipelines/PowerShell-Release-Official-Azure.yml | 3 +-- .pipelines/PowerShell-Release-Official.yml | 6 +++--- .pipelines/apiscan-gen-notice.yml | 2 +- .pipelines/templates/linux.yml | 1 + .pipelines/templates/mac.yml | 1 + .pipelines/templates/windows-hosted-build.yml | 2 ++ build.psm1 | 12 +++++++----- 9 files changed, 21 insertions(+), 15 deletions(-) diff --git a/.pipelines/PowerShell-Coordinated_Packages-Official.yml b/.pipelines/PowerShell-Coordinated_Packages-Official.yml index 8de89b0c508..73c6e4f39b8 100644 --- a/.pipelines/PowerShell-Coordinated_Packages-Official.yml +++ b/.pipelines/PowerShell-Coordinated_Packages-Official.yml @@ -65,7 +65,7 @@ variables: - name: __DOTNET_RUNTIME_FEED value: ${{ parameters.InternalSDKBlobURL }} - name: LinuxContainerImage - value: onebranch.azurecr.io/linux/ubuntu-2004:latest + value: mcr.microsoft.com/onebranch/azurelinux/build:3.0 - name: WindowsContainerImage value: onebranch.azurecr.io/windows/ltsc2019/vse2022:latest - name: CDP_DEFINITION_BUILD_COUNT @@ -86,6 +86,8 @@ variables: # Disable BinSkim at job level to override NonOfficial template defaults - name: ob_sdl_binskim_enabled value: false + - name: ps_official_build + value: ${{ parameters.OfficialBuild }} extends: template: ${{ variables.templateFile }} @@ -130,7 +132,7 @@ extends: - job: SetVars displayName: Set Variables pool: - type: windows + type: linux variables: - name: ob_outputDirectory diff --git a/.pipelines/PowerShell-Packages-Official.yml b/.pipelines/PowerShell-Packages-Official.yml index f0d428bf1d6..b756b6f8c36 100644 --- a/.pipelines/PowerShell-Packages-Official.yml +++ b/.pipelines/PowerShell-Packages-Official.yml @@ -56,7 +56,7 @@ variables: - name: WindowsContainerImage value: 'onebranch.azurecr.io/windows/ltsc2022/vse2022:latest' # Docker image which is used to build the project - name: LinuxContainerImage - value: mcr.microsoft.com/onebranch/cbl-mariner/build:2.0 + value: mcr.microsoft.com/onebranch/azurelinux/build:3.0 - group: mscodehub-feed-read-general - group: mscodehub-feed-read-akv - name: branchCounterKey @@ -66,7 +66,6 @@ variables: - group: MSIXSigningProfile - name: templateFile value: ${{ iif ( parameters.OfficialBuild, 'v2/OneBranch.Official.CrossPlat.yml@onebranchTemplates', 'v2/OneBranch.NonOfficial.CrossPlat.yml@onebranchTemplates' ) }} - resources: pipelines: diff --git a/.pipelines/PowerShell-Release-Official-Azure.yml b/.pipelines/PowerShell-Release-Official-Azure.yml index 8e144f1ee55..1f210ac6745 100644 --- a/.pipelines/PowerShell-Release-Official-Azure.yml +++ b/.pipelines/PowerShell-Release-Official-Azure.yml @@ -47,11 +47,10 @@ variables: - name: WindowsContainerImage value: 'onebranch.azurecr.io/windows/ltsc2022/vse2022:latest' - name: LinuxContainerImage - value: mcr.microsoft.com/onebranch/cbl-mariner/build:2.0 + value: mcr.microsoft.com/onebranch/azurelinux/build:3.0 - group: PoolNames - name: templateFile value: ${{ iif ( parameters.OfficialBuild, 'v2/OneBranch.Official.CrossPlat.yml@onebranchTemplates', 'v2/OneBranch.NonOfficial.CrossPlat.yml@onebranchTemplates' ) }} - resources: repositories: diff --git a/.pipelines/PowerShell-Release-Official.yml b/.pipelines/PowerShell-Release-Official.yml index 9d543eae3a9..0c943871462 100644 --- a/.pipelines/PowerShell-Release-Official.yml +++ b/.pipelines/PowerShell-Release-Official.yml @@ -57,7 +57,7 @@ variables: - name: WindowsContainerImage value: 'onebranch.azurecr.io/windows/ltsc2022/vse2022:latest' - name: LinuxContainerImage - value: mcr.microsoft.com/onebranch/cbl-mariner/build:2.0 + value: mcr.microsoft.com/onebranch/azurelinux/build:3.0 - name: ReleaseTagVar value: ${{ parameters.ReleaseTagVar }} - group: PoolNames @@ -284,7 +284,7 @@ extends: - stage: PublishGitHubReleaseAndNuget displayName: Publish GitHub and Nuget Release - dependsOn: + dependsOn: - setReleaseTagAndChangelog - UpdateChangeLog variables: @@ -404,7 +404,7 @@ extends: - stage: ChangesToMaster displayName: Ensure changes are in GH master - dependsOn: + dependsOn: - PublishPMC jobs: - template: /.pipelines/templates/approvalJob.yml@self diff --git a/.pipelines/apiscan-gen-notice.yml b/.pipelines/apiscan-gen-notice.yml index 1507b9345bd..af122fb2365 100644 --- a/.pipelines/apiscan-gen-notice.yml +++ b/.pipelines/apiscan-gen-notice.yml @@ -26,7 +26,7 @@ variables: - group: 'ComponentGovernance' - group: 'PoolNames' - name: LinuxContainerImage - value: onebranch.azurecr.io/linux/ubuntu-2004:latest + value: mcr.microsoft.com/onebranch/azurelinux/build:3.0 - name: WindowsContainerImage value: onebranch.azurecr.io/windows/ltsc2022/vse2022:latest - ${{ if eq(parameters['FORCE_CODEQL'],'true') }}: diff --git a/.pipelines/templates/linux.yml b/.pipelines/templates/linux.yml index d6026dc5336..ccfac3fbc8e 100644 --- a/.pipelines/templates/linux.yml +++ b/.pipelines/templates/linux.yml @@ -199,5 +199,6 @@ jobs: - template: /.pipelines/templates/obp-file-signing.yml@self parameters: binPath: $(DropRootPath) + OfficialBuild: $(ps_official_build) - template: /.pipelines/templates/step/finalize.yml@self diff --git a/.pipelines/templates/mac.yml b/.pipelines/templates/mac.yml index 310c5695979..b08becedc22 100644 --- a/.pipelines/templates/mac.yml +++ b/.pipelines/templates/mac.yml @@ -148,5 +148,6 @@ jobs: - template: /.pipelines/templates/obp-file-signing.yml@self parameters: binPath: $(DropRootPath) + OfficialBuild: $(ps_official_build) - template: /.pipelines/templates/step/finalize.yml@self diff --git a/.pipelines/templates/windows-hosted-build.yml b/.pipelines/templates/windows-hosted-build.yml index 8f8273f4ec8..1f732a0145c 100644 --- a/.pipelines/templates/windows-hosted-build.yml +++ b/.pipelines/templates/windows-hosted-build.yml @@ -204,6 +204,7 @@ jobs: - template: /.pipelines/templates/obp-file-signing.yml@self parameters: binPath: '$(Pipeline.Workspace)/Symbols_$(Architecture)' + OfficialBuild: $(ps_official_build) ## first we sign all the files in the bin folder - ${{ if eq(variables['Architecture'], 'fxdependent') }}: @@ -211,6 +212,7 @@ jobs: parameters: binPath: '$(GlobalToolArtifactPath)/publish/PowerShell.Windows.x64/release' globalTool: 'true' + OfficialBuild: $(ps_official_build) - pwsh: | Get-ChildItem '$(GlobalToolArtifactPath)/obj/PowerShell.Windows.x64/release' diff --git a/build.psm1 b/build.psm1 index ffaf7b02f9d..21bf0f332ab 100644 --- a/build.psm1 +++ b/build.psm1 @@ -193,7 +193,7 @@ function Get-EnvironmentInformation $environment += @{'IsRedHatFamily' = $environment.IsCentOS -or $environment.IsFedora -or $environment.IsRedHat} $environment += @{'IsSUSEFamily' = $environment.IsSLES -or $environment.IsOpenSUSE} $environment += @{'IsAlpine' = $LinuxInfo.ID -match 'alpine'} - $environment += @{'IsMariner' = $LinuxInfo.ID -match 'mariner'} + $environment += @{'IsMariner' = $LinuxInfo.ID -match 'mariner' -or $LinuxInfo.ID -match 'azurelinux'} # Workaround for temporary LD_LIBRARY_PATH hack for Fedora 24 # https://github.com/PowerShell/PowerShell/issues/2511 @@ -353,8 +353,8 @@ function Start-PSBuild { $PSModuleRestore = $true } - if ($Runtime -eq "linux-arm" -and $environment.IsLinux -and -not $environment.IsUbuntu) { - throw "Cross compiling for linux-arm is only supported on Ubuntu environment" + if ($Runtime -eq "linux-arm" -and $environment.IsLinux -and -not $environment.IsUbuntu -and -not $environment.IsMariner) { + throw "Cross compiling for linux-arm is only supported on AzureLinux/Ubuntu environment" } if ("win-arm","win-arm64" -contains $Runtime -and -not $environment.IsWindows) { @@ -2196,6 +2196,8 @@ function Get-RedHatPackageManager { "yum install -y -q" } elseif ($environment.IsFedora -or (Get-Command -Name dnf -CommandType Application -ErrorAction SilentlyContinue)) { "dnf install -y -q" + } elseif ($environment.IsMariner -or (Get-Command -Name Test-DscConfiguration -CommandType Application -ErrorAction SilentlyContinue)) { + "tdnf install -y -q" } else { throw "Error determining package manager for this distribution." } @@ -2267,8 +2269,8 @@ function Start-PSBootstrap { # Note that when it is null, Invoke-Expression (but not &) must be used to interpolate properly $sudo = if (!$NoSudo) { "sudo" } - if ($BuildLinuxArm -and $environment.IsLinux -and -not $environment.IsUbuntu) { - Write-Error "Cross compiling for linux-arm is only supported on Ubuntu environment" + if ($BuildLinuxArm -and $environment.IsLinux -and -not $environment.IsUbuntu -and -not $environment.IsMariner) { + Write-Error "Cross compiling for linux-arm is only supported on AzureLinux/Ubuntu environment" return } From 30814e81966ca7ebb9b5904fd54188ab6cf838e4 Mon Sep 17 00:00:00 2001 From: PowerShell Team Bot <69177312+pwshBot@users.noreply.github.com> Date: Fri, 5 Sep 2025 13:26:32 -0700 Subject: [PATCH 150/173] [release/v7.5] Make logical template name consistent between pipelines (#25991) Co-authored-by: Travis Plunk --- .pipelines/MSIXBundle-vPack-Official.yml | 4 ++-- .pipelines/PowerShell-Coordinated_Packages-Official.yml | 2 +- .pipelines/PowerShell-Packages-Official.yml | 4 ++-- .pipelines/PowerShell-Release-Official-Azure.yml | 4 ++-- .pipelines/PowerShell-Release-Official.yml | 4 ++-- .pipelines/PowerShell-vPack-Official.yml | 4 ++-- 6 files changed, 11 insertions(+), 11 deletions(-) diff --git a/.pipelines/MSIXBundle-vPack-Official.yml b/.pipelines/MSIXBundle-vPack-Official.yml index ef96f63f045..8e175c5a6bb 100644 --- a/.pipelines/MSIXBundle-vPack-Official.yml +++ b/.pipelines/MSIXBundle-vPack-Official.yml @@ -29,7 +29,7 @@ variables: resources: repositories: - - repository: templates + - repository: onebranchTemplates type: git name: OneBranch.Pipelines/GovernedTemplates ref: refs/heads/main @@ -44,7 +44,7 @@ resources: - releases/* extends: - template: v2/Microsoft.Official.yml@templates + template: v2/Microsoft.Official.yml@onebranchTemplates parameters: platform: name: 'windows_undocked' # windows undocked diff --git a/.pipelines/PowerShell-Coordinated_Packages-Official.yml b/.pipelines/PowerShell-Coordinated_Packages-Official.yml index 73c6e4f39b8..b309791d77d 100644 --- a/.pipelines/PowerShell-Coordinated_Packages-Official.yml +++ b/.pipelines/PowerShell-Coordinated_Packages-Official.yml @@ -1,4 +1,3 @@ -name: bins-$(BUILD.SOURCEBRANCHNAME)-$(Build.BuildId) trigger: none parameters: @@ -30,6 +29,7 @@ parameters: type: boolean default: false +name: bins-$(BUILD.SOURCEBRANCHNAME)-prod.${{ parameters.OfficialBuild }}-$(Build.BuildId) resources: repositories: diff --git a/.pipelines/PowerShell-Packages-Official.yml b/.pipelines/PowerShell-Packages-Official.yml index b756b6f8c36..333d73276b8 100644 --- a/.pipelines/PowerShell-Packages-Official.yml +++ b/.pipelines/PowerShell-Packages-Official.yml @@ -28,7 +28,7 @@ parameters: # parameters are shown up in ADO UI in a build queue time type: boolean default: false -name: pkgs-$(BUILD.SOURCEBRANCHNAME)-$(Build.BuildId) +name: pkgs-$(BUILD.SOURCEBRANCHNAME)-prod.${{ parameters.OfficialBuild }}-$(Build.BuildId) variables: - name: CDP_DEFINITION_BUILD_COUNT @@ -78,7 +78,7 @@ resources: - releases/* repositories: - - repository: templates + - repository: onebranchTemplates type: git name: OneBranch.Pipelines/GovernedTemplates ref: refs/heads/main diff --git a/.pipelines/PowerShell-Release-Official-Azure.yml b/.pipelines/PowerShell-Release-Official-Azure.yml index 1f210ac6745..f4c41143b5f 100644 --- a/.pipelines/PowerShell-Release-Official-Azure.yml +++ b/.pipelines/PowerShell-Release-Official-Azure.yml @@ -17,7 +17,7 @@ parameters: # parameters are shown up in ADO UI in a build queue time type: boolean default: false -name: ev2-$(BUILD.SOURCEBRANCHNAME)-$(Build.BuildId) +name: ev2-$(BUILD.SOURCEBRANCHNAME)-prod.${{ parameters.OfficialBuild }}-$(Build.BuildId) variables: - name: CDP_DEFINITION_BUILD_COUNT @@ -54,7 +54,7 @@ variables: resources: repositories: - - repository: templates + - repository: onebranchTemplates type: git name: OneBranch.Pipelines/GovernedTemplates ref: refs/heads/main diff --git a/.pipelines/PowerShell-Release-Official.yml b/.pipelines/PowerShell-Release-Official.yml index 0c943871462..974b8f328c8 100644 --- a/.pipelines/PowerShell-Release-Official.yml +++ b/.pipelines/PowerShell-Release-Official.yml @@ -29,7 +29,7 @@ parameters: # parameters are shown up in ADO UI in a build queue time type: boolean default: false -name: release-$(BUILD.SOURCEBRANCHNAME)-$(Build.BuildId) +name: release-$(BUILD.SOURCEBRANCHNAME)-prod.${{ parameters.OfficialBuild }}-$(Build.BuildId) variables: - name: CDP_DEFINITION_BUILD_COUNT @@ -71,7 +71,7 @@ variables: resources: repositories: - - repository: templates + - repository: onebranchTemplates type: git name: OneBranch.Pipelines/GovernedTemplates ref: refs/heads/main diff --git a/.pipelines/PowerShell-vPack-Official.yml b/.pipelines/PowerShell-vPack-Official.yml index 5783785cfd6..f110ff0366a 100644 --- a/.pipelines/PowerShell-vPack-Official.yml +++ b/.pipelines/PowerShell-vPack-Official.yml @@ -50,7 +50,7 @@ variables: - group: Azure Blob variable group - group: certificate_logical_to_actual # used within signing task - name: templateFile - value: ${{ iif ( parameters.OfficialBuild, 'v2/Microsoft.Official.yml@templates', 'v2/Microsoft.NonOfficial.yml@templates' ) }} + value: ${{ iif ( parameters.OfficialBuild, 'v2/Microsoft.Official.yml@onebranchTemplates', 'v2/Microsoft.NonOfficial.yml@onebranchTemplates' ) }} - group: DotNetPrivateBuildAccess - group: certificate_logical_to_actual # We shouldn't be using PATs anymore @@ -58,7 +58,7 @@ variables: resources: repositories: - - repository: templates + - repository: onebranchTemplates type: git name: OneBranch.Pipelines/GovernedTemplates ref: refs/heads/main From efdb4a61859cf3381c107a8a0473db32dab9a48f Mon Sep 17 00:00:00 2001 From: Travis Plunk Date: Fri, 5 Sep 2025 14:09:47 -0700 Subject: [PATCH 151/173] Update third-party library versions in ThirdPartyNotices.txt to 9.0.8 (#25995) --- ThirdPartyNotices.txt | 102 +++++++++++++++++++++--------------------- 1 file changed, 51 insertions(+), 51 deletions(-) diff --git a/ThirdPartyNotices.txt b/ThirdPartyNotices.txt index c97524423aa..ce31689d1f0 100644 --- a/ThirdPartyNotices.txt +++ b/ThirdPartyNotices.txt @@ -284,7 +284,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI --------------------------------------------------------- -Microsoft.Extensions.ObjectPool 8.0.17 - MIT +Microsoft.Extensions.ObjectPool 8.0.19 - MIT Copyright Jorn Zaefferer @@ -374,7 +374,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI --------------------------------------------------------- -Microsoft.Win32.Registry.AccessControl 9.0.6 - MIT +Microsoft.Win32.Registry.AccessControl 9.0.8 - MIT Copyright (c) 2021 @@ -464,7 +464,7 @@ SOFTWARE. --------------------------------------------------------- -Microsoft.Win32.SystemEvents 9.0.6 - MIT +Microsoft.Win32.SystemEvents 9.0.8 - MIT Copyright (c) 2021 @@ -554,7 +554,7 @@ SOFTWARE. --------------------------------------------------------- -Microsoft.Windows.Compatibility 9.0.6 - MIT +Microsoft.Windows.Compatibility 9.0.8 - MIT (c) Microsoft Corporation @@ -607,7 +607,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. --------------------------------------------------------- -runtime.android-arm.runtime.native.System.IO.Ports 9.0.6 - MIT +runtime.android-arm.runtime.native.System.IO.Ports 9.0.8 - MIT Copyright (c) 2021 @@ -697,7 +697,7 @@ SOFTWARE. --------------------------------------------------------- -runtime.android-arm64.runtime.native.System.IO.Ports 9.0.6 - MIT +runtime.android-arm64.runtime.native.System.IO.Ports 9.0.8 - MIT Copyright (c) 2021 @@ -787,7 +787,7 @@ SOFTWARE. --------------------------------------------------------- -runtime.android-x64.runtime.native.System.IO.Ports 9.0.6 - MIT +runtime.android-x64.runtime.native.System.IO.Ports 9.0.8 - MIT Copyright (c) 2021 @@ -877,7 +877,7 @@ SOFTWARE. --------------------------------------------------------- -runtime.android-x86.runtime.native.System.IO.Ports 9.0.6 - MIT +runtime.android-x86.runtime.native.System.IO.Ports 9.0.8 - MIT Copyright (c) 2021 @@ -967,7 +967,7 @@ SOFTWARE. --------------------------------------------------------- -runtime.linux-arm.runtime.native.System.IO.Ports 9.0.6 - MIT +runtime.linux-arm.runtime.native.System.IO.Ports 9.0.8 - MIT Copyright (c) 2021 @@ -1057,7 +1057,7 @@ SOFTWARE. --------------------------------------------------------- -runtime.linux-arm64.runtime.native.System.IO.Ports 9.0.6 - MIT +runtime.linux-arm64.runtime.native.System.IO.Ports 9.0.8 - MIT Copyright (c) 2021 @@ -1147,7 +1147,7 @@ SOFTWARE. --------------------------------------------------------- -runtime.linux-bionic-arm64.runtime.native.System.IO.Ports 9.0.6 - MIT +runtime.linux-bionic-arm64.runtime.native.System.IO.Ports 9.0.8 - MIT Copyright (c) 2021 @@ -1237,7 +1237,7 @@ SOFTWARE. --------------------------------------------------------- -runtime.linux-bionic-x64.runtime.native.System.IO.Ports 9.0.6 - MIT +runtime.linux-bionic-x64.runtime.native.System.IO.Ports 9.0.8 - MIT Copyright (c) 2021 @@ -1327,7 +1327,7 @@ SOFTWARE. --------------------------------------------------------- -runtime.linux-musl-arm.runtime.native.System.IO.Ports 9.0.6 - MIT +runtime.linux-musl-arm.runtime.native.System.IO.Ports 9.0.8 - MIT Copyright (c) 2021 @@ -1417,7 +1417,7 @@ SOFTWARE. --------------------------------------------------------- -runtime.linux-musl-arm64.runtime.native.System.IO.Ports 9.0.6 - MIT +runtime.linux-musl-arm64.runtime.native.System.IO.Ports 9.0.8 - MIT Copyright (c) 2021 @@ -1507,7 +1507,7 @@ SOFTWARE. --------------------------------------------------------- -runtime.linux-musl-x64.runtime.native.System.IO.Ports 9.0.6 - MIT +runtime.linux-musl-x64.runtime.native.System.IO.Ports 9.0.8 - MIT Copyright (c) 2021 @@ -1597,7 +1597,7 @@ SOFTWARE. --------------------------------------------------------- -runtime.linux-x64.runtime.native.System.IO.Ports 9.0.6 - MIT +runtime.linux-x64.runtime.native.System.IO.Ports 9.0.8 - MIT Copyright (c) 2021 @@ -1687,7 +1687,7 @@ SOFTWARE. --------------------------------------------------------- -runtime.maccatalyst-arm64.runtime.native.System.IO.Ports 9.0.6 - MIT +runtime.maccatalyst-arm64.runtime.native.System.IO.Ports 9.0.8 - MIT Copyright (c) 2021 @@ -1777,7 +1777,7 @@ SOFTWARE. --------------------------------------------------------- -runtime.maccatalyst-x64.runtime.native.System.IO.Ports 9.0.6 - MIT +runtime.maccatalyst-x64.runtime.native.System.IO.Ports 9.0.8 - MIT Copyright (c) 2021 @@ -1912,7 +1912,7 @@ SOFTWARE. --------------------------------------------------------- -runtime.native.System.IO.Ports 9.0.6 - MIT +runtime.native.System.IO.Ports 9.0.8 - MIT Copyright (c) 2021 @@ -2002,7 +2002,7 @@ SOFTWARE. --------------------------------------------------------- -runtime.osx-arm64.runtime.native.System.IO.Ports 9.0.6 - MIT +runtime.osx-arm64.runtime.native.System.IO.Ports 9.0.8 - MIT Copyright (c) 2021 @@ -2092,7 +2092,7 @@ SOFTWARE. --------------------------------------------------------- -runtime.osx-x64.runtime.native.System.IO.Ports 9.0.6 - MIT +runtime.osx-x64.runtime.native.System.IO.Ports 9.0.8 - MIT Copyright (c) 2021 @@ -2182,7 +2182,7 @@ SOFTWARE. --------------------------------------------------------- -System.CodeDom 9.0.6 - MIT +System.CodeDom 9.0.8 - MIT Copyright (c) 2021 @@ -2358,7 +2358,7 @@ SOFTWARE. --------------------------------------------------------- -System.ComponentModel.Composition 9.0.6 - MIT +System.ComponentModel.Composition 9.0.8 - MIT Copyright (c) 2021 @@ -2448,7 +2448,7 @@ SOFTWARE. --------------------------------------------------------- -System.ComponentModel.Composition.Registration 9.0.6 - MIT +System.ComponentModel.Composition.Registration 9.0.8 - MIT Copyright (c) 2021 @@ -2538,7 +2538,7 @@ SOFTWARE. --------------------------------------------------------- -System.Configuration.ConfigurationManager 9.0.6 - MIT +System.Configuration.ConfigurationManager 9.0.8 - MIT Copyright (c) 2021 @@ -2628,7 +2628,7 @@ SOFTWARE. --------------------------------------------------------- -System.Data.Odbc 9.0.6 - MIT +System.Data.Odbc 9.0.8 - MIT Copyright (c) 2021 @@ -2718,7 +2718,7 @@ SOFTWARE. --------------------------------------------------------- -System.Data.OleDb 9.0.6 - MIT +System.Data.OleDb 9.0.8 - MIT Copyright (c) 2021 @@ -2827,7 +2827,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI --------------------------------------------------------- -System.Diagnostics.DiagnosticSource 9.0.6 - MIT +System.Diagnostics.DiagnosticSource 9.0.8 - MIT Copyright (c) 2021 @@ -2917,7 +2917,7 @@ SOFTWARE. --------------------------------------------------------- -System.Diagnostics.EventLog 9.0.6 - MIT +System.Diagnostics.EventLog 9.0.8 - MIT Copyright (c) 2021 @@ -3007,7 +3007,7 @@ SOFTWARE. --------------------------------------------------------- -System.Diagnostics.PerformanceCounter 9.0.6 - MIT +System.Diagnostics.PerformanceCounter 9.0.8 - MIT Copyright (c) 2021 @@ -3097,7 +3097,7 @@ SOFTWARE. --------------------------------------------------------- -System.DirectoryServices 9.0.6 - MIT +System.DirectoryServices 9.0.8 - MIT Copyright (c) 2021 @@ -3187,7 +3187,7 @@ SOFTWARE. --------------------------------------------------------- -System.DirectoryServices.AccountManagement 9.0.6 - MIT +System.DirectoryServices.AccountManagement 9.0.8 - MIT Copyright (c) 2021 @@ -3277,7 +3277,7 @@ SOFTWARE. --------------------------------------------------------- -System.DirectoryServices.Protocols 9.0.6 - MIT +System.DirectoryServices.Protocols 9.0.8 - MIT Copyright (c) 2021 @@ -3367,7 +3367,7 @@ SOFTWARE. --------------------------------------------------------- -System.Drawing.Common 9.0.6 - MIT +System.Drawing.Common 9.0.8 - MIT (c) Microsoft Corporation @@ -3402,7 +3402,7 @@ SOFTWARE. --------------------------------------------------------- -System.IO.Packaging 9.0.6 - MIT +System.IO.Packaging 9.0.8 - MIT Copyright (c) 2021 @@ -3492,7 +3492,7 @@ SOFTWARE. --------------------------------------------------------- -System.IO.Ports 9.0.6 - MIT +System.IO.Ports 9.0.8 - MIT Copyright (c) 2021 @@ -3582,7 +3582,7 @@ SOFTWARE. --------------------------------------------------------- -System.Management 9.0.6 - MIT +System.Management 9.0.8 - MIT Copyright (c) 2021 @@ -3672,7 +3672,7 @@ SOFTWARE. --------------------------------------------------------- -System.Net.Http.WinHttpHandler 9.0.6 - MIT +System.Net.Http.WinHttpHandler 9.0.8 - MIT Copyright (c) 2021 @@ -3847,7 +3847,7 @@ SOFTWARE. --------------------------------------------------------- -System.Reflection.Context 9.0.6 - MIT +System.Reflection.Context 9.0.8 - MIT Copyright (c) 2021 @@ -4077,7 +4077,7 @@ SOFTWARE. --------------------------------------------------------- -System.Runtime.Caching 9.0.6 - MIT +System.Runtime.Caching 9.0.8 - MIT Copyright (c) 2021 @@ -4242,7 +4242,7 @@ SOFTWARE. --------------------------------------------------------- -System.Security.Cryptography.Pkcs 9.0.6 - MIT +System.Security.Cryptography.Pkcs 9.0.8 - MIT Copyright (c) 2021 @@ -4332,7 +4332,7 @@ SOFTWARE. --------------------------------------------------------- -System.Security.Cryptography.ProtectedData 9.0.6 - MIT +System.Security.Cryptography.ProtectedData 9.0.8 - MIT Copyright (c) 2021 @@ -4422,7 +4422,7 @@ SOFTWARE. --------------------------------------------------------- -System.Security.Cryptography.Xml 9.0.6 - MIT +System.Security.Cryptography.Xml 9.0.8 - MIT Copyright (c) 2021 @@ -4512,7 +4512,7 @@ SOFTWARE. --------------------------------------------------------- -System.Security.Permissions 9.0.6 - MIT +System.Security.Permissions 9.0.8 - MIT Copyright (c) 2021 @@ -4851,7 +4851,7 @@ SOFTWARE. --------------------------------------------------------- -System.ServiceModel.Syndication 9.0.6 - MIT +System.ServiceModel.Syndication 9.0.8 - MIT Copyright (c) 2021 @@ -4941,7 +4941,7 @@ SOFTWARE. --------------------------------------------------------- -System.ServiceProcess.ServiceController 9.0.6 - MIT +System.ServiceProcess.ServiceController 9.0.8 - MIT Copyright (c) 2021 @@ -5031,7 +5031,7 @@ SOFTWARE. --------------------------------------------------------- -System.Speech 9.0.6 - MIT +System.Speech 9.0.8 - MIT Copyright (c) 2021 @@ -5121,7 +5121,7 @@ SOFTWARE. --------------------------------------------------------- -System.Text.Encoding.CodePages 9.0.6 - MIT +System.Text.Encoding.CodePages 9.0.8 - MIT Copyright (c) 2021 @@ -5211,7 +5211,7 @@ SOFTWARE. --------------------------------------------------------- -System.Text.Encodings.Web 9.0.6 - MIT +System.Text.Encodings.Web 9.0.8 - MIT Copyright (c) 2021 @@ -5301,7 +5301,7 @@ SOFTWARE. --------------------------------------------------------- -System.Threading.AccessControl 9.0.6 - MIT +System.Threading.AccessControl 9.0.8 - MIT Copyright (c) 2021 @@ -5427,7 +5427,7 @@ SOFTWARE. --------------------------------------------------------- -System.Windows.Extensions 9.0.6 - MIT +System.Windows.Extensions 9.0.8 - MIT Copyright (c) 2021 From bcd6bc473f257c09f1d9c226b83a433c83af174b Mon Sep 17 00:00:00 2001 From: "Travis Plunk (HE/HIM)" Date: Tue, 2 Sep 2025 16:58:56 -0700 Subject: [PATCH 152/173] Fix race condition in RemoteHyperVSocket --- .github/workflows/linux-ci.yml | 1 + .github/workflows/macos-ci.yml | 1 + .github/workflows/windows-ci.yml | 1 + build.psm1 | 27 +- .../host/msh/CommandLineParameterParser.cs | 131 ++- .../host/msh/ConsoleHost.cs | 49 +- .../CommandLineParameterParserStrings.resx | 3 + .../resources/ConsoleHostStrings.resx | 6 + .../common/RemoteSessionHyperVSocket.cs | 800 ++++++++++++++---- .../fanin/OutOfProcTransportManager.cs | 24 +- .../server/OutOfProcServerMediator.cs | 28 + .../resources/RemotingErrorIdStrings.resx | 6 + test/xUnit/csharp/test_CommandLineParser.cs | 22 + test/xUnit/csharp/test_RemoteHyperV.cs | 661 +++++++++++++++ 14 files changed, 1563 insertions(+), 197 deletions(-) create mode 100644 test/xUnit/csharp/test_RemoteHyperV.cs diff --git a/.github/workflows/linux-ci.yml b/.github/workflows/linux-ci.yml index a7523f430cf..2bf61ca3e48 100644 --- a/.github/workflows/linux-ci.yml +++ b/.github/workflows/linux-ci.yml @@ -21,6 +21,7 @@ on: - master - release/** - github-mirror + - "*-feature" # Path filters for PRs need to go into the changes job concurrency: diff --git a/.github/workflows/macos-ci.yml b/.github/workflows/macos-ci.yml index 9184dc088f0..e0a85042053 100644 --- a/.github/workflows/macos-ci.yml +++ b/.github/workflows/macos-ci.yml @@ -19,6 +19,7 @@ on: - master - release/** - github-mirror + - "*-feature" # Path filters for PRs need to go into the changes job concurrency: diff --git a/.github/workflows/windows-ci.yml b/.github/workflows/windows-ci.yml index 1e955c78be6..2e392987cb0 100644 --- a/.github/workflows/windows-ci.yml +++ b/.github/workflows/windows-ci.yml @@ -18,6 +18,7 @@ on: - master - release/** - github-mirror + - "*-feature" # Path filters for PRs need to go into the changes job diff --git a/build.psm1 b/build.psm1 index 21bf0f332ab..fe7eff67b2f 100644 --- a/build.psm1 +++ b/build.psm1 @@ -1973,7 +1973,9 @@ function Test-PSPesterResults function Start-PSxUnit { [CmdletBinding()]param( - [string] $xUnitTestResultsFile = "xUnitResults.xml" + [string] $xUnitTestResultsFile = "xUnitResults.xml", + [switch] $DebugLogging, + [string] $Filter ) # Add .NET CLI tools to PATH @@ -2031,9 +2033,28 @@ function Start-PSxUnit { # We run the xUnit tests sequentially to avoid race conditions caused by manipulating the config.json file. # xUnit tests run in parallel by default. To make them run sequentially, we need to define the 'xunit.runner.json' file. - dotnet test --configuration $Options.configuration --test-adapter-path:. "--logger:xunit;LogFilePath=$xUnitTestResultsFile" + $extraParams = @() + if($Filter) { + $extraParams += @( + '--filter' + $Filter + ) + } + + if($DebugLogging) { + $extraParams += @( + "--logger:console;verbosity=detailed" + ) + } else { + $extraParams += @( + "--logger:xunit;LogFilePath=$xUnitTestResultsFile" + ) + } + dotnet test @extraParams --configuration $Options.configuration --test-adapter-path:. - Publish-TestResults -Path $xUnitTestResultsFile -Type 'XUnit' -Title 'Xunit Sequential' + if(!$DebugLogging){ + Publish-TestResults -Path $xUnitTestResultsFile -Type 'XUnit' -Title 'Xunit Sequential' + } } finally { $env:DOTNET_ROOT = $originalDOTNET_ROOT diff --git a/src/Microsoft.PowerShell.ConsoleHost/host/msh/CommandLineParameterParser.cs b/src/Microsoft.PowerShell.ConsoleHost/host/msh/CommandLineParameterParser.cs index 50d2bd77d0f..bafaa9cabdf 100644 --- a/src/Microsoft.PowerShell.ConsoleHost/host/msh/CommandLineParameterParser.cs +++ b/src/Microsoft.PowerShell.ConsoleHost/host/msh/CommandLineParameterParser.cs @@ -203,35 +203,35 @@ internal static int MaxNameLength() [Flags] internal enum ParameterBitmap : long { - Command = 0x00000001, // -Command | -c - ConfigurationName = 0x00000002, // -ConfigurationName | -config - CustomPipeName = 0x00000004, // -CustomPipeName - EncodedCommand = 0x00000008, // -EncodedCommand | -e | -ec - EncodedArgument = 0x00000010, // -EncodedArgument - ExecutionPolicy = 0x00000020, // -ExecutionPolicy | -ex | -ep - File = 0x00000040, // -File | -f - Help = 0x00000080, // -Help, -?, /? - InputFormat = 0x00000100, // -InputFormat | -inp | -if - Interactive = 0x00000200, // -Interactive | -i - Login = 0x00000400, // -Login | -l - MTA = 0x00000800, // -MTA - NoExit = 0x00001000, // -NoExit | -noe - NoLogo = 0x00002000, // -NoLogo | -nol - NonInteractive = 0x00004000, // -NonInteractive | -noni - NoProfile = 0x00008000, // -NoProfile | -nop - OutputFormat = 0x00010000, // -OutputFormat | -o | -of - SettingsFile = 0x00020000, // -SettingsFile | -settings - SSHServerMode = 0x00040000, // -SSHServerMode | -sshs - SocketServerMode = 0x00080000, // -SocketServerMode | -sockets - ServerMode = 0x00100000, // -ServerMode | -server - NamedPipeServerMode = 0x00200000, // -NamedPipeServerMode | -namedpipes - STA = 0x00400000, // -STA - Version = 0x00800000, // -Version | -v - WindowStyle = 0x01000000, // -WindowStyle | -w - WorkingDirectory = 0x02000000, // -WorkingDirectory | -wd - ConfigurationFile = 0x04000000, // -ConfigurationFile - NoProfileLoadTime = 0x08000000, // -NoProfileLoadTime - CommandWithArgs = 0x10000000, // -CommandWithArgs | -cwa + Command = 0x0000000000000001, // -Command | -c + ConfigurationName = 0x0000000000000002, // -ConfigurationName | -config + CustomPipeName = 0x0000000000000004, // -CustomPipeName + EncodedCommand = 0x0000000000000008, // -EncodedCommand | -e | -ec + EncodedArgument = 0x0000000000000010, // -EncodedArgument + ExecutionPolicy = 0x0000000000000020, // -ExecutionPolicy | -ex | -ep + File = 0x0000000000000040, // -File | -f + Help = 0x0000000000000080, // -Help, -?, /? + InputFormat = 0x0000000000000100, // -InputFormat | -inp | -if + Interactive = 0x0000000000000200, // -Interactive | -i + Login = 0x0000000000000400, // -Login | -l + MTA = 0x0000000000000800, // -MTA + NoExit = 0x0000000000001000, // -NoExit | -noe + NoLogo = 0x0000000000002000, // -NoLogo | -nol + NonInteractive = 0x0000000000004000, // -NonInteractive | -noni + NoProfile = 0x0000000000008000, // -NoProfile | -nop + OutputFormat = 0x0000000000010000, // -OutputFormat | -o | -of + SettingsFile = 0x0000000000020000, // -SettingsFile | -settings + SSHServerMode = 0x0000000000040000, // -SSHServerMode | -sshs + SocketServerMode = 0x0000000000080000, // -SocketServerMode | -sockets + ServerMode = 0x0000000000100000, // -ServerMode | -server + NamedPipeServerMode = 0x0000000000200000, // -NamedPipeServerMode | -namedpipes + STA = 0x0000000000400000, // -STA + Version = 0x0000000000800000, // -Version | -v + WindowStyle = 0x0000000001000000, // -WindowStyle | -w + WorkingDirectory = 0x0000000002000000, // -WorkingDirectory | -wd + ConfigurationFile = 0x0000000004000000, // -ConfigurationFile + NoProfileLoadTime = 0x0000000008000000, // -NoProfileLoadTime + CommandWithArgs = 0x0000000010000000, // -CommandWithArgs | -cwa // Enum values for specified ExecutionPolicy EPUnrestricted = 0x0000000100000000, // ExecutionPolicy unrestricted EPRemoteSigned = 0x0000000200000000, // ExecutionPolicy remote signed @@ -241,6 +241,8 @@ internal enum ParameterBitmap : long EPBypass = 0x0000002000000000, // ExecutionPolicy bypass EPUndefined = 0x0000004000000000, // ExecutionPolicy undefined EPIncorrect = 0x0000008000000000, // ExecutionPolicy incorrect + // V2 Socket Server Mode + V2SocketServerMode = 0x0000100000000000, // -V2SocketServerMode | -v2so } internal ParameterBitmap ParametersUsed = 0; @@ -597,6 +599,33 @@ internal bool RemoveWorkingDirectoryTrailingCharacter return _removeWorkingDirectoryTrailingCharacter; } } + + internal DateTimeOffset? UTCTimestamp + { + get + { + AssertArgumentsParsed(); + return _utcTimestamp; + } + } + + internal string? Token + { + get + { + AssertArgumentsParsed(); + return _token; + } + } + + internal bool V2SocketServerMode + { + get + { + AssertArgumentsParsed(); + return _v2SocketServerMode; + } + } #endif #endregion Internal properties @@ -916,6 +945,14 @@ private void ParseHelper(string[] args) _showBanner = false; ParametersUsed |= ParameterBitmap.SocketServerMode; } +#if !UNIX + else if (MatchSwitch(switchKey, "v2socketservermode", "v2so")) + { + _v2SocketServerMode = true; + _showBanner = false; + ParametersUsed |= ParameterBitmap.V2SocketServerMode; + } +#endif else if (MatchSwitch(switchKey, "servermode", "s")) { _serverMode = true; @@ -1176,6 +1213,35 @@ private void ParseHelper(string[] args) { _removeWorkingDirectoryTrailingCharacter = true; } + else if (MatchSwitch(switchKey, "token", "to") ) + { + ++i; + if (i >= args.Length) + { + SetCommandLineError( + string.Format(CultureInfo.CurrentCulture, CommandLineParameterParserStrings.MissingMandatoryArgument, "-Token")); + break; + } + + _token = args[i]; + // Not adding anything to ParametersUsed, because it is required with V2 socket server mode + // So, we can assume it based on that bit + } + else if (MatchSwitch(switchKey, "utctimestamp", "utc") ) + { + ++i; + if (i >= args.Length) + { + SetCommandLineError( + string.Format(CultureInfo.CurrentCulture, CommandLineParameterParserStrings.MissingMandatoryArgument, "-UTCTimestamp")); + break; + } + + // Parse as iso8601UtcString + _utcTimestamp = DateTimeOffset.ParseExact(args[i], "yyyy-MM-dd'T'HH:mm:ssK", CultureInfo.InvariantCulture, DateTimeStyles.RoundtripKind); + // Not adding anything to ParametersUsed, because it is required with V2 socket server mode + // So, we can assume it based on that bit + } #endif else { @@ -1530,6 +1596,9 @@ private bool CollectArgs(string[] args, ref int i) } private bool _socketServerMode; +#if !UNIX + private bool _v2SocketServerMode; +#endif private bool _serverMode; private bool _namedPipeServerMode; private bool _sshServerMode; @@ -1562,6 +1631,10 @@ private bool CollectArgs(string[] args, ref int i) private string? _executionPolicy; private string? _settingsFile; private string? _workingDirectory; +#if !UNIX + private string? _token; + private DateTimeOffset? _utcTimestamp; +#endif #if !UNIX private ProcessWindowStyle? _windowStyle; diff --git a/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleHost.cs b/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleHost.cs index 8cc7ee00f57..aa5d532da2a 100644 --- a/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleHost.cs +++ b/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleHost.cs @@ -198,7 +198,26 @@ internal static int Start( } // Servermode parameter validation check. - if ((s_cpp.ServerMode && s_cpp.NamedPipeServerMode) || (s_cpp.ServerMode && s_cpp.SocketServerMode) || (s_cpp.NamedPipeServerMode && s_cpp.SocketServerMode)) + int serverModeCount = 0; + if (s_cpp.ServerMode) + { + serverModeCount++; + } + if (s_cpp.NamedPipeServerMode) + { + serverModeCount++; + } + if (s_cpp.SocketServerMode) + { + serverModeCount++; + } +#if !UNIX + if (s_cpp.V2SocketServerMode) + { + serverModeCount++; + } +#endif + if (serverModeCount > 1) { s_tracer.TraceError("Conflicting server mode parameters, parameters must be used exclusively."); s_theConsoleHost?.ui.WriteErrorLine(ConsoleHostStrings.ConflictingServerModeParameters); @@ -242,6 +261,34 @@ internal static int Start( configurationName: s_cpp.ConfigurationName); exitCode = 0; } +#if !UNIX + else if (s_cpp.V2SocketServerMode) + { + if (s_cpp.Token == null) + { + s_tracer.TraceError("Token is required for V2SocketServerMode."); + s_theConsoleHost?.ui.WriteErrorLine(string.Format(CultureInfo.CurrentCulture, ConsoleHostStrings.MissingMandatoryParameter, "-Token", "-V2SocketServerMode")); + return ExitCodeBadCommandLineParameter; + } + + if (s_cpp.UTCTimestamp == null) + { + s_tracer.TraceError("UTCTimestamp is required for V2SocketServerMode."); + s_theConsoleHost?.ui.WriteErrorLine(string.Format(CultureInfo.CurrentCulture, ConsoleHostStrings.MissingMandatoryParameter, "-UTCTimestamp", "-v2socketservermode")); + return ExitCodeBadCommandLineParameter; + } + + ApplicationInsightsTelemetry.SendPSCoreStartupTelemetry("V2SocketServerMode", s_cpp.ParametersUsedAsDouble); + ProfileOptimization.StartProfile("StartupProfileData-V2SocketServerMode"); + HyperVSocketMediator.Run( + initialCommand: s_cpp.InitialCommand, + configurationName: s_cpp.ConfigurationName, + token: s_cpp.Token, + tokenCreationTime: s_cpp.UTCTimestamp.Value + ); + exitCode = 0; + } +#endif else if (s_cpp.SocketServerMode) { ApplicationInsightsTelemetry.SendPSCoreStartupTelemetry("SocketServerMode", s_cpp.ParametersUsedAsDouble); diff --git a/src/Microsoft.PowerShell.ConsoleHost/resources/CommandLineParameterParserStrings.resx b/src/Microsoft.PowerShell.ConsoleHost/resources/CommandLineParameterParserStrings.resx index 34bb696c33c..33445ceebd2 100644 --- a/src/Microsoft.PowerShell.ConsoleHost/resources/CommandLineParameterParserStrings.resx +++ b/src/Microsoft.PowerShell.ConsoleHost/resources/CommandLineParameterParserStrings.resx @@ -225,4 +225,7 @@ Valid formats are: Invalid ExecutionPolicy value '{0}'. + + An argument is required to be supplied to the '{0}' parameter. + diff --git a/src/Microsoft.PowerShell.ConsoleHost/resources/ConsoleHostStrings.resx b/src/Microsoft.PowerShell.ConsoleHost/resources/ConsoleHostStrings.resx index ce124ec084c..9bc06e0d42f 100644 --- a/src/Microsoft.PowerShell.ConsoleHost/resources/ConsoleHostStrings.resx +++ b/src/Microsoft.PowerShell.ConsoleHost/resources/ConsoleHostStrings.resx @@ -182,4 +182,10 @@ The current session does not support debugging; execution will continue. Run as Administrator + + PushRunspace can only push a remote runspace. + + + The '{0}' parameter is mandatory and must be specified when using the '{1}' parameter. + diff --git a/src/System.Management.Automation/engine/remoting/common/RemoteSessionHyperVSocket.cs b/src/System.Management.Automation/engine/remoting/common/RemoteSessionHyperVSocket.cs index 7fae8118310..a9de12c3931 100644 --- a/src/System.Management.Automation/engine/remoting/common/RemoteSessionHyperVSocket.cs +++ b/src/System.Management.Automation/engine/remoting/common/RemoteSessionHyperVSocket.cs @@ -7,8 +7,10 @@ using System.Net.Sockets; using System.Text; using System.Threading; +using System.Buffers; using Dbg = System.Diagnostics.Debug; +using SMA = System.Management.Automation; namespace System.Management.Automation.Remoting { @@ -140,6 +142,10 @@ internal sealed class RemoteSessionHyperVSocketServer : IDisposable private readonly object _syncObject; private readonly PowerShellTraceSource _tracer = PowerShellTraceSourceFactory.GetTraceSource(); + // This is to prevent persistent replay attacks. + // it is not meant to ensure all replay attacks are impossible. + private const int MAX_TOKEN_LIFE_MINUTES = 10; + #endregion #region Properties @@ -175,64 +181,74 @@ internal sealed class RemoteSessionHyperVSocketServer : IDisposable public RemoteSessionHyperVSocketServer(bool LoopbackMode) { - // TODO: uncomment below code when .NET supports Hyper-V socket duplication - /* - NamedPipeClientStream clientPipeStream; - byte[] buffer = new byte[1000]; - int bytesRead; - */ _syncObject = new object(); Exception ex = null; try { - // TODO: uncomment below code when .NET supports Hyper-V socket duplication - /* - if (!LoopbackMode) - { - // - // Create named pipe client. - // - using (clientPipeStream = new NamedPipeClientStream(".", - "PS_VMSession", - PipeDirection.InOut, - PipeOptions.None, - TokenImpersonationLevel.None)) - { - // - // Connect to named pipe server. - // - clientPipeStream.Connect(10*1000); - - // - // Read LPWSAPROTOCOL_INFO. - // - bytesRead = clientPipeStream.Read(buffer, 0, 1000); - } - } + Guid serviceId = new Guid("a5201c21-2770-4c11-a68e-f182edb29220"); // HV_GUID_VM_SESSION_SERVICE_ID_2 + Guid loopbackId = new Guid("e0e16197-dd56-4a10-9195-5ee7a155a838"); // HV_GUID_LOOPBACK + Guid parentId = new Guid("a42e7cda-d03f-480c-9cc2-a4de20abb878"); // HV_GUID_PARENT + Guid vmId = LoopbackMode ? loopbackId : parentId; + HyperVSocketEndPoint endpoint = new HyperVSocketEndPoint(HyperVSocketEndPoint.AF_HYPERV, vmId, serviceId); + + Socket listenSocket = new Socket(endpoint.AddressFamily, SocketType.Stream, (System.Net.Sockets.ProtocolType)1); + listenSocket.Bind(endpoint); + + listenSocket.Listen(1); + HyperVSocket = listenSocket.Accept(); + + Stream = new NetworkStream(HyperVSocket, true); + + // Create reader/writer streams. + TextReader = new StreamReader(Stream); + TextWriter = new StreamWriter(Stream); + TextWriter.AutoFlush = true; // - // Create duplicate socket. + // listenSocket is not closed when it goes out of scope here. Sometimes it is + // closed later in this thread, while other times it is not closed at all. This will + // cause problem when we set up a second PowerShell Direct session. Let's + // explicitly close listenSocket here for safe. // - byte[] protocolInfo = new byte[bytesRead]; - Array.Copy(buffer, protocolInfo, bytesRead); + if (listenSocket != null) + { + try { listenSocket.Dispose(); } + catch (ObjectDisposedException) { } + } + } + catch (Exception e) + { + ex = e; + } - SocketInformation sockInfo = new SocketInformation(); - sockInfo.ProtocolInformation = protocolInfo; - sockInfo.Options = SocketInformationOptions.Connected; + if (ex != null) + { + Dbg.Fail("Unexpected error in RemoteSessionHyperVSocketServer."); - socket = new Socket(sockInfo); - if (socket == null) - { - Dbg.Assert(false, "Unexpected error in RemoteSessionHyperVSocketServer."); + // Unexpected error. + string errorMessage = !string.IsNullOrEmpty(ex.Message) ? ex.Message : string.Empty; + _tracer.WriteMessage("RemoteSessionHyperVSocketServer", "RemoteSessionHyperVSocketServer", Guid.Empty, + "Unexpected error in constructor: {0}", errorMessage); - tracer.WriteMessage("RemoteSessionHyperVSocketServer", "RemoteSessionHyperVSocketServer", Guid.Empty, - "Unexpected error in constructor: {0}", "socket duplication failure"); - } - */ + throw new PSInvalidOperationException( + PSRemotingErrorInvariants.FormatResourceString(RemotingErrorIdStrings.RemoteSessionHyperVSocketServerConstructorFailure), + ex, + nameof(PSRemotingErrorId.RemoteSessionHyperVSocketServerConstructorFailure), + ErrorCategory.InvalidOperation, + null); + } + } + + public RemoteSessionHyperVSocketServer(bool LoopbackMode, string token, DateTimeOffset tokenCreationTime) + { + _syncObject = new object(); - // TODO: remove below 6 lines of code when .NET supports Hyper-V socket duplication + Exception ex = null; + + try + { Guid serviceId = new Guid("a5201c21-2770-4c11-a68e-f182edb29220"); // HV_GUID_VM_SESSION_SERVICE_ID_2 HyperVSocketEndPoint endpoint = new HyperVSocketEndPoint(HyperVSocketEndPoint.AF_HYPERV, Guid.Empty, serviceId); @@ -242,6 +258,31 @@ public RemoteSessionHyperVSocketServer(bool LoopbackMode) listenSocket.Listen(1); HyperVSocket = listenSocket.Accept(); + TimeSpan timeout = TimeSpan.FromMinutes(MAX_TOKEN_LIFE_MINUTES); + DateTimeOffset timeoutExpiry = tokenCreationTime.Add(timeout); + DateTimeOffset now = DateTimeOffset.UtcNow; + + // Calculate remaining time and create cancellation token + TimeSpan remainingTime = timeoutExpiry - now; + + // Check if the token has already expired + if (remainingTime <= TimeSpan.Zero) + { + throw new PSDirectException( + PSRemotingErrorInvariants.FormatResourceString(RemotingErrorIdStrings.InvalidCredential, "Token has expired")); + } + + // Set socket timeout for receive operations to prevent indefinite blocking + int timeoutMs = (int)remainingTime.TotalMilliseconds; + HyperVSocket.ReceiveTimeout = timeoutMs; + HyperVSocket.SendTimeout = timeoutMs; + + // Create a cancellation token that will be cancelled when the timeout expires + using var cancellationTokenSource = new CancellationTokenSource(remainingTime); + CancellationToken cancellationToken = cancellationTokenSource.Token; + + ValidateToken(HyperVSocket, token, cancellationToken); + Stream = new NetworkStream(HyperVSocket, true); // Create reader/writer streams. @@ -257,8 +298,13 @@ public RemoteSessionHyperVSocketServer(bool LoopbackMode) // if (listenSocket != null) { - try { listenSocket.Dispose(); } - catch (ObjectDisposedException) { } + try + { + listenSocket.Dispose(); + } + catch (ObjectDisposedException) + { + } } } catch (Exception e) @@ -272,8 +318,12 @@ public RemoteSessionHyperVSocketServer(bool LoopbackMode) // Unexpected error. string errorMessage = !string.IsNullOrEmpty(ex.Message) ? ex.Message : string.Empty; - _tracer.WriteMessage("RemoteSessionHyperVSocketServer", "RemoteSessionHyperVSocketServer", Guid.Empty, - "Unexpected error in constructor: {0}", errorMessage); + _tracer.WriteMessage( + "RemoteSessionHyperVSocketServer", + "RemoteSessionHyperVSocketServer", + Guid.Empty, + "Unexpected error in constructor: {0}", + errorMessage); throw new PSInvalidOperationException( PSRemotingErrorInvariants.FormatResourceString(RemotingErrorIdStrings.RemoteSessionHyperVSocketServerConstructorFailure), @@ -283,7 +333,6 @@ public RemoteSessionHyperVSocketServer(bool LoopbackMode) null); } } - #endregion #region IDisposable @@ -333,6 +382,79 @@ public void Dispose() } #endregion + + /// + /// Validates the token received from the client over the HyperVSocket. + /// Throws PSDirectException if the token is invalid or not received in time. + /// + /// The connected HyperVSocket. + /// The expected token string. + /// Cancellation token for timeout handling. + internal static void ValidateToken(Socket socket, string token, CancellationToken cancellationToken = default) + { + // Check for cancellation before starting validation + cancellationToken.ThrowIfCancellationRequested(); + + // We should move to this pattern and + // in the tests I found I needed to get a bigger buffer than the token length + // and test length of the received data similar to this pattern. + string responseString = RemoteSessionHyperVSocketClient.ReceiveResponse(socket, RemoteSessionHyperVSocketClient.VERSION_REQUEST.Length + 4); + if (string.IsNullOrEmpty(responseString) || responseString.Length != RemoteSessionHyperVSocketClient.VERSION_REQUEST.Length) + { + socket.Send("FAIL"u8); + throw new PSDirectException( + PSRemotingErrorInvariants.FormatResourceString(RemotingErrorIdStrings.HyperVInvalidResponse, "Client", "Version Request: " + responseString)); + } + + cancellationToken.ThrowIfCancellationRequested(); + + socket.Send(Encoding.UTF8.GetBytes(RemoteSessionHyperVSocketClient.CLIENT_VERSION)); + responseString = RemoteSessionHyperVSocketClient.ReceiveResponse(socket, RemoteSessionHyperVSocketClient.CLIENT_VERSION.Length + 4); + + // In the future we may need to handle different versions, differently. + // For now, we are just checking that we exchanged versions correctly. + if (string.IsNullOrEmpty(responseString) || !responseString.StartsWith(RemoteSessionHyperVSocketClient.VERSION_PREFIX, StringComparison.Ordinal)) + { + socket.Send("FAIL"u8); + throw new PSDirectException( + PSRemotingErrorInvariants.FormatResourceString(RemotingErrorIdStrings.HyperVInvalidResponse, "Client", "Version Response: " + responseString)); + } + + cancellationToken.ThrowIfCancellationRequested(); + + socket.Send("PASS"u8); + + // The client should send the token in the format TOKEN + // the token should be up to 256 bits, which is less than 50 characters. + // I'll double that to 100 characters to be safe, plus the "TOKEN " prefix. + // So we expect a response of length 6 + 100 = 106 characters. + responseString = RemoteSessionHyperVSocketClient.ReceiveResponse(socket, 110); + + cancellationToken.ThrowIfCancellationRequested(); + + if (string.IsNullOrEmpty(responseString) || !responseString.StartsWith("TOKEN ", StringComparison.Ordinal)) + { + socket.Send("FAIL"u8); + // If the response is not in the expected format, we throw an exception. + // This is a failure to authenticate the client. + // don't send this response for risk of information disclosure. + throw new PSDirectException( + PSRemotingErrorInvariants.FormatResourceString(RemotingErrorIdStrings.HyperVInvalidResponse, "Client", "Token Response")); + } + + // Extract the token from the response. + string responseToken = responseString.Substring(6).Trim(); + + if (!string.Equals(responseToken, token, StringComparison.Ordinal)) + { + socket.Send("FAIL"u8); + throw new PSDirectException( + PSRemotingErrorInvariants.FormatResourceString(RemotingErrorIdStrings.InvalidCredential)); + } + + // Acknowledge the token is valid with "PASS". + socket.Send("PASS"u8); + } } internal sealed class RemoteSessionHyperVSocketClient : IDisposable @@ -340,7 +462,15 @@ internal sealed class RemoteSessionHyperVSocketClient : IDisposable #region Members private readonly object _syncObject; - private readonly PowerShellTraceSource _tracer = PowerShellTraceSourceFactory.GetTraceSource(); + + #region tracer + /// + /// An instance of the PSTraceSource class used for trace output. + /// + [SMA.TraceSource("RemoteSessionHyperVSocketClient", "Class that has PowerShell Direct Client implementation")] + private static readonly PSTraceSource s_tracer = PSTraceSource.GetTracer("RemoteSessionHyperVSocketClient", "Class that has PowerShell Direct Client implementation"); + + #endregion tracer private static readonly ManualResetEvent s_connectDone = new ManualResetEvent(false); @@ -354,6 +484,14 @@ internal sealed class RemoteSessionHyperVSocketClient : IDisposable #endregion + #region version constants + + internal const string VERSION_REQUEST = "VERSION"; + internal const string CLIENT_VERSION = "VERSION_2"; + internal const string VERSION_PREFIX = "VERSION_"; + + #endregion + #region Properties /// @@ -364,7 +502,7 @@ internal sealed class RemoteSessionHyperVSocketClient : IDisposable /// /// Returns the Hyper-V socket object. /// - public Socket HyperVSocket { get; } + public Socket HyperVSocket { get; private set; } /// /// Returns the network stream object. @@ -381,6 +519,37 @@ internal sealed class RemoteSessionHyperVSocketClient : IDisposable /// public StreamWriter TextWriter { get; private set; } + /// + /// True if the client is a Hyper-V container. + /// + public bool IsContainer { get; } + + /// + /// True if the client is using backwards compatible mode. + /// This is used to determine if the client should use + /// the backwards compatible or not. + /// In modern mode, the vmicvmsession service will + /// hand off the socket to the PowerShell process + /// inside the VM automatically. + /// In backwards compatible mode, the vmicvmsession + /// service create a new socket to the PowerShell process + /// inside the VM. + /// + public bool UseBackwardsCompatibleMode { get; private set; } + + /// + /// The authentication token used for the session. + /// This token is provided by the broker and provided to the server to authenticate the server session. + /// This protocol uses two connections: + /// 1. The first is to the broker or vmicvmsession service to exchange credentials and configuration. + /// The broker will respond with an authentication token. The broker also launches a PowerShell + /// server process with the authentication token. + /// 2. The second is to the server process, that was launched by the broker, + /// inside the VM, which uses the authentication token to verify that the client is the same client + /// that connected to the broker. + /// + public string AuthenticationToken { get; private set; } + /// /// Returns true if object is currently disposed. /// @@ -393,7 +562,9 @@ internal sealed class RemoteSessionHyperVSocketClient : IDisposable internal RemoteSessionHyperVSocketClient( Guid vmId, bool isFirstConnection, - bool isContainer = false) + bool useBackwardsCompatibleMode = false, + bool isContainer = false, + string authenticationToken = null) { Guid serviceId; @@ -412,28 +583,16 @@ internal RemoteSessionHyperVSocketClient( EndPoint = new HyperVSocketEndPoint(HyperVSocketEndPoint.AF_HYPERV, vmId, serviceId); - HyperVSocket = new Socket(EndPoint.AddressFamily, SocketType.Stream, (System.Net.Sockets.ProtocolType)1); + IsContainer = isContainer; - // - // We need to call SetSocketOption() in order to set up Hyper-V socket connection between container host and Hyper-V container. - // Here is the scenario: the Hyper-V container is inside a utility vm, which is inside the container host - // - if (isContainer) - { - var value = new byte[sizeof(uint)]; - value[0] = 1; + UseBackwardsCompatibleMode = useBackwardsCompatibleMode; - try - { - HyperVSocket.SetSocketOption((System.Net.Sockets.SocketOptionLevel)HV_PROTOCOL_RAW, - (System.Net.Sockets.SocketOptionName)HVSOCKET_CONTAINER_PASSTHRU, - (byte[])value); - } - catch - { - throw new PSDirectException( - PSRemotingErrorInvariants.FormatResourceString(RemotingErrorIdStrings.RemoteSessionHyperVSocketClientConstructorSetSocketOptionFailure)); - } + if (!isFirstConnection && !useBackwardsCompatibleMode && !string.IsNullOrEmpty(authenticationToken)) + { + // If this is not the first connection and we are using backwards compatible mode, + // we should not set the authentication token here. + // The authentication token will be set during the Connect method. + AuthenticationToken = authenticationToken; } } @@ -489,6 +648,81 @@ public void Dispose() #region Public Methods + private void ShutdownSocket() + { + if (HyperVSocket != null) + { + // Ensure the socket is disposed properly. + try + { + s_tracer.WriteLine("ShutdownSocket: Disposing of the HyperVSocket."); + HyperVSocket.Dispose(); + } + catch (Exception ex) + { + s_tracer.WriteLine("ShutdownSocket: Exception while disposing the socket: {0}", ex.Message); + } + } + + // Dispose of the existing stream if it exists. + if (Stream != null) + { + try + { + Stream.Dispose(); + } + catch (Exception ex) + { + s_tracer.WriteLine("ShutdownSocket: Exception while disposing the stream: {0}", ex.Message); + } + } + } + + /// + /// Recreates the HyperVSocket and connects it to the endpoint, updating the Stream if successful. + /// + private bool ConnectSocket() + { + HyperVSocket = new Socket(EndPoint.AddressFamily, SocketType.Stream, (System.Net.Sockets.ProtocolType)1); + + // + // We need to call SetSocketOption() in order to set up Hyper-V socket connection between container host and Hyper-V container. + // Here is the scenario: the Hyper-V container is inside a utility vm, which is inside the container host + // + if (IsContainer) + { + var value = new byte[sizeof(uint)]; + value[0] = 1; + + try + { + HyperVSocket.SetSocketOption( + (System.Net.Sockets.SocketOptionLevel)HV_PROTOCOL_RAW, + (System.Net.Sockets.SocketOptionName)HVSOCKET_CONTAINER_PASSTHRU, + value); + } + catch + { + throw new PSDirectException( + PSRemotingErrorInvariants.FormatResourceString(RemotingErrorIdStrings.RemoteSessionHyperVSocketClientConstructorSetSocketOptionFailure)); + } + } + + s_tracer.WriteLine("Connect: Client connecting, to {0}; isContainer: {1}.", EndPoint.ServiceId.ToString(), IsContainer); + HyperVSocket.Connect(EndPoint); + + // Check if the socket is connected. + // If it is connected, create a NetworkStream. + if (HyperVSocket.Connected) + { + s_tracer.WriteLine("Connect: Client connected, to {0}; isContainer: {1}.", EndPoint.ServiceId.ToString(), IsContainer); + Stream = new NetworkStream(HyperVSocket, true); + return true; + } + + return false; + } + /// /// Connect to Hyper-V socket server. This is a blocking call until a /// connection occurs or the timeout time has elapsed. @@ -516,100 +750,51 @@ public bool Connect( } } - HyperVSocket.Connect(EndPoint); - - if (HyperVSocket.Connected) + if (ConnectSocket()) { - _tracer.WriteMessage("RemoteSessionHyperVSocketClient", "Connect", Guid.Empty, - "Client connected."); - - Stream = new NetworkStream(HyperVSocket, true); - if (isFirstConnection) { - if (string.IsNullOrEmpty(networkCredential.Domain)) + var exchangeResult = ExchangeCredentialsAndConfiguration(networkCredential, configurationName, HyperVSocket, this.UseBackwardsCompatibleMode); + if (!exchangeResult.success) { - networkCredential.Domain = "localhost"; - } + // We will not block here for a container because a container does not have a broker. + if (IsRequirePsDirectAuthenticationEnabled(@"SOFTWARE\\Microsoft\\PowerShell", Microsoft.Win32.RegistryHive.LocalMachine)) + { + s_tracer.WriteLine("ExchangeCredentialsAndConfiguration: RequirePsDirectAuthentication is enabled, requiring latest transport version."); + throw new PSDirectException( + PSRemotingErrorInvariants.FormatResourceString(RemotingErrorIdStrings.HyperVNegotiationFailed)); + } - bool emptyPassword = string.IsNullOrEmpty(networkCredential.Password); - bool emptyConfiguration = string.IsNullOrEmpty(configurationName); - - byte[] domain = Encoding.Unicode.GetBytes(networkCredential.Domain); - byte[] userName = Encoding.Unicode.GetBytes(networkCredential.UserName); - byte[] password = Encoding.Unicode.GetBytes(networkCredential.Password); - byte[] response = new byte[4]; // either "PASS" or "FAIL" - string responseString; - - // - // Send credential to VM so that PowerShell process inside VM can be - // created under the correct security context. - // - HyperVSocket.Send(domain); - HyperVSocket.Receive(response); - - HyperVSocket.Send(userName); - HyperVSocket.Receive(response); - - // - // We cannot simply send password because if it is empty, - // the vmicvmsession service in VM will block in recv method. - // - if (emptyPassword) - { - HyperVSocket.Send("EMPTYPW"u8); - HyperVSocket.Receive(response); - responseString = Encoding.ASCII.GetString(response); - } - else - { - HyperVSocket.Send("NONEMPTYPW"u8); - HyperVSocket.Receive(response); + this.UseBackwardsCompatibleMode = true; + s_tracer.WriteLine("ExchangeCredentialsAndConfiguration: Using backwards compatible mode."); - HyperVSocket.Send(password); - HyperVSocket.Receive(response); - responseString = Encoding.ASCII.GetString(response); + // If the first connection fails in modern mode, fall back to backwards compatible mode. + ShutdownSocket(); // will terminate the broker + ConnectSocket(); // restart the broker + exchangeResult = ExchangeCredentialsAndConfiguration(networkCredential, configurationName, HyperVSocket, this.UseBackwardsCompatibleMode); + if (!exchangeResult.success) + { + s_tracer.WriteLine("ExchangeCredentialsAndConfiguration: Failed to exchange credentials and configuration in backwards compatible mode."); + throw new PSDirectException( + PSRemotingErrorInvariants.FormatResourceString(RemotingErrorIdStrings.HyperVInvalidResponse, "Broker", "Credential")); + } } - - // - // There are 3 cases for the responseString received above. - // - "FAIL": credential is invalid - // - "PASS": credential is valid, but PowerShell Direct in VM does not support configuration (Server 2016 TP4 and before) - // - "CONF": credential is valid, and PowerShell Direct in VM supports configuration (Server 2016 TP5 and later) - // - - // - // Credential is invalid. - // - if (string.Equals(responseString, "FAIL", StringComparison.Ordinal)) + else { - HyperVSocket.Send(response); - - throw new PSDirectException( - PSRemotingErrorInvariants.FormatResourceString(RemotingErrorIdStrings.InvalidCredential)); + this.AuthenticationToken = exchangeResult.authenticationToken; } + } - // - // If PowerShell Direct in VM supports configuration, send configuration name. - // - if (string.Equals(responseString, "CONF", StringComparison.Ordinal)) + if (!isFirstConnection) + { + if (!this.UseBackwardsCompatibleMode) { - if (emptyConfiguration) - { - HyperVSocket.Send("EMPTYCF"u8); - } - else - { - HyperVSocket.Send("NONEMPTYCF"u8); - HyperVSocket.Receive(response); - - byte[] configName = Encoding.Unicode.GetBytes(configurationName); - HyperVSocket.Send(configName); - } + s_tracer.WriteLine("Connect-Server: Performing transport version and token exchange for Hyper-V socket. isFirstConnection: {0}, UseBackwardsCompatibleMode: {1}", isFirstConnection, this.UseBackwardsCompatibleMode); + RemoteSessionHyperVSocketClient.PerformTransportVersionAndTokenExchange(HyperVSocket, this.AuthenticationToken); } else { - HyperVSocket.Send(response); + s_tracer.WriteLine("Connect-Server: Skipping transport version and token exchange for backwards compatible mode."); } } @@ -621,8 +806,7 @@ public bool Connect( } else { - _tracer.WriteMessage("RemoteSessionHyperVSocketClient", "Connect", Guid.Empty, - "Client unable to connect."); + s_tracer.WriteLine("Connect: Client unable to connect."); result = false; } @@ -630,12 +814,318 @@ public bool Connect( return result; } + /// + /// Performs the transport version and token exchange sequence for the Hyper-V socket connection. + /// Throws PSDirectException on failure. + /// + /// The socket to use for communication. + /// The authentication token to send. + public static void PerformTransportVersionAndTokenExchange(Socket socket, string authenticationToken) + { + if (string.IsNullOrEmpty(authenticationToken)) + { + s_tracer.WriteLine("PerformTransportVersionAndTokenExchange: Authentication token is null or empty. Aborting transport version and token exchange."); + throw new PSDirectException( + PSRemotingErrorInvariants.FormatResourceString(RemotingErrorIdStrings.InvalidCredential)); + } + + socket.Send(Encoding.UTF8.GetBytes(VERSION_REQUEST)); + string responseStr = ReceiveResponse(socket, 16); + + // Check if the response starts with the expected version prefix. + // We will rely on the broker to determine if the two can communicate. + // At least, for now. + if (!responseStr.StartsWith(VERSION_PREFIX, StringComparison.Ordinal)) + { + s_tracer.WriteLine("PerformTransportVersionAndTokenExchange: Server responded with an invalid response of {0}. Notifying the transport manager to downgrade if allowed.", responseStr); + throw new PSDirectException( + PSRemotingErrorInvariants.FormatResourceString(RemotingErrorIdStrings.HyperVInvalidResponse, "Server", "TransportVersion")); + } + + socket.Send(Encoding.UTF8.GetBytes(CLIENT_VERSION)); + string response = ReceiveResponse(socket, 4); // either "PASS" or "FAIL" + + if (!string.Equals(response, "PASS", StringComparison.Ordinal)) + { + s_tracer.WriteLine( + "PerformTransportVersionAndTokenExchange: Transport version negotiation with server failed. Response: {0}", response); + throw new PSDirectException( + PSRemotingErrorInvariants.FormatResourceString(RemotingErrorIdStrings.HyperVInvalidResponse, "Server", "TransportVersion")); + } + + byte[] tokenBytes = Encoding.UTF8.GetBytes("TOKEN " + authenticationToken); + socket.Send(tokenBytes); + + // This is the opportunity for the server to tell the client to go away. + string tokenResponse = ReceiveResponse(socket, 256); // either "PASS" or "FAIL", but get a little more buffer to allow for better error in the future + if (!string.Equals(tokenResponse, "PASS", StringComparison.Ordinal)) + { + s_tracer.WriteLine( + "PerformTransportVersionAndTokenExchange: Server Authentication Token exchange failed. Response: {0}", tokenResponse); + throw new PSDirectException( + PSRemotingErrorInvariants.FormatResourceString(RemotingErrorIdStrings.InvalidCredential)); + } + } + + /// + /// Checks if the registry key RequirePsDirectAuthentication is set to 1. + /// Returns true if fallback should be aborted. + /// Uses the 64-bit registry view on 64-bit systems to ensure consistent behavior regardless of process architecture. + /// On 32-bit systems, uses the default registry view since there is no WOW64 redirection. + /// + internal static bool IsRequirePsDirectAuthenticationEnabled(string keyPath, Microsoft.Win32.RegistryHive registryHive) + { + const string regValueName = "RequirePsDirectAuthentication"; + + try + { + Microsoft.Win32.RegistryView registryView = Environment.Is64BitOperatingSystem + ? Microsoft.Win32.RegistryView.Registry64 + : Microsoft.Win32.RegistryView.Default; + + using (Microsoft.Win32.RegistryKey baseKey = Microsoft.Win32.RegistryKey.OpenBaseKey( + registryHive, + registryView)) + { + using (Microsoft.Win32.RegistryKey key = baseKey.OpenSubKey(keyPath)) + { + if (key != null) + { + var value = key.GetValue(regValueName); + if (value is int intValue && intValue != 0) + { + return true; + } + } + + return false; + } + } + } + catch (Exception regEx) + { + s_tracer.WriteLine("IsRequirePsDirectAuthenticationEnabled: Exception while checking registry key: {0}", regEx.Message); + return false; // If we cannot read the registry, assume the feature is not enabled. + } + } + + /// + /// Handles credential and configuration exchange with the VM for the first connection. + /// + public static (bool success, string authenticationToken) ExchangeCredentialsAndConfiguration(NetworkCredential networkCredential, string configurationName, Socket HyperVSocket, bool useBackwardsCompatibleMode) + { + // Encoding for the Hyper-V socket communication + // To send the domain, username, password, and configuration name, use UTF-16 (Encoding.Unicode) + // All other sends use UTF-8 (Encoding.UTF8) + // Receiving uses ASCII encoding + // NOT CONFUSING AT ALL + + if (!useBackwardsCompatibleMode) + { + HyperVSocket.Send(Encoding.UTF8.GetBytes(VERSION_REQUEST)); + // vmicvmsession service in VM will respond with "VERSION_2" or newer + // Version 1 protocol will respond with "PASS" or "FAIL" + // Receive the response and check for VERSION_2 or newer + string responseStr = ReceiveResponse(HyperVSocket, 16); + if (!responseStr.StartsWith(VERSION_PREFIX, StringComparison.Ordinal)) + { + s_tracer.WriteLine("When asking for version the server responded with an invalid response of {0}.", responseStr); + s_tracer.WriteLine("Session is invalid, continuing session with a fake user to close the session with the broker for stability."); + // If not the new protocol, finish the conversation + // Send a fake user + // Use ? <> that are illegal in user names so no one can create the user + string probeUserName = "?"; // must be less than or equal to 20 characters for Windows Server 2016 + s_tracer.WriteLine("probeUserName (static): length: {0}", probeUserName.Length); + SendUserData(probeUserName, HyperVSocket); + responseStr = ReceiveResponse(HyperVSocket, 4); // either "PASS" or "FAIL" + s_tracer.WriteLine("When sending user {0}.", responseStr); + + // Send that the password is empty + HyperVSocket.Send("EMPTYPW"u8); + responseStr = ReceiveResponse(HyperVSocket, 4); // either "CONF", "PASS" or "FAIL" + s_tracer.WriteLine("When sending EMPTYPW: {0}.", responseStr); // server responds with FAIL so we respond with FAIL and the conversation is done + HyperVSocket.Send("FAIL"u8); + + s_tracer.WriteLine("Notifying the transport manager to downgrade if allowed."); + // end new code + return (false, null); + } + + HyperVSocket.Send(Encoding.UTF8.GetBytes(CLIENT_VERSION)); + ReceiveResponse(HyperVSocket, 4); // either "PASS" or "FAIL" + } + + if (string.IsNullOrEmpty(networkCredential.Domain)) + { + networkCredential.Domain = "localhost"; + } + + System.Security.SecureString securePassword = networkCredential.SecurePassword; + int passwordLength = securePassword.Length; + bool emptyPassword = (passwordLength <= 0); + bool emptyConfiguration = string.IsNullOrEmpty(configurationName); + + string responseString; + + // Send credential to VM so that PowerShell process inside VM can be + // created under the correct security context. + SendUserData(networkCredential.Domain, HyperVSocket); + ReceiveResponse(HyperVSocket, 4); // only "PASS" is expected + + SendUserData(networkCredential.UserName, HyperVSocket); + ReceiveResponse(HyperVSocket, 4); // only "PASS" is expected + + // We cannot simply send password because if it is empty, + // the vmicvmsession service in VM will block in recv method. + if (emptyPassword) + { + HyperVSocket.Send("EMPTYPW"u8); + responseString = ReceiveResponse(HyperVSocket, 4); // either "CONF", "PASS" or "FAIL" (note, "PASS" is not used in VERSION_2 or newer mode) + } + else + { + HyperVSocket.Send("NONEMPTYPW"u8); + ReceiveResponse(HyperVSocket, 4); // only "PASS" is expected + + // Get the password bytes from the SecureString, send them, and then zero out the byte array. + byte[] passwordBytes = Microsoft.PowerShell.SecureStringHelper.GetData(securePassword); + try + { + HyperVSocket.Send(passwordBytes); + } + finally + { + // Zero out the byte array for security + Array.Clear(passwordBytes); + } + + responseString = ReceiveResponse(HyperVSocket, 4); // either "CONF", "PASS" or "FAIL" (note, "PASS" is not used in VERSION_2 or newer mode) + } + + // Check for invalid response from server + if (!string.Equals(responseString, "FAIL", StringComparison.Ordinal) && + !string.Equals(responseString, "PASS", StringComparison.Ordinal) && + !string.Equals(responseString, "CONF", StringComparison.Ordinal)) + { + s_tracer.WriteLine("ExchangeCredentialsAndConfiguration: Server responded with an invalid response of {0} for credentials.", responseString); + throw new PSDirectException( + PSRemotingErrorInvariants.FormatResourceString(RemotingErrorIdStrings.HyperVInvalidResponse, "Broker", "Credential")); + } + + // Credential is invalid. + if (string.Equals(responseString, "FAIL", StringComparison.Ordinal)) + { + HyperVSocket.Send("FAIL"u8); + // should we be doing this? Disabling the test for now + // HyperVSocket.Shutdown(SocketShutdown.Both); + s_tracer.WriteLine("ExchangeCredentialsAndConfiguration: Server responded with FAIL for credentials."); + throw new PSDirectException( + PSRemotingErrorInvariants.FormatResourceString(RemotingErrorIdStrings.InvalidCredential)); + } + + // If PowerShell Direct in VM supports configuration, send configuration name. + if (string.Equals(responseString, "CONF", StringComparison.Ordinal)) + { + if (emptyConfiguration) + { + HyperVSocket.Send("EMPTYCF"u8); + } + else + { + HyperVSocket.Send("NONEMPTYCF"u8); + ReceiveResponse(HyperVSocket, 4); // only "PASS" is expected + + SendUserData(configurationName, HyperVSocket); + } + } + else + { + HyperVSocket.Send("PASS"u8); + } + + if (!useBackwardsCompatibleMode) + { + // Receive the token from the server + // Getting 1024 bytes because it is well above the expected token size + // The expected size at the time of writing this would be about 50 based64 characters, + // plus the 6 characters for the "TOKEN " prefix. + // The 50 character size is designed to last 10 years of cryptographic changes. + // Since the broker completely controls the cryptographic portion here, + // allowing a significant larger size, allows the broker to make almost arbitrary changes, + // without breaking the client. + string token = ReceiveResponse(HyperVSocket, 1024); // either "PASS" or "FAIL" + if (token == null || !token.StartsWith("TOKEN ", StringComparison.Ordinal)) + { + s_tracer.WriteLine("ExchangeCredentialsAndConfiguration: Server did not respond with a valid token. Response: {0}", token); + throw new PSDirectException( + PSRemotingErrorInvariants.FormatResourceString(RemotingErrorIdStrings.HyperVInvalidResponse, "Broker", "Token " + token)); + } + + token = token.Substring(6); // remove "TOKEN " prefix + + HyperVSocket.Send("PASS"u8); // acknowledge the token + return (true, token); + } + + return (true, null); + } + public void Close() { Stream.Dispose(); HyperVSocket.Dispose(); } + /// + /// Receives a response from the socket and decodes it. + /// + /// The socket to receive from. + /// The size of the buffer to use for receiving data. + /// The decoded response string. + internal static string ReceiveResponse(Socket socket, int bufferSize) + { + System.Buffers.ArrayPool pool = System.Buffers.ArrayPool.Shared; + byte[] responseBuffer = pool.Rent(bufferSize); + int bytesReceived = 0; + try + { + bytesReceived = socket.Receive(responseBuffer); + if (bytesReceived == 0) + { + return null; + } + + string response = Encoding.ASCII.GetString(responseBuffer, 0, bytesReceived); + + // Handle null terminators and log if found + if (response.EndsWith('\0')) + { + int originalLength = response.Length; + response = response.TrimEnd('\0'); + // Cannot log actual response, because we don't know if it is sensitive + s_tracer.WriteLine( + "ReceiveResponse: Removed null terminator(s). Original length: {0}, New length: {1}", + originalLength, + response.Length); + } + + return response; + } + finally + { + pool.Return(responseBuffer); + } + } + + /// + /// Sends user data (domain, username, etc.) over the HyperVSocket using Unicode encoding. + /// + private static void SendUserData(string data, Socket socket) + { + // this encodes the data in UTF-16 (Unicode) + byte[] buffer = Encoding.Unicode.GetBytes(data); + socket.Send(buffer); + } #endregion } } diff --git a/src/System.Management.Automation/engine/remoting/fanin/OutOfProcTransportManager.cs b/src/System.Management.Automation/engine/remoting/fanin/OutOfProcTransportManager.cs index 96a8b833885..d9532c8691a 100644 --- a/src/System.Management.Automation/engine/remoting/fanin/OutOfProcTransportManager.cs +++ b/src/System.Management.Automation/engine/remoting/fanin/OutOfProcTransportManager.cs @@ -1014,7 +1014,7 @@ internal void OnCloseTimeOutTimerElapsed(object source) } #endregion - + #region Protected Methods /// @@ -1544,8 +1544,9 @@ internal VMHyperVSocketClientSessionTransportManager( /// public override void CreateAsync() { - _client = new RemoteSessionHyperVSocketClient(_vmGuid, true); - if (!_client.Connect(_networkCredential, _configurationName, true)) + // isFirstConnection: true - specifies to use VM_SESSION_SERVICE_ID socket. + _client = new RemoteSessionHyperVSocketClient(_vmGuid, useBackwardsCompatibleMode: false, isFirstConnection: true); + if (!_client.Connect(_networkCredential, _configurationName, isFirstConnection: true)) { _client.Dispose(); throw new PSInvalidOperationException( @@ -1555,11 +1556,14 @@ public override void CreateAsync() ErrorCategory.InvalidOperation, null); } + bool useBackwardsCompatibleMode = _client.UseBackwardsCompatibleMode; + string token = _client.AuthenticationToken; - // TODO: remove below 3 lines when Hyper-V socket duplication is supported in .NET framework. _client.Dispose(); - _client = new RemoteSessionHyperVSocketClient(_vmGuid, false); - if (!_client.Connect(_networkCredential, _configurationName, false)) + + // isFirstConnection: false - specifies to use the SESSION_SERVICE_ID_2 socket. + _client = new RemoteSessionHyperVSocketClient(_vmGuid, useBackwardsCompatibleMode: useBackwardsCompatibleMode, isFirstConnection: false, authenticationToken: token); + if (!_client.Connect(_networkCredential, _configurationName, isFirstConnection: false)) { _client.Dispose(); throw new PSInvalidOperationException( @@ -1617,7 +1621,9 @@ internal ContainerHyperVSocketClientSessionTransportManager( /// public override void CreateAsync() { - _client = new RemoteSessionHyperVSocketClient(_targetGuid, false, true); + // Container scenario is not working. + // When we fix it we need to setup the token in ContainerConnectionInfo and use it here. + _client = new RemoteSessionHyperVSocketClient(_targetGuid, isFirstConnection: false, useBackwardsCompatibleMode: false, isContainer: true); if (!_client.Connect(null, string.Empty, false)) { _client.Dispose(); @@ -1716,7 +1722,7 @@ public override void CreateAsync() // Start connection timeout timer if requested. // Timer callback occurs only once after timeout time. _connectionTimer = new Timer( - callback: (_) => + callback: (_) => { if (_connectionEstablished) { @@ -2505,7 +2511,7 @@ internal OutOfProcessServerSessionTransportManager(OutOfProcessTextWriter outWri _stdErrWriter = errWriter; _cmdTransportManagers = new Dictionary(); - this.WSManTransportErrorOccured += (object sender, TransportErrorOccuredEventArgs e) => + this.WSManTransportErrorOccured += (object sender, TransportErrorOccuredEventArgs e) => { string msg = e.Exception.TransportMessage ?? e.Exception.InnerException?.Message ?? string.Empty; _stdErrWriter.WriteLine(StringUtil.Format(RemotingErrorIdStrings.RemoteTransportError, msg)); diff --git a/src/System.Management.Automation/engine/remoting/server/OutOfProcServerMediator.cs b/src/System.Management.Automation/engine/remoting/server/OutOfProcServerMediator.cs index 14b0240858b..6c794e21b24 100644 --- a/src/System.Management.Automation/engine/remoting/server/OutOfProcServerMediator.cs +++ b/src/System.Management.Automation/engine/remoting/server/OutOfProcServerMediator.cs @@ -635,6 +635,16 @@ private HyperVSocketMediator() originalStdErr = new HyperVSocketErrorTextWriter(_hypervSocketServer.TextWriter); } + private HyperVSocketMediator(string token, + DateTimeOffset tokenCreationTime) + : base(false) + { + _hypervSocketServer = new RemoteSessionHyperVSocketServer(false, token: token, tokenCreationTime: tokenCreationTime); + + originalStdIn = _hypervSocketServer.TextReader; + originalStdOut = new OutOfProcessTextWriter(_hypervSocketServer.TextWriter); + originalStdErr = new HyperVSocketErrorTextWriter(_hypervSocketServer.TextWriter); + } #endregion #region Static Methods @@ -656,6 +666,24 @@ internal static void Run( configurationFile: null); } + internal static void Run( + string initialCommand, + string configurationName, + string token, + DateTimeOffset tokenCreationTime) + { + lock (SyncObject) + { + s_instance = new HyperVSocketMediator(token, tokenCreationTime); + } + + s_instance.Start( + initialCommand: initialCommand, + cryptoHelper: new PSRemotingCryptoHelperServer(), + workingDirectory: null, + configurationName: configurationName, + configurationFile: null); + } #endregion } diff --git a/src/System.Management.Automation/resources/RemotingErrorIdStrings.resx b/src/System.Management.Automation/resources/RemotingErrorIdStrings.resx index da56deb4598..05f12b0c29b 100644 --- a/src/System.Management.Automation/resources/RemotingErrorIdStrings.resx +++ b/src/System.Management.Automation/resources/RemotingErrorIdStrings.resx @@ -1723,4 +1723,10 @@ SSH client process terminated before connection could be established. Failed to get Hyper-V VM State. The value was of the type {0} but was expected to be Microsoft.HyperV.PowerShell.VMState or System.String. + + Hyper-V {0} sent an invalid {1} response during the connection negotiation. + + + Negotiating a secure connection to Hyper-V failed. Make sure the Host and Guest are updated with all relevant Microsoft Updates. + diff --git a/test/xUnit/csharp/test_CommandLineParser.cs b/test/xUnit/csharp/test_CommandLineParser.cs index 5025584d6ac..01f572d230d 100644 --- a/test/xUnit/csharp/test_CommandLineParser.cs +++ b/test/xUnit/csharp/test_CommandLineParser.cs @@ -48,6 +48,9 @@ public static void TestDefaults() Assert.False(cpp.ShowVersion); Assert.False(cpp.SkipProfiles); Assert.False(cpp.SocketServerMode); +#if !UNIX + Assert.False(cpp.V2SocketServerMode); +#endif Assert.False(cpp.SSHServerMode); if (Platform.IsWindows) { @@ -336,6 +339,25 @@ public static void TestParameter_SocketServerMode(params string[] commandLine) Assert.Null(cpp.ErrorMessage); } +#if !UNIX + [Theory] + [InlineData("-v2socketservermode", "-token", "natoheusatoehusnatoeu", "-utctimestamp", "2023-10-01T12:00:00Z")] + [InlineData("-v2so", "-token", "asentuhasoneuthsaoe", "-utctimestamp", "2025-06-09T12:00:00Z")] + public static void TestParameter_V2SocketServerMode(params string[] commandLine) + { + var cpp = new CommandLineParameterParser(); + + cpp.Parse(commandLine); + + Assert.False(cpp.AbortStartup); + Assert.True(cpp.NoExit); + Assert.False(cpp.ShowShortHelp); + Assert.False(cpp.ShowBanner); + Assert.True(cpp.V2SocketServerMode); + Assert.Null(cpp.ErrorMessage); + } +#endif + [Theory] [InlineData("-servermode")] [InlineData("-s")] diff --git a/test/xUnit/csharp/test_RemoteHyperV.cs b/test/xUnit/csharp/test_RemoteHyperV.cs new file mode 100644 index 00000000000..f694f6894df --- /dev/null +++ b/test/xUnit/csharp/test_RemoteHyperV.cs @@ -0,0 +1,661 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +using System; +using System.Collections.Generic; +using System.Management.Automation.Language; +using System.Management.Automation.Subsystem; +using System.Management.Automation.Subsystem.Prediction; +using System.Threading; +using System.Net; +using System.Net.Sockets; +using System.Text; +using System.Reflection; +using System.Threading.Tasks; +using Xunit; +using Xunit.Abstractions; + +namespace PSTests.Sequential +{ + public class RemoteHyperVTests + { + private static ITestOutputHelper _output; + private static TimeSpan timeout = TimeSpan.FromSeconds(15); + + public RemoteHyperVTests(ITestOutputHelper output) + { + if (!System.Management.Automation.Platform.IsWindows) + { + throw new SkipException("RemoteHyperVTests are only supported on Windows."); + } + + _output = output; + } + + // Helper method to connect with retries + private static void ConnectWithRetry(Socket client, IPAddress address, int port, ITestOutputHelper output, int maxRetries = 10) + { + int retryDelayMs = 500; + int attempt = 0; + bool connected = false; + while (attempt < maxRetries && !connected) + { + try + { + client.Connect(address, port); + connected = true; + } + catch (SocketException) + { + attempt++; + if (attempt < maxRetries) + { + output?.WriteLine($"Connect attempt {attempt} failed, retrying in {retryDelayMs}ms..."); + Thread.Sleep(retryDelayMs); + retryDelayMs *= 2; + } + else + { + output?.WriteLine($"Failed to connect after {maxRetries} attempts. This is most likely an intermittent failure due to environmental issues."); + throw; + } + } + } + } + + private static void StartHandshakeServer( + string name, + int port, + IEnumerable<(string message, + Encoding encoding)> expectedClientSends, + IEnumerable<(string message, Encoding encoding)> serverResponses, + bool verifyConnectionClosed, + CancellationToken cancellationToken, + bool sendFirst = false) + { + var expectedMessages = new Queue<(string message, byte[] bytes, Encoding encoding)>(); + foreach (var item in expectedClientSends) + { + var itemBytes = item.encoding.GetBytes(item.message); + expectedMessages.Enqueue((message: item.message, bytes: itemBytes, encoding: item.encoding)); + } + + var serverResponseBytes = new Queue(); + foreach (var item in serverResponses) + { + serverResponseBytes.Enqueue(item.encoding.GetBytes(item.message)); + } + + StartHandshakeServer(name, port, expectedMessages, serverResponseBytes, verifyConnectionClosed, cancellationToken, sendFirst); + } + + private static void StartHandshakeServer(string name, int port, Queue<(string message, byte[] bytes, Encoding encoding)> expectedClientSends, Queue serverResponses, bool verifyConnectionClosed, CancellationToken cancellationToken, bool sendFirst = false) + { + var buffer = new byte[1024]; + var listener = new TcpListener(IPAddress.Loopback, port); + listener.Start(); + try + { + using (var client = listener.AcceptSocket()) + { + if (sendFirst) + { + // Send the first message from the serverResponses queue + if (serverResponses.Count > 0) + { + var resp = serverResponses.Dequeue(); + client.Send(resp, resp.Length, SocketFlags.None); + _output.WriteLine($"Mock {name} - sent response: " + Encoding.ASCII.GetString(resp)); + } + } + + while (expectedClientSends.Count > 0) + { + client.ReceiveTimeout = 2 * 1000; // 2 seconds timeout for receiving data + cancellationToken.ThrowIfCancellationRequested(); + var expectedMessage = expectedClientSends.Dequeue(); + var expected = expectedMessage.bytes; + Array.Clear(buffer, 0, buffer.Length); + int received = client.Receive(buffer); + // Optionally validate received data matches expected + string expectedString = expectedMessage.message; + string bufferString = expectedMessage.encoding.GetString(buffer, 0, received); + string alternativeEncodedString = string.Empty; + if (expectedMessage.encoding == Encoding.Unicode) + { + alternativeEncodedString = Encoding.UTF8.GetString(buffer, 0, received); + } + else if (expectedMessage.encoding == Encoding.UTF8) + { + alternativeEncodedString = Encoding.Unicode.GetString(buffer, 0, received); + } + + if (received != expected.Length) + { + string errorMessage = $"Mock {name} - Expected {expected.Length} bytes, but received {received} bytes: `{bufferString}`(alt encoding: `{alternativeEncodedString}`); expected: {expectedString}"; + _output.WriteLine(errorMessage); + throw new Exception(errorMessage); + } + if (!string.Equals(bufferString, expectedString, StringComparison.OrdinalIgnoreCase)) + { + string errorMessage = $"Mock {name} - Expected `{expectedString}`; length {expected.Length}, but received; length {received}; `{bufferString}`(alt encoding: `{alternativeEncodedString}`) instead."; + _output.WriteLine(errorMessage); + throw new Exception(errorMessage); + } + _output.WriteLine($"Mock {name} - received expected message: " + expectedString); + if (serverResponses.Count > 0) + { + var resp = serverResponses.Dequeue(); + client.Send(resp, resp.Length, SocketFlags.None); + _output.WriteLine($"Mock {name} - sent response: " + Encoding.ASCII.GetString(resp)); + } + } + + if (verifyConnectionClosed) + { + _output.WriteLine($"Mock {name} - verifying client connection is closed."); + // Wait for the client to close the connection synchronously (no timeout) + try + { + while (true) + { + int bytesRead = client.Receive(buffer, SocketFlags.None); + if (bytesRead == 0) + { + break; + } + + // If we receive any data, log and throw (assume UTF8 encoding) + string unexpectedData = Encoding.UTF8.GetString(buffer, 0, bytesRead); + _output.WriteLine($"Mock {name} - received unexpected data after handshake: {unexpectedData}"); + throw new Exception($"Mock {name} - received unexpected data after handshake: {unexpectedData}"); + } + _output.WriteLine($"Mock {name} - client closed the connection."); + } + catch (SocketException ex) + { + _output.WriteLine($"Mock {name} - socket exception while waiting for client close: {ex.Message} {ex.GetType().FullName}"); + } + catch (ObjectDisposedException) + { + // Socket already closed + } + } + } + + _output.WriteLine($"Mock {name} - on port {port} completed successfully."); + } + finally + { + listener.Stop(); + } + } + + // Helper function to create a random 4-character ASCII response + private static string CreateRandomAsciiResponse() + { + var rand = new Random(); + // Randomly return either "PASS" or "FAIL" + return rand.Next(0, 2) == 0 ? "PASS" : "FAIL"; + } + + // Helper method to create test data + private static (List<(string, Encoding)> expectedClientSends, List<(string, Encoding)> serverResponses) CreateHandshakeTestData(NetworkCredential cred) + { + var expectedClientSends = new List<(string message, Encoding encoding)> + { + (message: cred.Domain, encoding: Encoding.Unicode), + (message: cred.UserName, encoding: Encoding.Unicode), + (message: "NONEMPTYPW", encoding: Encoding.ASCII), + (message: cred.Password, encoding: Encoding.Unicode) + }; + + var serverResponses = new List<(string message, Encoding encoding)> + { + (message: CreateRandomAsciiResponse(), encoding: Encoding.ASCII), // Response to domain + (message: CreateRandomAsciiResponse(), encoding: Encoding.ASCII), // Response to username + (message: CreateRandomAsciiResponse(), encoding: Encoding.ASCII) // Response to non-empty password + }; + + return (expectedClientSends, serverResponses); + } + + private static List<(string message, Encoding encoding)> CreateVersionNegotiationClientSends() + { + return new List<(string message, Encoding encoding)> + { + (message: "VERSION", encoding: Encoding.UTF8), + (message: "VERSION_2", encoding: Encoding.UTF8), + }; + } + + private static List<(string, Encoding)> CreateV2Sends(NetworkCredential cred, string configurationName) + { + var sends = CreateVersionNegotiationClientSends(); + var password = cred.Password; + var emptyPassword = string.IsNullOrEmpty(password); + + sends.AddRange(new List<(string message, Encoding encoding)> + { + (message: cred.Domain, encoding: Encoding.Unicode), + (message: cred.UserName, encoding: Encoding.Unicode) + }); + + if (!emptyPassword) + { + sends.AddRange(new List<(string message, Encoding encoding)> + { + (message: "NONEMPTYPW", encoding: Encoding.UTF8), + (message: cred.Password, encoding: Encoding.Unicode) + }); + } + else + { + sends.Add((message: "EMPTYPW", encoding: Encoding.UTF8)); // Empty password and we don't expect a response + } + + if (!string.IsNullOrEmpty(configurationName)) + { + sends.Add((message: "NONEMPTYCF", encoding: Encoding.UTF8)); + sends.Add((message: configurationName, encoding: Encoding.Unicode)); // Configuration string and we don't expect a response + } + else + { + sends.Add((message: "EMPTYCF", encoding: Encoding.UTF8)); // Configuration string and we don't expect a response + } + + sends.Add((message: "PASS", encoding: Encoding.ASCII)); // Response to TOKEN + + return sends; + } + + private static List<(string, Encoding)> CreateV2Responses(string version = "VERSION_2", bool emptyConfig = false, string token = "FakeToken0+/=", bool emptyPassword = false) + { + var responses = new List<(string message, Encoding encoding)> + { + (message: version, encoding: Encoding.ASCII), // Response to VERSION + (message: "PASS", encoding: Encoding.ASCII), // Response to VERSION_2 + (message: "PASS", encoding: Encoding.ASCII), // Response to domain + (message: "PASS", encoding: Encoding.ASCII), // Response to username + }; + + if (!emptyPassword) + { + responses.Add((message: "PASS", encoding: Encoding.ASCII)); // Response to non-empty password + } + + responses.Add((message: "CONF", encoding: Encoding.ASCII)); // Response to configuration + + if (!emptyConfig) + { + responses.Add((message: "PASS", encoding: Encoding.ASCII)); // Response to non-empty configuration + } + responses.Add((message: "TOKEN " + token, encoding: Encoding.ASCII)); // Response to with a token than uses each class of character in base 64 encoding + + return responses; + } + + // Helper method to create test data + private static (List<(string, Encoding)> expectedClientSends, List<(string, Encoding)> serverResponses) + CreateHandshakeTestDataV2(NetworkCredential cred, string version, string configurationName, string token) + { + bool emptyConfig = string.IsNullOrEmpty(configurationName); + bool emptyPassword = string.IsNullOrEmpty(cred.Password); + return (CreateV2Sends(cred, configurationName), CreateV2Responses(version, emptyConfig, token, emptyPassword)); + } + + // Helper method to create test data + private static (List<(string, Encoding)> expectedClientSends, List<(string, Encoding)> serverResponses) CreateHandshakeTestDataForFallback(NetworkCredential cred) + { + var expectedClientSends = new List<(string message, Encoding encoding)> + { + (message: "VERSION", encoding: Encoding.UTF8), + (message: @"?", encoding: Encoding.Unicode), + (message: "EMPTYPW", encoding: Encoding.UTF8), // Response to domain + (message: "FAIL", encoding: Encoding.UTF8), // Response to domain + }; + + List<(string message, Encoding encoding)> serverResponses = new List<(string message, Encoding encoding)> + { + (message: "PASS", encoding: Encoding.ASCII), // Response to VERSION but v1 server expects domain so it says "PASS" + (message: "PASS", encoding: Encoding.ASCII), // Response to username + (message: "FAIL", encoding: Encoding.ASCII) // Response to EMPTYPW + }; + + return (expectedClientSends, serverResponses); + } + + // Helper to create a password with at least one non-ASCII Unicode character + public static string CreateRandomUnicodePassword(string prefix) + { + var rand = new Random(); + var asciiPart = new char[6 + prefix.Length]; + // Copy prefix into asciiPart + Array.Copy(prefix.ToCharArray(), 0, asciiPart, 0, prefix.Length); + for (int i = prefix.Length; i < asciiPart.Length; i++) + { + asciiPart[i] = (char)rand.Next(33, 127); // ASCII printable + } + // Add a random Unicode character outside ASCII range (e.g., U+0100 to U+017F) + char unicodeChar = (char)rand.Next(0x0100, 0x017F); + // Insert the unicode character at a random position + int insertPos = rand.Next(0, asciiPart.Length + 1); + var passwordChars = new List(asciiPart); + passwordChars.Insert(insertPos, unicodeChar); + return new string(passwordChars.ToArray()); + } + + public static NetworkCredential CreateTestCredential() + { + return new NetworkCredential(CreateRandomUnicodePassword("username"), CreateRandomUnicodePassword("password"), CreateRandomUnicodePassword("domain")); + } + + [SkippableFact] + public async Task PerformCredentialAndConfigurationHandshake_V1_Pass() + { + // Arrange + int port = 50000 + (int)(DateTime.Now.Ticks % 10000); + var cred = CreateTestCredential(); + string configurationName = CreateRandomUnicodePassword("config"); + + var (expectedClientSends, serverResponses) = CreateHandshakeTestData(cred); + expectedClientSends.Add(("PASS", Encoding.ASCII)); + serverResponses.Add(("PASS", Encoding.ASCII)); + + using var cts = new CancellationTokenSource(TimeSpan.FromMinutes(1)); + var serverTask = Task.Run(() => StartHandshakeServer("Broker", port, expectedClientSends, serverResponses, verifyConnectionClosed: false, cts.Token), cts.Token); + + using (var client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)) + { + ConnectWithRetry(client, IPAddress.Loopback, port, _output); + var exchangeResult = System.Management.Automation.Remoting.RemoteSessionHyperVSocketClient.ExchangeCredentialsAndConfiguration(cred, configurationName, client, true); + var result = exchangeResult.success; + _output.WriteLine($"Exchange result: {result}, Token: {exchangeResult.authenticationToken}"); + System.Threading.Thread.Sleep(100); // Allow time for server to process + Assert.True(result, $"Expected Exchange to pass"); + } + + await serverTask; + } + + [SkippableTheory] + [InlineData("VERSION_2", "configurationname1", "FakeTokenaaaaaaaaaAAAAAAAAAAAAAAAAAAAAAA0FakeTokenaaaaaaaaaAAAAAAAAAAAAAAAAAAAAAA0+/==")] // a fake base64 token about 512 bits long (double the size when this was spec'ed) + [InlineData("VERSION_10", null, "FakeTokenaaaaaaaaaAAAAAAAAAAAAAAAAAAAAAA0+/=")] // a fake base64 token about 256 bits Long (the size when this was spec'ed) + public async Task PerformCredentialAndConfigurationHandshake_V2_Pass(string versionResponse, string configurationName, string token) + { + // Arrange + int port = 50000 + (int)(DateTime.Now.Ticks % 10000); + var cred = CreateTestCredential(); + + var (expectedClientSends, serverResponses) = CreateHandshakeTestDataV2(cred, versionResponse, configurationName, token); + + using var cts = new CancellationTokenSource(TimeSpan.FromMinutes(1)); + var serverTask = Task.Run(() => StartHandshakeServer("Broker", port, expectedClientSends, serverResponses, verifyConnectionClosed: true, cts.Token), cts.Token); + + using (var client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)) + { + client.Connect(IPAddress.Loopback, port); + var exchangeResult = System.Management.Automation.Remoting.RemoteSessionHyperVSocketClient.ExchangeCredentialsAndConfiguration(cred, configurationName, client, false); + var result = exchangeResult.success; + System.Threading.Thread.Sleep(100); // Allow time for server to process + Assert.True(result, $"Expected Exchange to pass for version response '{versionResponse}'"); + Assert.Equal(token, exchangeResult.authenticationToken); + } + + await serverTask; + } + + [SkippableFact] + public async Task PerformCredentialAndConfigurationHandshake_V1_Fallback() + { + // Arrange + int port = 50000 + (int)(DateTime.Now.Ticks % 10000); + var cred = CreateTestCredential(); + string configurationName = CreateRandomUnicodePassword("config"); + + var (expectedClientSends, serverResponses) = CreateHandshakeTestDataForFallback(cred); + + using var cts = new CancellationTokenSource(TimeSpan.FromMinutes(1)); + var serverTask = Task.Run(() => StartHandshakeServer("Broker", port, expectedClientSends, serverResponses, verifyConnectionClosed: false, cts.Token), cts.Token); + + bool isFallback = false; + using (var client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)) + { + _output.WriteLine("Starting handshake with V2 protocol."); + client.Connect(IPAddress.Loopback, port); + var exchangeResult = System.Management.Automation.Remoting.RemoteSessionHyperVSocketClient.ExchangeCredentialsAndConfiguration(cred, configurationName, client, false); + isFallback = !exchangeResult.success; + + System.Threading.Thread.Sleep(100); // Allow time for server to process + _output.WriteLine("Handshake indicated fallback to V1."); + Assert.True(isFallback, "Expected fallback to V1."); + } + _output.WriteLine("Handshake completed successfully with fallback to V1."); + + await serverTask; + } + + [SkippableFact] + public async Task PerformCredentialAndConfigurationHandshake_V2_InvalidResponse() + { + // Arrange + int port = 51000 + (int)(DateTime.Now.Ticks % 10000); + var cred = CreateTestCredential(); + + var (expectedClientSends, serverResponses) = CreateHandshakeTestData(cred); + //expectedClientSends.Add("FAI1"); + serverResponses.Add(("FAI1", Encoding.ASCII)); + + using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(30)); + + //cts.Token.Register(() => throw new OperationCanceledException("Test timed out.")); + + var serverTask = Task.Run(() => StartHandshakeServer("Broker", port, expectedClientSends, serverResponses, verifyConnectionClosed: false, cts.Token), cts.Token); + + using (var client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)) + { + _output.WriteLine("connecting on port " + port); + ConnectWithRetry(client, IPAddress.Loopback, port, _output); + + var ex = Record.Exception(() => System.Management.Automation.Remoting.RemoteSessionHyperVSocketClient.ExchangeCredentialsAndConfiguration(cred, "config", client, true)); + + try + { + await serverTask; + } + catch (AggregateException exAgg) + { + Assert.Null(exAgg.Flatten().InnerExceptions[1].Message); + } + cts.Token.ThrowIfCancellationRequested(); + + Assert.NotNull(ex); + Assert.NotNull(ex.Message); + Assert.Contains("Hyper-V Broker sent an invalid Credential response", ex.Message); + } + } + + [SkippableFact] + public async Task PerformCredentialAndConfigurationHandshake_V1_Fail() + { + // Arrange + int port = 51000 + (int)(DateTime.Now.Ticks % 10000); + var cred = CreateTestCredential(); + + var (expectedClientSends, serverResponses) = CreateHandshakeTestData(cred); + expectedClientSends.Add(("FAIL", Encoding.ASCII)); + serverResponses.Add(("FAIL", Encoding.ASCII)); + + using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(15)); + + // This scenario does not close the connection in a timely manner, so we set verifyConnectionClosed to false + var serverTask = Task.Run(() => StartHandshakeServer("Broker", port, expectedClientSends, serverResponses, verifyConnectionClosed: false, cts.Token), cts.Token); + + using (var client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)) + { + client.Connect(IPAddress.Loopback, port); + + var ex = Record.Exception(() => System.Management.Automation.Remoting.RemoteSessionHyperVSocketClient.ExchangeCredentialsAndConfiguration(cred, "config", client, true)); + + try + { + await serverTask; + } + catch (AggregateException exAgg) + { + Assert.Null(exAgg.Flatten().InnerExceptions[1].Message); + } + + cts.Token.ThrowIfCancellationRequested(); + + Assert.NotNull(ex); + Assert.NotNull(ex.Message); + Assert.Contains("The credential is invalid.", ex.Message); + } + } + + [SkippableTheory] + [InlineData("VERSION_2", "FakeTokenaaaaaaaaaAAAAAAAAAAAAAAAAAAAAAA0FakeTokenaaaaaaaaaAAAAAAAAAAAAAAAAAAAAAA0+/==")] // a fake base64 token about 512 bits long (double the size when this was spec'ed) + [InlineData("VERSION_10", "FakeTokenaaaaaaaaaAAAAAAAAAAAAAAAAAAAAAA0+/=")] // a fake base64 token about 256 bits Long (the size when this was spec'ed) + public async Task PerformTransportVersionAndTokenExchange_Pass(string version, string token) + { + // Arrange + int port = 50000 + (int)(DateTime.Now.Ticks % 10000); + var cred = CreateTestCredential(); + + var expectedClientSends = CreateVersionNegotiationClientSends(); + expectedClientSends.Add((message: "TOKEN " + token, encoding: Encoding.ASCII)); + + var serverResponses = new List<(string message, Encoding encoding)>{ + (message: version, encoding: Encoding.ASCII), // Response to VERSION + (message: "PASS", encoding: Encoding.ASCII), // Response to VERSION_2 + (message: "PASS", encoding: Encoding.ASCII) // Response to token + }; + + using var cts = new CancellationTokenSource(TimeSpan.FromMinutes(1)); + var serverTask = Task.Run(() => StartHandshakeServer("Server", port, expectedClientSends, serverResponses, verifyConnectionClosed: true, cts.Token), cts.Token); + + using (var client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)) + { + ConnectWithRetry(client, IPAddress.Loopback, port, _output); + System.Management.Automation.Remoting.RemoteSessionHyperVSocketClient.PerformTransportVersionAndTokenExchange(client, token); + System.Threading.Thread.Sleep(100); // Allow time for server to process + } + + await serverTask; + } + + [SkippableTheory] + [InlineData(1, true)] + [InlineData(2, true)] + [InlineData(0, false)] + [InlineData(null, false)] + [System.Runtime.Versioning.SupportedOSPlatform("windows")] + public void IsRequirePsDirectAuthenticationEnabled(int? regValue, bool expected) + { + const string testKeyPath = @"SOFTWARE\Microsoft\TestRequirePsDirectAuthentication"; + const string valueName = "RequirePsDirectAuthentication"; + if (!System.Management.Automation.Platform.IsWindows) + { + throw new SkipException("RemoteHyperVTests are only supported on Windows."); + } + + // Clean up any previous test key + var regHive = Microsoft.Win32.RegistryHive.CurrentUser; + var baseKey = Microsoft.Win32.RegistryKey.OpenBaseKey(regHive, Microsoft.Win32.RegistryView.Registry64); + baseKey.DeleteSubKeyTree(testKeyPath, false); + + bool? result = null; + + // Create the test key + using (var key = baseKey.CreateSubKey(testKeyPath)) + { + if (regValue.HasValue) + { + key.SetValue(valueName, regValue.Value, Microsoft.Win32.RegistryValueKind.DWord); + } + else + { + // Ensure the value does not exist + key.DeleteValue(valueName, false); + } + + result = System.Management.Automation.Remoting.RemoteSessionHyperVSocketClient.IsRequirePsDirectAuthenticationEnabled(testKeyPath, regHive); + } + + Assert.True(result.HasValue, "IsRequirePsDirectAuthenticationEnabled should return a value."); + Assert.True(expected == result.Value, + $"Expected IsRequirePsDirectAuthenticationEnabled to return {expected} when registry value is {(regValue.HasValue ? regValue.ToString() : "not set")}."); + + return; + } + + [SkippableTheory] + [InlineData("testToken", "testToken")] + [InlineData("testToken\0", "testToken")] + public async Task ValidatePassesWhenTokensMatch(string token, string expectedToken) + { + int port = 50000 + (int)(DateTime.Now.Ticks % 10000); + + var expectedClientSends = new List<(string message, Encoding encoding)>{ + (message: "VERSION", encoding: Encoding.ASCII), // Response to VERSION + (message: "VERSION_2", encoding: Encoding.ASCII), // Response to VERSION_2 + (message: $"TOKEN {token}", encoding: Encoding.ASCII) + }; + + var serverResponses = new List<(string message, Encoding encoding)>{ + (message: "VERSION_2", encoding: Encoding.ASCII), // Response to VERSION_2 + (message: "PASS", encoding: Encoding.ASCII), // Response to VERSION_2 + (message: "PASS", encoding: Encoding.ASCII) // Response to token + }; + + using var cts = new CancellationTokenSource(TimeSpan.FromMinutes(1)); + var serverTask = Task.Run(() => StartHandshakeServer("Client", port, serverResponses, expectedClientSends, verifyConnectionClosed: true, cts.Token, sendFirst: true), cts.Token); + + using (var client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)) + { + ConnectWithRetry(client, IPAddress.Loopback, port, _output); + System.Management.Automation.Remoting.RemoteSessionHyperVSocketServer.ValidateToken(client, expectedToken); + System.Threading.Thread.Sleep(100); // Allow time for server to process + } + + await serverTask; + } + + [SkippableTheory] + [InlineData("abc", "xyz")] + [InlineData("abc", "abcdef")] + [InlineData("abcdef", "abc")] + [InlineData("abc\0def", "abc")] + public async Task ValidateFailsWhenTokensMismatch(string token, string expectedToken) + { + int port = 50000 + (int)(DateTime.Now.Ticks % 10000); + + var expectedClientSends = new List<(string message, Encoding encoding)>{ + (message: "VERSION", encoding: Encoding.ASCII), // Initial request + (message: "VERSION_2", encoding: Encoding.ASCII), // Response to VERSION_2 + (message: $"TOKEN {token}", encoding: Encoding.ASCII) + }; + + var serverResponses = new List<(string message, Encoding encoding)>{ + (message: "VERSION_2", encoding: Encoding.ASCII), // Response to VERSION + (message: "PASS", encoding: Encoding.ASCII), // Response to VERSION_2 + (message: "FAIL", encoding: Encoding.ASCII) // Response to token + }; + + using var cts = new CancellationTokenSource(TimeSpan.FromMinutes(1)); + var serverTask = Task.Run(() => StartHandshakeServer("Client", port, serverResponses, expectedClientSends, verifyConnectionClosed: true, cts.Token, sendFirst: true), cts.Token); + + using (var client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)) + { + ConnectWithRetry(client, IPAddress.Loopback, port, _output); + var exception = Assert.Throws( + () => System.Management.Automation.Remoting.RemoteSessionHyperVSocketServer.ValidateToken(client, expectedToken)); + System.Threading.Thread.Sleep(100); // Allow time for server to process + Assert.Contains("The credential is invalid.", exception.Message); + } + + await serverTask; + } + } +} From 37086d441c9704d2fe66ce6dc0d5057e9e9e5668 Mon Sep 17 00:00:00 2001 From: "Travis Plunk (HE/HIM)" Date: Fri, 5 Sep 2025 17:50:40 -0700 Subject: [PATCH 153/173] Add LinuxHost Network configuration to PowerShell Packages pipeline --- .pipelines/PowerShell-Packages-Official.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.pipelines/PowerShell-Packages-Official.yml b/.pipelines/PowerShell-Packages-Official.yml index 333d73276b8..552e7d10a68 100644 --- a/.pipelines/PowerShell-Packages-Official.yml +++ b/.pipelines/PowerShell-Packages-Official.yml @@ -92,6 +92,8 @@ extends: WindowsHostVersion: Version: 2022 Network: KS3 + LinuxHostVersion: + Network: KS3 linuxEsrpSigning: true incrementalSDLBinaryAnalysis: true globalSdl: From 653e93df4d2aa529752425642dc27126b434c0b2 Mon Sep 17 00:00:00 2001 From: PowerShell Team Bot <69177312+pwshBot@users.noreply.github.com> Date: Sat, 6 Sep 2025 12:32:38 -0700 Subject: [PATCH 154/173] [release/v7.5] Add LinuxHost Network configuration to PowerShell Packages pipeline (#26002) Co-authored-by: Travis Plunk --- .pipelines/PowerShell-Packages-Official.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.pipelines/PowerShell-Packages-Official.yml b/.pipelines/PowerShell-Packages-Official.yml index 333d73276b8..552e7d10a68 100644 --- a/.pipelines/PowerShell-Packages-Official.yml +++ b/.pipelines/PowerShell-Packages-Official.yml @@ -92,6 +92,8 @@ extends: WindowsHostVersion: Version: 2022 Network: KS3 + LinuxHostVersion: + Network: KS3 linuxEsrpSigning: true incrementalSDLBinaryAnalysis: true globalSdl: From 82c9317ad186500d446b8cf3da4170c798ada485 Mon Sep 17 00:00:00 2001 From: "Travis Plunk (HE/HIM)" Date: Mon, 8 Sep 2025 12:00:32 -0700 Subject: [PATCH 155/173] Fix variable reference for release environment in pipeline --- .pipelines/PowerShell-Release-Official.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pipelines/PowerShell-Release-Official.yml b/.pipelines/PowerShell-Release-Official.yml index 974b8f328c8..986f803361b 100644 --- a/.pipelines/PowerShell-Release-Official.yml +++ b/.pipelines/PowerShell-Release-Official.yml @@ -288,7 +288,7 @@ extends: - setReleaseTagAndChangelog - UpdateChangeLog variables: - ob_release_environment: ${{ parameters.releaseEnvironment }} + ob_release_environment: ${{ variables.releaseEnvironment }} jobs: - template: /.pipelines/templates/release-githubNuget.yml@self parameters: From 5ad67e1697cb9f3ac70f7f55c9d4361adde336e1 Mon Sep 17 00:00:00 2001 From: PowerShell Team Bot <69177312+pwshBot@users.noreply.github.com> Date: Mon, 8 Sep 2025 12:53:26 -0700 Subject: [PATCH 156/173] [release/v7.5] Add v7.5.3 Changelog (#26015) Co-authored-by: Justin Chung <124807742+jshigetomi@users.noreply.github.com> --- CHANGELOG/7.5.md | 43 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/CHANGELOG/7.5.md b/CHANGELOG/7.5.md index d2071727790..e231ce6b0e2 100644 --- a/CHANGELOG/7.5.md +++ b/CHANGELOG/7.5.md @@ -1,5 +1,47 @@ # 7.5 Changelog +## [7.5.3] + +### General Cmdlet Updates and Fixes + +- Fix `Out-GridView` by replacing the use of obsolete `BinaryFormatter` with custom implementation. (#25559) +- Remove `OnDeserialized` and `Serializable` attributes from `Microsoft.Management.UI.Internal` project (#25831) +- Make the interface `IDeepCloneable` internal (#25830) + +### Tools + +- Add CodeQL suppressions (#25972) + +### Tests + +- Fix updatable help test for new content (#25944) + +### Build and Packaging Improvements + +
+ + + +

Update to .NET SDK 9.0.304

+ +
+ +
    +
  • Make logical template name consistent between pipelines (#25991)
  • +
  • Update container images to use mcr.microsoft.com for Linux and Azure Linux (#25986)
  • +
  • Add build to vPack Pipeline (#25975)
  • +
  • Remove AsyncSDL from Pipelines Toggle Official/NonOfficial Runs (#25964)
  • +
  • Update branch for release (#25942)
  • +
+ +
+ +### Documentation and Help Content + +- Fix typo in CHANGELOG for script filename suggestion (#25963) + +[7.5.3]: https://github.com/PowerShell/PowerShell/compare/v7.5.2...v7.5.3 + ## [7.5.2] - 2025-06-24 ### Engine Updates and Fixes @@ -41,7 +83,6 @@ [7.5.2]: https://github.com/PowerShell/PowerShell/compare/v7.5.1...v7.5.2 - ## [7.5.1] ### Engine Updates and Fixes From a77962d18346f59ab32b52a179504ed9d218d74d Mon Sep 17 00:00:00 2001 From: PowerShell Team Bot <69177312+pwshBot@users.noreply.github.com> Date: Mon, 8 Sep 2025 14:32:56 -0700 Subject: [PATCH 157/173] [release/v7.5] Fix variable reference for release environment in pipeline (#26013) Co-authored-by: Travis Plunk --- .pipelines/PowerShell-Release-Official.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pipelines/PowerShell-Release-Official.yml b/.pipelines/PowerShell-Release-Official.yml index 974b8f328c8..986f803361b 100644 --- a/.pipelines/PowerShell-Release-Official.yml +++ b/.pipelines/PowerShell-Release-Official.yml @@ -288,7 +288,7 @@ extends: - setReleaseTagAndChangelog - UpdateChangeLog variables: - ob_release_environment: ${{ parameters.releaseEnvironment }} + ob_release_environment: ${{ variables.releaseEnvironment }} jobs: - template: /.pipelines/templates/release-githubNuget.yml@self parameters: From b72c7ab1238c2d95b5c9004bca8399b8b3ca88ac Mon Sep 17 00:00:00 2001 From: PowerShell Team Bot <69177312+pwshBot@users.noreply.github.com> Date: Mon, 8 Sep 2025 12:53:26 -0700 Subject: [PATCH 158/173] [release/v7.5] Add v7.5.3 Changelog (#26015) Co-authored-by: Justin Chung <124807742+jshigetomi@users.noreply.github.com> --- CHANGELOG/7.5.md | 43 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/CHANGELOG/7.5.md b/CHANGELOG/7.5.md index d2071727790..e231ce6b0e2 100644 --- a/CHANGELOG/7.5.md +++ b/CHANGELOG/7.5.md @@ -1,5 +1,47 @@ # 7.5 Changelog +## [7.5.3] + +### General Cmdlet Updates and Fixes + +- Fix `Out-GridView` by replacing the use of obsolete `BinaryFormatter` with custom implementation. (#25559) +- Remove `OnDeserialized` and `Serializable` attributes from `Microsoft.Management.UI.Internal` project (#25831) +- Make the interface `IDeepCloneable` internal (#25830) + +### Tools + +- Add CodeQL suppressions (#25972) + +### Tests + +- Fix updatable help test for new content (#25944) + +### Build and Packaging Improvements + +
+ + + +

Update to .NET SDK 9.0.304

+ +
+ +
    +
  • Make logical template name consistent between pipelines (#25991)
  • +
  • Update container images to use mcr.microsoft.com for Linux and Azure Linux (#25986)
  • +
  • Add build to vPack Pipeline (#25975)
  • +
  • Remove AsyncSDL from Pipelines Toggle Official/NonOfficial Runs (#25964)
  • +
  • Update branch for release (#25942)
  • +
+ +
+ +### Documentation and Help Content + +- Fix typo in CHANGELOG for script filename suggestion (#25963) + +[7.5.3]: https://github.com/PowerShell/PowerShell/compare/v7.5.2...v7.5.3 + ## [7.5.2] - 2025-06-24 ### Engine Updates and Fixes @@ -41,7 +83,6 @@ [7.5.2]: https://github.com/PowerShell/PowerShell/compare/v7.5.1...v7.5.2 - ## [7.5.1] ### Engine Updates and Fixes From ca3365b94be7af48ccd057ab9692a39881a42e13 Mon Sep 17 00:00:00 2001 From: PowerShell Team Bot <69177312+pwshBot@users.noreply.github.com> Date: Wed, 10 Sep 2025 10:15:45 -0700 Subject: [PATCH 159/173] [release/v7.5] Update Ev2 Shell Extension Image to AzureLinux 3 for PMC Release (#26032) Co-authored-by: Anam Navied --- .pipelines/EV2Specs/ServiceGroupRoot/ServiceModel.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.pipelines/EV2Specs/ServiceGroupRoot/ServiceModel.json b/.pipelines/EV2Specs/ServiceGroupRoot/ServiceModel.json index 00555349c35..ce974fe69e5 100644 --- a/.pipelines/EV2Specs/ServiceGroupRoot/ServiceModel.json +++ b/.pipelines/EV2Specs/ServiceGroupRoot/ServiceModel.json @@ -17,8 +17,8 @@ { "type": "Run", "properties": { - "imageName": "adm-mariner-20-l", - "imageVersion": "v11" + "imageName": "adm-azurelinux-30-l", + "imageVersion": "v2" } } ] From 8272044640ecc6908c894c53712b6176ba147f2a Mon Sep 17 00:00:00 2001 From: PowerShell Team Bot <69177312+pwshBot@users.noreply.github.com> Date: Mon, 22 Sep 2025 14:06:31 -0700 Subject: [PATCH 160/173] [release/v7.5] Suppress false positive PSScriptAnalyzer warnings in tests and build scripts (#26059) Co-authored-by: Patrick Meinecke --- ....Cmdlets.LocalAccounts.LocalUser.Tests.ps1 | 4 +- .../Set-Service.Tests.ps1 | 4 ++ .../CmsMessage.Tests.ps1 | 4 ++ .../GetCredential.Tests.ps1 | 4 ++ .../UserConfigProviderModVersion1.psm1 | 60 ++++++++--------- .../UserConfigProviderModVersion2.psm1 | 66 +++++++++---------- .../UserConfigProviderModVersion3.psm1 | 58 ++++++++-------- .../certificateCommon.psm1 | 3 + .../ConvertTo-SecureString.Tests.ps1 | 4 ++ .../ConfigProvider.Tests.ps1 | 3 + .../engine/Api/Serialization.Tests.ps1 | 5 +- .../engine/Remoting/PSSession.Tests.ps1 | 3 + .../Remoting/RemoteSession.Basic.Tests.ps1 | 3 + .../Modules/WebListener/WebListener.psm1 | 4 ++ tools/WindowsCI.psm1 | 2 + tools/ci.psm1 | 3 + 16 files changed, 127 insertions(+), 103 deletions(-) diff --git a/test/powershell/Modules/Microsoft.PowerShell.LocalAccounts/Pester.Command.Cmdlets.LocalAccounts.LocalUser.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.LocalAccounts/Pester.Command.Cmdlets.LocalAccounts.LocalUser.Tests.ps1 index e6e5ebb8d4f..2e56df87256 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.LocalAccounts/Pester.Command.Cmdlets.LocalAccounts.LocalUser.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.LocalAccounts/Pester.Command.Cmdlets.LocalAccounts.LocalUser.Tests.ps1 @@ -4,6 +4,9 @@ # Module removed due to #4272 # disabling tests +[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingConvertToSecureStringWithPlainText', '')] +param() + return Set-Variable dateInFuture -Option Constant -Value "12/12/2036 09:00" @@ -1557,4 +1560,3 @@ try { finally { $global:PSDefaultParameterValues = $originalDefaultParameterValues } - diff --git a/test/powershell/Modules/Microsoft.PowerShell.Management/Set-Service.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Management/Set-Service.Tests.ps1 index 2c5f0fed3ee..bcb7a56ccde 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Management/Set-Service.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Management/Set-Service.Tests.ps1 @@ -1,5 +1,9 @@ # Copyright (c) Microsoft Corporation. # Licensed under the MIT License. + +[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingConvertToSecureStringWithPlainText', '')] +param() + Import-Module (Join-Path -Path $PSScriptRoot '..\Microsoft.PowerShell.Security\certificateCommon.psm1') Describe "Set/New/Remove-Service cmdlet tests" -Tags "Feature", "RequireAdminOnWindows" { diff --git a/test/powershell/Modules/Microsoft.PowerShell.Security/CmsMessage.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Security/CmsMessage.Tests.ps1 index 50cbdebab69..a40dfc8cfcd 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Security/CmsMessage.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Security/CmsMessage.Tests.ps1 @@ -1,5 +1,9 @@ # Copyright (c) Microsoft Corporation. # Licensed under the MIT License. + +[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingConvertToSecureStringWithPlainText', '')] +param() + Import-Module (Join-Path -Path $PSScriptRoot 'certificateCommon.psm1') -Force Describe "CmsMessage cmdlets and Get-PfxCertificate basic tests" -Tags "CI" { diff --git a/test/powershell/Modules/Microsoft.PowerShell.Security/GetCredential.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Security/GetCredential.Tests.ps1 index cb9d0ee70ed..fad8285aab3 100755 --- a/test/powershell/Modules/Microsoft.PowerShell.Security/GetCredential.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Security/GetCredential.Tests.ps1 @@ -1,5 +1,9 @@ # Copyright (c) Microsoft Corporation. # Licensed under the MIT License. + +[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingConvertToSecureStringWithPlainText', '')] +param() + Describe "Get-Credential Test" -Tag "CI" { BeforeAll { $th = New-TestHost diff --git a/test/powershell/Modules/Microsoft.PowerShell.Security/TestData/CatalogTestData/UserConfigProv/DSCResources/UserConfigProviderModVersion1/UserConfigProviderModVersion1.psm1 b/test/powershell/Modules/Microsoft.PowerShell.Security/TestData/CatalogTestData/UserConfigProv/DSCResources/UserConfigProviderModVersion1/UserConfigProviderModVersion1.psm1 index fd85fef1552..45188075fbc 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Security/TestData/CatalogTestData/UserConfigProv/DSCResources/UserConfigProviderModVersion1/UserConfigProviderModVersion1.psm1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Security/TestData/CatalogTestData/UserConfigProv/DSCResources/UserConfigProviderModVersion1/UserConfigProviderModVersion1.psm1 @@ -5,56 +5,50 @@ # This cmdlet executes the user supplied script (i.e., the script is responsible for validating the desired state of the # DSC managed node). The result of the script execution is in the form of a hashtable containing all the information # gathered from the GetScript execution. -function Get-TargetResource -{ +function Get-TargetResource { [CmdletBinding()] - param - ( - [parameter(Mandatory = $true)] - [ValidateNotNullOrEmpty()] - [string] - $text - ) + param( + [Parameter(Mandatory = $true)] + [ValidateNotNullOrEmpty()] + [string] + $Text + ) $result = @{ - Text = "Hello from Get!"; - } - $result; + Text = "Hello from Get!" + } + + $result } # The Set-TargetResource cmdlet is used to Set the desired state of the DSC managed node through a powershell script. # The method executes the user supplied script (i.e., the script is responsible for validating the desired state of the # DSC managed node). If the DSC managed node requires a restart either during or after the execution of the SetScript, # the SetScript notifies the PS Infrastructure by setting the variable $DSCMachineStatus.IsRestartRequired to $true. -function Set-TargetResource -{ +function Set-TargetResource { [CmdletBinding()] - param - ( - [parameter(Mandatory = $true)] - [ValidateNotNullOrEmpty()] - [string] - $text - ) - $path = "$env:SystemDrive\dscTestPath\hello1.txt" - New-Item -Path $path -Type File -Force - Add-Content -Path $path -Value $text + param( + [Parameter(Mandatory = $true)] + [ValidateNotNullOrEmpty()] + [string] + $Text + ) + $path = "$env:SystemDrive\dscTestPath\hello1.txt" + New-Item -Path $path -Type File -Force + Add-Content -Path $path -Value $text } # The Test-TargetResource cmdlet is used to validate the desired state of the DSC managed node through a powershell script. # The method executes the user supplied script (i.e., the script is responsible for validating the desired state of the # DSC managed node). The result of the script execution should be true if the DSC managed machine is in the desired state # or else false should be returned. -function Test-TargetResource -{ +function Test-TargetResource { [CmdletBinding()] - param - ( - [parameter(Mandatory = $true)] + param( + [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [string] - $text - ) - $false + $Text + ) + $false } - diff --git a/test/powershell/Modules/Microsoft.PowerShell.Security/TestData/CatalogTestData/UserConfigProv/DSCResources/UserConfigProviderModVersion2/UserConfigProviderModVersion2.psm1 b/test/powershell/Modules/Microsoft.PowerShell.Security/TestData/CatalogTestData/UserConfigProv/DSCResources/UserConfigProviderModVersion2/UserConfigProviderModVersion2.psm1 index d2f6a9ac719..05dbdcec7e1 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Security/TestData/CatalogTestData/UserConfigProv/DSCResources/UserConfigProviderModVersion2/UserConfigProviderModVersion2.psm1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Security/TestData/CatalogTestData/UserConfigProv/DSCResources/UserConfigProviderModVersion2/UserConfigProviderModVersion2.psm1 @@ -5,57 +5,51 @@ # This cmdlet executes the user supplied script (i.e., the script is responsible for validating the desired state of the # DSC managed node). The result of the script execution is in the form of a hashtable containing all the information # gathered from the GetScript execution. -function Get-TargetResource -{ +function Get-TargetResource { [CmdletBinding()] - param - ( - [parameter(Mandatory = $true)] - [ValidateNotNullOrEmpty()] - [string] - $text - ) + param( + [Parameter(Mandatory = $true)] + [ValidateNotNullOrEmpty()] + [string] + $Text + ) $result = @{ - Text = "Hello from Get!"; - } - $result; - } + Text = "Hello from Get!" + } + + $result +} # The Set-TargetResource cmdlet is used to Set the desired state of the DSC managed node through a powershell script. # The method executes the user supplied script (i.e., the script is responsible for validating the desired state of the # DSC managed node). If the DSC managed node requires a restart either during or after the execution of the SetScript, # the SetScript notifies the PS Infrastructure by setting the variable $DSCMachineStatus.IsRestartRequired to $true. -function Set-TargetResource -{ +function Set-TargetResource { [CmdletBinding()] - param - ( - [parameter(Mandatory = $true)] - [ValidateNotNullOrEmpty()] - [string] - $text - ) + param( + [Parameter(Mandatory = $true)] + [ValidateNotNullOrEmpty()] + [string] + $Text + ) - $path = "$env:SystemDrive\dscTestPath\hello2.txt" - New-Item -Path $path -Type File -Force - Add-Content -Path $path -Value $text + $path = "$env:SystemDrive\dscTestPath\hello2.txt" + New-Item -Path $path -Type File -Force + Add-Content -Path $path -Value $text } # The Test-TargetResource cmdlet is used to validate the desired state of the DSC managed node through a powershell script. # The method executes the user supplied script (i.e., the script is responsible for validating the desired state of the # DSC managed node). The result of the script execution should be true if the DSC managed machine is in the desired state # or else false should be returned. -function Test-TargetResource -{ +function Test-TargetResource { [CmdletBinding()] - param - ( - [parameter(Mandatory = $true)] - [ValidateNotNullOrEmpty()] - [string] - $text - ) - $false + param( + [Parameter(Mandatory = $true)] + [ValidateNotNullOrEmpty()] + [string] + $Text + ) + $false } - diff --git a/test/powershell/Modules/Microsoft.PowerShell.Security/TestData/CatalogTestData/UserConfigProv/DSCResources/UserConfigProviderModVersion3/UserConfigProviderModVersion3.psm1 b/test/powershell/Modules/Microsoft.PowerShell.Security/TestData/CatalogTestData/UserConfigProv/DSCResources/UserConfigProviderModVersion3/UserConfigProviderModVersion3.psm1 index 45987a71f76..134158d62a9 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Security/TestData/CatalogTestData/UserConfigProv/DSCResources/UserConfigProviderModVersion3/UserConfigProviderModVersion3.psm1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Security/TestData/CatalogTestData/UserConfigProv/DSCResources/UserConfigProviderModVersion3/UserConfigProviderModVersion3.psm1 @@ -5,57 +5,51 @@ # This cmdlet executes the user supplied script (i.e., the script is responsible for validating the desired state of the # DSC managed node). The result of the script execution is in the form of a hashtable containing all the information # gathered from the GetScript execution. -function Get-TargetResource -{ +function Get-TargetResource { [CmdletBinding()] - param - ( - [parameter(Mandatory = $true)] + param( + [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [string] - $text - ) + $Text + ) $result = @{ - Text = "Hello from Get!"; - } - $result; - } + Text = "Hello from Get!" + } + + $result +} # The Set-TargetResource cmdlet is used to Set the desired state of the DSC managed node through a powershell script. # The method executes the user supplied script (i.e., the script is responsible for validating the desired state of the # DSC managed node). If the DSC managed node requires a restart either during or after the execution of the SetScript, # the SetScript notifies the PS Infrastructure by setting the variable $DSCMachineStatus.IsRestartRequired to $true. -function Set-TargetResource -{ +function Set-TargetResource { [CmdletBinding()] - param - ( - [parameter(Mandatory = $true)] + param( + [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [string] - $text - ) + $Text + ) - $path = "$env:SystemDrive\dscTestPath\hello3.txt" - New-Item -Path $path -Type File -Force - Add-Content -Path $path -Value $text + $path = "$env:SystemDrive\dscTestPath\hello3.txt" + New-Item -Path $path -Type File -Force + Add-Content -Path $path -Value $text } # The Test-TargetResource cmdlet is used to validate the desired state of the DSC managed node through a powershell script. # The method executes the user supplied script (i.e., the script is responsible for validating the desired state of the # DSC managed node). The result of the script execution should be true if the DSC managed machine is in the desired state # or else false should be returned. -function Test-TargetResource -{ +function Test-TargetResource { [CmdletBinding()] - param - ( - [parameter(Mandatory = $true)] - [ValidateNotNullOrEmpty()] - [string] - $text - ) - $false + param( + [Parameter(Mandatory = $true)] + [ValidateNotNullOrEmpty()] + [string] + $Text + ) + $false } - diff --git a/test/powershell/Modules/Microsoft.PowerShell.Security/certificateCommon.psm1 b/test/powershell/Modules/Microsoft.PowerShell.Security/certificateCommon.psm1 index 5601767a120..46092386fe3 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Security/certificateCommon.psm1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Security/certificateCommon.psm1 @@ -1,6 +1,9 @@ # Copyright (c) Microsoft Corporation. # Licensed under the MIT License. +[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingConvertToSecureStringWithPlainText', '')] +param() + Function New-GoodCertificate { <# diff --git a/test/powershell/Modules/Microsoft.PowerShell.Utility/ConvertTo-SecureString.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Utility/ConvertTo-SecureString.Tests.ps1 index e58a227fbcf..5a2660ed621 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Utility/ConvertTo-SecureString.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Utility/ConvertTo-SecureString.Tests.ps1 @@ -1,5 +1,9 @@ # Copyright (c) Microsoft Corporation. # Licensed under the MIT License. + +[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingConvertToSecureStringWithPlainText', '')] +param() + Describe "ConvertTo--SecureString" -Tags "CI" { Context "Checking return types of ConvertTo--SecureString" { diff --git a/test/powershell/Modules/Microsoft.WSMan.Management/ConfigProvider.Tests.ps1 b/test/powershell/Modules/Microsoft.WSMan.Management/ConfigProvider.Tests.ps1 index 49d60cd1283..1845933e8f4 100644 --- a/test/powershell/Modules/Microsoft.WSMan.Management/ConfigProvider.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.WSMan.Management/ConfigProvider.Tests.ps1 @@ -1,6 +1,9 @@ # Copyright (c) Microsoft Corporation. # Licensed under the MIT License. +[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingConvertToSecureStringWithPlainText', '')] +param() + Describe "WSMan Config Provider" -Tag Feature,RequireAdminOnWindows { BeforeAll { #skip all tests on non-windows platform diff --git a/test/powershell/engine/Api/Serialization.Tests.ps1 b/test/powershell/engine/Api/Serialization.Tests.ps1 index 6b011ffc6ab..317a0907ca5 100644 --- a/test/powershell/engine/Api/Serialization.Tests.ps1 +++ b/test/powershell/engine/Api/Serialization.Tests.ps1 @@ -1,5 +1,9 @@ # Copyright (c) Microsoft Corporation. # Licensed under the MIT License. + +[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingConvertToSecureStringWithPlainText', '')] +param() + Describe "Serialization Tests" -tags "CI" { BeforeAll { $testfileName="SerializationTest.txt" @@ -99,4 +103,3 @@ Describe "Serialization Tests" -tags "CI" { SerializeAndDeserialize($versionObject).TestScriptProperty | Should -Be $versionObject.TestScriptProperty } } - diff --git a/test/powershell/engine/Remoting/PSSession.Tests.ps1 b/test/powershell/engine/Remoting/PSSession.Tests.ps1 index cbf7313eed0..689e587ddb1 100644 --- a/test/powershell/engine/Remoting/PSSession.Tests.ps1 +++ b/test/powershell/engine/Remoting/PSSession.Tests.ps1 @@ -5,6 +5,9 @@ # PSSession tests for non-Windows platforms # +[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingConvertToSecureStringWithPlainText', '')] +param() + function GetRandomString() { return [System.IO.Path]::GetFileNameWithoutExtension([System.IO.Path]::GetRandomFileName()) diff --git a/test/powershell/engine/Remoting/RemoteSession.Basic.Tests.ps1 b/test/powershell/engine/Remoting/RemoteSession.Basic.Tests.ps1 index 43f92cef295..a5d49b75005 100644 --- a/test/powershell/engine/Remoting/RemoteSession.Basic.Tests.ps1 +++ b/test/powershell/engine/Remoting/RemoteSession.Basic.Tests.ps1 @@ -1,6 +1,9 @@ # Copyright (c) Microsoft Corporation. # Licensed under the MIT License. +[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingConvertToSecureStringWithPlainText', '')] +param() + Import-Module HelpersCommon function GetRandomString() diff --git a/test/tools/Modules/WebListener/WebListener.psm1 b/test/tools/Modules/WebListener/WebListener.psm1 index 15ce1d8fe38..7f590b79b76 100644 --- a/test/tools/Modules/WebListener/WebListener.psm1 +++ b/test/tools/Modules/WebListener/WebListener.psm1 @@ -1,6 +1,10 @@ # Copyright (c) Microsoft Corporation. # Licensed under the MIT License. +[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingConvertToSecureStringWithPlainText', '')] +[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingPlainTextForPassword', '')] +param() + Class WebListener { [int]$HttpPort diff --git a/tools/WindowsCI.psm1 b/tools/WindowsCI.psm1 index 57d506bda8b..685882546c2 100644 --- a/tools/WindowsCI.psm1 +++ b/tools/WindowsCI.psm1 @@ -15,6 +15,8 @@ function New-LocalUser .OUTPUTS .NOTES #> + [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingUsernameAndPasswordParams', '')] + [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingPlainTextForPassword', '')] param( [Parameter(Mandatory=$true)] [string] $username, diff --git a/tools/ci.psm1 b/tools/ci.psm1 index 317f05effd0..7b13ded1811 100644 --- a/tools/ci.psm1 +++ b/tools/ci.psm1 @@ -1,6 +1,9 @@ # Copyright (c) Microsoft Corporation. # Licensed under the MIT License. +[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingConvertToSecureStringWithPlainText', '')] +param() + Set-StrictMode -Version 3.0 $ErrorActionPreference = 'continue' From ce08de80517b41077bdb48ce25df1fda0004bcee Mon Sep 17 00:00:00 2001 From: PowerShell Team Bot <69177312+pwshBot@users.noreply.github.com> Date: Thu, 9 Oct 2025 13:14:23 -0700 Subject: [PATCH 161/173] [release/v7.5] Ensure that socket timeouts are set only during the token validation (#26079) --- .../common/RemoteSessionHyperVSocket.cs | 57 +++--- test/xUnit/csharp/test_RemoteHyperV.cs | 186 ++++++++++++++++-- 2 files changed, 197 insertions(+), 46 deletions(-) diff --git a/src/System.Management.Automation/engine/remoting/common/RemoteSessionHyperVSocket.cs b/src/System.Management.Automation/engine/remoting/common/RemoteSessionHyperVSocket.cs index a9de12c3931..d62805d7e89 100644 --- a/src/System.Management.Automation/engine/remoting/common/RemoteSessionHyperVSocket.cs +++ b/src/System.Management.Automation/engine/remoting/common/RemoteSessionHyperVSocket.cs @@ -258,30 +258,7 @@ public RemoteSessionHyperVSocketServer(bool LoopbackMode, string token, DateTime listenSocket.Listen(1); HyperVSocket = listenSocket.Accept(); - TimeSpan timeout = TimeSpan.FromMinutes(MAX_TOKEN_LIFE_MINUTES); - DateTimeOffset timeoutExpiry = tokenCreationTime.Add(timeout); - DateTimeOffset now = DateTimeOffset.UtcNow; - - // Calculate remaining time and create cancellation token - TimeSpan remainingTime = timeoutExpiry - now; - - // Check if the token has already expired - if (remainingTime <= TimeSpan.Zero) - { - throw new PSDirectException( - PSRemotingErrorInvariants.FormatResourceString(RemotingErrorIdStrings.InvalidCredential, "Token has expired")); - } - - // Set socket timeout for receive operations to prevent indefinite blocking - int timeoutMs = (int)remainingTime.TotalMilliseconds; - HyperVSocket.ReceiveTimeout = timeoutMs; - HyperVSocket.SendTimeout = timeoutMs; - - // Create a cancellation token that will be cancelled when the timeout expires - using var cancellationTokenSource = new CancellationTokenSource(remainingTime); - CancellationToken cancellationToken = cancellationTokenSource.Token; - - ValidateToken(HyperVSocket, token, cancellationToken); + ValidateToken(HyperVSocket, token, tokenCreationTime, MAX_TOKEN_LIFE_MINUTES * 60); Stream = new NetworkStream(HyperVSocket, true); @@ -389,9 +366,33 @@ public void Dispose() ///
/// The connected HyperVSocket. /// The expected token string. - /// Cancellation token for timeout handling. - internal static void ValidateToken(Socket socket, string token, CancellationToken cancellationToken = default) + /// The creation time of the token. + /// The maximum lifetime of the token in seconds. + internal static void ValidateToken(Socket socket, string token, DateTimeOffset tokenCreationTime, int maxTokenLifeSeconds) { + TimeSpan timeout = TimeSpan.FromSeconds(maxTokenLifeSeconds); + DateTimeOffset timeoutExpiry = tokenCreationTime.Add(timeout); + DateTimeOffset now = DateTimeOffset.UtcNow; + + // Calculate remaining time and create cancellation token + TimeSpan remainingTime = timeoutExpiry - now; + + // Check if the token has already expired + if (remainingTime <= TimeSpan.Zero) + { + throw new PSDirectException( + PSRemotingErrorInvariants.FormatResourceString(RemotingErrorIdStrings.InvalidCredential, "Token has expired")); + } + + // Create a cancellation token that will be cancelled when the timeout expires + using var cancellationTokenSource = new CancellationTokenSource(remainingTime); + CancellationToken cancellationToken = cancellationTokenSource.Token; + + // Set socket timeout for receive operations to prevent indefinite blocking + int timeoutMs = (int)remainingTime.TotalMilliseconds; + socket.ReceiveTimeout = timeoutMs; + socket.SendTimeout = timeoutMs; + // Check for cancellation before starting validation cancellationToken.ThrowIfCancellationRequested(); @@ -430,6 +431,7 @@ internal static void ValidateToken(Socket socket, string token, CancellationToke // So we expect a response of length 6 + 100 = 106 characters. responseString = RemoteSessionHyperVSocketClient.ReceiveResponse(socket, 110); + // Final check if we got the token before the timeout cancellationToken.ThrowIfCancellationRequested(); if (string.IsNullOrEmpty(responseString) || !responseString.StartsWith("TOKEN ", StringComparison.Ordinal)) @@ -454,6 +456,9 @@ internal static void ValidateToken(Socket socket, string token, CancellationToke // Acknowledge the token is valid with "PASS". socket.Send("PASS"u8); + + socket.ReceiveTimeout = 0; // Disable the timeout after successful validation + socket.SendTimeout = 0; } } diff --git a/test/xUnit/csharp/test_RemoteHyperV.cs b/test/xUnit/csharp/test_RemoteHyperV.cs index f694f6894df..27f7fb17375 100644 --- a/test/xUnit/csharp/test_RemoteHyperV.cs +++ b/test/xUnit/csharp/test_RemoteHyperV.cs @@ -63,15 +63,51 @@ private static void ConnectWithRetry(Socket client, IPAddress address, int port, } } + private static void SendResponse(string name, Socket client, Queue<(byte[] bytes, int delayMs)> serverResponses) + { + if (serverResponses.Count > 0) + { + _output.WriteLine($"Mock {name} ----------------------------------------------------"); + var respTuple = serverResponses.Dequeue(); + var resp = respTuple.bytes; + + if (respTuple.delayMs > 0) + { + _output.WriteLine($"Mock {name} - delaying response by {respTuple.delayMs} ms"); + Thread.Sleep(respTuple.delayMs); + } + if (resp.Length > 0) { + client.Send(resp, resp.Length, SocketFlags.None); + _output.WriteLine($"Mock {name} - sent response: " + Encoding.ASCII.GetString(resp)); + } + } + } + private static void StartHandshakeServer( string name, int port, - IEnumerable<(string message, - Encoding encoding)> expectedClientSends, + IEnumerable<(string message, Encoding encoding)> expectedClientSends, IEnumerable<(string message, Encoding encoding)> serverResponses, bool verifyConnectionClosed, CancellationToken cancellationToken, bool sendFirst = false) + { + IEnumerable<(string message, Encoding encoding, int delayMs)> serverResponsesWithDelay = new List<(string message, Encoding encoding, int delayMs)>(); + foreach (var item in serverResponses) + { + ((List<(string message, Encoding encoding, int delayMs)>)serverResponsesWithDelay).Add((item.message, item.encoding, 1)); + } + StartHandshakeServer(name, port, expectedClientSends, serverResponsesWithDelay, verifyConnectionClosed, cancellationToken, sendFirst); + } + + private static void StartHandshakeServer( + string name, + int port, + IEnumerable<(string message, Encoding encoding)> expectedClientSends, + IEnumerable<(string message, Encoding encoding, int delayMs)> serverResponses, + bool verifyConnectionClosed, + CancellationToken cancellationToken, + bool sendFirst = false) { var expectedMessages = new Queue<(string message, byte[] bytes, Encoding encoding)>(); foreach (var item in expectedClientSends) @@ -80,17 +116,27 @@ private static void StartHandshakeServer( expectedMessages.Enqueue((message: item.message, bytes: itemBytes, encoding: item.encoding)); } - var serverResponseBytes = new Queue(); + var serverResponseBytes = new Queue<(byte[] bytes, int delayMs)>(); foreach (var item in serverResponses) { - serverResponseBytes.Enqueue(item.encoding.GetBytes(item.message)); + (byte[] bytes, int delayMs) queueItem = (item.encoding.GetBytes(item.message), item.delayMs); + serverResponseBytes.Enqueue(queueItem); } - StartHandshakeServer(name, port, expectedMessages, serverResponseBytes, verifyConnectionClosed, cancellationToken, sendFirst); + _output.WriteLine($"Mock {name} - starting listener on port {port} with {expectedMessages.Count} expected messages and {serverResponseBytes.Count} responses."); + StartHandshakeServerImplementation(name, port, expectedMessages, serverResponseBytes, verifyConnectionClosed, cancellationToken, sendFirst); } - private static void StartHandshakeServer(string name, int port, Queue<(string message, byte[] bytes, Encoding encoding)> expectedClientSends, Queue serverResponses, bool verifyConnectionClosed, CancellationToken cancellationToken, bool sendFirst = false) + private static void StartHandshakeServerImplementation( + string name, + int port, + Queue<(string message, byte[] bytes, Encoding encoding)> expectedClientSends, + Queue<(byte[] bytes, int delayMs)> serverResponses, + bool verifyConnectionClosed, + CancellationToken cancellationToken, + bool sendFirst = false) { + DateTime startTime = DateTime.UtcNow; var buffer = new byte[1024]; var listener = new TcpListener(IPAddress.Loopback, port); listener.Start(); @@ -101,19 +147,16 @@ private static void StartHandshakeServer(string name, int port, Queue<(string me if (sendFirst) { // Send the first message from the serverResponses queue - if (serverResponses.Count > 0) - { - var resp = serverResponses.Dequeue(); - client.Send(resp, resp.Length, SocketFlags.None); - _output.WriteLine($"Mock {name} - sent response: " + Encoding.ASCII.GetString(resp)); - } + SendResponse(name, client, serverResponses); } while (expectedClientSends.Count > 0) { + _output.WriteLine($"Mock {name} - time elapsed: {(DateTime.UtcNow - startTime).TotalMilliseconds} milliseconds"); client.ReceiveTimeout = 2 * 1000; // 2 seconds timeout for receiving data cancellationToken.ThrowIfCancellationRequested(); var expectedMessage = expectedClientSends.Dequeue(); + _output.WriteLine($"Mock {name} - remaining expected messages: {expectedClientSends.Count}"); var expected = expectedMessage.bytes; Array.Clear(buffer, 0, buffer.Length); int received = client.Receive(buffer); @@ -143,12 +186,7 @@ private static void StartHandshakeServer(string name, int port, Queue<(string me throw new Exception(errorMessage); } _output.WriteLine($"Mock {name} - received expected message: " + expectedString); - if (serverResponses.Count > 0) - { - var resp = serverResponses.Dequeue(); - client.Send(resp, resp.Length, SocketFlags.None); - _output.WriteLine($"Mock {name} - sent response: " + Encoding.ASCII.GetString(resp)); - } + SendResponse(name, client, serverResponses); } if (verifyConnectionClosed) @@ -178,6 +216,7 @@ private static void StartHandshakeServer(string name, int port, Queue<(string me } catch (ObjectDisposedException) { + _output.WriteLine($"Mock {name} - socket already closed."); // Socket already closed } } @@ -185,8 +224,16 @@ private static void StartHandshakeServer(string name, int port, Queue<(string me _output.WriteLine($"Mock {name} - on port {port} completed successfully."); } + catch (Exception ex) + { + _output.WriteLine($"Mock {name} - Exception: {ex.Message} {ex.GetType().FullName}"); + _output.WriteLine(ex.StackTrace); + throw; + } finally { + _output.WriteLine($"Mock {name} - remaining expected messages: {expectedClientSends.Count}"); + _output.WriteLine($"Mock {name} - stopping listener on port {port}."); listener.Stop(); } } @@ -615,13 +662,111 @@ public async Task ValidatePassesWhenTokensMatch(string token, string expectedTok using (var client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)) { ConnectWithRetry(client, IPAddress.Loopback, port, _output); - System.Management.Automation.Remoting.RemoteSessionHyperVSocketServer.ValidateToken(client, expectedToken); + System.Management.Automation.Remoting.RemoteSessionHyperVSocketServer.ValidateToken(client, expectedToken, DateTimeOffset.UtcNow, 1); System.Threading.Thread.Sleep(100); // Allow time for server to process } await serverTask; } + [SkippableTheory] + [InlineData(5500, "A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond.", "SocketException")] // test the socket timeout + [InlineData(3200, "canceled", "System.OperationCanceledException")] // test the cancellation token + [InlineData(10, "", "")] + public async Task ValidateTokenTimeoutFails(int timeoutMs, string expectedMessage, string expectedExceptionType = "SocketException") + { + string token = "testToken"; + string expectedToken = token; + int port = 50000 + (int)(DateTime.Now.Ticks % 10000); + + var expectedClientSends = new List<(string message, Encoding encoding, int delayMs)>{ + (message: "VERSION", encoding: Encoding.ASCII, delayMs: timeoutMs), // Response to VERSION + (message: "VERSION_2", encoding: Encoding.ASCII, delayMs: timeoutMs), // Response to VERSION_2 + (message: $"TOKEN {token}", encoding: Encoding.ASCII, delayMs: 1) + }; + + var serverResponses = new List<(string message, Encoding encoding)>{ + (message: "VERSION_2", encoding: Encoding.ASCII), // Response to VERSION_2 + (message: "PASS", encoding: Encoding.ASCII), // Response to VERSION_2 + (message: "PASS", encoding: Encoding.ASCII) // Response to token + }; + + using var cts = new CancellationTokenSource(TimeSpan.FromMinutes(1)); + var serverTask = Task.Run(() => StartHandshakeServer("Client", port, serverResponses, expectedClientSends, verifyConnectionClosed: true, cts.Token, sendFirst: true), cts.Token); + + using (var client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)) + { + ConnectWithRetry(client, IPAddress.Loopback, port, _output); + if (expectedMessage.Length > 0) + { + var exception = Record.Exception( + () => System.Management.Automation.Remoting.RemoteSessionHyperVSocketServer.ValidateToken(client, expectedToken, DateTimeOffset.UtcNow, 5)); // set the timeout to 5 seconds or 5000 ms + Assert.NotNull(exception); + string exceptionType = exception.GetType().FullName; + _output.WriteLine($"Caught exception of type {exceptionType} with message: {exception.Message}"); + Assert.Contains(expectedExceptionType, exceptionType, StringComparison.OrdinalIgnoreCase); + Assert.Contains(expectedMessage, exception.Message, StringComparison.OrdinalIgnoreCase); + } + else + { + System.Management.Automation.Remoting.RemoteSessionHyperVSocketServer.ValidateToken(client, expectedToken, DateTimeOffset.UtcNow, 5); + } + System.Threading.Thread.Sleep(100); // Allow time for server to process + } + + if (expectedMessage.Length == 0) + { + await serverTask; + } + } + + [SkippableFact] + public async Task ValidateTokenTimeoutDoesAffectSession() + { + string token = "testToken"; + string expectedToken = token; + int port = 50000 + (int)(DateTime.Now.Ticks % 10000); + + var expectedClientSends = new List<(string message, Encoding encoding, int delayMs)>{ + (message: "VERSION", encoding: Encoding.ASCII, delayMs: 1), // Response to VERSION + (message: "VERSION_2", encoding: Encoding.ASCII, delayMs: 1), // Response to VERSION_2 + (message: $"TOKEN {token}", encoding: Encoding.ASCII, delayMs: 1), + (message: string.Empty, encoding: Encoding.ASCII, delayMs: 99), // Send some data after the handshake + (message: string.Empty, encoding: Encoding.ASCII, delayMs: 100), // Send some data after the handshake + (message: string.Empty, encoding: Encoding.ASCII, delayMs: 101), // Send some data after the handshake + (message: string.Empty, encoding: Encoding.ASCII, delayMs: 102), // Send some data after the handshake + (message: string.Empty, encoding: Encoding.ASCII, delayMs: 103) // Send some data after the handshake + }; + + var serverResponses = new List<(string message, Encoding encoding)>{ + (message: "VERSION_2", encoding: Encoding.ASCII), // Response to VERSION_2 + (message: "PASS", encoding: Encoding.ASCII), // Response to VERSION_2 + (message: "PASS", encoding: Encoding.ASCII), // Response to token + (message: "PSRP-Message0", encoding: Encoding.ASCII), // Indicate server is ready to receive data + (message: "PSRP-Message1", encoding: Encoding.ASCII), // Indicate server is ready to receive data + (message: "PSRP-Message2", encoding: Encoding.ASCII), // Indicate server is ready to receive data + (message: "PSRP-Message3", encoding: Encoding.ASCII), // Indicate server is ready to receive data + (message: "PSRP-Message4", encoding: Encoding.ASCII) // + + }; + + using var cts = new CancellationTokenSource(TimeSpan.FromMinutes(2)); + var serverTask = Task.Run(() => StartHandshakeServer("Client", port, serverResponses, expectedClientSends, verifyConnectionClosed: false, cts.Token, sendFirst: true), cts.Token); + + using (var client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)) + { + ConnectWithRetry(client, IPAddress.Loopback, port, _output); + System.Management.Automation.Remoting.RemoteSessionHyperVSocketServer.ValidateToken(client, expectedToken, DateTimeOffset.UtcNow, 5); + for (int i = 0; i < 5; i++) + { + System.Threading.Thread.Sleep(1500); + client.Send(Encoding.ASCII.GetBytes($"PSRP-Message{i}")); // Send some data after the handshake + } + } + + await serverTask; + } + [SkippableTheory] [InlineData("abc", "xyz")] [InlineData("abc", "abcdef")] @@ -649,8 +794,9 @@ public async Task ValidateFailsWhenTokensMismatch(string token, string expectedT using (var client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)) { ConnectWithRetry(client, IPAddress.Loopback, port, _output); + DateTimeOffset tokenCreationTime = DateTimeOffset.UtcNow; // Token created 10 minutes ago var exception = Assert.Throws( - () => System.Management.Automation.Remoting.RemoteSessionHyperVSocketServer.ValidateToken(client, expectedToken)); + () => System.Management.Automation.Remoting.RemoteSessionHyperVSocketServer.ValidateToken(client, expectedToken, tokenCreationTime, 5)); System.Threading.Thread.Sleep(100); // Allow time for server to process Assert.Contains("The credential is invalid.", exception.Message); } From 0a404341482af00449210c503aa448f60e95f000 Mon Sep 17 00:00:00 2001 From: PowerShell Team Bot <69177312+pwshBot@users.noreply.github.com> Date: Thu, 9 Oct 2025 13:54:02 -0700 Subject: [PATCH 162/173] [release/v7.5] Automate Store Publishing (#26164) --- .pipelines/PowerShell-Release-Official.yml | 13 +- .../store/PDP/PDP-Media/en-US/Error.png | Bin 0 -> 120539 bytes .../PDP-Media/en-US/Experimental_Features.png | Bin 0 -> 161370 bytes .../PDP/PDP-Media/en-US/Feedback_Provider.png | Bin 0 -> 167038 bytes .../PDP/PDP-Media/en-US/Predictor_Inline.png | Bin 0 -> 110258 bytes .../PDP-Media/en-US/Predictor_ListView.png | Bin 0 -> 146469 bytes .../store/PDP/PDP-Media/en-US/Prompt.png | Bin 0 -> 132747 bytes .../PDP/PDP-Media/en-US/Stable_Release.png | Bin 0 -> 179123 bytes .../store/PDP/PDP-Media/en-US/pwshLogo.png | Bin 0 -> 13152 bytes .pipelines/store/PDP/PDP/en-US/PDP.xml | 176 ++++++++++++++++++ .pipelines/store/SBConfig.json | 67 +++++++ .pipelines/templates/channelSelection.yml | 31 +++ .pipelines/templates/package-create-msix.yml | 128 +++++++++++++ .pipelines/templates/release-MSIX-Publish.yml | 115 ++++++++++++ .../templates/release-SetTagAndChangelog.yml | 4 +- tools/packaging/packaging.psm1 | 11 ++ 16 files changed, 539 insertions(+), 6 deletions(-) create mode 100644 .pipelines/store/PDP/PDP-Media/en-US/Error.png create mode 100644 .pipelines/store/PDP/PDP-Media/en-US/Experimental_Features.png create mode 100644 .pipelines/store/PDP/PDP-Media/en-US/Feedback_Provider.png create mode 100644 .pipelines/store/PDP/PDP-Media/en-US/Predictor_Inline.png create mode 100644 .pipelines/store/PDP/PDP-Media/en-US/Predictor_ListView.png create mode 100644 .pipelines/store/PDP/PDP-Media/en-US/Prompt.png create mode 100644 .pipelines/store/PDP/PDP-Media/en-US/Stable_Release.png create mode 100644 .pipelines/store/PDP/PDP-Media/en-US/pwshLogo.png create mode 100644 .pipelines/store/PDP/PDP/en-US/PDP.xml create mode 100644 .pipelines/store/SBConfig.json create mode 100644 .pipelines/templates/channelSelection.yml create mode 100644 .pipelines/templates/release-MSIX-Publish.yml diff --git a/.pipelines/PowerShell-Release-Official.yml b/.pipelines/PowerShell-Release-Official.yml index 986f803361b..36bee13a0c7 100644 --- a/.pipelines/PowerShell-Release-Official.yml +++ b/.pipelines/PowerShell-Release-Official.yml @@ -25,6 +25,10 @@ parameters: # parameters are shown up in ADO UI in a build queue time displayName: Skip Copying Archives and Installers to PSInfrastructure Public Location type: boolean default: false + - name: skipMSIXPublish + displayName: Skip MSIX Publish + type: boolean + default: false - name: OfficialBuild type: boolean default: false @@ -363,13 +367,12 @@ extends: - stage: PublishMsix dependsOn: PushGitTagAndMakeDraftPublic displayName: Publish MSIX to store + variables: + ob_release_environment: Production jobs: - - template: /.pipelines/templates/approvalJob.yml@self + - template: /.pipelines/templates/release-MSIX-Publish.yml@self parameters: - displayName: Publish the MSIX Bundle package to store - jobName: PublishMsix - instructions: | - Ask Steve to release MSIX bundle package to Store + skipMSIXPublish: ${{ parameters.skipMSIXPublish }} - stage: PublishVPack dependsOn: PushGitTagAndMakeDraftPublic diff --git a/.pipelines/store/PDP/PDP-Media/en-US/Error.png b/.pipelines/store/PDP/PDP-Media/en-US/Error.png new file mode 100644 index 0000000000000000000000000000000000000000..48e96378055b5d7fbb4d744007c1ebc073da2453 GIT binary patch literal 120539 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

qKdpe4ED4mcn4J%^2KM0@o*9MuqiJ3p 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 literal 0 HcmV?d00001 diff --git a/.pipelines/store/PDP/PDP-Media/en-US/Experimental_Features.png b/.pipelines/store/PDP/PDP-Media/en-US/Experimental_Features.png new file mode 100644 index 0000000000000000000000000000000000000000..90420254a8e4a4720601e3050567db719819efc6 GIT binary patch literal 161370 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 literal 0 HcmV?d00001 diff --git a/.pipelines/store/PDP/PDP-Media/en-US/Feedback_Provider.png b/.pipelines/store/PDP/PDP-Media/en-US/Feedback_Provider.png new file mode 100644 index 0000000000000000000000000000000000000000..f4084360d5c630119e469b721dde87920d5a8346 GIT binary patch literal 167038 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 z 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 L$C>(5*M9y#()S`v literal 0 HcmV?d00001 diff --git a/.pipelines/store/PDP/PDP-Media/en-US/Predictor_Inline.png b/.pipelines/store/PDP/PDP-Media/en-US/Predictor_Inline.png new file mode 100644 index 0000000000000000000000000000000000000000..3b8d62284859c6ce60c96d643b3b2bdb994471d0 GIT binary patch literal 110258 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 W56C)9ct$q>0000&bOJEruf;N2sW%7_MGX zzd=Ps&qqada2a$6_{p7PL?+-HwdV~jRjT|p@D%V5nY(6JZFP02gn-W=D(WzMD%#yY z0lqkZFDfdURGObZq326I@bmM*<=tQQhJ9$GqEex{s(#tXkNU@;f9ze;Ai=eG?U}%= zKMby1(HwvAxr@d|fJWdfheVY1NwwZO%u0_UciBDkOD35!XSZKY@==^P>Fn)RF-N0;Dc_3Y9oQ(^A*Z`brUS8pd>$vH&V@mMmabK3Z!y<4g>!^&zV ze6$mf_bp7So@Kc=zg_9dJd?6ej6X6H^!(f5Tqo)f?z|tXu4Gye)4j99@`aDjSNn80 z&X!0!C~^r6mzjsvob2RRxlct+Lu<=AU#rskm2g||@Y?N}cV*w2P=4Q>KTApgzpKzs z#p3A)S36qDEe>wFknT$pu~oMHwdInwY0l&oZ=Ebl(%_I z*k>afy?{A17wpz&0^y@1}X@Cv!w%gOx9Jn_d zWwec4Y8^~vr>3E2niuS#X&?BgK;yi9n_SkmSk@oeoGm9yl1F!Z^FbiQ`K zwDbF*>eBf#F9c-f@SsGsq&g}AzFZ17HnW*h4fSO@N)-UTq)m1{SK4c|`rq$cSgAVFdP3mvVXb(LW0MgEcr# zLM#zc^^K-Z{m&2SlQV5H+Y(NV+g~0#>op*45E?6Hq#)XWc6anwh|3=+m32O!&1>4< zo@F!D@{Jgw#O{)9Rjj|yg>-||FOQC_CCkT4owz(EnN+IV8nltYU{4;l4p`~QS{zVk zR+tsu7Wa>RdwlWHG&){>+(7ZZf|6Wv8`}tBq=-Ep`^{2dKcWY;tNCCAO`~13LXu|0 zg+ob?=H+W1MiJF;*aC0BR+o_Jzg1v!dkO zH9;a9^_aL8;wla1=I0mtdY8)F5p@@t#fCTmgbr8cC1_O^NFdSq<4F%@)fy(1SrQ2_ zPa@T#ItLGzs4(xUXj}sGzI2wi{mSqU;Gh*2uDIJ@@&?Ni_+1om5!W#B?4>SdiHGRk zURWG+A9zo*_&lC#KQf}G5!U4O_#7vQaALXJ=0|GsZoCyIDZ0&>MUZI6Czb+d;Qw*W zdva_+0=D7>>DasU|2!%)I8B@&x12Z3VZ2`|U(6F7rz)z3v4{}DpcEF(45Zdu3X{zd z73gF8I#^)QI>R~!4E|1c%FW2?aniHeaq`h!$TMd;C?z?~57)*a&vixH?DwH7yYJ6+ zgY%ohW_y;{nLK98--lK?xbf!Ql$7y*Gbtel3x1@1Q)!>eyqVg)?W+JSMg8+4H#7*s;~vn9C5KKDm^1Rg0%cp@Rw4h@an*vPcj3^P(i)PLA7 zB%Zq<2fJtoUMFmCZ`Ul=t1pmx=KXc{d3;PS&s>o5x@ZTXjWyg+Sb zFZF)+#cv0(ji!%)zXdH?U%f#aE1#!(!jprWThFd7`6>~M6uZ>HV(;Zuyy?{kX$|{Z z?(I+OvW;^(>grUc0fTq!&e!FXa=MaZS|A#ego5(y>8zWDu8;W(M*Pr*UVQQiwCZy$ z67}@y(|0U_dhd$tut&hYUn4Iv{`I8P(=-b~da$=C^1h;6@;>Jojvae(YfQwV^!Wz! z^{zb`s#k8^Bi_Y3r^oIh?uN#oo0>Wn2Ui+UR-s&-eg7&h$QbhebJ+{G$l_0vAUJOkYD>-IM!jH=xmYclV|cpH_M;s0XYB zlSxqwER_Jf<9jiNc)q`c^x`sai1LX~gtg0gadC0QK^rR{`8`5*K5qT!xpc+vk3DFh zN+$hze~>H+I6c<(*GZ+1{R9p6VPI5Uc$0(L*@A%E-0Ob1#QHaonuq zS%3jfj0S^_;Sm$&CEjm^#CxUut+XGG9~=!#2k|2n{6B7T3)Lj<4dTz&)~TC+Wbz2L zZE9-zI=}FQMerHb;$m&E_}_j_4$50&7r`?u=Q|5ouYS(!L97)Q|Ks<;LM|=*G(Dfz z!Lc>4Vt^5q|7qCWn*x6cul)vmjaz6Z=eP)0kM*9wfsMBvZ#wW?nZCR>%Yq*Ue)H=6 zeE{(!f9e!`{qWQ1=!|$l{UiL?n7r}oGN;~Wi<#pOIb(m1rR^g$vYz1nQd2;)-C_JP zp3~pY8OO?RMm8+}buRF>6O$y8uo`CJfaOAUg65t~MfTu}^PynsJHKKb>k%4erRce= z+nhTcp?iAQ-pgBB%^1KVWDLIDlPiNbM;Z9zImp+aa0J9(g zg+8(4RsQSkA7tPoBO?-Wazf!%GMc_Ddx&Mu->|-_iZLkE|EbbUW>qRsC{!+F8zvj; zfQej{pxJ|s)Ya4W0Z?ME(WvxGLaCB83)RNk?1JXvZw>Zh5}+1+Yq#LRq`8!b7Y*`U zot$#lImy3t^QAFwOx$!Z*^h(%*2=n3 zT9|8zjPh^A3imlOcHdqe!Tbq#?*V3}z1ph<% ztjh9f5RinjgfCR0N<>1F4HlJI5i!nxfiCcTHo;-KDmEg~<)_j8(>vSs;E+Kn8jSCd zzg;so`HOz=rEy-5=0lS0xiqqF$pzLP~&}2kBewzR*zO$fSHROinZBFU|RePQ&|4>pUrHkmFG)Z z#OesYHuO৉_@RHYK?qICgM3gY!80&(!b=+^Y=YMc!;`E2uKcA2p&!DILBPtF4 z=~J=G)?yHWYSAU-FZ+8tWzg>|A z*mEgxn)dy$8U_E6L@P#K^rgT{p)g!YWk>(el52;ta*;5@(frr26bN7iPh^CwkxPJj5lt76h;vVYQn(??M75Yax@)`-=bCTY=+Muwe2( zO&d$#vO3DA6;Vpp*VQbl-@P4~n9=NGm9)LhQ=8b9qKs@pqccsUnC%IphTDR3=mo!I z9x+kYjd8)1NPTyuQg>$s$_bkUVsnjqe!0&ZeIw;rVIeWs!C;MmUR~)-fB{1Wmg}b^2k6Bm8*SQmg&y?4aR^jg=W~6#n}c?!GD1^B+yE7M)EZ{XkTP?!;iO zoKmo=cDOK8bvv+PJwZCdw8qP{ufpHvR6W9KOC~JJu^+6G@6w#Q_~?SiscVR%d@<~} zxQz&*uSpTIPmiW(s}Zp)?THcTe+67^$JbKu>nSgE-zV6VINcC-N?kiwcdy&hckqY> zYW$~P`oGP|`bKIB^_ZV(C3=*~o5qnxghj-t|HFs&8+T3L844cDG(A+#`hDUJnnxC`2X0U{5P+}yf<&UO{=x}h%PY;Ywk;oHRyIO~7~oas9#rMvd! zO4XLG{Y)QOBj&+7(1{r0*QUGPgemH=NH`(#6XD~LT~+*{Wl8&a)A_e zf0wM_CrndLNY@~e#W|(zFYAx0mlmDl67pB6bn{@jZ76s^_zSJMm-zgFb6rlqZo zJPs8rC&}@2ixR=T&@)~UDzs66P0359I51bq@N@^F$Y!ARuf^FQR-{tU83slM_JpT` z5m>)~Sxn(_Obl2Dx-n7K**<^8ywcXV!o3?e)mjkZO=;||x|C;CQt`uL^TtX{;MaEd zAx#xoQ>Ex>%=+e|YhU8Kn<8SDRQk&OEzAvDMm`r3JEr2b?)_Z=!bURk5nGb&_~q2bz%UuaxIlxWvI**TCvn7 zZ|LMnA_EyB2nE8gsP>lsgWzuC*CR8kG7)+3>tw^55d`9L(AaBO2Sgkt@75*Pa-Cmk>Qr-zYY|V&*<8 zyhFB_V%(YAkyc#U5{!tzG}!mQV3>N*T_v%#QZRE>47F|7IgQKdywfA2+F0U%k@bR@ zXwem5HQ}UX; z4xoyXM5|Yu=6rnkKy^azJ^w|(#xO_i-1hBhDRTXtkY6jj9Y%o zUVXNjWI1=OcB{WOHXKt^)CD#mdlNWUoVLAETQ( zP)o#4>00vOvgrno9$ih~1u~h;Izlj>B0?9$Ix2T6cg_q_GNez;70s!h9s}_JjPIQu zKOrv&qLxV|dh7NN?$HaS0 zkeoqpUA?(lb1UWkOeL1H>vUM-2-r5TPV|u#oSR31xtXaiJ#32v6=P@O8wIgwy)W-I zVcK$!VO zX)yMe!oj!3oSc%AM@k{f-?PXxvwN*M{=QwB`?hx>DMj{DOS< zFh=>cW>b@(T8qJqU$&6PMcbRKsN*W4`32_Ha?WQ}+a0@|uY@7}FEOOdRb9iZN6OU~ z8=SsmJ~ZLT+!27^81ntH4pYoNix#B7R*H}*Y@-n>rpNrox1&mN*IJ_T(I|(5qZ_l8 zbI)9u>zyU^as`!`+nuHEuu%_XH|X3VI3TspNW`$CcCr+a65p;>iAkMBIAiz|_ z4u2QsN8`_}&pox>ahW{L=s2YZ#|F)M+FM)mR&NZ>iRPTrx;wVEJzR<3n$4w;;7N^` zljN@g&uBv_9Z&J5EpoAY$ReNDsnTH9Cm`!GrmAiIFr`&elQXkw^amH;G9U}^+6~Nm z)S+^L6HXkQoFZ(`4`5KoJ($(ojN>Ai7Gi=oJD0mdq@PJSnikleB9>C zHLWw!1OA%#*v&?nE;rjU>*O0OKEIuvrpoDy+RrWkv(CQpsdFF-YRlc;CtC2uoyRDimw!|tY3}`pxlBc#F6JRxh{`c zxS-NEO_fFileBn(ibp&=sMd8|0}TBY>0*%q(^-$VQhufK|Hw;Bu$k#l$;KcKpk?nT zm#xEQyA}Jt{BU1ZUKUkY03YWPIvbs8{apqQvt;)q7*ygBJ3 z!loNW=olu?WAPfumm!KLAbCy-ruSrGaQE^q2Ineg3lZ5IBM5#jxh1pl8?D7r8-yVT z)+sZ?YKm8~BeBBnHF9ZJ)TiNVMN&I;I%0V_NnOYBp;*ED3iuKr68B!JPS2rqKg78D zHE?D;z{Du7^c0tXc=ZWx|DH+0qnW}(s@LO@n|GQgjuSKj7rzKL=Ry0#+9Rku5OW2eV+d@1KA?(+mR@=Al4Nd964Zpvpm9MEy7r zVgSoG%CEBd+O+!oRwW*$AAonQlDG8byFbv~ofy3Qz0hmUlv{geO04!(G*7TxR8+E< zDu!7Jag@VUm?x0{EoXZ}h_WcnWJoH_AR;K2fvSqL?X-5EV7(b`-YwWKf6SslGa2xt zIOokyBFoc6UhBWh(R(n-j-9xHFf?7c9 zPJPAp4mD)b#Y|AC25uZ>o{KVA%ln2>FsbZHL6-qkj7q`b&&VWMH?Z=RvB;ur8&7nrh!FMU91tGe-KJL8bR=sfKeUEDbX*N@JpE5hU zYsqQL?aEv__@L!Nuj$^o%x_ERNRrLny95WO_1h=?7tKSMt%p9`(&m7aoKf6}SF_JO z0G!53lu&h13CLE`LH0dv(mXk`&gq!1!a9N4rryB3p{{I zc4wU@L<)`kwoa#Y8?oN!f$d#7EFo|~N=k}s__1s#z%c+IHj{T_uf(#Z;9?LjTK|eB z^cNZX4>80GQ{D#|gOCv)f3h5LYKGFC95_x&BMI{rSeEfw`r}IM@70TsGsKudJElqUi2*IvHx@IGOnHaJ)v&_z@ zl)Sw#SNlqDb2-jy7Q@)l(?0b@2y@ZoCfV;JkaGa)d^+Yuzc)!bgUl(#&KisE_(lxA z;UZ5gQz5)kr$TYmWFK-!I{ek7p%T~bwq=iV&tZ)w^y2Qjdq164#L1e>#Sqn*a`jG8*#hVRfp-I6yQ00zJc65mCMT6lP|FFGwxvkr$|XEhh~JL2 z-{p9?+X7l?rEu9UWW{d0SO5lanm~k**fF=WJx9;$+et5JO7rjNz}r4fW67gxWoV=_ z6x`V6wK$d~pzTT z#zjY7a9=njCd{YLt-Q18In`^2xGETp6cdd~KP8c1#hGNU5@Mg>b4lom<1G z37k%Nsd--cH$P^HwxG9{+`L6`(+w!-tVJHhBJcUY&Sa^50#=6yIg?;B&&*mfzcobFGYV+>hq zD7I~Vy{r|otR=+j+oyf$x0U4&KvSJkXqC%Wlh?Sha(wXeymTbfBI@Ijg+5$PN2HaX z2F2C2`gHXQuHZ`dRtwI)f#R)U?Z=-Y6C^sgLk`h{ZlQVJ%_(hfEgKnZ`K^5ypIY&) zksVy@Gffv3!^ctR-uAgyZH*?r4}i=z6|mU9e_sk4?#EwUW#_~1ESiQGo2U-~oKKpT z9A#6#*;#t~_@^#NmJHp4BugzxqvW|Kp8m-oNmF64soE!8FtbU1X#nr}2Q5Ig`StV- z1}XiNAD>bZDrUK12`|*|t8mgz0D>}P`b&`jWO`9E|47V>wA{J})v<+#e`k|~SIPlJ zwz0f^G5y`l0v*k*tEO>!?7bC?+}7M#u=BOQQ$)J2T)05>2sNday=2?r5#|$JQEH4qdUcbEgWMml^vPSfp zm}l&`YigBpi0)A5lQe9bziXyXxV76cJ~UY1yD=j*5v4`OI5?g-lz+%h;3*`}4Z>AM z82||rhdsPEU#-}1GxIz8=9qf8ELTleaX$LUIat*0sa-Prs13UtNSg`4A03Ka+N6yu z3f)r&2Yj7=S^vd)%1%^@8#+Uzzq6}3|GW?{Qa@7UOx|An;@W+#-a0A7m&f`gn19Bgv7 zC$*6}Gg8E~Nm5Q%lgg~(n$Vhn+#w8y(3Mdkh#K>1nc6wfn8|^%uwz_b6GeMX3N-3u z%#9%Vr4-Mll7L!Gq764$#cMgzAFYt);E^UdR`|NNNrt&Cn)o@mx^WFR-Qr$tK7|?z zd4o2NNjF}I*u!Aw85m>UE!>6+VvlClZZ)lTLT7he z0>*~pr#43(+E1>4U^!K_4q@PQjP8`>9$G|tsVXPz1#HNGdp{Ig&+k* z?=>g$BKJUpgX^yW=5yL>`g0t>qO_d%_1;bgxsR)uwn(iI;u~(_=G`GNORXmSZL3m8 zCYxm36<41Wa*`vL3~tHNd_uW83D7EZg7K?0t0FQl*{BH+E;(!gw@kFGu|xc}2BIh*1vyQoVi(SNM7+aqh_nGa%$Aa<*P< z3jv6LsMZG-$F4|=s~8Ep*xh$N*FD%0Kn6JOIuCjYiu~O-o(@DLo<61XTIJj>IoMa} zJ9o{Zl>G0ti9Z#n!X&j)4b$)Qt`(?50ELJPQ87^&{JIb$Wp4ej$gfQy)jK5n24zKr z9wOze@Hj%*Qz8l>|Ds7t;69i&UJMoyIJ)-v3Cq-XRLGSB`e2=NLVSrtLA3COl}z-t z=5J>-!#Y*)W))K+fgLFE#%chZtnM*SM(7(+M+?>C++6dez@LU}A3&KWvrUe*t#+qO zZ}GRtn>HH@yOxhU{^%HlV0N-{NZMmRbbXVAtK*_z*C@|OZr>9T$?N19fta_f^QNjKide3A;W!+ z1tPUEr%s+cTZ?yCKXA0?x^?pl5kn#&tViN^@f4s6*N*qByhWy%yO;u<98~VKu0D|9 zyBw1|I%(|npEUx?kFq9SCOmm^Ne1#bDl z035Kjb-sOGH+Aj>teUnS`2w+A6lNMwCoSj7?czQ^b*G?Dq2Y0Ll}f zm5YEi73=-k#`W*n&re)zx1qWFvDC~EIz4?2gI{mLr=x4PqCN^O6iYwvmYx}Fd?+i5 zJt9U?UsFj!O({OUZ(I==^-be}lz80!pgg!3w!h1qCmqMy;QRxwi$X0EHV$ z;;aEeeP1sGm^=`OZ?)c{_|WgQ;=f~1?X%ZIV+CK#yK`&o^M$_jI)5a@R&Fr7R{Tdf z{9liRpJr!Lwes*_{5_NP-)^gYkVX|VxV7Da`0wTaCZhl>;2AxLPfQj?w+Gn!uh&hw zPy@yA;1JvW^_^RPIT#w7m^^S`4`rMGTDn)+eI^gzTIHhsDf5RhKqT6Fv+)0V)E=~~ z!a@avs>CCE_tM(*pXZr*03tapxT>;01sfE(V5S%HmK^!=mUU(QFep=^l zJ1Mv0ojdO!wq&}xfS|#y-&Zz(rkGPSA`E<5RQ`bc0WjatiUvW%reQG2vfB0^<;cm}saR7N*^ffALFHqu@Q}Chj;PG9)qx)yIcvoqyec)@K zKKxa5{MX&?VyC%?TVtf_OOB5r4%odM^Z(%OYo?PwgynQUi)C%5Ke6!oyFd7s;r!-< zb>rb>-H9lIDZn%i^p{!h$-aJ}TO`YSz*n(JKdamyyfRJRf=Bujw!aKU3I_P$Ui@nH z{H>_|+)mwF+A}x)h!IYRWtV)Nw9i+Y@c|euJf>lB=J$vDU)~aKau~!{cCAC^*XH;1 z!6f`X)8Y~TZ!h-MGN+Pi3@kG5nZ*9I0nWWPVP^dD?o5mhQ__$lMsLDaDWNmDD9wmkA5QBuiyOZhkG%AHxGnF zUHh-|{QYu)-Gu^M!Pm@>r{ZF_d_b_{fUvs^tr_K1Xv z{~uiWSBV0p&bo*bK-3slF!*+V26!H#0`ed6ncZKo`GFre4AU{kvU_{q+3so6v!8^l z<;_CuX#!VgQ%c7U&>ee6$L(j`Crh_4)vFfc4IS8+D^C}$nkntih!PA{h-%o+ppUf% zXt^NV*!+$*?aB-=J(~>rqn4cKn&Q*8pQqecnFFHd)opo~sUvf>JKOezL9b5T&ScbwzqVZr-wg1oN9lgHdO~dFa@XMzDKDUa0mLv?Yr|W$4AKB zP^5lhe`BS(@QU$29pL}j=0C^;ewxjX%sB*6C@g?E>>O7P9Eyol zSqM|!963Qv=rxDL1h)dc*|`cnp$>^fjRQnZmHf64(Ik@sk!(Iw3&~iBqU*k9-%_Oy z9!hk)Y0y|^kaSKROij4Qs4%aR*8lYghD^WkR4we7Zpu)JqiI8|$FXmsT9SA$0`dCJ z-AtvO^5;bJDUqhCNt=wY1T{|E^XN`lf1_LxuGTY$v{H?knBbOes#(`tvm0} zy8yxpHd{Bf?kz?GE%*AQ^}?7Sr>1rXT5}R#H*9HkuySekd#ORJG)gY@j$~0?z_sC>=+^{U$}-VK5Q#gR^(I(W)jo}9~x6E3?es`865Sde?r8_DIUgvBN9 z2j)@_!>>*FT?!retl0eR^n-ln;=Iy;VVV5he$~FyTykFb`rOkVg1rz~<{oK*=0UR* zQUOwG45r%XzukGrZ1myATy01n3ukqbJ=cVLYy-xi#GKck+pS_h9{Pof^@p@;ywYa# zimL;LCg|40X*dB^(_hM*pI4R+QrAlL1+3;AU1}P?S6X%x86_zf9nn!X=+pl_y+_$? zxb6WuiR1l87Mmu)2{4qNKE?4art}B*`jlN}Q_ymtvTj+`y7F^$?Sf<3yO0eF*K1GQy$u;&d`Oux= zux-CSh>az3ZLL6m(9m+}`&Ie9W2_3}5p~(I=W-RtJ&LAVjg(w`a?__x84bI0j+8la z8{CqiizS?LuX<^MT)mymr*+>ygUvJFL<^Ax6->r{8U`(DUYF)EC9X8j!F2saC@q;9 zJ0J!0R#6mZ5dYZ$rzCy+$t7|@l2v16FL81&8QR~W=<;I~{m@ua0lyGYvk|Z7g5z~- z5zjtSRw@5rg^0$Mpi;ZyQS-D|x1fPZ z7UQTSd-C*W&p{UI$yfD_F|4@Pc8+8emQ@bnSk;Rd|NV5#ui&^nh=z+t)g|Mjiz0}# zfG>NZ?L>v;Y_;DaLBw` zNU~_7B4emW_~YcKmz2>H%b4ha2tlCBOA15SJ-BYJnhwFm;V;+U`^9tewaX z%7#yZT@b=v5S{`hI`rNbt>Sw4s1L5c}>WZw|m_F#5_#zUxwDZ1IV+6(wxY_UZ>ic91{C?b;HFBdt%#_iNVZG}>o%q4nrTYs50VU%O-h=_yeCOO-8As4$*;dIHe=+-e zS|uQOuR9=F)p}-?d{ap!zxm;03iI`?9<-8_-AR8S8o6scC`=oO{_qE+=nBBPQoDi?H!^N=jp|25jQ3&yF zlx3w)D=u9)U(0wj+q()6KH);9;eT%xWRio1{_rC+&8wnw0OE?(#l==>Ar~YZGD@f& z(pj|+qK(gVm)T2{^w-}g3Vv|n8;eaAaf2jAPd6<&%RUA35nie0FyD##;89usaVf=9 zdXMG0`WLMZ1xs$R2z@8BWi6CyrCHC+mP2_AeP6%y4mNB1QeMWB_pT_S|GXBAX zocwbnau4xAYT3aTA^_3$#FN)A>j?p6@TQF8MHC_ZwZ1|o_XDf1#InxHIA_|3q{IAL zOo4!Nw$E@t`wuZIxR_p1R8BK2Ge}tT3|SlZ*B7IUu&caCgCXB{F9}inkX#@s?lb$J z@yUPG-(Lb-eq8tQQLKEFD-f`2%cbwe8|I*ZH>?j6y*hN2oZjGK1;Q19zWjRhuEjrl z)R+Wuv8dEY7=Z>89WxNjmxoOr1(R&_72owd`QYhNL~agp+H*b>TXWw%g-%sQZ z2V=vrK*v3))1lYh=zMyY!U$NdeCmjHSxr=XQlUf{Ohyy)+SaCH^P z_d2=3xERt1VUj5*F>O56B~9p)d;Tl$&jCv^o_Tz#&15p#{iKw969oI-Y6pO5lYBm8 zKX55TE|yuY?M7#r?0N7ffe zZ$WMQAZvuRQ%PzV=|L~U25GjDzJTFU12l*i52#I)sK^%-c-#4edh}t5qG+E-;q3HG zjyd@`DR5$ATS?~}&~yrxago433JuK}8U0haAGczg1>cUkKZVY)bWh(JAHeV9o}Ec& z__hml2!4Q$ttxc<7%%aOmYFXQ<4tXE%waPpN>a{+Tk_mFlLHRTUv+JC57KRID`CaX zmR#gN2{w)*vBnV1i6p4+7Q~VbR?TfG+t9vJB91Lmes_^Y*_lSkvbFZIjaX81Ny6b+VY!#!yrAOdIYg)h@0 zT`Olwv+O=^!zL8G(^78ms@5*7M?ou3Ym~2@*6<$HWR1nlN<4x#9-6LRhdnhY zc#vGsyN?7#SdDkFDX8%K?aaBTvaK71udc8(7VNB*)LNdRF+siilX_uO2j&RaGLEqGF^L9kVY+ynTyCh|hONzWDDN$)2Jyz{_b1 z0d(=Z0q%XhOeJ;W;32`p_CyM$BIKgU?;X_tfR#!hEky_paK`;MPDc9?G&PN)u-lvC zi|Sa>_IhB(fB_DS^Q<(f=KeW#xF;p@%2R0rubu`<0ZY4+qvPOjfr;mt;5Z%DmCOTi)Ptz|3N=O)b2F-R3LuCDq#K-9jVjnXZOeCmE9V+ zp9oKRPyp-LMom7=;_(lGw7)sr<(Dc(AA{DLp;q}qLYO0tD?Ris3m&%gJm@qJ)=@U) z(yS4Wwelg^ddxy^ZAk4`j5ql21XBgQTLxNBfQ_!U=>@79T@IeV#W!Yu_So+>ULGnv~X1 zxN9}J>*H5PglW;L#!h+J5dR$x&#BL;wk@FSn; z?dhw<5UkYgoUT>weKthSm1Li#<2)eVGM>$Gv5@uCjDQw}Gz`z5=Hg5aUzmm#&A?)q zpXbxX5ge^Rs87xA5r0|ZB#8R7SN}4HOW@$L5N0(fXa$%khyv!%C2a2bcjIh2ZG$ES z5A1>Nho_$izwaiV$32;>Uw)|`$$Yle`3=r_X=`RcwDb}%gwT~^)7?;6*wzT#g0XE| zYem{(V~GwKi_;qY)@g2Z=T})j%B;Xrrb zlyrv&`RS?ua^4XCSh+ z9cIG%W@!BNmmk=ucGv2+3v?kNTR)^(O^Jqs60 zZ#a*Q{_dWv+_P{HR5Mjv37Gj@Wn&%7t;ZdB7MaCn!Bxhx%6ag%ygQ=$Qs(;y5Z6eC zEG&_$Yojf*-ZyB-9b7x-Qnk>OrCq4p{c>T$ahDsUX*PIOW$@D9LFFec3THd)1p~=u zAL&*rV}3vLeWetdY?Urc)7e@~;jp7;lNPsHelqV~+;1g)19l?=s)=xrc1l zMpPyG$r=gm@&t432WDc`bnyi8>$swoO5`& zHXOfYpK-z6+tM9c(ikLO0zTi?ZAVJl7;|o!p*TMNI*nnDcCmF?xBA`PgOiGI2OL2& z$1&sew5l*i_gv%!J6gds+=0|@(n@*x^RK({lds0rBcO{4b^*a@^FB4wuAUbpc%=I@ z-Fz}q9jkYomZIHlJztZCG(9nM85FDfGy_bDd4ddO4qqE$b-Aa42oWtr1UMEy4nX!s zlWZmm;F_yr^R6{g7We_XeCN%Y$n2&_`&&FVpY22&8Wqshe<4NPwG-i0?oibHHITnQ zpG&p>yWH;<3=5)jPbYSk-^)Op4ZO==m6E0l?FWx--LdX-mp^tU2k@960j;}JdJH~g zHZx8C9{BHGlzZZAN{p6dc*V<&Y2z0HEwY_G?n+81IVbUv$=(SQ#)`HsY3w;y61I(K z$C>uZ(K|+SRbpv28&0G^mRUEM22)_6rUvA1X-;;CR8U8whM!i{B z=X@3S>JVBN_Wo&`Qhu|l9@)l9WQ+~jf4#bm^?JdO&Cik+aIN6SuvlVtKr%ZsYluK{ ze-mG%$%_rR!mLQJ%XJeEg&!O_PBliaWL~KIN!D<|QibH&eF66_pD-^W8ZIkq;Zz9WxA&Fwr5$l!6gjX$wh;(#VUXphV#hU{W+*ZDBTh8z)J;;6aP#G%n0vDf!t@cu&*%rYffT zxI$Z9A;JNe#P2LR_+%-lFfS~TFtlC_I)&}xHv%9pD_P$tX}fMljiC~~Sx{^HzKWZA z+LnlSyCC=*-Xv9k)+4-_`+2Uui_#|o#f<(iV3knC{KqmR?AI-iD^fhtMJdAfAwe$O z1(Z$A?lkBYjEvCiUg}xuomlOeL~L$SJkwm$cs-5pt)9xh33=Px5S00*)l>bd%HEnGLdxfEO&Gt# zP{iJlqC0(_`Td zufH*HtL^|UPU}W!oWPg@(ym3yxBDLu>8D0m+tczV-(-lD3UCM&CWs@cZdc!ME~0L= zoo%N6N`Y`bI!9!2Y9(lpy8|qosEWQNlUO5(ju50xZtb?HO^arN6A2q#I1QiC^mMtC ze4r)@ft!@|AG#PEYLO$-6tm=6LJ3SEk#dGY@)wd&Ry>|Hp7(51T3gbF>}m*_J8Pjq z;=pZ;tE#l`i5tljg`ZK2u=ehSajlPIl-D*$#5{aU&(f*o8J->)2&Q`jOC)7~1AEL@1UQ$c61$3}mm<20% z#S$6l*V6Siz`djuSKH^Cu?12@+m%jZXfWbavOkUH|4vEZZO7k-U0V9VpL`10OOt?_ zgO!OZde#tHGIwq_WGv)1K7N>#GIyIMg_$F7qiuI`F^ld#X_Xk<>O>4M0p=g&8l>pV z)AWB}$t9+YRAOUXVk;?Kc@wYI6rU@b?qqj+{6NcxW1VnuIdkr^6O*t0f@&4t!{@Jp zP|ROKsseSVi`_^twQARm#;JrSb0PPP)6(1g^0}>*mgC{4Hl!*p;J2fi-Xn6t-V*v? zy4i%^^{vCl*?WK}&cXP@2ks8Y)1=RUEAE+ z`H`ako~yegvpM2Xox%n9(WrPdYXlv&TJ0t^%3q%WJNSZdCN);&47bDc`!i2y4ly1* zWPh6zp~Yd#KQHj$KL6np_r4V$^;qQ42^>BdNu*`G1PWETaPt4*?akw%ZomKWa_f%j z4nwJI*@;M5vdhkd?E8|T1w-~MLrU5AHOoxdw;|ieuCnih!C=ZZ7)xdh#`+uY`%b;P z-`nT$eLQ~u4aRFZ=UnHU>v^8%T=(C1?K)*!{X>x75z&4wMyi{X0f@u zd1HCx(ypG4EGJ-7v}U=BYD^A6DKL;PLNSQ`}ZFM2sEmcXE}c#R>{z& z)Z3*H(cP@wK)|U=Cv);@cws~SEa`@#K{lD9K^LRW53JFJCDWq@h!U+=8gqog>o|9c z3uz&F_Od&&&Cb^Vu5nZY7}mY$h|*;fo0ZaKs$u`-@ArSlNER0yeSu(^Gr$bV`#46czg^11|Fuft8J!^BRR*sXHd{_@olaK$ieZUbiR@gz3u9#-F%79@Yjr+W@@O zyza>GRdSQp(`*`8?3n+}2y9mE!ujx(@3Fw6Ic|hd5Jx5<&gE{Y9tNfhPBl;0UnNhn9@+*D$@0IqGRs#ss? z*1t?@^!$-J|H!6i_s3(YJlL<6DAOWbAero`=|TvAj><`A)T0jo@;17cJ?p+pqf4`F zs_asl+U!*S(Hj4Hv8H+2Z`L-HvYZ7PoV2J!MU_=HM~%uc48$V852u&ghpNFdo$4>Kz3{U#Pnrw;ePw|MBc@Ru$#`%4ukL}b8Ga{Mu;#J zmz_m=8_sy1-@f0gpPcIgYbt)%de%;Gyg0B-T*xInQYvVnu1~i7T3W-pMJ+|U^*elX z(yM7JhL=63x$QiPdh7d`mzAw$_<5Ym(j~j4YjP=i6{Tf5Uosx6|359gRQV?IDuBCs zRx&L+kh~zTa)(F4C4{0vZNlyxNohDBqSWzmDknmkf%3kqHJJDYe+@0_p8pvUVI*@i z3^U_QmqgWLsktaj4Tyn7%}+#RCSvXYh>P-zyy)< z@rOc=pRE67Q|9m|f#Fw$?DtD$LT~T~IB80y0#?sslwNaE=G6NG);(yHeHd)7Ba`fA ze)~A%otXAN8RNTrat@gxmFFguvaTOn2KS1!{ZK<;4dI+`!k^Fbq+KZC($0V1%c{{* zR8a!B;Im%4DRR15w|oAJ)5hBhr)n3-{Ns&mwZJs|9U?^(cHznSzicI7irjlK|q&CFP<~5uV)5RCodXsRAWLb ze{LYJwg@c3aV;_5JVP2r7iZ~V5%U@ot22Y-c%(@%1wEbXOsIA{EBoF5j#`n`vdxMF z$)A6+)zUs}5qO`{Lu1=#t-K^K_A~P}^>Qt-DM^bCB%*^&whF$5tvW>L%&qWo$F2bR z!6A8V%FnO=FTU?2g(4Z3a$>u-{9W46^StsA0|BVfNcXu$oO(-NX(Le5pu&oQ7GGa{ zC_#TJpT%$ct$vRqC|xwBpj`P=$fZAw!Rk-2sF8_BfC=w%Fmb!a&k~Gyj9fZcekfZ$ zS--M^s`Ba6=u=QmEvEO6$a64##mDsJM|i1VdsiY2)!>+oU*j50c!vo4B4%3-gf{of z)Vyo1$AQy%+Z433IHN79{INC)sQ(m|emJ=P$Y+#7u55;a9`SQr&RLbk!5_`znp;U@ z*^ToZY1|BNdQx#b>QVAbXfm1BBs!3xBv{MoZA>Mz_bYJ-Fb;SyM6~vBu$Qt<=ULGA zA~JTpPOkwcNsywCCZ6w1LFN~P;*Awl46OANP6XZh4ZVy6?;;9?!t>P_;RotpCiMiy z=Pn)ltaD0MBWyNU8_g&7n6@bs;Rp7Zo%BtbXt-k%T(Mt9jXWI~9OY`$9`wKYZZ0x$ zR$Dq+&kJ)N@P~fD_XQLcQ;{LYoXnabLhe&CT!A9%cAb%xb5*>x2X&je8KV;Z`YH#r z$$XX>_E=aaUxz28d+Vu%t(yR6rzWMj{#34!GD3Z44V<-kf!D|{H+H<;Sv8?=E(Al} zFu!ctFrT6&dQqmN$4^~Rz}ZKpS2^9TKQ6PEF2DZO?pjANWVwzqd}S2jE|VNlb5oq9y8%7lnOHHi zGU{jUW>x;!7Mx0Z6kBOX(+wSzd`q>_Lqj@s0>p4i9Kxwk-4`=y{5Yo9;`w(6B0n@zc0c6 z_6oXy?a#0Sy&*F?L&OCG6SoO7a`QDs^)FZ0M|N-;yXMWMI797B*XIkP4>})O=4c%1 zm-J$arzf~r>Kom6c}wA)NJ=<%c`x0k2VCQd#br z3YqlpPDFrP1|KMxq94$;FV!tqJyzI9syttcKg`|?5AaQvP zUoncCnnJ);>zNv36GolNEZQCnEIenA*Ws(H-`X3cwq#jS-X3nt9(H+D`R#sY@z+k5 zhVaNAY)7>fxGUb7+6g%EKNj-Xe=}j~XL7IP1lUT+t4OZ>Yu-Sx(`1eQB0Eh58;cLk zMoq?5;NJ2+^=VF`+Vf*A0lELus|okP%;BCO%JzrO|A(a$z(yv%UV4poy^4bM%Wm(4=KHHyS_$$t56kbM9qZh}I z|6i|cs_^9#m244dShH(ZqoS{Q--@bl z(L$SHv6*oP=7$56v%*tQQ+nZBUiY-L#tZ+TP=fANQ#^U{XWhY^>)&4_{6tK21i9(=AOFiW|9+=8 z!K4d>-O#2uPB`SOI>-eq8_d!r-0e!viaAc?37FSZ%&vZs{L>t)oXOwQ3p%zx`H`di zwc)-f{{?O+Q=%zNwCY1KtTB~Ld2KbzOSNhIc)9?MtKU3naGx|5&O(k%|6L{dv=;W8 z>pfG+3k$c&uSQ?}qNF7OA$5Az>rlkdzH9%>EW_pA^wr-!fXBH;H3qo+J=+P;A!G61 za|REPPL3IYTDGYP${FlF)Iy_Oe`Cc-D1-LFqCNM|j+FUnt$$ZhK+n~ylk4mkVxq-B z!eTk}*@E;~3E%nd*EOF{lSmz_)h{3`-Rn`U7fy@czS{o)x7flhWUKj z_>^IP56{|5>z|HTFIY@*ltAaetCKV)KacO2Nt{Rdu4K*Ynf8|Y@@^SL&D^KVY8{Ev z_)Lr!%a_P^;q;nH%E38D=o71_!cunz=X^tJF-W%tVCqj{{!i-+*d*_T$)Xzu9V1`| z+hM=0mz;}NW?wbwlYC4Q4VmhtwcPnMwk*3_4+*Fccf+naqiiLq19HTrnh(pF+V#7S z@sm5`)T~bZR)YyHWI|`+$bEvNyNK8Gvn)KYnR!X1_Ugi7i+YK$(g)`S9$$o`k)*~C z?~8bkeU8M%fClpWF`h|dzturQPi(!)S2av%w&4A`PR;zJhw4sg`X9yV9(6qRjATXJ zU6%{Fv@UmX$)|l!w2n2T!A;FB3e1CGS97*f4vyVhz{=Gp4kf9fp+!`bB(rV$oi_Rs z5hHu(b%A{j{3K~{{1vraQw{5HYGNbGas$nv!6Y43l#1LmNXfguCMC498lt!$L^9@p z#}pgY^jIWV2liMh_reb={VNA)s-vuf%r(=TESEA zh`{lNJ}jS3iLKftzh)LJ6ENW$jBiy{4K7mLuxJ11K}pV$R_nGn2rz4DgOa=0n`o7r znoo}SC^Z|V0QL6Z%ybg|a#nFAL^JgCEtBGjlN=s)lsq2`*nBWLvv8LieFG*Qeo4+N zI=N@FWwxd#`hp#CeL^Hc8Q8wb=DU7k zp~--{|4J~07vHNC%}7N#dl~G3>Jxeg12#dQ;t3leRL!g4hr5s4#o$if%m~4+9qc{3 z6Qg%$gy7vF&)@;N+e5;Jx!(dr|L&ktRplhkRa{EFUAA$g%|Bff|BI$l-if_=B#WNl z{%qJ1(&-R>^A3(~W$^bSFI2yf*v>}4Hv(*;ufF3T>mK8bFsLpGwK_^OayYNj%ttVY zZ9-{s4xXPz?p1&^?5Rg>NT!y0t0sJIKAcnfKLV8w3;}A2?aT!sG5$LSz2(EX#s) zmVg)CI9UOo?A*tflw2bfiTgGwC3`@=5>w7D0ohgI&+Y+Cev| z!&t}0}pc&;lkBMU0&>6opdbVA^9VMmh2ZGXbjZ~`o2WIHSNQtteVkYqw! zOE!pS*N;(mh1V%uoToNl{Oz77{@$D#mi>+WsGqz!KFg`O_bsNXeOuhoesI)Yzru;V zBCr~4A3~HG8cA-qsN32W9cmc)B)auV0##;MCScLvD~?U-VZeVL$M5s3*B1X#4n~P? zsmQj?1+gug>ZGbqA!EH3z$x(eOxP)E)S}DsK1--tI*TZ`UTb-zd&<08suv5`Q#w&A z>np`}byB%RYbD6_MsH&*c5-i{0aZi4V$!gb1)Ui$G9Ph-!S`sjfK#$vg{W3{@nZS{ zY;`l<962fhV{_$0J>ZA;4xu=UxShMPmo%hdSlnmoJ#iMx*aKRfu0w$c=~ow zh0KX(BRmrS>3Zb^ea}n-Lo|5Zu1ehB;w0N!paYwwU(-$XYFAz)*9s1~Jf_ zy-~M!@0vLXb*2HhpR8M5njGKV*nX!WzIV+i2}F@aF+0M+XWyp>hMjF|uuSoXRP9Ws z@7J@MjyvIB@|d!8Q$ZeQ3m6lHMn+3p%Zg>wOqod&pm43{qJGW6tS*spO%tAvb9L?7 zuF;41q&g79Sx(gqBvM5qRo>fwbQtTae7r+XnE^4?zQqo!dn3NX7&Y^LVt1LZl%nms z%aXGKlSgU{lr`AqI^``gc)F`mnd}&(HJr)`nyBWYWk(WoZ-&~L#io$A54;L&2hisZ zTFMeR5+Kp^5GMeW*qG#v?q24A9Qs6>xaKq7A1q=w+Nv;OO@r;m z7{Ce64qh%SVlzpcLUlj1SHQ-spsL>w6UB>6v+avIE9Yo->*8lvUx!OKCVixnMFOq5 zcOys2CZxSI`!@3hi{gtP=euN+&9fqDdoqODT(9MYV65E9OB;OF?U^N~GT@$(BuH0;c}N6=`J)o5;`@5aE?eY&k{x&vW{bqwMK z0sv>tXAT~=+_t9jHrWy=pHn6W`0b9k>-OD^PnRBQW;XHa=YacM1o`V%MvKSa(J$xI z@A0xMKYV^+t`8Mw^mf&3@$8{qYHFW^bo+8gY0|+5Sd^Ztm849=!fR7Fs!1y7Vk}=C3k*&pEu&sq#Uh^TpxT#_y3;W&#iW;-g3njC-ge$_i|%leV`wH zswl20iv(;gG+e44_xTcg)mT<3#``I0#`?FV%+ojb6_u74tRHxW!YQBoZ?!V0kT-?; z@_#MW3KdSHJ;Rq$I#wf8!4F!E)-z?1GaWB$6;)DI9+Y8om5HglOyfA+l1V=d3?;e}(l%OJycD z;oEg~8^FzwY0|m72&J zvX`;QoLVjxIMP9NHidT4)48unv2w#(h%zBL1Gnm68n=KuZmWgiV z8&2Hd*X~~-)nUtXseIV)xP<)v023le#kaER^%dVq`2+N9N}-T4k)CiOuBCQNz6-i7 z?VF&elK3J&=mRg47G?DCfs>^_L~989vc;VZP0DDVw5+6^Fn)QrefecOfT6HwkmF8S zcB3Dz14=QrYlqnz8LzBksXuI3*_`t8UNPZ2^bxzAagxQ|pl68E_HNN^i=Ov@1shKh zA3JN4*#A8IH z5kmKIP$cvE;oJGGe*0n4YBjY0ciQhQ#mb^>rAunphALAf=)DTNTf*q0g2C|O9tPTe z5A&+Z^K(0IMfV_|$1O0ToN}W66$h=A85?I+9)LnnrOC7NEoqmD_7Zcsvgo-Kt+C}; zddy>b27_E|r4s>D5rMUuWE|SbnnmUf?r!vNb(LN!h_ar3ImT(9A}EMn+F^jO*h#;( ztG11A8p9Rnm`>0*$jU~%EVk_vUdR@@7 zjn=64rqx~(HrCuUwEwnbc%&J(s^&24nwI=mo^Apdy*npp$aWDK;yY8VM{eU}x}vVS z%+ADDAO*T{x6sXA8<#CA&(AF}fOhJQP zGMc6kysegCYzXxaNXOj~tgPpe?ER|8gc|`~jT{@bZ%v!`OoIW0oD5Mk+21nAs~nzTzT17Ff#YBRyc0=*L>B$!HZds0*C4yP@cnykh8_G^XgrT52c>e zr+()Y?1?fND@q%r-%}u%3Kbk|?hdz2}OVE*sEKTR5ku@62uX5c4+g((s z5+m$w9_;c2YS2(X>L(5W^PY7FMxZSfUF7@uXIc^?D)t!}-^L}P0g*&+_g!q-+JIol zTNFhGXrDDI0-Ubl95sM*?;%`{s@WWYII42#_N=+zN>$i(t!c$HDabrQcSI?Me-kjM z7P&4HRAt;4WTJJcYtP7KKKcZHHu{v$KgHuCpe&u7qgUF;yK-&No@Xr^=Bv&7{2k>} zU9$1v6s-6)N=I(=Fbm8&-rBzy+tA#v@qFP@LUk_{i@vdp$k^(V7~$B60kTC1W=`u7#eGMx^6wWSnry@&{3*GccK-~ z=)@J^-tEMGSt-K&R0I%;E-KwE|Db58J!|LM;)=_#DSS9LUooi|P)!a6uWGqoi6Y@& z_pR}6ar0Y7QoG~k7-@LPn(puxc2N)9TbaIn>SU=}NEpF)`m>SsRxF`;_k)r5m1PXY z4XuBL3yP9++`LW`*2^lFx+s_-hupD$Zo}lGT{c|q0vuI$)yY-kUHn8H6P)?YG+YBE7vdLu8>9ZlJ))MtTb zG^`myxLh)FS8`O=F!D_*tVLmR$+#q9dPdoV6s?^dv+51qq`UVr^VUQ2!0y2?UPF7U?RB5^t+BC~H8=Kd* zl-ArP*hn0`w?A=BGSrGOlX;h?E!4ZnW{!j;xU3n`#6WJAmK`N+KsGCFBu56HS1FYC zQA)ZVI^@ag4Ed>Ka$h=mN+56^v3K7uO8gqO{Q8|_nUvF4X1G4&jPTP&ziuz@-6i3l zHJ@KVKTmMoX`;R4HaRJuBntfCj%hg|>j{o5yk5xcQNiV&4 zM*gm9)xd|wi!&Gu;NZ*nM%vYmx^jj-Z2RUUAbO$YY4FBo0xh4sO-K#9%6`gwE%H^o z@Q>Q9COH=kD=p!@SNny8?I}V3F|!--H|{vMTZqS>5I++R3E(k8xN;)k{3r!7K+&~M z8x)=8R296jXO8pLrROk3I++AT%?8LWqU56txia^g>eUum05ma6<2A{ki31}O{cUGs z^(8KF8oTD%OwNW~^qNY0o!E2F6Dz$m6dRM~elBsgHudogA zVkWDP|Apo#@?&Q^uWkjPDQn=wutc++lfD5)X}R-sej{!7zn*v**rX8Rm$~vn*~62= z1EFWw+xZU6^(8a5pu(bNH|bl?MIIq~GVL4A2YbZo_pex}jac8ndPMK%2g*q}ssqzW zud2bGD&zEABV9zhj6Q-_HncUK-V4)7V(r~+vh=*xga2^g8q1A*sfHx3pln&l#L1kQ zX2%YAcn=vf%0oXoA#pFy(i>b`pjT^E*RbaYiC-l4lyyms6|HB9{jBdJ81RPFNm`Ds zGPZSf9&Af_XVkRuT*Pa-i0$RYgX`xm48JerCQ(=#*p?HEl?UYa#_PaIlfoACDD7L|tEn&ME#P_MG|8O@U8jq#tbsN5UL0KFkl z$ivjZQ8p9Gw^$uILV-hppu6ZR8G5CDnZXSbxL+*Hee(7XD78C*wAyWGS%6RLR;bir z7PW|*f(@hqIebZewnRK;fCNI!zUhgl-uW_{xU$gV#o~M?T)yB@9Ap`M`Jlx^ER=u8 zEo+T&`SYe3mITRF59TV`+(gQR&m}bj4lq3+jwaS|CKtagLXZeT@Ph||-Kj^=JS{q<71_y~c_ zGCj`Gc9M6P3N-Ei*!O%xaVlv@|6kkN8%|`kS_V|y>-{RyQy%N3Cl6hNZSs97V-5-Q zjSHO0t84;^_lSk0YI(7~MUiiG^&Lqe@1&X$6|?Aa?f@$5SzArU5SFFbRs*)M?TaB+1A{QmN;DGm}(WG|DVVR{E&$EW1q4UK_U`r4Xd6tr>i@YZwVH;XS z83P>W=hYSdc1uuiYr@Jtc}-p|YlLpM#-naubax)zZ|{&^GLo}Z9;vn{WhdDP*R9|8?h|+v}N5E^rVQmj*pKN6G5d`D--2ggw zIF}ix3#IKnKv2uP61AH-H817a17xZVi)&tvBghqu&d?Le&DCBn+DfomaSl3k)d8juggz@Z+ zDkh4qu3wp)7coGFjIi}_6st`$m2fh=&@+}qCRI74{!z~BKLe56$!U0GzM*El`=|@H zwVT~XZNNPY?Mi|Y;Ml)Io{H8u?5Zt zM=TJbp`Z zJ_upQXRFKa0o@*?*Vthg%XwdXDPKIAbbi3&5kH%Nshr=h=6=r_Nr-l1o2;K(y+wab zNU+9}G`2w{j^&mX^wX~|e=8q>+VV`7F7Muypl|6k@LPu0Gx9&q)fkJHrc|88V3Ah8G_b|?O@!alcTay30D~}qmZ>^yx{2waWb45khXNU|mEx|3 zx*)&erSkKRU85w2Ec?ph#CT#`G&W@X0Y55IZVTskKHfxan76*3^ z5qoSigE4n02dAe+W;xuIZ6<9glc?rQm`mNf@Wl@aFPMo>sT60lQuMjl;--2$5_8IHqp?t<-i8wnd)BID9U7bE zmAT*uP;=8T#{iL=i8_L9dUdLWP^gdA>g$#Kk1Q3MHH9Vn4G+XRrL?bJG$AYz^S0+Rq2(j8QQcd4cFw|IDVh{Klc z&EdVNSzAGU#<4$I7ulLcq9K(JFTQ{an_n=a;jib?GM@>TBjb+4jnNQ|>3i|FfIWsZo zaQ&kKcHDoW8eIFQrN4=OW^s@2wNb{qD=k;wQIK`7DV?L$jJ*4WM4sZi9|DI;=9sxH>tfRNzhUz4>lgsNY`>02GnNzo(2Q}$PPEUU%#+cl$VkFaMY<0 z;7Gm=`(yIGw*6)DWOUah?z+G~{UvED=3AI?+>oF6@vEKOo zsB-7qQk0=trP2Kr(ab~jJsGDakNo34Im6#fm;?yX2b`rB&^u^(m2t|v#_e(K)&74+ z$l2id_74uDH||5g1*JQFm`U2xZO08OCj!K2ZwCkNJ?XWWX80G+S z7U*ips7^<3Z||hf48v>N;xHZG?{$LAm7ByYTxAdR|GQK~Xrf0)V--8plLXAm_z{2m z!e4ilJ9#oB;<{RV(ME4AH-FdZ0zwX<;DJ<;J2ZQiX`*+v)A+7J)`YTud zVN?bbdr1#_^`iEqABq8RpQKOX)PI8e|A!0wqM9P=Q6v*E*mv89itp6_6Q_@h#OdpK zY4(e%{`XhCszBoO{eEujfB%nPgd>;Il)32Oa=gO+t1y}#{K@Hy{QsNN_v67GL<72# z1Pw`Ck8$iQi6&D3OcDTl1T8ZC&EHu4Mo~v%v+oyck+Vu@YGd)QOCgOEn5w(%GUC5*svS4KytwP5 z$*M>iQdacoMUJ?GrHo~eQ^oi7NV@KAI#$_<3C+#Lv8XBkLsbI0eqEUWYup)*@$K5~ zwJ*^pWv-_ri)89O;5#eW5*EhtIPQDbT02bh3Uo@t14U(e)}xfySayTR$Gd6w-@20q z*)5UIf6bd0ZSDT>Nyv6BTF%Z-jFMW=?ERCgfEdn<5hh&PCksXv;_RBf21XZR1!c^R zoqk%OXB^1_E4vbJawTBMcYS8c&F}F(94}T09ZJwj$1m$(t~;f|AUdv{@7*R7UDoVi z-nQgAAZ%OCqOSv|zD(l4`Xzr%mW4ctpp%utUBVs!wm2=xhSj_7&P1pdkQBee`A_z5 z74r}7U&q@2mH9`-{4?{9ezFLW2t|?$=Wx6Z%Nv0=m-X zc`RQUCOcWLid50A>rIz5G_Ut|zXE(aNpwnG zjuSwLMKtLl=W?8}pIM-go&L<#G|D1->DO4axGQs^`);em?MaFvY)x8mP{j{W>mOEO z~wHwj3|ksOoAXMwl#vyuvA<~oTtmz}8o zh***xHEc1~T+uHFm1 z8;4E{lCvbs#}<`nEFJIS|BNEZp-u4G-RCnT?pY%;i@ZHiEP<-xd!r)BpS_zr0!~R> z(f!j?8s4M&!ZwQSpDd-Sld=K&q?S2STvP}blR9WIDe@67&TI1yVYVCs20I9j(W9Ih z(bvdKexqS^8jki{;>XWYGxVJa;van>$8-|fh+R16so9tA-Us!5P$}4%uTMGc0=kuE zXk(fT*W2qTh+p! ze3LmPqt9sNgD`LO-p-4qqngS7&Pt;`m#U*S1fg`eep)se?sWV2qj231bfdhjBYV9l z3C}^nA9BLgLoHK(wJ-y8{&n(EDSZS1xU^F#fiB$O73lW%a#2%Y8deS>`>gpkJxZ7P@hFGJ$QqZf6F3t)`ryb>R>JH%u;+`88O;a@KwMy7?OWH;ubFNGp^p5U+q2OWoF!8v~||SH55YG%#~^r z1x-Ue+*c>66GRE}HCb>jOVO`;q!i20Z{B1kPTe{!g^J61M2n5jMTgf=HZp%RUaXZd zesU=7o?oh09xjVO(=Xy6+gI$B;r>SJinm`Ey=)s;%r76CZrd?>&|IvI^5v5Ih9-8`=J4}u$zox$%wd3?`w)^ zFtR9+?)hVK4Y)S&z&;#1=-@Onf~I%bXCciF5aAy3OT`ZEI=TvslQx?OLQ}~p=Rb6- zh2r+`eZ^Cau^uz-NhToaq^A~y1gRII-MTW$^9DI3=H<8MJ(#c|BT^xe`%-y6j^QAS zwoEq}T9N$=nZ2H}@t+N`1jQsr{C>3gXliN?stC^Wh7w3|ydy z?BpHsD;TBFn7%N-mdf^|h+XV^flR7j`8*52@4Wms?cFFtO}(mBX2ENz*Rr0uNNV|3 zdlnS;L>)fm&nNT?+K6RC>f85otcSNOcY<1PUVCFXo4BdSyW=}kKQp{`_@pRUjp^Z- z7ir((172X6nMHL8X&V#9bSi9#)!+@_N*xJeub!Sg_A&u#ly?D?##Clhds-_o zL69|}bAj{z<5;T^i*c{ovRq%zF#?9aL_^Z&)i$@9oC9G|;+0w^`vbcPT~~Px6Bc1h zH9QyfOE-{tpF+=CDU!5gN4@%Mi7O?yVVYNF^ewHx3chWaRo}*=PJ7dzN4uF$+r?7-0XRIl;Z7(|)oa zEi8eMD#Rc^iekHrK#%>vIMLqU2$g^A3XPqsCsoC?n(uC|G+f3YZu9o_tqYAMj3@T# zO2IZRcimQLvnW&_)Bc-J+oV)&=6hR6-VEqcZ~NL($*U>h^btKo%*V}E33H3XhDjq5 zs%1I?$I4huTRTwkRQZUE2d!sgA^Q`4jA1@72&ZBEkFfwZ!~^Oip2`_+T$h9>XrSL0 z0=@eO72tm{6O}j-!hw&(l(|Jw)$rzaap(0TTB0FXQ1(n(>Yh`XA!_s@bSSKG2-wMZ zrk;ZzBE(;N@Df&)pXAA3wd$k{Dz5_d-s#DlfVgV*q1VHBuB;DY`Spu8 z4C&QJ{t)7?Uu|RT>S;K$>64UlT7z`{_WRKk>E<2jd8rt1k0HJ)Fsf5M99EO4zC@*+ z^9L=l5N94&x_C1&U)-egx_+@6d}-Wp={pYc*EVRBi)`>ga&Q&65qbSp!lm11+*~2| zs%7MD>{YxkqDt(6bNtzCx=D7{I&;2?5A0w3v=^ffP|0;LqB7W7U|meL^nZtQrJbS* zi6PAj-DGy#Jg!$0Q-2syjhd%P=3k;(%~C?f-0PWd6I2s zYwXszLv`EC!<5=g) z*2Kl70ClnkAPp+vQp1w|2Yb=QbST^wnI*5My8&V?lVr^+{2o5O8NPPET;l_vXA&tGL97iAXNC%#EM-7bxOQ zNE2yph-X;VZ`C4{)~OD_XK6r|Lm?()adD4cx{-`N7e+xqmRn8~RjM(j4P81aHL8`z zxOTo$5;Bmq2m})!7`0jOAGuM!E0-TXaGb0hB*Ht1Hv4$5pDHWvfMmTu2c}7Sc0(U3 zGXMvcTSAA*=~~HY3&@6C4lGXYQaU1TD7hC*Vjo=cwN;{ zZ=@=pEYzA&soml#Q`h!Fhn)&oEF{v_X_1#;eZ3(sPOdykRZg2kLzk|H% z$QGQ+fK5eO%oAm{T}RHNZjyQ5e@(0QXiwN;lWdZI-Xb3BYsY*}`g9K!%1$Oy=yZ<^ z>M><=(t>-&7FXXZC^~=hl|^BW2}l=WtTS~FZ*y+S;_CIBgNEEq{>PJpJHs3jiS@j? z>dEmYpkexu=)GG3n+dSmlJMau9oTTg-e*^Zx~gGfjzk0OTB>!1Z+Qs>NaEZ=5zY~z zTR;MkcQ|og$@jqc^se;jsy!Gl6w;dV!g=9UL$1=U0#lp20kRyIG6H=+RnW+(w&~8K zUUUi7kLFk(hnt?wz0wuycfI~@+G%HBxW6;J(iePTxC$65I>We7d*q&NB;BdP{Xq=$ z2~k@Nk`Gb5BOeBR>i59-zf5A&#CGPx#eW9Dnz*RnJ#)%$SonXSQhJ@5Dd&j!i%ALZ zoEkX`Gt_+Y19%xxw7Sk_gEsUD{`|>M&CO<5L;9R|s_wEsi3Yj$s9lnDc2Q`d_{p*} zuSZAE#-Nn%Cq5cGqLkZc1u`o2drTolikS`<_P4-QTL$NL6=POcnx6f>A>Wr9f1|Y* z1@t}~)DfJjdp6qH3O2u7-<=9v+L@M^^IvUoDsa%X@GUjFR`$(f<)wqV+1sQhchKz0 z-BOtMI^1J8h$pL;k}l_)>tk?{z29!${cL+>Qv@l@)?nXs9g$&CiH51TD~&a?eV+Gi z5JAb@y7&=q8#QcMpq=)F9R_T_r6bAg!+>m`fJ_y?eXkk3Xa>0`iSLn36&6bOh9=8i z36nSg?|dndEMKcS@P%OqQOjj47+n&FQUy|AnhBo(Aar{^NLXOg=$*sen8HFVWnHcP zEs;rve&+rV>6Kjab_3U*3xg4M(rJiHKzi;oyFwLF)=$=_ zTVCvfY^=9@XiZA&!RAQ38mu(U1&%|SGb%9c;!)n_Iq#$Y*%zEskeeRlVPtB>Z5!xJ zkFT48(eksYc+>`ub{<^L%iN9IuBsT$BflxF>mwv*sU|#oslO!ZDQfqV%rVA7qTq}x zwU5N?2Q_|LXm@{ZQ&`>$4!>Q*^GW+1YSxnOL@o)#WhfJ5Ep2W~tf}BDb=^QOE5Z0- zVCjHuoDBDYFrWAOMWr{PnpwW2(+M}8-_8+b3o|lo16WkhNM<{PCtxh|a>o0C27;ZD zuDA7r>Ii^fkmzQLP%e=Pg8?8%YY44@{0iOgSm!%xo&t@o?2B;?aCeoU>>|RZ)69qx ztm#Y5o2d=W86r<7NxWE?ZpItN61uqjV$yQ__|9xl3J2*6Vb=FAz~0305lIAi=fv#% zc`MnHHaOGTq=uzQS$oBNLNRPGt4zbcwz={KrjILp&I}pXj&SpB*x&tY*>7G$a3#^JJ97MTyf4eKrug?w`#wPX%(@BJYDS>2o=CSgmqxG~%Q znL~Vh1hUQvwVCO!Tg*NG8;aE4Xx!MA#%;cehZ-%_;4y9EYtx=fDd7&ly_H*uWiV?4 zj0&u>AWJs>*M_(NeKJ75`gVb38Pq=XqZ!eddv=(JKKz;|oC9RZzAq#lw%j_z@k(Z~{2t2Ypy9@1K9ZNJx0pVMw^U?8Y4 za|u;F1T>SZT3tzln2Mz~tY}F$);G%7840Ak5kyxs1`?S{WJgAGw9O+1r#zrVaaFAb z8S&N1$znK8d$|G@>r}vG@+51OcDwF$`8cv(!8L~$?g|wqa+SJ=e5vW^P3ujHM5p;O zqmsn?K9ufG*~luh6r1`?m%F6e=gu16s=R0i!P&Ed#)LCat__a+P!}k_d(ZWCNq3DA zIF0#3%Soe@p8Sz(_CF1j_zPX1rBqGx+1yz2S`>-j8q{jYqq{RoUdMZK#jc0Im_S|? zx3(0eC8SQ8AM0*uy})(HExgkV6BJdz4@+_IB&2#DFNHT$0mi}6oKhoV@27u@UrT0Y zB*2TsrAL)nOW4k|sWvxIx$gpmu(uRr?`B);u7Fi~dAd4>n40hEtACm{Np zwB#I9yfoi93LNhmwOdgn~ZL~edcsVbX%tg zI7zC}7?i5)DO;09kMl_9wtK8P1!x;J0h?BS-Ew#6P!!U>S4+oQvsOZQtXrkf8^@&# zynLABS0UcmyQ|3{i!}D=6o23Amsr8nc=xI(ud}n6DUdvzbEWMj7%AU+6R_+lHS*qL z-L9RG>NRLfzKN}<=hD6Yhft!cX`#+O$1li-919uXbz-m*hWbs<2EFzh`+c!HWs&tf zV@t->oDSLI`Jc1mH|__kHfwKRZ_OtH*g2Ad;lLfa%g4a!4dH;yMsXpxvzL9mt-MJC zI0`Kr_p9pL+p2@4rBxSM_eni=K$)ku-CBwJi>@R&&+Pjy8R=vdR2 z-UafFkAx#|djM&j39y-HfJpL%hRun;Y8oP^6Y16oKl6}SeH|~U@&J$9?T&LFc$b%= zK$+7lXYbe1rZQ({c=(w92sEcA*TEXoF&3t8pA!nqdqQzoIuIqti1Zsll#3!i3eWVK zi2U);AO>M)De zid8A9vD4V3s;8(uW2eKY-5}HoS`|ChlGs`+B}R#ei1GXAIL~>`^ZdTw?|*q^+_^vZ zb=}u}jraAw%^dE!sK2;gT_{7MvE?$4N~AuGU-)!{>7Ga2-_UW~p~0N1+UX+aZGv$<@~RfBz--5bB`_Gj+K|D7fM)+ z)GrJ~#?FL4#%-<>5(RS3eBIvbp|xLgmbo@_1c@Mv;ibU=j8y}u3H zYK{u%6ckuM4r+*Z1Gjv#-7dFn4DhtBgG?5GTuoLz^9+g9{uae_IL0x_)6zKU#*wtd zhqHA&U4fj=*@BsJz|JCHrGK*~`g`BIgYeKF&!{)HUl`GZ&nIiD4GKCmYMv+D5hIyj zxNRjv;G6PuwQI`~gM4eAo#nJ=FN<|)V7YhrLk5{>)FksAUpnM*X6wy*<%Q*8NN-Y} zoD{XbYLr{vz5_bI9dz$+3GDCdrowhTK8Wm&DHw?-yc1qMcfebpOSnLo(dG>iP@KD2 zviQ;4ETp?MEizk_ewL7vM>DrN$@P~{lP0;>Hyt2O<+#rIL?EqfqAzS=#qT~R4!|7x z9NBLP0IwBAb$Hhkl0=yWbl3RY0`2|#y?4|!TYQuukp699 zYVNh>{(ZCd@{S0On=UpJ>x!Lw;L}6VywXHX#4BS;3%|Wo%#~d?esjywWL6@uK=;6- zFYej-!}KJY>Nmty$@(zMVnWBm>VH)Dy0af%;0Hj+5@}hFD{R$@x5RU9kEh+}i@@hB zO}xEn98(|Q4Fr1i+e+L%dghQ4Du7LuNE7@wOy)3FM)V6>plA&yum{0**x!EABGNw? zNWtDfq>UP}#nxXnHdHtwml&fI-??h1cpqHYi84t*^o(c(qko*c<`8u5RTnm=nJ=NrrmGFvjtNA&m^=tLDV zw4b__DE505m7YZnR67HZAae#>LAi#`{3K}o4!Z&#>BsRJ1S)iDAk?$o*27lCTOE8! zigrBnanS$C*K6l#NWPr$7-U0iU+-wZqTP=zMC_fE(m*qAJwQ#s{GT z79o&5v-Y>rXtTo6>-$qHuXn($+m83?vf3bDyfSw*4KA#dU8@y;wEk#1TMTRM;(nv) zEOt_f<=1ar_lH6T-nlSbCLwHbiZhpPJaPa5BzaSb+#+WspRVqqSr@N1R;&??G|*!$ z!XUvD*56`n2NfD$7n5xPL~DC)@WKG*eJ%Y+1XHX=4mCS0csK_-wpR?@%(YF$50DDC z5-pk!>NzC0oZdR|6Vb}oQbxIZZrrwcR!5n9{N0sd3B&_bxnA&}_B)$qsyVl9>UXTG z`p&%i2-C~N+%58-WVG%$aeieiyyGuHaTH>@b~ILq0oIc9r2;w9yiFTY3D79C+Vrra z(Nsnq2&kB0qH2c-ynE3|-PJYU_QAqwl}>tmU7IPTnYhddnshsiLCxdhp#wKV99aH+ zA%A0jA|}-0mgK2KysxXq|56@TXZyJr_OY}?HE;8d{uU?(-$H~}zWB@JJL%h-Bh-eH zQsM#{Bqkx6RkRSg9>StZP(-{q@p1d^W|Z9;mq@`2DMjTo&ntM00@2>4W1=~6eLnr+ z8bE8fdgGfao_l)JRXrLwo~ndD+sr@(QwPZwGQL^gfv^tWfv~0#zj;G061OzoCZb8S z58d9xgHTubIT^}bsd0&f8>Sp*uv7NFiddkV-RGZ0qqOv$%Lydt*yFM@p$ z*R!MC2y8{Snr^(|-WPq*$U&7KK*5e?-RPM}v?VR%mGy81W?G!pD7bGBW4H8_Y{173 zM`*h6Z*5A~*H)kCQs_7DdJ4P0o%*@HE7*5nvmq9+k`g066H=Bhbvq-Rin8m-uUwe( zLo{4g3xFGNiA7~0#{Y0DniV+De}S5!ju~tKtTvh^C0BMiU+#29JbstwhPyg}^%izo zq#s|LQ<|XwnW4CTyK7G#T+omxdJsLV=ELnWq46)Y+p~kA*NWLLpGK-Z@bL;UgrC_; zdHBXa4((YYCi{9-YT}w@YVgs6yFgv$=}TU4ws=sgn<}x5hVIONtXf!orY$l7Q!+}Y zklYmO2M${5Fh_&hs7yCeC-S;F=S1!19m{6k^E4MZE6nJF>xbAq9Xy#%zEcXR@t7Dt z$~)5K5Ou|cskh(nK6_^KWvZ+DmGBhJY5wSSWRR3sv<-~Faf&<>5?hcmlJ9oEcXktX zPIY#xm)-|(6RO+3EJ62NF@;Rrg6fX@l#ZxCu`a0<$cp8Dgi}MGF1p~`E2fCt z9_EX)!xd!Tc4}))<65wnyA{wc`Mz$+WAY<(+%=zIlTCpxbCYRll-zPRSw+4!Y0T~P z4YlXq4kbnn8jAvHbP4J6Tl45ADHA@B4^;@L= zq~i7NSo-tQVcj9_D8Qzz=_Ku3t(GX0yn3HKH*du_10!hZ8V2BOIsd}hrdDHO= z`Zcf6wl~kDx7zkK$yUZHq&I)KW5|H6HNM8Y=B*fuvfU&n>7G?sCtdgtq%GUS|BAF_ z07W*3lD0|dmZ+E{J8-Ew)Q(&Xl(T;TeV>*x+io)93A6HB$=%HKO3k8oENOYF3ly0i^IdtMEW= zO-8gV3rFKvbfX`~H^_gT1^4DDA&aIe4Ml9-g3BJOHTiI{c z^EufHWn~6oR}Uk_PF6I+-8=Mk4+_r`NF?nLzV6TxU*`W8Kv8b zDFp#s8%4G@d?6%&Zkc$&;|yV5B!aAB zr@ICAPUkmW5iaFwM_Wl_5ErOhhV&1L<>ZT%i%{20|4H1v*al)F`}MD;o1-^{nJEoZ z*ekkuZaSyqhbm;Nrs_&_BJ0jTU-p|rAtU8_Q?K1d$|!lUrskO=axCPfeTAU@0dy=0 zD4moZK3Cv%UpLzE=<_XqFT#YZ4R#~3Mg=bqI7VgFBk?C+#z>%yhSx9#L$bsog^-*7 z$cX|iU2NC+GowthDqnnkS0tbN+U(J!N#HqiF|A&@y3fw?Zai{vk2C|K__rwJLnc5# z7AT^2LFmg8kRqU-fB8OVex3qQ@?R45TA30vTGA1ZJ=<`z)^N?0Gd4Kbj=1V5a`jR* zY~=O8L9O6DqOL|1XBmTTzw#PKbyYPw-9_+~Wvaxwks@m@Uhs(W zTp0OqQ6Q;Js;mXwT^B35h9*7v`jV;xO&z4(Xd4eXu6`h$K! zF0OuO_XEdNUiF`E&bnywEP(H?NBZC zeKwR){5-GMaV9-cPvDBp--)8`u9W@EcIH=gU-AiFX#bAOz04HS=u&TXOyQF3Kc>&Z zyfq=zSp|A5z|E?v&HRk@tn%aL1EG82ci5CnLMF%#8+20>bM*I|Z@YApW zs{$SX*23*{vlT{K#6a`!e*JknCgW$yc1A0%N7?ppZ<1ps{d3ik%A=_#W`2F|#G_{P z>1g|Z#7%p?Z77`+pn}s!9&db;&9Zz%)$=~G#J37xxK=( zhpprHyvaQcAnUw5yZ09B$LDGCq1OZp1%{~0U$TN*75}knd$O|Px_QeOV7Y^DyNZ8j zLCa!&ZPw#*;oJUyI*IvbzoUjr*2^c9H86Zt|H@`tamL5xwT}Ga0+{y$sjptAzFMsO zFWlSqL(JR;x4uJzRbGgBdq!B z4@~hK2e;U;W|D%mB@t(QoNz|80Qp>i{`&UFV1aMr7YA;Qg2u zd>8+Dm3@SwKF&{nizt4)>`v1_hMcx z4<=T?{Imi?oZklw%qH}S`7bH_j9R)=e`A^+Vm}=FD}Ve!>*4kG!w;1X|HpVh47^7Y z2%sx<>%=Zi{5w?G{v1=uZPSGO@9O$%zwJ#ZO(Ybk+2`%?Mdd=d1cB6b!yaSQs#^MA z-?Co<76~8x_}f3cRAAmWwY3}|dR&_l0QS72VsMXrENwsVD3*tQH~i=00_+^uU0rXy zxSI!P+#Sn*IXuk{Y-+2Z-E9U(@qJp;*qY$-_VRllX525$|9b%UA1nXQf7$y&=nBBd zI)@ln+-VmX_+nn#2Ic7b>uL5@{{J+}&joJ&gLClM>E&ye#-C~Q{U=f1|8*z;rN;qq z_MHSD`s@P+5yFc-N97$a4+dY3{-CrDW=a2984wR(rd=BF% z0#M~;(_XI+F-6bxc|GbdKC9PrM+&Lpz0ugg{6k5E;#}rFactEz(V+N8A z+&LM)!2<42{x68I@3r^}xKxUFQ4&}D!d;nnYLt6x1^rp1%;X3wYUol@Q! zzsqEe%v7seJN&Uv|mByT1ie*jzW^wRDl|9KRIpMA&cmb;!;4XMgQNnCLg4 zU(viNgy9j0+C#P0)_28?iZc=Z)3m_w)S;+SobhM>n-5R1c1JYl+al#J zH*l7?QWC?iuur;Ptib z#_c_u9*^r?KXNbQ-Og^P2gk911Hbfn5ZKL%M|SpT{v=iahQ3!j6!RvPL=WBx|3%C^ zAE?1Td|=P}-@}81L3~!3b$7))#xLK_R)*y-t+mvixbq+uaX|nehC2|dK)HgrH&*Xk zz6t1%li2KCb^-R{7X}%FUEbT6(Ff!6$*zu2XJ_Z~dt2IpV-y`qKkUO!{G?)8b|SBw zemc5M4lcb$9khc6yA2EohD8$kP`g_s$sV6Mqo7Nrn9o~uilmRS(wXyZ78%r!${K9} zrL`R$Ytgz;@To&_I7oSWNGAa;+`zlR0C@*^^Olm^{ zeQM=81tC)8;ml99{aN#5I|&+g@usGMeY>oie5%?=0WRz>B!33mgYDh7Pc>X8?J#?Z zwA+!aZ=mWEM?qTETR9C+8)Ph4QByn^37t!sR*r4`~s89Bcays5B<^`zAFH_ zKfGmY*!^y&3a2+q(yjC~Ep9#u?-Rn)kt}y!%&vXBBp9iT{~K`GI{Pg-*3(8N%ATcH;Q&v$_{h<_qI1c|nnyo8e4yi^f|B)nq!acC(deuUb z@PcmlwIVS%lT5raD}nMj31U zkF6IPBlLkZqyaC#CGc-)O#oiV@3pvjO8Agq=-)eOn(r}3JRap-+=H3!0q%WE3^4qm zqq`qc-n152E89H*_^skIIlRVCZ~}m*Bk8;eGj1@5K%nrxiWpxtF+Koj4DK+DUD z@2q`M?Qqwe3OOX`&0p(dmajt!lWj9$ssxG&B}Rqlt{51hJwmL_KCxox>`Cv2rOc2b z*DGpKa@ms_ZB{86O@;n4ekb*81Z{9PgH1l3EV+QRGa7_FK?vQ{vM(Z6G#`7~ovh^^ zJngLHtYUxgfh2sw)?P7Dh6Dhx^}J^iuXds~h2UjQHN ziiVyFPi-99Y$k_(frtv(oJ%2Tqmz!jiaSv^cM|+@<1^WZD{ZoF)UaahB-4>WAEw%- z)AZfj?|P&2ozbFOjq*|nJ(a0}SizSC1{9ZQ1@y1pi{F?DI$A2x1|J!lVa^48{4QLxt5_-nN9$=Za$$Pc2 zL0CFWYs-Iyt6cPKY~hu77fN2PYn5g{de%+f6mMRZt;94IOFExArY2ZUIH7-6{y@ab zW~Bj<-Th+O_((kyc!%EZi{@LTiShp&ZO_5xZ!`*fQHghaTu1)LVM+RwTs zTqr97Mt}K>|J9!WeE&1Tcb8xNpoKjSy1p~)zIG8Pe*ovTL}-Svc%lMQYu?#QZ~v1F zP@W@B*l(&W=GZ54M!B`Bm*RJ@x73>%7fIuXFZSQK@aa2|Yy{#5k?am|e>XrR%LdaOzQ5{tv=@ge z_(dYi*1z^C;lGo}78thGLFn=j|1=hU-odaoAtoRsBG@@wiFCQgUHXkd7?m&&8F zHt%(4s)~a&z~V;OufzBiQ{Ft;Htz{b(cirFwnkbySBUvUh~?iQ0%u9dI81SGG$Y zm|J}3Ku>fHDE{R)H*k0_zOMFntG5Sc3z~A~H|G{{XtRlwhSJkz4E2{HTSsdxj>5hT z!4#S%&1gv*-AB5!3Uud>b~m1!IrN7EVd20yznX^26JZte`;Uv*(I6 zz)!2CG;3l)3bT;}p~@g>7gQYb+tdLpe=fDf_EF5&HY@#W zp|!Tn1_{C*r)W3&mh-NzPY)0A?BA??os8~3d4~ezu=`OO(2f%n)txhbODC%s`7t;6 zF7>48ccaiXAu+cQ7h=7F;8G!?v`E>u3h6MV^&(9q3H96`s^8{ExZo6G*y{gWu9FN~ z>}vaPLn97j=5NP{cFcO|FnIPoI^MHdCdS`}U71BREf)G3d&?5}!0nm<*D;Ji#TOE6 zqzPZ5-V-IeYgmabnpo}Is$R!XiPP2u>}gWuGC6UbsN95XWwR>~IZuEqud66=KQCN< z4=I~~#LV0*L7N&rL`ymA-1rp=w}}aHmOn1zI-(~fc`BTTn6LK1|L9JBuThFvQ=W1M zy=3QWLnrmd+3wWCLvn`W`9aq)$1cj-#xIab>r)nc`MlZ}f5ZDnvhv@LrObccXVX`+ zuy*)j@Kl-1+$B8@%;xbl0dGZr-j z^}ns?n=y~41~st5`p$>1Y2wgpCynSIX`(KjvuXa;s{VC)e0tQ}9(4m^R%gu($a&){ zqv8#EHep_63Oa(-Au&Cz!@Pk|Xf8o|1dl1C)KYuq0XNR6{z2x`K{X^v5TeGstN^>Y zFsugctnSQg5?#1$_M*KXZf1grkaJ6Gw@X>hh&Di?^?UkE+zY)8@Cpzcq?=z9tb_kn zKOEJnJm4&O6y+uAV7P)=_3EkF>Nl$%>E)znLLu!VvxRlqvoW$pPu4ti z!4Uki1miNe>+JbixblF?pf9rt?P(n&#shS_Y|hq|8gAQ!A)|~ z*Ad{~J+^#DtN3nH^L+tUAUt9Dyi%Gyt=h?<@B%hnY zBNs?JIP@NJ-6oJXA%HjWzWL<2$OGJ`yGK49T&jcRfv%ajx$D{%p11*e8qBPKSAKt) zBzm<&b{*C{e=W06&aAqNzyOULmo{RG9IT#=oxL^3zc6WJdI|%8h)jp_DTT-|1Najq z&=UvcyIedyV2>L2vcp5wHSaN|i;+>A)~YaGJ<&l@U^}BJWt3_#YVDMJ(Wj8RE{(Ndw-O#b^q#m^CK{4ss*T5q8yHj1cv(=iY z?|}2}nzDw>*=Ip|7%0sgajG?>mHZY(BVO;scFxzn8==9w%}O%QK^*mJ4D=l`D~cQH zF!#IB(Xd-IbG$Th*-udBj$#{psC8tcE#yK^OLBRw%4&-k`d-~~a&%!$q4LKW|KcSN zbR7&%E~bkjqzdutuH|ZA@IpiNO2!(gZCntV6aB?^-s&m&YLPylU0d3O1nSB9$fo%2 zVnCHz^*heA`%(pUGGszs9ZZz``DXu2xSb-dfv1b~oVZ-r<}E&MIv7dwpK!9~+pdK# z%cqhB_6`5MnL#S)I|%-i5sNpJt5tz&!8C2Xxe+(_#s}_}Ki|4q2;8^jO$Q*!L$Pk1 zv8%V1_i$4gFmuc&_6yvGW;In#VxYRS4e6H$ zQvZ&E&)on}@Opyp3b%<-X2B*mrV3V8L8Z40aXC%pnHenF_)8Nx>lX!aX<_JWWdUE# z`9pmiJ-lohTUO6x+k5gpD!hDF0W?hv^B40I4b_M8q8)Xk)2xiD1lp9#>E&A={WbqM ziaAAeSvHL}OSgJCb=|PzO!XL5$u@2U3wadLKX~7I686|RZPg_jt&cH9@&rdf+~6X7 zT|_hE;QHKquzTZ^%gdlu*^54%=0i#$aD2u&K@{|^mWriOxcmd`BE>8VzjHF0n5an#E*wE>*3Aw~DA~2j*xI=*u3`X|H2pf%I+Z_)$W+rtlt(=VwRha;_F!ZwnoH3kDQkM2bJHfq)M+Rj^_JL%QA zoGhR-%so?3C6)kN8}Z81}F~(Ynt|*5Td}g{N7FwH?O5O~J?-MbWwawMMl(rRQGmDu=90>e#7CY*|QrqlKyT zJ+#f}7M(+^a!_Rx`i}&E>JkJ_Eq-ilo6(df&>^XQ`k|&`Zuz)7al8MZ!H|jInJ3>Q zo`Sb(3)g3of=wV0Qk67kmi|nQ$F=Sm6yY}@B>qgkun29qix+ErogwG7xbSHyaIyQ2 zl-{g?HHSCt0#)oHZb}_p)&p3wz!z-T7x#>bE;lj~Z$xTpCmW;Y+p698ATf?$%~>lf zXxYzZrp<7hXi?=)h^}_jro!;q70alwCv_8rV+t-dL`M`_-$rbu%T(eI}dJ ziyt3*JnTKn!qjAxa3t*^+g%qm-ZR|GhfWI~&AeL`(V}~3-(j}9Q+Z~VgX4FbKmXbM z+0|9LVO5SVjO8HH)4QI>IUXgVPce;)w#0e;0s38A=tMMnqG30x8bOen%x5TWK}bQMUF92soHi`3P;6OGmYMC zn-pz)He`LqUGK@n47sIWIk{YszVRh7XUX#2-LEhO7U}hzf?5M;rhd9KT5~vgksKt_ z{Mt6)k-T>Z*tU4SE|og!;mDA+<)HSuS+3g3lTMKy;7P9iccd)*-ALBUrM+F+3^|k- zJxXIpn&s^bOuhiW4D)B?Acq1wWG&|Tr^=3L3GNzp(nP*|2s{j;8#Ou=7p{Sq;?@nb zk#vgReb-XsUFo)tlhkoxJS1*ed-w#&YTJ}_Y_W)D5c6r%f;_^i1X@-lk+=J)tMT|r z(eer8N931ND6+aHaFHdEfg!pVdy=YGBLz z#Sk&;H=3}Foo~|trkC32gRB;U;Lh$YQG?zlSDNm_9|Bd%Z|-0|O=RVa=kJo3(9+TJ zWTvF%0b+FJ3+!om2e*abW_*A#EB%YF0XQ%k+kb;DW>*D?19PHSqV} zy@kL=o_Nej!H-LR7Tg>PtDucQhD*u9*29Y|H8H24f}zSx{w43x^kI3irktwYY=Jzw zOKcw!c0XP4H4bfh$(Bx$icOc-Aj)-6pElQTRtm8|bsE84vieq3i-3_^TCKOVoQpM} zRL9~H*oaSruLde$`Od2HhdSb@a}aU8RHK|$j=>r=R$l9u9$D|F#bcwlz)lcqI}HiL z_tef{4gtiJ{9&~XuRMA+?V6_23WdIAdEgnYDT{%t7Lo==O*L&BR#can`WYpc6a@Q7 ztTGnga_tn7$J4gjfI`(UaV*|!-}3(eGmyd2au;huNSibGP7~XZ9{-vp7K$vmAr670 zZn+vGOS|4wVMm9J{C`NOS%Hc3E?;PQ!75J?xU@I4Ho*yy5`tdCcrMGRl6A1qRnseW zH*NV)3c<}MI0xl)Hr*B*`7T^QM$m(5O+NczlsLY&LXW_n9$4vG9G2dbIkB}x@~GU! z7zNMI26|wJY;Lg&?8FIfJ!1@NAH8bHSzk?2^xW{rpNw^s)5x3q;R}*-iIf|hwrI&n&JZk|9LfuPJ zEH=YCw>YIJCp^kRzB`qm$w%CjTB6e&@l>!KJ8h%)}~*5*c8;XV;8b>=GmKZ?~MRvZKM5H!d*@s zl{br1gHUdbhu3Ja|Bx_HIA;>$e9Rw;TRB`7^!sf^F?aqcuuZ`ONapYUkgH$Rj(Uwf zK~q^BVo{>0tlT>(aY54x#j7Vh=BagAtP!yRB;EvYXdi+xXG9FQ@?gF4`qRy3QxUq3 z`~2Z=HWe$%S`ew_oaR3X3mwXM=rU>H%XS?T=Yv~uwI?Wg%&AJggvA=OrSE&Av|8r_ zE(@JZ#-!fptx4v)!~z9{XO!49VVEo{=_bUYU^PRD6D~JAXc>&?Cj~euFI$;DBxn3B zL_RJcOVvLTPY)RK)dvOJy377C6{3!45tVvtk9sx?t*xp1V7BRI%kKiF6HC*ZDDu19sHro*)t%q7DE#~xf z=BS*v%x{A544*4@QW-zVl z(n+SDo9QDHZFjcyqv)Y&9z}gS`e>ZT&TQ#!!*(k1Lyzs~_4fvw&P`jPvoS=i^-Q;& zFRII&+Zp~wozK%vlpza;N(2ri%Ja%utXN?r($#j6F@Nad!c$IxWmdRcsv?nZnY9z=@`=nyNb||jz z4Xeh^OZ?Vq#~*@7cJY0UD$A$!lQvRdk!q@NIYr_CmLfwgxJO=u3U|~*k^MT3iZ{##t=a{@`7^(MUoe^cU z2tG?N zcdol-H`~;`vPmwVNb1=3YUdI6ZmdxOEnh5xX^+-p<~Mi{D?HiCqoX_TS!wHI)?Du5 zuUj|9U)Mbq_Czy*5y$PMa-VPl8utBAvyRqcZfkRG;C$J4G@c(Vz)9&lkkfb~`Kq?V z@hQ>N^JPfQtqmh`O$~X4*hqzBm^3wlmpd3T z=oHmZR`&qLV$Je6tt@TqrTKhFou6mbV>|Yp2yE5?>sZSq=>pLskkc$#t@@Ajq7xuB z7lx0x6^3~WpKzXdc81iu67XOSYh5hbC?847=PMRVlFg9r$y?)-q@rr2B*5 zkHEux{L9dKT~sli_+ zV<#N4N=6=0z44IByr6$qd67zm$8D16`*Mw=arrCjOWS$7#ATmXc zKs(&O2!dxO(=%WP++a%!L|VZhveuA+aox4_fzb=jV`16V3LP^8B=ESe?sDbGaPUyZ zDXK|1LvI{98}d{(`S&|UF4ie^Rr5CMJ^nF4v9;5TlubQTe|?Z_rLPZJ9Ypcci)~5W zC1TexnP{jDvj=S}u((%*DX8qrIMy9DxUPiRv`4vt7siUG2zG5LQF6lLw=FXQ*R2N zYLZrlK#0$-zsHA3Kk_Hf0G^z6lUrF0Q!Fi8r`A$ySm}0wc)g)1i)2BG%;X{$$I8Jg z~Zq`=r*s+Lk75_+<9pvlQi(*VJ^P+JR0TaXI+JzkS z;;8?yWB~!G4H2bz84~C51ZRjw8Fgn^e-(3%MX)Nm*Ks5@m=|*4kpx-PPK+E(svcKC z<@a`tD^#xvWIV4_#6N$aj^fb9t-GS+ELW`tOi@5j+WkF`uDvR>I4m=B#nY<*_&y$#)ed1A4lBE_#g zUho$FbVR!8yr>gNGu!9&m7O$JF-QIi-Zsk zG5Z7d#ka_6SDBW5N^G;OmQn&SECqo%t`xMHZ$HzpO2s!imo9?qeUi|OaOtu;!HxaM z`%&0KK(VpMkv6dLz_irAJe@KQ01M*-QKoOqq-CwF7R8AVRgTa;knh_NgWRinQ7XZf z_^C6ol5lC4RKFgo#LR3!IR4`d$RAPhSSR}$o}Nh7bRM0qQojU)Z+8aFm9K`BdYP<( z%Aw;3+8{DOztLS8i!7nts$Z}(|NH@~M)0pK>-4TI-?kk6glGgdL#=hwGJvZ<*e;E@ z<9-=)0$0Stk;3LL&nv(!@BDpcgIrI2=3@xE&kX7npL(CWqc>G>lL!Gzpnfd9l3VDA zYO(a$%Vo~$*yPVsbx^@zN+xxrjH(vq&Cea$j`(JdfZsg7s?qYE^OZG=5wWGyCPumP zia!DUYUeb^_3+iG@aKA({F?Ifm8I@#;wQl`JVZ85Yciiy%^z31;1rFtntM&TiyEDVDd+_1kTJL@tTm z56;n12SXa*OJiN0ci&0GE@Skq++r;6fg#VV?XG?`bT=;!F0Eb!ubl7LXOm#g%u>}k zUXx|2LIzj!B6g~uQ3A8@O$qz68x2k%OBS0wsMa&DLmJm-+~&6TUl(fIwl)x}z&$yE~CY0i@#Y8V5pAEUx%E zLu_Ju$xw9{AlF^*Wo#N4g4f?i<0b+rJ*z&Xi%uG`%~NO~f>r*QV*drPHOb@ggejI> zcZJ@xUT8FSJRvUfA*sFG@F*K@J}9$KcejgUcHUuCdq9nG-%NWTWd2tEfV)6!h3j%X?nwH8d)SXVB zBL%sV)qRESUkMx(Z7Rfy&&^_It98KnWe6DVhDWwH)+-BEV7|Pgv^dxGe3Zt^Q`!(v zW<>QjSyjqi5{>h-DLSP$i%ISHfDxG&$U$?Hw|0C;NxLb{kz6G_{skYL_+vH)s7sAJ9d!0a{I>dZLL449v%R9R zT7>)@FIavwGEqD z-HaEFzyv~EJ8*b)qbIAqi;+R(ki}9+uk#$)*Bw!;?!T4d)4%;e#l6&xeo|?jSFVQL zt1MbNZxNocaFj70$WU>!6{M6?q-SC=aH(<=_wVx)Cfs_Rujq);kx zi87C3VA*GxV!Mc)I*C-bVD{<7jz(tAxc$P&XH&rF8LZYa zxRl?f2hBSr=N#ImuA3J`2A5i9bjd=osdoA6$+BW@l1&@?DK|d=T)do*Rk*WEt2t(P z;U_w4ZflNI^F$!-&g?{mZ_k7x%8YaNiLPH0ByL-`>1Zg7gVg^3J6bcUCs7Q{o9Uf% zBV?lA`CF@nHG+Za^S5dwhrLVcRD9X_4j1$z^F%p?WVyF)+D++h`o*y1HijOfdX-Y4 za*?2tL&3dw$s3~)>4_AR*z%^W#JC<@DW}4evC8xO# z=$eu^$;t-3B0z5Lom}eXFzOSaE<4X@fIb&==Pd^l-k4FV#0t_!khOyIzvT^@lTcws zt7t~U1g$~sZdUYw{E}TKyd?Kv5+M8g-b4+Y znY2D+j3=Znb?GUAP;(`f)dc62k9%j}$SxxbS_*km_N6{geLI@spMJYR?1wi}&GqVc zlfW+5QNB<3>tY&9A--_|>+ZeLZxhy2ICiIpS_X!1rpwBEmcf*zm?FcO z62e#c4rs~vv!60w$3YE0d6#}ND!uk0;8d$E3H5tU!D_|N!&AufP$((Z_-kHjt;c6~ z=09+U-ut&rNfg)xa~-KCB!;CB&ymvTZJ?#8mbFBVby|;n$dH>dR%>nIX0vvgO>`!! zPXvoDLxvHH4DPBYOubdc){c+V3>DJ0_)i`*-m%hiH}$YVmc_wHo_(fsU3H?IqeKQT z?_4S{J@}jBNvoDOht=0k(xeiqsr%EOLkt}m!@;~$piYZ`Lpe|FY~ti>1MofGu6WWr ztUppNz?LXJHApPV@iEHdtqYHsBB+o6_mH;u4lSG3WX(BMf9w{&K;D)GNRN5u>N96s zVK;YYL(_4j9B%VPt~vo4#I7&h7rW{&o1(BB_Y5}<)suW!+*`h8>Jc(Ci1sr1*k7)_ zeQZXsVgbBsmJW?sHnY?t)TcDLjj)yUAsMsEw1!bbm!ZTbWn#vi&jBye4)7u?f;AOu zU|S7YBUk5s9b}D6ocyW^dR~&Kv_7R+OS#tyObLOMs0XFI@nHCv_ej&$i05GMOTq1r zske=f{|e$k`{YkAzb9yjGx_42F1QO)A3*u}Go)J8Tay|glh5I57Q75t^%vRon=kx&dMXts5}Szd{kryE(cx-c z7HU`G!i}^qaWeW{m;B~wDZKpl=0%Mt zD`JYbVJc&~usUT6*yAY`Q8$zkFJkq^5cpCAG`d_J8>PKnccqcMRU&9)AA`-xbgsf) ztd1+Fu+ zWqp-(puJJA0r!+r5#w`!I26EtMVgj9_GaudcuzO&^`Bw?z;8>H#l^^3H{o&@e+E9R zSx>aE;gWW5PZf>T8l8~sml-j-_Ss{66JOuCAP<8DNd&ldAii`qf!nGUe*UJ7Ib_Ng zvFt+wjvB$8dUlBN;I+Mcj4zYp@#Ol$W~{E_@y_|3l>_b;DMLESzCInjwIE+`#i;68 znlzr;(1)ZkJ|1VX6w(y>n(d`P`otLbA4*jrl3nXBR_~pt&HSOIno*>F1FN68K%fVT zSy&6U;GAhCK4Y~XyIL!_d_mnQJEuN6W`h5rnxe;F8&I3+QGEDa*B_SDS?EZp96gin z_(zlcE9^Nlrp=1C8}H90G0u|ebnJ4V_(GZ)ldPoI_7NeC5#mnQAH7|r0p`kkDGX2G z>XHp94Hh2wnID4N(+YdOP|e*>sL_ViFQ|!Q$18;pR6fvnW6kAXH5SKxm)Z+PRp+mM ze?x_N5|7Y%Z9@0o1~`^u6Q{ZNugz@R-tnH8wyycw1zS|6+Jc3gY`PI0LcK`oa4ygG)f}4o`QivZ9<$0TlDZad@{$lE0P-u9w*?EP{=jpj$AtmdP zH^Te&wVU@3W&Egu$>=xhxAPF5XK4TRTzfAHM8AFQd)bm6FY8PDA%e~d7&l&#P!~DC{|I0_s0Y9XbN#Ao7*KZe7JCo%9re^=^ z0KkgzocXrZ(*s|+I#6UXlD}S zE}#+Q$Dni=g{<-ymBjvU!~Fa!C5cdyVUfbQf0yY0`s3ys2U~;M@u&xfZ^!;?hM~nr zA}r_0GmMGdot_#jwKO0J&g3jA<3SJ7+2~_ud8uB<7ed!#FpFiCCYb^4qOOIsRML!_RWQ zuZg|eJ`@squP0G?e& zTS%aq7^TT_8)~s+CyCdiFndl=buG(;ApR`v;^{0(@zSdd>T?mK0sr9E0 znB#mV7Q5uh*^`74sM$NT={{O-^FoByuIaJ{eV{aT-|*Y$c`Z*a3SuEwd(X}!AV z0J2`utdJxhxLIi;ON%URb+3+TdC!7jVpWwh(Yl5hB`m8}f5N2BCqWVij$>*OR9bjlVgi!6Pnzrw?z3I^Z*8a83c(-zQJ+s+n zknG+X&mj0=FNwsZf?@>ccB4izv2i+zn(s`cnP=jsg_n!O$SVlQWJ-2xzPMab z&V}d=hxSd=IM)?+<^^R>3_nqtTWQ4J*QTlG7SEhIc+T_In3VNy(( z%%z}E7W-_mxX0fPmA|>P94xBWNBQjv&%l=a0&gH@_FPliEYH}Tezm8~Y%4V$so!$P zxlWA=|2SGV!ZVnH*&~@x!j&OK2wE$1-r_=b8ea5GxZ+)-L7Fgo=#2G+#q`j)KP@|e zxTz3k`fVdw*kq?}e`>mM8XMsfCUIuyr;G)v^3FAdh(~lX6U5|r`3y-Wd7pcxYMc%C3+UB!D zw90=omE_QW40pUFu_(E(y|21Lp=!&NS=~Uhbrfk2W)$Y3a1m(}NUQoq_Y1PxOuapv zemheHWwsuC4ug7cz{w%C&Li4GOVRn$o*njjgA?8q?pviMU4@ZeeHpsslfH@FZ|!P} z__4&sVJyX1G$P};?w2RDl9y9GBZ+NG?!B6BK#ms?;g#es$B34xQDRxci=X82i zg8b0<`3T8wqshAW>q!O$Ex|2ei=`C&Czem`Q#zlJdiDB-u!FXpv}yAFu4dg{9`h>n zk#}`Gs#{BZwF#c7j69uDl%Mcge$P*PRuUp#WCSJn#@&3GuGCeIdG6&H`?A%mLRAii zy-SrMKG9lfL3kxRlUYpOqiRAmA-#)=cj#}R*ZDtD>pNb@1d(to;W$;u+cJmInEyEL zna?4@2vUxr1?zf@mrA}l*{5~?y|!9LB13mdxT^~Uq@U}G?YkApMIu|?dvZxVFB{*4 zB5`48Ezj)~-e?}JN7Y7ooLGZ4SnG;yeG-_Q?!xR)#`-UEGB!@?-@0Rz8jc!SukL(F zW3~k7o1=7Xe=FULUXuRI{sL3_1a~JCo)G=Y0e+iuGGjUO9`MN zF<7nKNBy+uFp9vdw-z6yF#}UQJfd)4n~;Z50M2yoT0F+grCiL}k7XfBGhf)>@lOo24nOV;+U9&<>TXsl(BeBsA`>zMd$t+N(LJE)YTo#9~5x)o`@`$#gnLlK{v~qD$IyHQ99#ZG?h-U z>5x;pVvnr4|EyZ3zutdh&k~6!oLo`=f&mtF_J}DgAVuy@Mvf$1oo| z>8Ngn2Bv78d<9`dm5PkYiy~7{L1qatnn+6WO;&t?|5;QWnJTn9C{tiBK41KJZoFMe z{dE&F8EP|zszMocs|^`}SGvVf@6yQorp!zTN!I-DTeC^0GZ-X)Onr>1vd=cUnJ5Bp ze|DRP2&nGr$`$P>dy)=sJd=RLyV=RXT)+4lOq0jVV;_;oXB&ut%vf=79C(@Tk=QKS z7fwBdFF#nXX>Zk$SQLdbIiOZNsOw=4XSHr(j!3sQyg!Y_W#B)y(#4fRGo8&0J55pf zZxCh#O)XgcM=x(?>^Az~z&l^(Cc<>M{y;cG!NcZM)h&X|#EUwrC;?s)l$}Ukr{Oty zpEcTZzks&sE3R8TUPbov9jOZRC!Lzg#Z7;j4R7|HZZ&y$@7N$X2krMHm`2Y`_$N4& zBj4Cm#GA*L-=4g@rKMH^)r*mRzyHek?KVLlA%pZ0AAb-Vft(lIY7?yPPW|bU;ZIH? z!zG_iVpPrvU3^q)SBbbgpqr6zeY|eAm?yD2XD$X(Ufq0dQ+HnCdh<`$)8fSto7+rW$Lg}L#K?7DBN}p+nJ{<|3JnOUVj!SWdV~lZ~lioC86%TQ|C6_-YIz3Nu zqImbFhZPOiX{GjMmqg_$@zJ4}r)}nB-$ra~{qb@sRLfG07^MjN6#e1*uo#LM)#zgM z`zYgQ3@wj~!Bm{=q3TQ0Np)k`eJZ$ice~`*7}ES zv0mac*{9R+)8pZ-G75C^x$3SkR(!ZkGk(gaNP&3kV%$t)^Je@T%9<|qz6kBx24a0k zjFV;tVtFs@Fb+Ob95JGn%m7s%yG5(AH%@E`C2!6c{TMqOOEIHio!sxAFnpYUy)1uZ zbeXW)1+PA(E#+rKjO=3fzm5I1REWzV4nwA?7x^ZvC-kTpXsIMmqpTY62yjE$2XmAf zUboebd$ea~i2JvQgT=F7z=gX&Z-ElAm1gChd)#*@g=$^@f%-ab&P< z*Pj{2mdGobFw5ZJIAccw&g0g|V}>t99##v-rR&yv*gaE#KQN}gE^8XUr?luod&mpi zW$j2`jJFjmcH40UM9s_Qu=y;22KDj8k{g8F1&@!|fK-CNioT72+kTjem5Cq~;g{ zbFUD#tU6nleeUM8#V0M#lpG1A1huY>efig>6p894o;7tg3W|E==`qYbYxdS)>wEVY zQMi%ZO&SU?OEN3zM6&UOm^H<6ow|g<`cK(+(-~finMLU%@{}{pKJu1X3I?bmXXytD zxo##)zjELL?|w%;-cL>g5=75_+h(3$>J}F0(t|Gt0>Zg(h)+rjy}SBLRm1)00+mfq z?xx4z$&dWVt_;VPW_fp!bGNBFr+t!j4)>cXne-*sA8n-HuBnY4bVX)&bhL|#_)rNyZj!c8KcP1f z5f%5;&QGBAuu|@B-I9&ik-8o|k)E|wtj%O@pTMgVg3krA7Jp!t=>}z@iut+B?X0VE zG6NC|f`^a2j1NxnOn-lu-YkJ$uUk$Rei|xA8E!pnOid`XCTP>PzuG%2uq{`%+%PDG zq^O#^UGvMMe)sL8kEw@NI^D|oU=aCEov*LUoMI6-a@?>uGBcc|*bqdwtCkjDXGr() zb2YEZpzL}{+5+D^keQR)XIftQRt=R_Aa3r=wNhpMZ#)bkAy7LmJSmXO%b~b-Y0M| zxdRb$e-Cs7EILd{Kg z@M`kLo8&`L<(=W1=y^{^uz1fYm+QJ(9j}wEs}LRTB8A`xyW2nc?!a(sRTinkT!Eg# z=eb=$GSJm zR>d#f6Eazcx~Tb}s-!VU=Zdc1D~W~2uuCklFQlFPY(KD;Oen(Du->M9Lx2n2cq*7abB#__dfUvA*l1n{oU+cR?fKOAY^jh~12N2DYHv=RwmHzJZ~2Jk%GLbL627&HlLPTB473=-HYBB*C|!xFUy~ zQ(LJWij~28H9oQvf=Rb(lX14S!^KUeR_Yz{_|6kfU$F4V)8z+)Dp45s5OE~vN(dcM zNVsa(@j8&d`Vxb(hVTro?v=CSCf_Xwd$E3T;wN(}hD-JK^w(IsRAg>dj*}T$e&WUM zoT!PSwB2<*Ufx)rJIy8up&o@*NSwsrl+~+n#wiQB-NljoqU}?N`~!t_b`IS@VDm~` zcB_!T6S5;I9-G@OxHnyQZ-Gp0vje4Bbcg7xLXUt!Q$H*U+j7H#?p*e0zvE#?m$LYC zp!MU^hb>z_nYrtDSsC_+R*qK*?XA*O+%bD7-xEe8>={DX2dd0Tnf&5s-d*;4D=bVN zY)NfGnHN?7AE|DD_-lKzoV7Mwd{PDeZ)GXx8Q*&n@yphS}e?ialxV@9aVheo0j9-s{%_sHRV z_~4RRAWd(y$rZn9;62)uA9TkXJJViZBo5kqW~%ol~%5Hz}6Yj(yi@=Wf-EDEqtk|ZGZPYWIdR>`giWm z8o!vPKnfHe!&rV=JIPF(k^AL+8l(8nKn>qMJgQ~LlzOc}gjtoSdzAM3$IHD>F4oRtJ zb~g2zJUHAwNTO%%M2?uMw>PTtrjAD|8Jc^DQxZ%j;+>9Xw4Dak96OWCPoaG4C$tF7 z#!tPBh~^ic^jS+NjRh1Ndht@QnK>s5Y1!M;i7-NWQk7U$@`t7(r`r1KiAZd*rj`+0 z{gF#ZW;gN(YFKJ8_*0v_ffmlurFhIz2|j(?gi7u(@A9c+z3TV4*;V*~0VBSsybp6t z6Niu0V&Rtd(wjF+5G;Bd^CR%nxSr7_vhWx8m{|3CWTI~f;Z?cYK#+gd%Pa4Y87cLL zO+v;hFTkbd8d>#%t7Wz&YrL8$C~6($>)WD5UxzQI)7LJEI1u0-=f$_v zk1@42zJI2&efW5C=7Uc=N8HsUX}NQUCWc2lH&TyPsni)Vf7!xyMfzUuHu|>LcEn}} zZhnG6-05P?4E-V3;%;}iHnpJRcgDo|zI5Wm%HRK-B29 zw#843=kufcVD)aOO1BpttVbEw{oJk2))+1>?S@?^Ng#v8p25X^j!%cv#V^&z4!}Gz z7`2tgt!L2rgp7}|O)U`_Ne=$XZ-j4;C}0W=De=AQ?8@xziubEqpp28vV46#C`$b?2 z&tz)*^Wk%>OXBN4nM@zot8duZkF_wG4t!GSVdmp2VcsDh(t%u_{^3c=$fl|Rkr`dO zdUtc8M*YP?xP3wHrwL4koM2=ubup&ED=z)cD$MrIB1gtho6ns|R)!jZ75`F`aSGFf zp_fSEn~0j;Bnt(sLVcl1WBgae(^!3DK`W1MaLGB;GXuVwU}VT*TKV+P9b4Tom=xR3 zO_`v>Oi9bACxOzXITyq%Lq|mO=I>H=7N)p7xI2(MKJhuGqlj5s??0V$Nl|?mWK*&V z@2h!_Yx@md9fa{86}CI@+&zUAJITGNgHZMAwPwkYl7wnIr%HZ7g0q#z;~FKI1JTS^ zc2=RJzKBiW3*``hXcZ54z^-V)kwA=i&Gi%efXrvIAm8XVnhc;*W;Xes9TGYqM| z^sI$M48eklN1b!=PgBJC^u-b1Axp-_o$n%?iA}S%SX8JpB15~FZgy$;Sd`bLFR|(< zO(DjUVY|19GPom`T8ti$TVLALk$oaZ-1Dfk;)-U}iD{HYJ;wZSrDnnkz_5uIH{xef zaT+sPja;)jrs|L8sY4CG3I}d@2RDz+rVWqQNLq4vTP%E8s4q^os_*tZ&bVMy+--J? zf?}oX?-)I)b2iZa6l6T8nmvm{#RbltQ4mZ;;&67iYiUd9mKiK(e-# z#HC`XV_f^z6{eqm-?kuE#+J4yEK|cr{4C#MVk2{qwF6i8dSZ-gc*j<8*P!6&&qVJX zO)FI|JCl81rivG4l90Cd?8hzCn~|(LJFL%+q9(5$HElfKQ_hRO887e z#_+NH4+PDgpg0BQc)Ww7*7^P^DY|&I*M$VzV5#Wg0gE82a0xwMxXaxzjO@LvcOY(^ z?D6`7^bz-xgaS)-cLAqEW|-68davRMsyN?#hyJ!uI6Ps}r|-GR{m;3X%3|h&Qp|*g z@p$*Ac;ZQOme*oF5$QrTgjWbxUED|O+pHT+_Li|q?NPSEPZz+tn2z0 ze(mY^l`%y^zHJ3x%-6vZCjG|i)V*H4mbvGZ;G3h-+mXQipzOqwtuAJ`7d)Z{lH#^U zG_Tzbl*0xl;Gbo=6V`5C7?I!6H6^1p6ry}Uz*D19&S2{eg&D*L)Ya1lBIL<+PN4}+ z^pC5`E02Xa^Tmf~*>gTVbqG8)`J11 z7ni-94i?%SKfz#K%so876N}M_4P-JlU^`ZKvpzYnext1`?(4ufJgtiO1{3aWJ;rql zrbkLCF}J!BF5T4C&ahEUIn>>o!!rHyT73yhfAYwez!MptL;u_+Mvkg_s**6S+;Liq z(M61Tmgy3GU}$(YW9Om;syTL*&_7s^TE86Daf!@oJW?Lml)w9`n`X6JG&cV+tFv06 zV~xn(M*4|dEXg^pG@oaGz>&!}3M1eO><^Vo?qL_azTi-qOh;~C)2FswfS-7HhkM-4 z@;5Tu1z(yeFs07+r!IPXw%@|p`RaJx#n_iz+!)dKJ@=b^f(OKO9SDWF;tg?6bZ~wj z7FIemsroB+nZ8;xj95)R*hY9m-&|LcDU;qKc;rQQzC@2$>J-eW_!2o*qwjl8#`PWd2w}*ucgb4=R9%Py6``+MVpKnkeV%YC#NrK$a^`#yq0NeTerMEE^tSs(W_Tgyt?_W%0P__53`@LRm}An=)|c#k|j9R zWjZ8jmhHKl(>uJ5NWpFYVmLs5i)8qsAH2-Rjp1`P6Wv?65Wa6v&G!i@lVw3~D|>qO zIH9zK8Sy>SS==&&g&U8PN$?VS*;Q3#^4f*4q?!uMib6Q3_>xDraEli=Ik!dO` zFx!6S7UqBY*bH$?$Jz|$;<^;p7L-~$h8(`nCf>j(MRpd$SZ3+)9^|`v@1_cu9i_9S zIsU3WjCkLmMsKne&!=!E#VnYCJyfG?wPd#ajN2bCx*;p$`ZB}d zK&M;V$+Coz@qUc9>!=G}tYNEQjfKK&qv?bbym+;15p`QtEmuQ%%ANx)9{2Z{s@Zu6 zx?m<{5L@#kxpr?O%Y?Dg?1Q=k73SK{tn?pzFv7Uk;dSGYDT|Ku1)}irEt?5h=@wQq zMe*-@eBCE>Nx7gwnJJHO3?g{nuvAbBdrtD&LV;7_h^GE(7t)SmDc%%OiR#z5fyEC) zY1wlAAquBbD^x<0Ej=SYtW$CLkdo|#ooFO5<2Cwr-LcWC|FlOvIoQEwYjU4^1(O6L zRFx?ATXnem)~6U7s`tdbw|UKyi)a$Q7?srDEf)rx= z#c+xsY)3~f_+))51JrdKLkzw+UrcT~F!7o@s=wMmO@V)>xjHlj;S zyS=axbr;wFPAhcR1WjY&ko?y|G9CH1_vv{xk(SBT6o)16^dv`{!>=Nxol@mth;79R zOZE~LR?a3R)XNSm$eSxq16_eJOQbNJT|64N$n{A)o71m)!c4m2W$N#VW^K+8yfK*y zPJ699rn{DC=UKRXZ%G^f6!lARrv{v94uDYc>drv}A}!x4$465Wo!jB(lYGK~n}8R-*b`H|eRX9QxnXdL#okTw z37-_{$ckbk%6+X<7++lOmCC@rHe-S>zoP7nrL#E9*r^(yG3-Yfj+;VqMInjB`$-m| zuShvZld7FUMQZU;d3?PK-erzr@-oPi5)OC?_|nM zD2wB|ZNfvvjH&C_DU};wFE=A&--9a^idL8oxXGi;F|AAUZcXV&xhUh*+gVr+#- zqaln^w!03an(=9>O@^RE6Ir@LzUPBoci>q%Za4mrRh=TCOUhk2$TMMLXEF)<64te` z99iA@cG$1)3Fc%;X6Fr=RuMvYlkiQ-q167(a1cJk*S~nGZz*9xXq72vU~r>Jo6p*d z6o^wdB5CINqG?4>{o&DHitPr?LQHi zZ4)?=VTapq^}@#TJ$`xlSkJ_^yNo8-j$Bv*1JQ=hbBdF=<8?15{VFTc#}L09RI0<$ zoTB-ojD=-Gb3 ziB`GPj<~N+={a0E;}=xg;9HN;HX=uAd1_%COyfF^nN7Sf*;9ucj6qRbMtj^Qj8eYl z{2r{?jLx9vG$Cs?P2R1a8YiX4kB4edT+RuhUl-ev_jOE6Ohuy~InTc7vynn-Nm!Of z73<%%zOi^TX8IrC>rK{LQ}Vx9=2g^Y-7f9mk&MrZwEgI7$-M}l^P(6uxzQ9}{r2^^ zK2qaJl{~(?lw48RA5#UpJ;ju2JQh8?tX6dM=>{CA>$US3+AV&eEX_#GRML-ETwBc+ z`}lUCE%rgc3;7T%Mm4=#gh=kSAlsp=(4Swo`3sh=Kpr~Qdfohn0 z&4V#v^U%P^o(Z#tH>}SIXH9cLi+hoJtqmC-VsJB=`o#KQK|mT3N)T4UPEu%;Q7m0p z!B~keC**cOqM9{U!~8m&m3WuhO6+Y^zhcriEb6hf>#^SrtwxN;{cPeXa><8cqsaVT zVM`@yYpQi9>&3(#Q8FPGE>o^Qg%CjG){UGvA4}CGL>x4(N~f$MO4m1=Ie0P^ng-%1s_Ox*l4)rALkN_pD}(kdHi;SI!SflGoji zoxDT|2hDKlr~6}`xx{Iu^Ou#h@t047G<>%W*Oxxu-ZY6lICA8Nh#c>p>5N+Ggiqi` zrD@$M(}o^G6TM`&$>HgD`bi;b8Iyh~MFi2S;HYqaoCV5sy4^UfFVm{rzr`z!U>$Ly z>$!3@wT4JZ+2*^3Vdv)mrbrjZitL;ex9ENZbK(~@^a zmzoO7&;>vESVu`ek{DwaZNn=dY*r)oDBMmv{WYcKYV%j}iSF%{=em!+X=u#ag-7P(UH6U=+)()a)Fxu} z4ezccx!I{#!i;iq?2R*LQ|Mo-H?#UIuG}yvb)$5mu3V#Zekw3bDmr0U<1NZ0Ts&*T zXR`eZ!B3ul2w4>!k#pBZ!?&iSc^jx;3$Y2o*tlX|_GCLsR4FyA=&_&;AuZ9O{esyy zm&gylH$VK`typ0Kq_THz@7raE`l4t`qa(9MBvZ#Kri`hngszXRjj!J}@&(;3d!O;%91ZC1O=zv^a)9dYC<%vUzIajY~*XA|KLFN!)*EGNY;z7 zXIHmANtbnN6CxP|Q43ZWq-E^JS$N!jK_ifP)J`;z2{I$r4$E^|?-7ra>JP2Q zzpVS%thFnLGA!{WB)i7RzA?+=NWFb)1L2u`eO&g0{h^5Qw7M?&D?%0q+f^oZaozKw z5^2L8BG_R;mQVS?xcc20{Gj%|_py^0NJUxyhG=m&cemhOvmMcd5@r~)w$sUnacf@E zf^ZTRqdn<{?M8(@*E_O9z7&Ihu}M-0WL1cN&!l2?TIHgf6hr++M`T~+7V7stAm;bf zMjuyg&Of@2F zu3IkIKwy#sx>Jh!zjxK~i0XFc!&V_v>;~88tw+BCP5SY}-c?^tCvd+>&+fME$*xj6 zj~l*S>%G9ILZJ>mHQV-<>F~Af?d|J&%R*t5;Z7y-`2NCvb?Y&C>irP)$2Ps(vIE4x z=O%Bj3>Eh>Vd6sgrv`=xqMLY~PHc>^EN@08s7zO}?fVo(X!HPJ!L#db!UOjYN| zjF2uZk1CLuFrRoXn-K5T5mBF?B&S#0m642^ZER~3DJTi1@tcid{Znf+y3VWePZd6j zv>>nCds{O>&FzSqUnMS$au%hI-aX;op+Szv5ar}88s5@39#$J&R;`(!;6~Cb_?(<_ zz{ZdlTj*a2P*T3LP35>J66(OU8~=DqqIF!Bsd|dsALVkyxxDROB;8y^V4jpz`*h{ zH9N7V8f!)^&#R_~W`u&;u~3a=?k!#`G5`<9Z!R$%7D$}V%JN`UFG|g{DaDM!M}oSL zGbSo}hZEZ<3Vj0yi`6*>7c-BJpTD zB28bc+C!m???@6liIv( zCQ=;LvkCe1x+&ymRkhvx^p@2Xgy)~Bx?0I(Ykg0Lk$x-jKx0Cbs(XKyRJ!J{Qlya_ zB4q+IdEL6p97m;}ORv3WkYdA)j$$zr;aYv7cGSX1SZ;xS5OTXFs3!5za(0%8%IWrf zLc+M8ZF=9-oPlSZv_{M{AY2rGfv@L7*tANJkH)(d$Z|Szj8n-i8Y$JphWp&XU@vw7BkckwLNed!kuLV3mAN@Z!%=`=p=eb)T-^ zEXp#_Qd|a)^tolwNKx`{ikF%Ypcp%*?)l!?gOMBRWM~gp;#EQ)xq*A3zWA5;v)ky7 ziPvBPH*Z}dL;02a)2oBLC;H;d>=Pf_eXT%PwycpbTCwMRsOGL6XFqPK8m!?4Z6|rg zT`#Gq)!^(nFV~$AL^i7b}`@&w3MHD*RYzPon^o{ottWQhi(+?d8d^Uy&}HPQ zoi{~Yt0dK-Clx9N`})V_JUm+B0h!TXQ+{d6>_WeG** zyxrF$qf$Cg_kv#%77^Yv%)fOJrJs^qa=|+Fswb#Snr-SZe5FVkZ7UOw-@57hd4=me zoi}3Id5FR1M?}BBz_&VyF5Wj7G;O&|PsS?I43oo~o(BaC7Y9AE99uiodC6a0AN1sP zwkGI__ufKSi&EZIpD~&Q;FHA8qXUpj7WCBEQPl6ET%`0FeIz?;HECJu_Kb z2M^6?-yLiWz3~$;W%l^WBCx! z^JX!!)#+BWf(`OZQe2C|qjJ#5Lb`a`a$pvNbV{Q0rt#rdLtz%aE%j5L2j`0F4OV)C zJ`n}%p;q`NF2xbIZEEAHIc3`_z%@yJdn?K>^O%2!FxbW1QZDl88ehHI@5*vZ1-Z?$ z)|b$#wnpr}*{PHzX|!{;6%L&xbff+nsXhR-SahYeK6&vq%=ju|hDYc6;nGaFCH=>$ zCGH)OUHJX{sWTFEQY4&kdAe-&2geNp3s+s)tej}V^ZoAur8jv;xnnKs?6Yso zo>y9i2Gj>ozBtIs%WO2&rC0XO%Cifsy9p;i|3n8h!AbXI?A!u# zJx+5}VE04(G(giquWJcv@?tN)c$)_6*#~4#5uOLn7d3!;F|B=xRf7# z0)IaVJSIm#;9AkIFLr(-{-2-wuYa)&D}}3sDm>kNf37F>r}z2SlV;zgw1CU#Q)oiX zwQWlgR(APwo_Kz%=WRse1+O{&zCCR|bk->eknHx`D)&QP=0#QS4U#-9JLdUbbNjH3 z0&AIB3PF1@NwAVIXCipET#Qq@BEaStpw9J{w58z$h^q70IkU#Ux*m$?Cq`eUjt3JxOsw>?r$587>6lIg>Gp%G`|Jsv_@x*_jIot zse7(AY~Hiiah2TA^xL`e#pdo`LXSe@BhRkI;vGN>bLNGce#fK-HaY_CC3hnsE~glH^d2Ew=xWM0Bp*TM?Qdx=I_eHF(J#U$#DmH@^qA zeoo2%&O&~d*Q>ymFS*#y-uV0m4`zW^(%FAzG27Ff!vjRnwP4gieKP#JD^TY5s#3?w z)@v`@rw8%Yl?7-%fMmrEhC@{Bp(DVAC@phz2a?*IDKbM7vHx&H^Z*Oc5) zS6)dwHHOoJ7WOv-_eh)e4Ef#FUvp3Wi|v2~0rY!8+i%f!3}V`~BQD~XeahS@EXfZ(L|dj`*s9drA9KAYf~8W4qsr8>9F zLO;9QueT1(Uvkh>U>enhd=MJ!J1sZVR@;^8mV{nA5|@2|$!+=QHHD}A7IQ_as6wyAsXMyR3a1rSg=r!=!Ou79Bbzxz|^1Hk#c z>o|+e(d2)bj2iwUot3@#VePNy5cBkxUv0#7Za+czWOvz-3SB*j;ko2nU;x|BW!`~g zY!{%V(ByH{Ck$8MvY@0v$u^IJmf zi;U;g>u(@7S_~}<;s7sYZ^(%C%vT5_-jo>#QP8df3;4?|s1g10WgtJ9^Z(IeoikbR z!0MZ4&j{!!_OMEJQZDQ`zt$vC*xA1=D|>gu@km_qNY=9XIlJ@RL1FgCihkT6ItL2= zl4YeY0t9I!& z%x%krr4)$XP{l}Op>(&%Duo|+n$CwFlFzr# z=!&@*k7s-crKxse*>a69|AlNA5xje3cr7_1h24^|C{a&5ZSN^ z@chtk9S{Y~ccUxHa<|{*%-d{!&TsJflx?f14It+r-K#Vo8Yp#KwPPQNhYW+ZSLEs) z`v$WSWQgI!ali!W*idM?@cC3JPd=eHF6Q@)`P=Q5>H!`EyJ|thy$?=Vb0RsZe9AQAV@;B06ooJ{;~R({F2tVdyr<9 zo<|dv!d#5@`Aw1$6%p4;plPYVcy1|$G_JO9nsHznqQzW*Rs%wNKO&0=m_3UEV%H`EjB{|ij>=Psw7w$`h7Z!nYJwCrzf^3NJ`Sz*ZDWwKecBq*%# z^uoVHl|N6M1%IVWW?_J2KGfW>1W*NuW!ex`VF(SRbIHN&5P@c=ekl(V|C5K!@)TOAF05tBv71psJO4()k9Zn$%S7oKVrfzo*L7UtJLZJ+m5ngDn!3xas zvMPBEjSZ#>zzvaVWTDaJvb^oJHjgPjqdBh3%f8qa13^J5B|wv}x7h)L?gYBJ1|-cx z(}4w})cRievvK>2Uvvmu^@222&jF|`3Rj>?r_2t% zP+6&riLl!c_5HIM2y4h=aS-c_egTGa#RV;B#W)Y_!K`?q7sQn5dI05A9xx%+G{w(` zHO?I^(CFbP0OHVqUTJ6|hFk;U(0r6VG(YluF933j?uSA%>>P&uWZ(W%hUIDTX^%N} z_CsSdPtodo%6QDHh_H^c`9GBYFD&JcKcQ!X`qL}4q4^!jA(Kvrd-1m>$4;z;CMc3` zi%XsS`wvyL&#YMh&6PZ#4Kd;{snB%iGH{V?QyB{uK=a2Gpxy*TKD5(r9R_e)?K4X` zFZN9v{$Y;IrY+iKEg_}=bnskVorfyK2-MHe)UJu=NT{~*KI=!l>`%GVwu%s6j) zcJ>3~Z12*{gv0=z{@KGOrKcIt=;7)K+-jCezwf-a_tkHE0?0-ZX(T|ShiV}pe#?4K zEod%I9fX|J<$V-r^oX?r5q$p&_3u5u^9)4Laf{=DbtWr}c|fBGPpp1tJ;}ROv_rq* zy>=aZzbwQErqhL2BjMU)u5+gkG~ghhI-5|*pSZjZ8d?2k36!z2aITScet--O=e3l; zi`08;Nrw1>w)S5S41ssBH~*(p!nN4HWAt2iTuB>5QI&KRnmgXqI+Pp&Ei=}+87S4G z$L-KgnM)4=%WHJvF${{`1=q4325j7XkpYbxu0mjo5v#rkLzD6lp&k3Q4!5Eps^WgI z#f=B{`~uArJp%Ly4fm9QCf2ebgQ|7t&VM({0Fn?7Ex@p#v0Cz&wXLWIZ@%wMzImFn z?*#8O1>A-exBssBe;%yRL4aAb)q9{JKr{^a%22we3N*I$fLYb2KQDkNkKhPftBKeS zO&%lHj<3Vh>|G&-THJiAhBkID%51*{i6W&UK#uF*K2(CnY}I2xX>=TOp@F_x3Hb$Z zP5yt8YdiLBw@F+Ck&GstcGon-eeAuU0VACUVWst?al31ln@gTT6H1<4;6T$^k6I3G z+9i-NCG;P?1Wj*hfpEpVD}>f+ibisE$-fYEFD7k-R{ZhyB*=HlmBc{H!aS9=y=IxA z1hM&S7tn3zDrzq@D)xb59|GmbS!h%|3an2Itx#J=E_+B^f3Vp)qkO7lze4K8+tbCG|WAnym43^9W0kFH7-4TTuvzjm#yX@E?*i zkNG+wKmZKaLTuXFECn?0;U+0)5e4V9ey|2D#ML3)ow?r>A`JyD$PG1%`3SjJ^R+=M zdehm9Ci1ixhb{(E)+|Xi19ZCJp zd==ajctf?~gAflduYotbdH));{9u^0?X}qVze4PIJPfQd=IJ4bEof?73ew$*vUeda z#&eB#vOm~Hui}hI8B}tfDCJRmu_kf;8a}Jc-2f(%J*7qFq1ZpH0Qw+M@e1>6(1MAu zt$_T*;B(LvXam4f(hh>qf+U@EARo>u;m{I_H$dHUNZNtTP^{!au6*Es^V<(XD{hqJ zFpDitI_aez!sTt3A#zJnVB=7;IB;6Qs2I{I^VMl z^inQD=Dx!amlC+JeTP%1CT~7sH5bHJ0~KSIsR|dNz1ps|AU3i_L(G<3nvIS63?QBY z*3QO8rzP3kpVt6w4wNi=A{-(TfdezuyP9Xt!_ALr52AqWz~UZ5Ln3c20TMwh=CEs) z$bemhYA;fzi8Dk&6i_v_Z58iGxaJt(`y5APo9~XEUz+Fc0+^RVY~H+MAcQL2eT8`d zT1rCae;0@fOQ~G(vVi8?P62IARhEU;BLyM{y^7#YPTcU-w*9AZ1BYE~yZwJ5%=;(V zMPQ-udR|a>+}KUT(mj(AT;2A zg?rjDM53?@BP+F}XXV_@(`=de>j8T9h^qM#H?%B$m>h^uT5g|&w$Zb|M#54Bp|y?a zJOL=}N}e&EgJ1yYWKO8mKaE!$N35;W-fA z+0&(<-5i4U26lJ+7B@8S5(c8y*bjlbesF$1R_7D2yIos_!sZo0&KV?~+33zhqG4X< zmK`wO00DAH#zCDQYC4~-ngP3OhT<@5mO&h5{Sax6X8q7Uj%Klq3^4E%0 z0WHU8%}E7FEph?7X_ zx$biwNQ8)eivm`<`)ybZ4Q9XOjt#T$xd0K-D|B9qO*pvshba6Y#1EYD!^?j2G4cy# zyPL#Y|M>G?Ppw#{Dn*t(0TE>zl=9|h2P*&dqknk5Z^;}Qmth6-<|=5h1BX>?GIChO z7Hy7JvCRNStJqeEV*uwI2Abom*cl;?ubP9`k{nnu7jB=!U;VT>a9{-oR?LBj zxxk$5N_9A}f=vq!tl+>3Hkx1$IIw~PE7)j)J>b9!4y@q73J$FJGobp@FC19GffZ~t z!5(m61qW8J(FA+IffXEB@sGd?`}-r|b9VvEk^Bz}bNm*^Z?WAKd%*Eq9KXeOSL^}D zZ_OD|PE8;?DC8X8vtvO{mYtJjXQK)BfYWNgffZ~t!5(m04LGo34o$E_vVRm-48?_Y zFlsTUptY+lK>MJn*L-abEc(;#*{|_02Wvp{-ddA}J8a-EpMlQ7QeL%P*SD}`WnKf$ zQf%7(uM)6RT}r!t<+CJcSBx&?It7H+QvT`Me<`AD5fb z$AQyq6wMy|lUX`oHz#o}snHPo)OpTvPtTNh@T$Ex6r3|5^R&GUpvCev%~-S3?$`&O^er8gGLKYa2o+> z(>iFEpdAFa5hRn3L;K#QjuE(xAor%;U%ok80Otn({j9>Rq>X44dqO0kWSGGC%zA&> z?)^$K(1b&P6ZOvt2hTrgrvB@%?dafTqB?xdAl`f;kSF*}5M#ESfOcn!fGMzu))q%> zpjjL|FuwRjH)Pofz4;8DZ|b~OlyeUU&3J??jtvW4B49Kh^U3}n+oPqt2q#4pG-8MX zlPJM28P5)n<})b0AFz_vdUisH4MFBJP+jA?PfJ`!1DYe+4dgewY!upk`mWnLulZ^O zcthi`1K_a3?JovwlFnz)X- zGUT5qKqEU0kiBc+8)%YivY=PX|Di?mMu00OoLMt=@6a6xrKWx z^amG|K{IZuDqtG93DyVEKU8pC2@7pocncbEaCHXL>aqAnh%VyJVs0sk{6(vvVTaB( zZf>ari_jE^UP5{q&ps{pC7U6_hkRZzEmzzaA_CK2BXG^Po9`Gz1OZ(B%JTv=&q7W2QxH*QKxxX-q7aq%y%ovkW^`zud)4WDISWZm{GUR+Mmb_FKzlT+ z$5;NWU4Qk9p#g|oF46-b-fygm06~Fl$AK*e=aVa9{}1Qo{sg2Jp#Nje+5RF`QdAUc zQrmd_PrAY;`M(;VBLuz0Tr{qR89njb0__{p0i}m#W1laB#~~hECCh?Y(Ut(W^ST|x&{4TV^KUX9OBaJeQ8gD?N4Cm#3B(K<3;~(do5)Y!VJ>Gf%BJ+SI z349mphv&EaZDQ$XsVl9V6>H}96MO#!1=ytc^B`FUi1o_}U8kQP_jghkTQn=y)D5el zUEA(zJ}cI#+7K0<^K$=!ssA@PcW7x*QBe(&cVGM}6KEnPU@9%ig9r|X_aJk=_-M18ggm#ai_ogpXYi2`K^<= z2vMr;fi24Zx*8%mrsGOI3*#g>V*ES7=7{mnqW6D5jGK6P_E|sL2rV>Q$Yl&P?eTM{ zKzki9#14^ zaP|{91pYH{#!)hklKn0)_~AUi<}8c(R|!!AY3^Ob(7G`^mBE*m5$BzxOqqOyi$3jhyTv8;_N8 z()m9j5j5xM_xFhw^#AP9FDE8r+kmfw{|hPn(m^H@@uaYz;64Rv)rsUWG{LPrSevA& zsd+Ry*QKM*18T{Iz|&HSYFD`gRa`!A4}R}wAFuc~lbU`hQv1 zX&J|sdn-ky-D+G?3v$DnCLJ?l%9$+JiqH(vTySM+nVWZVA^+Xz~fc~3ml<_W>^*4fFU{*H&&y%4+K@?tMwTGKq#`S59oX=!OHU2wf z_z%nf39kOX>aL5?|H;kQKAKe|=ti`zDwdSWrmrOy-Q)K}&%wEFYIn6P#7-9AG#z|K z`F>3!uGK=VO(Yp;6WAl+tz4u|5f~toTY;GNOfg9mKOfeZ%89JKxgcDMRcMJ&Q1s4c z*me$5H!_z-r!xc!#o2xY5ku%K2FigTXt7l?DTQ*7u^QJWY1vqV%lWX(?H@TL2Fhe$Q?p#t zqmqac2BeZD5OjxWR&wGAM0PXmSS+trjBts7z>|H|->bJGBOc?UlBDfPgzL1hBzG$?_E5 zWh%PxOZJAu+|ea+C|;2MQ?_ohT zKrrx*S-L2|x-O3cyOmENq{Ig)LkVX)bqOPHh>fgY=TtNArNTxv;w5k9xprLO2*V6) zKtk!4jg#myU&;gyC_s^1P8f*KCzXvO(p9EMw2bu)cX|{?UTyQS!t7X^)l|0{F0*co zX~Q!9IfAkZ6*Q8i2ok2jrDyq+a2U{P>$Ex|Sb)U!!{&x>fu%Hb0_Iu$f^2n`Ry86~ z3&Tc=IGx-+8Cxph()G^#jUOI^N^4dajkeXa^SQbiw)%1 zrLdJd5aVnYfEP8P2E-24>~l=K_^H~fm3E7Q$NrQL)svMg6ZJ{YU=?E5L@G08`RiGU z$-sl1As!tc7J+nq#;C?j-hBX`Fz;r~ACvFrMf0gf|ZEU3!&-k_T^*rp;P6V?XnxW z!|kOa<(d*bBslWSO7Z^JC5yOV{Yhk!jqmH0mo%2)B;r@rAT_?aHIyGFOX{;|3BtXv z6y-KWDI?4|$r@kb?}LHvV7J30p~Ik;nU}xA>T?)b^je4`u0g-a(D)j1)ERLpctc4v zf9+*5Su{-b2r5^d!rTchwNJT_MGA7th>L1bP5glp@0oM1S4mg6rJ~X?(SGR9^yn zW+Ey=L{y#;-P0uosh%%8us1Mp&W9&nWYlHV*Q%|3_?qW?h+CeUdi7O@mTgV#)F%rG zRV5uhuC6q<_pea14nxT`QBpw`LAlbFN9nJ>q$%|8Nd}V=3p@H(h9!%I_|zb!d7C0g zM6-HY01#4$0>jyfDMZVa8v48P0?Ex&^J+oL$N`ktxj{ft+@fo5-^4a!7#;n$5y!^r z{eH6|>~^p9<1(Fqq2-;vEJRyKVv~W6&e6?092zTps0%J*+X~PevS<~lrg^(^)8w%h zqZRCRs}i0$>RZU9{}Gji$ASKA1FTQXYzwnEiC86PJQkvw!sb6Fzt(2T542lVdNF5I zmoJ|$eTrVv6aX?zh>8dD&BCSpHVOBlDHt+JDKr-?WRMCa6SXn!IZEG; zk}rk!#FjW1o}Ue+;Lv=S3v!lOp`o_Go`eamE`>#WxY1q3=>O(`mUdnN)a;@A;Kk}8 zNvY}%z~V`pho+j6u==r#w-D{} zSLmX*rx{Mv@vL8f8x6q<{kb`AG;L~Sq1%*bPg{xIc$+u!V2iv+;%6fN`*Bu{B26@{qE;HMlJ?2=HF!2C8=*$`Q$Z*Etx@|d=j~70`zQ_t>RfQYk1qMIT^J}SUqKLd;3WFoeP2M+^fBy+;5f;I9c5qm#Q|JArD2MEYHEF@YCZ3y*#Y{!pU2bN%fy z=P+}niT0xQt*<~BxzqujFfMDYF!l!j^y>bYNqpplgLgB(!#$Z_E`zy+^X*`hVVz^X zuGmMCFPwUgTKOp9;a>BKv26WI$ef98XsdoHFs&Y;7{pad4E-TTJg#Z7K@v`DMe?iSIQ>%h%f!_|qpr!q$yYVKY4V z(5GpTUbf?96B6TkIw#yG`kF18(lXhUN~V$zi5Db-2L+c%mzgLj^vJiSC+QKJbTyhsh67$45cZfbVGLEu?^FBZumeJ4S5n zgMp;XT}`$~T%NEVXNmii6MI>?CtVQK6dm7>G?o$;y|$a_1wq*uIyx`jHg?7Qd)wn4 zQyw0wJ#oPkoO=z6X)ey&T*^VD!_xK|+`v%LI6Trmq1!%LeN|kq$#pZQbgT^ha8~L9 zyk*GB|AnfElkj4>gHu$i0`?2da`(eF6?(krb5$Y0IP_R{X%$mXt-Ls8Zz=cW{jK4xm#TXFi28y)IX0;;Fl)bA)4zJx!O#H4eTXW;0*o~c{S{75l zMiwlu0!e5}K{m#zZ^_=di~-G8=)8Occ%v6~RwiVG4_7z@sKH$z$5R81Htw|HXg#z| zHG+wQb(VLhmK?JrYBU$(+1+5M;`d+W0K)3VQm4+GRZ5JgL@vY11G=HS4DA zx8C699in|lvd~oql53CwHl*QJG5Zuxh%f9p*~Oc#moifNrI2fZj=q*1@&;S30$Uxv zEhD)(x*?uA1&@`ksVo&YhZAZ6>mOx~N9!9(h&?9_d%zrdi#5Ik5$N^ihG^I!;WF>} zk;_+JI|aOmubHYi>%_GeU?36%J%&4(qD)C{4|7gRuv(oVQ)dRTmC+;PxoVT!k+r^cdSxG*(}!&ycVj!sDX` z>!(~wOihtel!iW1>=nlXA8Bd4L9_XE4ymN$NNk!%k#mWBaopny-nA7^R!NH=V|Wmx#C4ZT0+9684M4x?7y)so4*CfP8(dQzjriY>x0gvGa_Ij`oR9d|sQZ=A&_}a`Sbr zbPa@vQlkvpZHR2%g8Rm7mGC;rD&G|?D4X|NlCjn$wwhF&C-G0bbh`hqqa9$dJ~fp9 z$Tc--yRfF|b?*MGyR&&Z9~`bfNS$v)+(VFd)Fg*7zNRfd~e*T7K(B-J2sA#qdpw%Lw*@KoM}zQOw@ycipb|Sp z`$yn0-UFRCHvH@y2&56h*{R(v(EN96(W zq!#}OSOemPaW`+Kybg0r>{sYH_J{qjwZF-opQZqlqpn=;9uMmV^l$BlFb;v|VLmUs zNY#lf@{CY!Ck5KI*G~buJFiXMyFUicXy4Ne@2qz>ipqidl4N-REkm=A%YbaIKeI)9 z3Ow!i%+0cunPm=Fdf({puJr_FaP`PQ4<=M{9NQp;dnBa#;Wnm+t$^+|U}(rLF9~Pn zBd?{Mm&}LeyyrDYlEI+(G@Ge#59)*|=COZz#DZbdW8W_^7s|FvNo!43KHDPINWG({ zZlp0A3Pxf6K8e(m_76O0MADk9U6xD(U(7vepud|HAqR-zbMepaDYH~`WdzA_^3y~0 zcm+)DJ~_p1+f|Z~YGxe#}_-7jdMal?A z`Vd;2?fbcr04%aQcBNHpS?qKAlBB7`a`pL=>u#0z7gJx>y$q{3_pzm4$fZS*%$Dw* zG5WL}Qal9Hv3`#rBEC1yEz=FIZnIbq>Me$nBAo?oed{FXkLy~IMtI#X?Ri5U|C+5I zNyJlsJvUD| zMdZQYl-|0$(Nb=zjhzoDt04~}+tUWc1ygQO&l^;|zU%lzY(wLI>P{SM#SE7=V@29oZwPWu<=)}8p<>a)+? zC!ASMYiQ!mEohzEy#rBux2LzbF#?Y2LuJZ)^=GIEpt#+9kvH-84SC{RO#P?zTI?#yp->#J2q*F~;X zE_uPGw!I$4_C1|gcCeEl9VQ#Zv$XZ!=d#zb69W1 zMp$=C&rPG~*!i;SF61Av8>(K8yZH>+ZMwBPYQ^1z_77F{-0~jQ?z@vIXA1Tv_PdC-C-y8z)2{#WOq2(F<4rP`cIa-I2Ql5U+hs37um7>Q9f$@MC<22!rfB+jFa84P~*>(#n`4NLyJ$}I53O4ftH89-HIBrOLl|I zyla@$Jj?UH7f!x@AnT+_@?hZ?Hs&X_-Nsb$jteL52>jd=eu!o~jJ(^;5=uFbo!<#} z6d3EXxvknXe=G^*)FMe4FqK=A$ zmv0XYZOxm(QPqz&P+t^o`mH%cpHtvL>}DF1cl}H=xzPN!aqmp#(_Ulg)@3_GvE@B( z(u0<{akuk>@%yictgSVL8=PDk__Oat;SoWfgNbt&G#T%cswZ`s1GBsIb|WV(01x{} z*@(DwXY$i0oIbs`&_?+$<`>{#ApE<(We2*D|NN$~YWKWI7@2xz=C~lSdzifJAI-0L zyPRbVKw9hjUdBUt0Cttnl{OdMQA17FYWg_ zaY1r;1J>u`arcun%&tROgv`w|fn5JpPFcvA*1&L2s9)W1cJgVf$UD(-zfV;?=xXI0 z(#^h|2b%UmnC_N;?hJfW>vS>d?2P1Hi0W_A-M2~9hw*D9sqI)OJES{(5mlUHq~3hwBgi2Mp#?lK=n! literal 0 HcmV?d00001 diff --git a/.pipelines/store/PDP/PDP-Media/en-US/Prompt.png b/.pipelines/store/PDP/PDP-Media/en-US/Prompt.png new file mode 100644 index 0000000000000000000000000000000000000000..a40d6fddfdc44c9f7fb643ebc4e84eda527a395d GIT binary patch literal 132747 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ǟ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િI>b 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�E+=*#$Yf8)8vJb1}=9_dWABXCqD%pWa_q_sbD7Q@=YUrk0Qi3$a5 zS=Fn5S&oE`_j|oFZ_D+yPvE4}!D9m%`DxdI?vkAD0akeTcH_tF-D0v#6bqA-#hksR^_wjm7 zyHWIrZM^A4S~+x3trRbH2sw_R%>kr3D@}`AdQHe^23CtVu4>Z?VW2J{3z)kpX3whDnT;pQ~(JQt=qYXB@J*E z`j)AW*?o(cD5iTyBSl?%1T*pj(Mhn8j{Dn581t?JSt0V5nBup zr#y!T7rD<{n%b)KmcUc)W!X;ML^VqfRTr`;J7%D^sWcAewPS3Ce~Ry+HK#%)_m*%Bm%7Bv(isWuwV62RP1+#>ej!2Qj+T=BZoXm#6Wy3UVW{q2*z< z@rS&i9x~qb_2{|suO76K^2N~rF(LZ$2rNs7eOShLQTmIn zs}!8X)6LuL!GWy)qr&XsXculW*zV%^Ry5-MOb((ryxiJ%Cx`H(sK&F;m6Q~7!O!vC z`|u^VfW1L8oov2Rb`wihRWZ)9!bo!BorY5!dP~IeN!4lP8VE}?c-#Y_F|1E1rkJO> zBWVLXZL-bA1f}|`HzG2gWIPxB5rfkv1m8VAtDcb_5=R!u@k{#%ig#pGw$cHCR+Hr5 zd1G%;zQVt#Y=sQ=)Usc9PfI}KRWvm<#wnKnqi>}xq9`DTU~DRG$XyPwkeG`2E<^~9 z1&q0EFWm84d0}$Qm)aI=vo5>J3`D#EewALs?q%>$ z@M^VD&z-q@4bALulo1vxhQoh~v4TRv=2;hSa6}{Y1|+KPk77;>mo;O=uHxRMw>eAk z7vDV{S2n#u$!h_Sb{UOcO%x1)s1_JLQBdAdGv4_Qi*{X;DY~bykvu!-m0l2MO}oFY zoj?y88S9M%`oTX3PtuJkvjXnXVh z@t49=W46kmh%(uFe23)?AE)?l>z^8!+%2xlBN?%1#N)wfUGsT*XQ2$?CHs z7l_NKoC9Hdf!j0clfh+YVU3pj_<^e6zgUYthHO z@OLWR-Dj4~rz<31GS4IxH>WyWR-MYLi=30VJEB({YJI$KH44~;$Wc3OGGHbm^%0** ziQLKnvC7vZer-+o4bB=FdCD;%0&*Vb>$y@(usr;yEc18C&R7P2#j2hLbxm!ftxlYG zL57dNB2tJlBHmbj4EQLC8|5bYBjlI!K$YGXzdv13h@wQLr^?tUlMl|vf3IO&>>fp} z<)tCo_(&c+s?x`_Au7Wp^*XS3644_m�-ID=%B|=h~b5ZOc}~$w;f(<4)0Z?9))3 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 literal 0 HcmV?d00001 diff --git a/.pipelines/store/PDP/PDP-Media/en-US/pwshLogo.png b/.pipelines/store/PDP/PDP-Media/en-US/pwshLogo.png new file mode 100644 index 0000000000000000000000000000000000000000..c531f719c85429fa6192eae82bb434e0318de801 GIT binary patch literal 13152 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 + + + + + + + + + + + + Shell + + PowerShell + + Terminal + + Command Line + + Automation + + Task Automation + + Scripting + + + PowerShell is a task-based command-line shell and scripting language built on .NET. PowerShell helps system administrators and power-users rapidly automate task that manage operating systems (Linux, macOS, and Windows) and processes. + +PowerShell commands let you manage computers from the command line. PowerShell providers let you access data stores, such as the registry and certificate store, as easily as you access the file system. PowerShell includes a rich expression parser and a fully developed scripting language. + +PowerShell is Open Source. See https://github.com/powershell/powershell + + + + + + + + + + + + + + + + + + + + + + Please see our GitHub releases page for additional details. + + + + + + Prompt + + + + Inline Prediction + + + + Prediction List View + + + + Error Feedback Provider + + + + Feedback Provider + + + + Experimental Features + + + + + + + + + + + + + + + + + + + Interactive Shell + + Scripting Language + + Remote Management + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Microsoft Corporation + + + + + https://github.com/PowerShell/PowerShell + + https://github.com/PowerShell/PowerShell/issues + + https://go.microsoft.com/fwlink/?LinkID=521839 + diff --git a/.pipelines/store/SBConfig.json b/.pipelines/store/SBConfig.json new file mode 100644 index 00000000000..002333cba1d --- /dev/null +++ b/.pipelines/store/SBConfig.json @@ -0,0 +1,67 @@ +{ + "helpUri": "https:\\\\aka.ms\\StoreBroker_Config", + "schemaVersion": 2, + "packageParameters": { + "PDPRootPath": "", + "Release": "", + "PDPInclude": [], + "PDPExclude": [], + "LanguageExclude": [ + "default", + "qps-ploc", + "qps-ploca", + "qps-plocm" + ], + "MediaRootPath": "", + "MediaFallbackLanguage": "en-US", + "PackagePath": [], + "OutPath": "", + "OutName": "", + "DisableAutoPackageNameFormatting": false + }, + "appSubmission": { + "productId": "", + "targetPublishMode": "NotSet", + "targetPublishDate": null, + "visibility": "NotSet", + "pricing": { + "priceId": "NotAvailable", + "trialPeriod": "NoFreeTrial", + "marketSpecificPricings": {}, + "sales": [] + }, + "allowTargetFutureDeviceFamilies": { + "Xbox": false, + "Team": false, + "Holographic": false, + "Desktop": false, + "Mobile": false + }, + "allowMicrosoftDecideAppAvailabilityToFutureDeviceFamilies": false, + "enterpriseLicensing": "None", + "applicationCategory": "NotSet", + "hardwarePreferences": [], + "hasExternalInAppProducts": false, + "meetAccessibilityGuidelines": false, + "canInstallOnRemovableMedia": false, + "automaticBackupEnabled": false, + "isGameDvrEnabled": false, + "gamingOptions": [ + { + "genres": [], + "isLocalMultiplayer": false, + "isLocalCooperative": false, + "isOnlineMultiplayer": false, + "isOnlineCooperative": false, + "localMultiplayerMinPlayers": 0, + "localMultiplayerMaxPlayers": 0, + "localCooperativeMinPlayers": 0, + "localCooperativeMaxPlayers": 0, + "isBroadcastingPrivilegeGranted": false, + "isCrossPlayEnabled": false, + "kinectDataForExternal": "Disabled" + } + ], + "notesForCertification": "" + } +} diff --git a/.pipelines/templates/channelSelection.yml b/.pipelines/templates/channelSelection.yml new file mode 100644 index 00000000000..0e352ef7558 --- /dev/null +++ b/.pipelines/templates/channelSelection.yml @@ -0,0 +1,31 @@ +steps: +- pwsh: | + # Determine LTS, Preview, or Stable + $metadata = Get-Content "$repoRoot/tools/metadata.json" -Raw | ConvertFrom-Json + $LTS = $metadata.LTSRelease.Latest + $Stable = $metadata.StableRelease.Latest + $isPreview = '$(OutputReleaseTag.releaseTag)' -match '-' + + $IsLTS = [bool]$LTS + $IsStable = [bool]$Stable + $IsPreview = [bool]$isPreview + + $channelVars = @{ + IsLTS = $IsLTS + IsStable = $IsStable + IsPreview = $IsPreview + } + + $trueCount = ($channelVars.Values | Where-Object { $_ }) | Measure-Object | Select-Object -ExpandProperty Count + if ($trueCount -gt 1) { + Write-Error "Only one of IsLTS, IsStable, or IsPreview can be true. Current values: IsLTS=$IsLTS, IsStable=$IsStable, IsPreview=$IsPreview" + exit 1 + } + + foreach ($name in $channelVars.Keys) { + $value = if ($channelVars[$name]) { 'true' } else { 'false' } + Write-Verbose -Message "Setting $name variable: $value" -Verbose + Write-Host "##vso[task.setvariable variable=$name;isOutput=true]$value" + } + name: ChannelSelection + displayName: Select Preview, Stable, or LTS Channel diff --git a/.pipelines/templates/package-create-msix.yml b/.pipelines/templates/package-create-msix.yml index c8312ad926e..b97807a7e85 100644 --- a/.pipelines/templates/package-create-msix.yml +++ b/.pipelines/templates/package-create-msix.yml @@ -7,10 +7,16 @@ jobs: variables: - group: msixTools - group: 'Azure Blob variable group' + - group: 'Store Publish Variables' - name: ob_outputDirectory value: '$(Build.ArtifactStagingDirectory)/ONEBRANCH_ARTIFACT' steps: + - checkout: self + clean: true + env: + ob_restore_phase: true # This ensures checkout is done at the beginning of the restore phase + - template: release-SetReleaseTagandContainerName.yml@self - task: DownloadPipelineArtifact@2 @@ -110,3 +116,125 @@ jobs: Write-Verbose -Verbose "Uploaded Bundle:" Get-ChildItem -Path $(ob_outputDirectory) | Write-Verbose -Verbose displayName: Upload msixbundle to Artifacts + + - pwsh: | + Write-Verbose -Verbose "Pipeline.Workspace: $(Pipeline.Workspace)" + Get-ChildItem -Path $(Pipeline.Workspace) -Recurse | Select-Object -ExpandProperty FullName + Write-Verbose -Verbose "System.DefaultWorkingDirectory: $(System.DefaultWorkingDirectory)" + Get-ChildItem -Path $(System.DefaultWorkingDirectory) -Recurse | Select-Object -ExpandProperty FullName + Test-Path -Path '$(System.DefaultWorkingDirectory)/PowerShell/.pipelines/store/PDP-Private.xml' | Write-Verbose -Verbose + displayName: Output Pipeline.Workspace and System.DefaultWorkingDirectory + + - template: channelSelection.yml@self + + - pwsh: | + $IsLTS = '$(ChannelSelection.IsLTS)' -eq 'true' + $IsStable = '$(ChannelSelection.IsStable)' -eq 'true' + $IsPreview = '$(ChannelSelection.IsPreview)' -eq 'true' + + Write-Verbose -Verbose "Channel Selection - LTS: $IsLTS, Stable: $IsStable, Preview: $IsPreview" + + # Define app configurations for each channel + $channelConfigs = @{ + 'LTS' = @{ + AppStoreName = 'PowerShell-LTS' + ProductId = '$(productId-LTS)' + ServiceEndpoint = "StoreAppPublish-Stable" + } + 'Stable' = @{ + AppStoreName = 'PowerShell' + ProductId = '$(productId-Stable)' + ServiceEndpoint = "StoreAppPublish-Stable" + } + 'Preview' = @{ + AppStoreName = 'PowerShell (Preview)' + ProductId = '$(productId-Preview)' + ServiceEndpoint = "StoreAppPublish-Preview" + } + } + + $currentChannel = if ($IsLTS) { 'LTS' } + elseif ($IsStable) { 'Stable' } + elseif ($IsPreview) { 'Preview' } + else { + Write-Error "No valid channel detected" + exit 1 + } + + $config = $channelConfigs[$currentChannel] + Write-Verbose -Verbose "Selected channel: $currentChannel" + Write-Verbose -Verbose "App Store Name: $($config.AppStoreName)" + Write-Verbose -Verbose "Product ID: $($config.ProductId)" + + # Update PDP.xml file + $pdpPath = '$(System.DefaultWorkingDirectory)/PowerShell/.pipelines/store/PDP/PDP/en-US/PDP.xml' + if (Test-Path $pdpPath) { + Write-Verbose -Verbose "Updating PDP file: $pdpPath" + + [xml]$pdpXml = Get-Content $pdpPath -Raw + + $appStoreNameElement = $pdpXml.SelectSingleNode("//AppStoreName[@_locID]") + if ($appStoreNameElement) { + $appStoreNameElement.InnerText = $config.AppStoreName + Write-Verbose -Verbose "Updated AppStoreName to: $($config.AppStoreName)" + } else { + Write-Warning "AppStoreName element not found in PDP file" + } + + $pdpXml.Save($pdpPath) + Write-Verbose -Verbose "PDP file updated successfully" + } else { + Write-Error "PDP file not found: $pdpPath" + exit 1 + } + + # Update SBConfig.json file + $sbConfigPath = '$(System.DefaultWorkingDirectory)/PowerShell/.pipelines/store/SBConfig.json' + if (Test-Path $sbConfigPath) { + Write-Verbose -Verbose "Updating SBConfig file: $sbConfigPath" + + $sbConfigJson = Get-Content $sbConfigPath -Raw | ConvertFrom-Json + + $sbConfigJson.appSubmission.productId = $config.ProductId + Write-Verbose -Verbose "Updated productId to: $($config.ProductId)" + + $sbConfigJson | ConvertTo-Json -Depth 100 | Set-Content $sbConfigPath -Encoding UTF8 + Write-Verbose -Verbose "SBConfig file updated successfully" + } else { + Write-Error "SBConfig file not found: $sbConfigPath" + exit 1 + } + + Write-Host "##vso[task.setvariable variable=ServiceConnection]$($config.ServiceEndpoint)" + Write-Host "##vso[task.setvariable variable=SBConfigPath]$($config.SBConfigPath)" + name: UpdateConfigs + displayName: Update PDPs and SBConfig.json + + - task: MS-RDX-MRO.windows-store-publish-dev.package-task.store-package@3 + displayName: 'Create StoreBroker Package' + inputs: + serviceEndpoint: '$(ServiceConnection)' + sbConfigPath: '$(SBConfigPath)' + sourceFolder: '$(BundleDir)' + contents: '*.msixBundle' + outSBName: 'PowerShellStorePackage' + pdpPath: '$(System.DefaultWorkingDirectory)/PowerShell/.pipelines/store/PDP/PDP' + pdpMediaPath: '$(System.DefaultWorkingDirectory)/PowerShell/.pipelines/store/PDP/PDP-Media' + + - pwsh: | + $submissionPackageDir = "$(System.DefaultWorkingDirectory)/SBOutDir" + $jsonFile = "$submissionPackageDir/PowerShellStorePackage.json" + $zipFile = "$submissionPackageDir/PowerShellStorePackage.zip" + + if ((Test-Path $jsonFile) -and (Test-Path $zipFile)) { + Write-Verbose -Verbose "Uploading StoreBroker Package files:" + Write-Verbose -Verbose "JSON File: $jsonFile" + Write-Verbose -Verbose "ZIP File: $zipFile" + + Copy-Item -Path $submissionPackageDir -Destination "$(ob_outputDirectory)" -Verbose -Recurse + } + + else { + Write-Error "Required files not found in $submissionPackageDir" + } + displayName: 'Upload StoreBroker Package' diff --git a/.pipelines/templates/release-MSIX-Publish.yml b/.pipelines/templates/release-MSIX-Publish.yml new file mode 100644 index 00000000000..9a0dba8833f --- /dev/null +++ b/.pipelines/templates/release-MSIX-Publish.yml @@ -0,0 +1,115 @@ +parameters: + - name: skipMSIXPublish + type: boolean + +jobs: +- job: Store_Publish_MSIX + displayName: Publish MSIX to the Microsoft Store + pool: + type: release + os: windows + templateContext: + inputs: + - input: pipelineArtifact + pipeline: PSPackagesOfficial + artifactName: drop_msixbundle_CreateMSIXBundle + variables: + - group: 'Store Publish Variables' + - template: ./variable/release-shared.yml@self + parameters: + RELEASETAG: $[ stageDependencies.setReleaseTagAndChangelog.setTagAndChangelog.outputs['OutputReleaseTag.releaseTag'] ] + LTS: $[ stageDependencies.setReleaseTagAndChangelog.setTagAndChangelog.outputs['ChannelSelection.IsLTS'] ] + STABLE: $[ stageDependencies.setReleaseTagAndChangelog.setTagAndChangelog.outputs['ChannelSelection.IsStable'] ] + PREVIEW: $[ stageDependencies.setReleaseTagAndChangelog.setTagAndChangelog.outputs['ChannelSelection.IsPreview'] ] + steps: + - task: PowerShell@2 + inputs: + targetType: inline + script: | + Write-Verbose -Verbose "Release Tag: $(ReleaseTag)" + Get-ChildItem $(Pipeline.Workspace) -Recurse | Select-Object -ExpandProperty FullName + displayName: 'Capture ReleaseTag and Downloaded Packages' + + - task: PowerShell@2 + inputs: + targetType: inline + script: | + if ("$(ReleaseTag)" -eq '') { + Write-Error "ReleaseTag is not set. Cannot proceed with publishing to the Store." + exit 1 + } + $middleURL = '' + $tagString = "$(ReleaseTag)" + if ($tagString -match '-') { + $middleURL = "preview" + } + elseif ($tagString -match '(\d+\.\d+)') { + $middleURL = $matches[1] + } + + $endURL = $tagString -replace '[v\.]','' + $message = "Changelog: https://github.com/PowerShell/PowerShell/blob/master/CHANGELOG/$middleURL.md#$endURL" + Write-Verbose -Verbose "Release Notes for the Store:" + Write-Verbose -Verbose "$message" + $jsonPath = "$(Pipeline.Workspace)\SBOutDir\PowerShellStorePackage.json" + $json = Get-Content $jsonPath -Raw | ConvertFrom-Json + + $json.listings.'en-us'.baseListing.releaseNotes = $message + + $json | ConvertTo-Json -Depth 100 | Set-Content $jsonPath -Encoding UTF8 + displayName: 'Update Release Notes in JSON' + + - task: PowerShell@2 + inputs: + targetType: inline + script: | + Write-Verbose -Verbose "Channel Selection - LTS: $(LTS), Stable: $(Stable), Preview: $(Preview)" + + # Define app configurations for each channel using secret variables + $channelConfigs = @{ + 'LTS' = @{ + AppId = '$(AppID-LTS)' + ServiceEndpoint = 'StoreAppPublish-Stable' + } + 'Stable' = @{ + AppId = '$(AppID-Stable)' + ServiceEndpoint = 'StoreAppPublish-Stable' + } + 'Preview' = @{ + AppId = '$(AppID-Preview)' + ServiceEndpoint = 'StoreAppPublish-Preview' + } + } + + # Determine the current channel + $currentChannel = if ($IsLTS) { 'LTS' } + elseif ($IsStable) { 'Stable' } + elseif ($IsPreview) { 'Preview' } + else { + Write-Error "No valid channel detected" + exit 1 + } + + $config = $channelConfigs[$currentChannel] + Write-Verbose -Verbose "Selected channel: $currentChannel" + Write-Verbose -Verbose "App ID: $($config.AppId)" + Write-Verbose -Verbose "Service Endpoint: $($config.ServiceEndpoint)" + + # Set pipeline variables for use in the store-publish task + Write-Host "##vso[task.setvariable variable=SelectedAppId]$($config.AppId)" + Write-Host "##vso[task.setvariable variable=SelectedServiceEndpoint]$($config.ServiceEndpoint)" + Write-Host "##vso[task.setvariable variable=SelectedChannel]$currentChannel" + displayName: 'Set StoreBroker Configurations' + + - task: MS-RDX-MRO.windows-store-publish.publish-task.store-publish@3 + displayName: 'Publish LTS StoreBroker Package' + condition: ne('${{ parameters.skipMSIXPublish }}', 'true') + inputs: + serviceEndpoint: '$(SelectedServiceEndpoint)' + appId: '$(SelectedAppId)' + inputMethod: JsonAndZip + jsonPath: '$(Pipeline.Workspace)\SBOutDir\PowerShellStorePackage.json' + zipPath: '$(Pipeline.Workspace)\SBOutDir\PowerShellStorePackage.zip' + numberOfPackagesToKeep: 2 + jsonZipUpdateMetadata: true + targetPublishMode: 'Immediate' diff --git a/.pipelines/templates/release-SetTagAndChangelog.yml b/.pipelines/templates/release-SetTagAndChangelog.yml index f0c516dd28f..b33e652b3c7 100644 --- a/.pipelines/templates/release-SetTagAndChangelog.yml +++ b/.pipelines/templates/release-SetTagAndChangelog.yml @@ -19,7 +19,7 @@ jobs: clean: true env: ob_restore_phase: true - + - pwsh: | Write-Verbose -Verbose "Release Tag: $(OutputReleaseTag.releaseTag)" $releaseVersion = '$(OutputReleaseTag.releaseTag)' -replace '^v','' @@ -47,3 +47,5 @@ jobs: New-Item -Path $(ob_outputDirectory)/CHANGELOG -ItemType Directory -Force Copy-Item -Path $filePath -Destination $(ob_outputDirectory)/CHANGELOG displayName: Upload Changelog + + - template: channelSelection.yml@self diff --git a/tools/packaging/packaging.psm1 b/tools/packaging/packaging.psm1 index 560a985283b..26300523e9b 100644 --- a/tools/packaging/packaging.psm1 +++ b/tools/packaging/packaging.psm1 @@ -515,6 +515,7 @@ function Start-PSPackage { Architecture = $WindowsRuntime.Split('-')[1] Force = $Force Private = $Private + LTS = $LTS } if ($PSCmdlet.ShouldProcess("Create MSIX Package")) { @@ -3665,6 +3666,9 @@ function New-MSIXPackage # Produce private package for testing in Store [Switch] $Private, + # Produce LTS package + [Switch] $LTS, + # Force overwrite of package [Switch] $Force, @@ -3709,6 +3713,9 @@ function New-MSIXPackage } elseif ($ProductSemanticVersion.Contains('-')) { $ProductName += 'Preview' $displayName += ' Preview' + } elseif ($LTS) { + $ProductName += '-LTS' + $displayName += '-LTS' } Write-Verbose -Verbose "ProductName: $productName" @@ -3728,6 +3735,10 @@ function New-MSIXPackage # This is the PhoneProductId for the "Microsoft.PowerShellPreview" package. $PhoneProductId = "67859fd2-b02a-45be-8fb5-62c569a3e8bf" Write-Verbose "Using Preview assets" -Verbose + } elseif ($LTS) { + # This is the PhoneProductId for the "Microsoft.PowerShell-LTS" package. + $PhoneProductId = "a9af273a-c636-47ac-bc2a-775edf80b2b9" + Write-Verbose "Using LTS assets" -Verbose } # Appx manifest needs to be in root of source path, but the embedded version needs to be updated From bf11519f6f345d48c4b3000a8c3f6051d564d625 Mon Sep 17 00:00:00 2001 From: PowerShell Team Bot <69177312+pwshBot@users.noreply.github.com> Date: Thu, 9 Oct 2025 13:54:31 -0700 Subject: [PATCH 163/173] [release/v7.5] Remove UseDotnet task and use the dotnet-install script (#26169) --- .pipelines/PowerShell-Packages-Official.yml | 6 ++++ .pipelines/templates/install-dotnet.yml | 19 +++++++++++++ .pipelines/templates/linux-package-build.yml | 4 ++- .pipelines/templates/linux.yml | 7 +---- .pipelines/templates/mac.yml | 8 ++---- .pipelines/templates/nupkg.yml | 10 +------ .../release-validate-fxdpackages.yml | 7 +---- .../release-validate-globaltools.yml | 7 +---- .pipelines/templates/release-validate-sdk.yml | 7 +---- .pipelines/templates/testartifacts.yml | 28 ++++++++----------- .pipelines/templates/windows-hosted-build.yml | 11 ++++---- .../templates/windows-package-build.yml | 11 +++----- build.psm1 | 5 ++-- 13 files changed, 57 insertions(+), 73 deletions(-) create mode 100644 .pipelines/templates/install-dotnet.yml diff --git a/.pipelines/PowerShell-Packages-Official.yml b/.pipelines/PowerShell-Packages-Official.yml index 552e7d10a68..9c2dee1c571 100644 --- a/.pipelines/PowerShell-Packages-Official.yml +++ b/.pipelines/PowerShell-Packages-Official.yml @@ -27,6 +27,9 @@ parameters: # parameters are shown up in ADO UI in a build queue time - name: OfficialBuild type: boolean default: false + - name: disableNetworkIsolation + type: boolean + default: false name: pkgs-$(BUILD.SOURCEBRANCHNAME)-prod.${{ parameters.OfficialBuild }}-$(Build.BuildId) @@ -66,6 +69,8 @@ variables: - group: MSIXSigningProfile - name: templateFile value: ${{ iif ( parameters.OfficialBuild, 'v2/OneBranch.Official.CrossPlat.yml@onebranchTemplates', 'v2/OneBranch.NonOfficial.CrossPlat.yml@onebranchTemplates' ) }} + - name: disableNetworkIsolation + value: ${{ parameters.disableNetworkIsolation }} resources: pipelines: @@ -96,6 +101,7 @@ extends: Network: KS3 linuxEsrpSigning: true incrementalSDLBinaryAnalysis: true + disableNetworkIsolation: ${{ variables.disableNetworkIsolation }} globalSdl: disableLegacyManifest: true # disabled Armorty as we dont have any ARM templates to scan. It fails on some sample ARM templates. diff --git a/.pipelines/templates/install-dotnet.yml b/.pipelines/templates/install-dotnet.yml new file mode 100644 index 00000000000..c2a2cfebeca --- /dev/null +++ b/.pipelines/templates/install-dotnet.yml @@ -0,0 +1,19 @@ +steps: + - pwsh: | + if (-not (Test-Path '$(RepoRoot)')) { + $psRoot = '$(Build.SourcesDirectory)/PowerShell' + Set-Location $psRoot -Verbose + } + + $version = Get-Content ./global.json | ConvertFrom-Json | Select-Object -ExpandProperty sdk | Select-Object -ExpandProperty version + + Write-Verbose -Verbose "Installing .NET SDK with version $version" + + Import-Module ./build.psm1 -Force + Install-Dotnet -Version $version -Verbose + + displayName: 'Install dotnet SDK' + workingDirectory: $(RepoRoot) + env: + ob_restore_phase: true + diff --git a/.pipelines/templates/linux-package-build.yml b/.pipelines/templates/linux-package-build.yml index a9f4833cc1d..02839c7d650 100644 --- a/.pipelines/templates/linux-package-build.yml +++ b/.pipelines/templates/linux-package-build.yml @@ -87,6 +87,8 @@ jobs: env: ob_restore_phase: true # This ensures this done in restore phase to workaround signing issue + - template: /.pipelines/templates/install-dotnet.yml@self + - pwsh: | $packageType = '$(PackageType)' Write-Verbose -Verbose "packageType = $packageType" @@ -103,7 +105,7 @@ jobs: Import-Module "$repoRoot/build.psm1" Import-Module "$repoRoot/tools/packaging" - Start-PSBootstrap -Scenario Package + Start-PSBootstrap -Scenario Both $psOptionsPath = "$(Pipeline.Workspace)/CoOrdinatedBuildPipeline/${unsignedDrop}/psoptions/psoptions.json" diff --git a/.pipelines/templates/linux.yml b/.pipelines/templates/linux.yml index ccfac3fbc8e..cbf63c84b48 100644 --- a/.pipelines/templates/linux.yml +++ b/.pipelines/templates/linux.yml @@ -62,12 +62,7 @@ jobs: AnalyzeInPipeline: true Language: csharp - - task: UseDotNet@2 - inputs: - useGlobalJson: true - workingDirectory: $(PowerShellRoot) - env: - ob_restore_phase: true + - template: /.pipelines/templates/install-dotnet.yml@self - pwsh: | $runtime = $env:RUNTIME diff --git a/.pipelines/templates/mac.yml b/.pipelines/templates/mac.yml index b08becedc22..ff4787b9bcf 100644 --- a/.pipelines/templates/mac.yml +++ b/.pipelines/templates/mac.yml @@ -39,12 +39,8 @@ jobs: sudo chown $env:USER "$(Agent.TempDirectory)/PowerShell" displayName: 'Create $(Agent.TempDirectory)/PowerShell' - - task: UseDotNet@2 - displayName: 'Use .NET Core sdk' - inputs: - useGlobalJson: true - packageType: 'sdk' - workingDirectory: $(PowerShellRoot) + ## We cross compile for arm64, so the arch is always x64 + - template: /.pipelines/templates/install-dotnet.yml@self - pwsh: | Import-Module $(PowerShellRoot)/build.psm1 -Force diff --git a/.pipelines/templates/nupkg.yml b/.pipelines/templates/nupkg.yml index d7837c5c3dc..175c847944a 100644 --- a/.pipelines/templates/nupkg.yml +++ b/.pipelines/templates/nupkg.yml @@ -94,15 +94,7 @@ jobs: parameters: repoRoot: $(PowerShellRoot) - - task: NuGetToolInstaller@1 - displayName: 'Install NuGet.exe' - - - task: UseDotNet@2 - displayName: 'Use .NET Core sdk' - inputs: - useGlobalJson: true - packageType: 'sdk' - workingDirectory: '$(PowerShellRoot)' + - template: /.pipelines/templates/install-dotnet.yml@self - pwsh: | Set-Location -Path '$(PowerShellRoot)' diff --git a/.pipelines/templates/release-validate-fxdpackages.yml b/.pipelines/templates/release-validate-fxdpackages.yml index 53657e6414a..191db42d743 100644 --- a/.pipelines/templates/release-validate-fxdpackages.yml +++ b/.pipelines/templates/release-validate-fxdpackages.yml @@ -61,12 +61,7 @@ jobs: Get-ChildItem "$(Pipeline.Workspace)/PSPackagesOfficial/$artifactName" -Recurse displayName: 'Capture Downloaded Artifacts' - - task: UseDotNet@2 - displayName: 'Use .NET Core sdk' - inputs: - useGlobalJson: true - packageType: 'sdk' - workingDirectory: $(Build.SourcesDirectory)/PowerShell" + - template: /.pipelines/templates/install-dotnet.yml@self - pwsh: | $artifactName = '$(artifactName)' diff --git a/.pipelines/templates/release-validate-globaltools.yml b/.pipelines/templates/release-validate-globaltools.yml index 3c88a278791..11e124e33d6 100644 --- a/.pipelines/templates/release-validate-globaltools.yml +++ b/.pipelines/templates/release-validate-globaltools.yml @@ -38,12 +38,7 @@ jobs: Get-ChildItem "$(Pipeline.Workspace)/PSPackagesOfficial/drop_nupkg_build_nupkg" -Recurse displayName: 'Capture Downloaded Artifacts' - - task: UseDotNet@2 - displayName: 'Use .NET Core sdk' - inputs: - useGlobalJson: true - packageType: 'sdk' - workingDirectory: $(REPOROOT) + - template: /.pipelines/templates/install-dotnet.yml@self - pwsh: | $repoRoot = "$(Build.SourcesDirectory)/PowerShell" diff --git a/.pipelines/templates/release-validate-sdk.yml b/.pipelines/templates/release-validate-sdk.yml index d879ab7f06e..3e58101f7e3 100644 --- a/.pipelines/templates/release-validate-sdk.yml +++ b/.pipelines/templates/release-validate-sdk.yml @@ -46,12 +46,7 @@ jobs: Get-ChildItem "$(Pipeline.Workspace)/PSPackagesOfficial/drop_nupkg_build_nupkg" -Recurse displayName: 'Capture Downloaded Artifacts' - - task: UseDotNet@2 - displayName: 'Use .NET Core sdk' - inputs: - useGlobalJson: true - packageType: 'sdk' - workingDirectory: $(REPOROOT) + - template: /.pipelines/templates/install-dotnet.yml@self - pwsh: | $repoRoot = "$(Build.SourcesDirectory)" diff --git a/.pipelines/templates/testartifacts.yml b/.pipelines/templates/testartifacts.yml index 240ceae80f7..751c9d5a53b 100644 --- a/.pipelines/templates/testartifacts.yml +++ b/.pipelines/templates/testartifacts.yml @@ -25,19 +25,16 @@ jobs: env: ob_restore_phase: true + - template: /.pipelines/templates/SetVersionVariables.yml@self + parameters: + ReleaseTagVar: $(ReleaseTagVar) + - template: /.pipelines/templates/insert-nuget-config-azfeed.yml@self parameters: - repoRoot: $(Build.SourcesDirectory)/PowerShell + repoRoot: $(RepoRoot) ob_restore_phase: true - - task: UseDotNet@2 - displayName: 'Use .NET Core sdk' - inputs: - useGlobalJson: true - packageType: 'sdk' - workingDirectory: $(Build.SourcesDirectory)/PowerShell" - env: - ob_restore_phase: true + - template: /.pipelines/templates/install-dotnet.yml@self - pwsh: | New-Item -Path '$(ob_outputDirectory)' -ItemType Directory -Force @@ -93,19 +90,16 @@ jobs: env: ob_restore_phase: true + - template: /.pipelines/templates/SetVersionVariables.yml@self + parameters: + ReleaseTagVar: $(ReleaseTagVar) + - template: /.pipelines/templates/insert-nuget-config-azfeed.yml@self parameters: repoRoot: $(Build.SourcesDirectory)/PowerShell ob_restore_phase: true - - task: UseDotNet@2 - displayName: 'Use .NET Core sdk' - inputs: - useGlobalJson: true - packageType: 'sdk' - workingDirectory: $(Build.SourcesDirectory)/PowerShell" - env: - ob_restore_phase: true + - template: /.pipelines/templates/install-dotnet.yml@self - pwsh: | New-Item -Path '$(ob_outputDirectory)' -ItemType Directory -Force diff --git a/.pipelines/templates/windows-hosted-build.yml b/.pipelines/templates/windows-hosted-build.yml index 1f732a0145c..b3c72a51b33 100644 --- a/.pipelines/templates/windows-hosted-build.yml +++ b/.pipelines/templates/windows-hosted-build.yml @@ -63,12 +63,7 @@ jobs: AnalyzeInPipeline: true Language: csharp - - task: UseDotNet@2 - inputs: - useGlobalJson: true - workingDirectory: $(PowerShellRoot) - env: - ob_restore_phase: true + - template: /.pipelines/templates/install-dotnet.yml@self - pwsh: | $runtime = switch ($env:Architecture) @@ -142,6 +137,7 @@ jobs: } Import-Module -Name $(PowerShellRoot)/build.psm1 -Force + Find-Dotnet ## Build global tool Write-Verbose -Message "Building PowerShell global tool for Windows.x64" -Verbose @@ -237,6 +233,9 @@ jobs: After that, we repack using Compress-Archive and rename it back to a nupkg. #> + Import-Module -Name $(PowerShellRoot)/build.psm1 -Force + Find-Dotnet + $packagingStrings = Import-PowerShellDataFile "$(PowerShellRoot)\tools\packaging\packaging.strings.psd1" $outputPath = Join-Path '$(ob_outputDirectory)' 'globaltool' diff --git a/.pipelines/templates/windows-package-build.yml b/.pipelines/templates/windows-package-build.yml index 08dd15fc79f..50309c5099b 100644 --- a/.pipelines/templates/windows-package-build.yml +++ b/.pipelines/templates/windows-package-build.yml @@ -78,12 +78,7 @@ jobs: env: ob_restore_phase: true # This ensures this done in restore phase to workaround signing issue - - task: UseDotNet@2 - inputs: - useGlobalJson: true - workingDirectory: $(REPOROOT) - env: - ob_restore_phase: true + - template: /.pipelines/templates/install-dotnet.yml@self - pwsh: | $msixUrl = '$(makeappUrl)' @@ -112,7 +107,9 @@ jobs: Import-Module "$repoRoot\build.psm1" Import-Module "$repoRoot\tools\packaging" - Start-PSBootstrap -Scenario Package + Start-PSBootstrap -Scenario Both + + Find-Dotnet $signedFilesPath, $psoptionsFilePath = if ($env:RUNTIME -eq 'minsize') { "$(Pipeline.Workspace)\CoOrdinatedBuildPipeline\drop_windows_build_windows_x64_${runtime}\$signedFolder" diff --git a/build.psm1 b/build.psm1 index fe7eff67b2f..aa49b6061c3 100644 --- a/build.psm1 +++ b/build.psm1 @@ -2081,8 +2081,8 @@ function Install-Dotnet { # Note that when it is null, Invoke-Expression (but not &) must be used to interpolate properly $sudo = if (!$NoSudo) { "sudo" } - # $installObtainUrl = "https://dot.net/v1" - $installObtainUrl = "https://dotnet.microsoft.com/download/dotnet/scripts/v1" + $installObtainUrl = "https://builds.dotnet.microsoft.com/dotnet/scripts/v1" + #$installObtainUrl = "https://dotnet.microsoft.com/download/dotnet/scripts/v1" $uninstallObtainUrl = "https://raw.githubusercontent.com/dotnet/cli/master/scripts/obtain" # Install for Linux and OS X @@ -2173,7 +2173,6 @@ function Install-Dotnet { $installArgs += @{ SkipNonVersionedFiles = $true } $installArgs | Out-String | Write-Verbose -Verbose - & ./$installScript @installArgs } else { From 559291f9d0fd4a1c7e76fe56aac0c8cdabda8eea Mon Sep 17 00:00:00 2001 From: PowerShell Team Bot <69177312+pwshBot@users.noreply.github.com> Date: Thu, 9 Oct 2025 15:57:12 -0700 Subject: [PATCH 164/173] [release/v7.5] add CodeQL suppressions for UpdatableHelp and NativeCommandProcessor methods (#26171) --- .../engine/NativeCommandProcessor.cs | 2 ++ src/System.Management.Automation/help/UpdatableHelpSystem.cs | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/System.Management.Automation/engine/NativeCommandProcessor.cs b/src/System.Management.Automation/engine/NativeCommandProcessor.cs index 43113d07425..12186f241ea 100644 --- a/src/System.Management.Automation/engine/NativeCommandProcessor.cs +++ b/src/System.Management.Automation/engine/NativeCommandProcessor.cs @@ -658,6 +658,8 @@ private void InitNativeProcess() { startInfo.ArgumentList.RemoveAt(0); } + + // codeql[cs/microsoft/command-line-injection-shell-execution] - This is expected Poweshell behavior where user inputted paths are supported for the context of this method. The user assumes trust for the file path specified on the user's system to retrieve process info for, and in the case of remoting, restricted remoting security guidelines should be used. startInfo.FileName = oldFileName; } } diff --git a/src/System.Management.Automation/help/UpdatableHelpSystem.cs b/src/System.Management.Automation/help/UpdatableHelpSystem.cs index 6ab8d469a97..14edabf9613 100644 --- a/src/System.Management.Automation/help/UpdatableHelpSystem.cs +++ b/src/System.Management.Automation/help/UpdatableHelpSystem.cs @@ -419,6 +419,7 @@ private string ResolveUri(string baseUri, bool verbose) using (HttpClient client = new HttpClient(handler)) { client.Timeout = new TimeSpan(0, 0, 30); // Set 30 second timeout + // codeql[cs/ssrf] - This is expected Poweshell behavior and the user assumes trust for the module they download and any URIs it references. The URIs are also not executables or scripts that would be invoked by this method. Task responseMessage = client.GetAsync(uri); using (HttpResponseMessage response = responseMessage.Result) { @@ -783,6 +784,7 @@ private bool DownloadHelpContentHttpClient(string uri, string fileName, Updatabl using (HttpClient client = new HttpClient(handler)) { client.Timeout = _defaultTimeout; + // codeql[cs/ssrf] - This is expected Poweshell behavior and the user assumes trust for the module they download and any URIs it references. The URIs are also not executables or scripts that would be invoked by this method. Task responseMsg = client.GetAsync(new Uri(uri), _cancelTokenSource.Token); // TODO: Should I use a continuation to write the stream to a file? From cf33058c466e0f35cf9f85e2f808d23393c4873b Mon Sep 17 00:00:00 2001 From: PowerShell Team Bot <69177312+pwshBot@users.noreply.github.com> Date: Thu, 9 Oct 2025 15:57:42 -0700 Subject: [PATCH 165/173] [release/v7.5] add CodeQL suppresion for NativeCommandProcessor (#26173) --- .../engine/NativeCommandProcessor.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/System.Management.Automation/engine/NativeCommandProcessor.cs b/src/System.Management.Automation/engine/NativeCommandProcessor.cs index 12186f241ea..f1fd575609e 100644 --- a/src/System.Management.Automation/engine/NativeCommandProcessor.cs +++ b/src/System.Management.Automation/engine/NativeCommandProcessor.cs @@ -1468,6 +1468,7 @@ private ProcessStartInfo GetProcessStartInfo( { using (ParameterBinderBase.bindingTracer.TraceScope("BIND argument [{0}]", NativeParameterBinderController.Arguments)) { + // codeql[cs/microsoft/command-line-injection ] - This is intended PowerShell behavior as NativeParameterBinderController.Arguments is what the native parameter binder generates based on the user input when invoking the command and cannot be injected externally. startInfo.Arguments = NativeParameterBinderController.Arguments; } } From 423fd1978f76e73188a31fb921f93830f380ef81 Mon Sep 17 00:00:00 2001 From: PowerShell Team Bot <69177312+pwshBot@users.noreply.github.com> Date: Tue, 14 Oct 2025 18:18:27 -0700 Subject: [PATCH 166/173] [release/v7.5] Mark the 3 consistently failing tests as pending to unblock PRs (#26196) --- test/powershell/Host/ConsoleHost.Tests.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/powershell/Host/ConsoleHost.Tests.ps1 b/test/powershell/Host/ConsoleHost.Tests.ps1 index 9a546302906..f3b25e00dcf 100644 --- a/test/powershell/Host/ConsoleHost.Tests.ps1 +++ b/test/powershell/Host/ConsoleHost.Tests.ps1 @@ -1000,7 +1000,7 @@ public enum ShowWindowCommands : int $global:PSDefaultParameterValues = $defaultParamValues } - It "-WindowStyle should work on Windows" -TestCases @( + It "-WindowStyle should work on Windows" -Pending -TestCases @( @{WindowStyle="Normal"}, @{WindowStyle="Minimized"}, @{WindowStyle="Maximized"} # hidden doesn't work in CI/Server Core From 083f2caf9f2e52b78db15aad8ae6b332abe4b7af Mon Sep 17 00:00:00 2001 From: PowerShell Team Bot <69177312+pwshBot@users.noreply.github.com> Date: Tue, 14 Oct 2025 18:47:49 -0700 Subject: [PATCH 167/173] [release/v7.5] Update branch for release (#26195) --- DotnetRuntimeMetadata.json | 2 +- global.json | 2 +- ...oft.PowerShell.Commands.Diagnostics.csproj | 8 +- ...soft.PowerShell.Commands.Management.csproj | 4 +- ...crosoft.PowerShell.Commands.Utility.csproj | 6 +- ...crosoft.PowerShell.CoreCLR.Eventing.csproj | 2 +- .../Microsoft.PowerShell.SDK.csproj | 98 ++++++++-------- .../Microsoft.WSMan.Management.csproj | 4 +- .../System.Management.Automation.csproj | 26 ++--- .../BenchmarkDotNet.Extensions.csproj | 5 +- .../dotnet-tools/Reporting/Reporting.csproj | 2 +- .../ResultsComparer/ResultsComparer.csproj | 7 +- ...soft.PowerShell.NamedPipeConnection.csproj | 27 ++--- .../nested/Test.Isolated.Nested.csproj | 2 +- test/tools/TestService/TestService.csproj | 94 +++++++-------- test/tools/WebListener/WebListener.csproj | 7 +- tools/cgmanifest.json | 108 +++++++++--------- 17 files changed, 204 insertions(+), 200 deletions(-) diff --git a/DotnetRuntimeMetadata.json b/DotnetRuntimeMetadata.json index eb802bfec36..6f09eb2d6ed 100644 --- a/DotnetRuntimeMetadata.json +++ b/DotnetRuntimeMetadata.json @@ -4,7 +4,7 @@ "quality": "daily", "qualityFallback": "preview", "packageVersionPattern": "9.0.0-preview.6", - "sdkImageVersion": "9.0.304", + "sdkImageVersion": "9.0.306", "nextChannel": "9.0.0-preview.7", "azureFeed": "", "sdkImageOverride": "" diff --git a/global.json b/global.json index 4c6e2601f69..345f67e389e 100644 --- a/global.json +++ b/global.json @@ -1,5 +1,5 @@ { "sdk": { - "version": "9.0.304" + "version": "9.0.306" } } diff --git a/src/Microsoft.PowerShell.Commands.Diagnostics/Microsoft.PowerShell.Commands.Diagnostics.csproj b/src/Microsoft.PowerShell.Commands.Diagnostics/Microsoft.PowerShell.Commands.Diagnostics.csproj index 0b8a4c35cfc..00eac01d55c 100644 --- a/src/Microsoft.PowerShell.Commands.Diagnostics/Microsoft.PowerShell.Commands.Diagnostics.csproj +++ b/src/Microsoft.PowerShell.Commands.Diagnostics/Microsoft.PowerShell.Commands.Diagnostics.csproj @@ -7,11 +7,11 @@ - - - + + + - + diff --git a/src/Microsoft.PowerShell.Commands.Management/Microsoft.PowerShell.Commands.Management.csproj b/src/Microsoft.PowerShell.Commands.Management/Microsoft.PowerShell.Commands.Management.csproj index d9f8e52e762..d992c2eab25 100644 --- a/src/Microsoft.PowerShell.Commands.Management/Microsoft.PowerShell.Commands.Management.csproj +++ b/src/Microsoft.PowerShell.Commands.Management/Microsoft.PowerShell.Commands.Management.csproj @@ -47,8 +47,8 @@ - - + + diff --git a/src/Microsoft.PowerShell.Commands.Utility/Microsoft.PowerShell.Commands.Utility.csproj b/src/Microsoft.PowerShell.Commands.Utility/Microsoft.PowerShell.Commands.Utility.csproj index 3e270da4164..1bb01e109e2 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/Microsoft.PowerShell.Commands.Utility.csproj +++ b/src/Microsoft.PowerShell.Commands.Utility/Microsoft.PowerShell.Commands.Utility.csproj @@ -13,7 +13,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive all - + @@ -41,8 +41,8 @@ - - + + diff --git a/src/Microsoft.PowerShell.CoreCLR.Eventing/Microsoft.PowerShell.CoreCLR.Eventing.csproj b/src/Microsoft.PowerShell.CoreCLR.Eventing/Microsoft.PowerShell.CoreCLR.Eventing.csproj index a02a0637693..04df0482c35 100644 --- a/src/Microsoft.PowerShell.CoreCLR.Eventing/Microsoft.PowerShell.CoreCLR.Eventing.csproj +++ b/src/Microsoft.PowerShell.CoreCLR.Eventing/Microsoft.PowerShell.CoreCLR.Eventing.csproj @@ -8,7 +8,7 @@ - + diff --git a/src/Microsoft.PowerShell.SDK/Microsoft.PowerShell.SDK.csproj b/src/Microsoft.PowerShell.SDK/Microsoft.PowerShell.SDK.csproj index e951707c28b..bd6c95cedd0 100644 --- a/src/Microsoft.PowerShell.SDK/Microsoft.PowerShell.SDK.csproj +++ b/src/Microsoft.PowerShell.SDK/Microsoft.PowerShell.SDK.csproj @@ -17,55 +17,55 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - + + + + + + - - - - - - - - - - - - - - + + + + + + + + + + + + + + - - + + - + diff --git a/src/Microsoft.WSMan.Management/Microsoft.WSMan.Management.csproj b/src/Microsoft.WSMan.Management/Microsoft.WSMan.Management.csproj index c820e3f235b..6195d3a80e1 100644 --- a/src/Microsoft.WSMan.Management/Microsoft.WSMan.Management.csproj +++ b/src/Microsoft.WSMan.Management/Microsoft.WSMan.Management.csproj @@ -7,11 +7,11 @@ - + - + diff --git a/src/System.Management.Automation/System.Management.Automation.csproj b/src/System.Management.Automation/System.Management.Automation.csproj index f3b62eafb49..c04785cacf3 100644 --- a/src/System.Management.Automation/System.Management.Automation.csproj +++ b/src/System.Management.Automation/System.Management.Automation.csproj @@ -28,29 +28,29 @@ - + - - - - - - + + + + + + - + - - - - + + + + - + diff --git a/test/perf/dotnet-tools/BenchmarkDotNet.Extensions/BenchmarkDotNet.Extensions.csproj b/test/perf/dotnet-tools/BenchmarkDotNet.Extensions/BenchmarkDotNet.Extensions.csproj index 9b5fb753394..564f890365b 100644 --- a/test/perf/dotnet-tools/BenchmarkDotNet.Extensions/BenchmarkDotNet.Extensions.csproj +++ b/test/perf/dotnet-tools/BenchmarkDotNet.Extensions/BenchmarkDotNet.Extensions.csproj @@ -13,11 +13,12 @@ - + + - + diff --git a/test/perf/dotnet-tools/Reporting/Reporting.csproj b/test/perf/dotnet-tools/Reporting/Reporting.csproj index 693cc1b6481..e15b95fc853 100644 --- a/test/perf/dotnet-tools/Reporting/Reporting.csproj +++ b/test/perf/dotnet-tools/Reporting/Reporting.csproj @@ -7,7 +7,7 @@ - + diff --git a/test/perf/dotnet-tools/ResultsComparer/ResultsComparer.csproj b/test/perf/dotnet-tools/ResultsComparer/ResultsComparer.csproj index 3eacb22eb51..a8e05fbbb96 100644 --- a/test/perf/dotnet-tools/ResultsComparer/ResultsComparer.csproj +++ b/test/perf/dotnet-tools/ResultsComparer/ResultsComparer.csproj @@ -13,12 +13,13 @@ - - + + + - + diff --git a/test/tools/NamedPipeConnection/src/code/Microsoft.PowerShell.NamedPipeConnection.csproj b/test/tools/NamedPipeConnection/src/code/Microsoft.PowerShell.NamedPipeConnection.csproj index 7fa3f53c83d..bcd8e6011df 100644 --- a/test/tools/NamedPipeConnection/src/code/Microsoft.PowerShell.NamedPipeConnection.csproj +++ b/test/tools/NamedPipeConnection/src/code/Microsoft.PowerShell.NamedPipeConnection.csproj @@ -17,21 +17,22 @@ - + - - - - - - - + + + + + + + + - - - - - + + + + + diff --git a/test/tools/TestAlc/nested/Test.Isolated.Nested.csproj b/test/tools/TestAlc/nested/Test.Isolated.Nested.csproj index 200b284b31a..a3c17907b03 100644 --- a/test/tools/TestAlc/nested/Test.Isolated.Nested.csproj +++ b/test/tools/TestAlc/nested/Test.Isolated.Nested.csproj @@ -20,7 +20,7 @@ - + diff --git a/test/tools/TestService/TestService.csproj b/test/tools/TestService/TestService.csproj index 5508aa6cd9b..7a3d777f431 100644 --- a/test/tools/TestService/TestService.csproj +++ b/test/tools/TestService/TestService.csproj @@ -15,56 +15,56 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - + + + + + - - - - - - - - + + + + + + + + - + diff --git a/test/tools/WebListener/WebListener.csproj b/test/tools/WebListener/WebListener.csproj index c65c90a3ff7..b8f1899736a 100644 --- a/test/tools/WebListener/WebListener.csproj +++ b/test/tools/WebListener/WebListener.csproj @@ -7,9 +7,10 @@ - - + + + - + diff --git a/tools/cgmanifest.json b/tools/cgmanifest.json index 9b00c6ac230..dd6bf54f46d 100644 --- a/tools/cgmanifest.json +++ b/tools/cgmanifest.json @@ -1,4 +1,5 @@ { + "$schema": "https://json.schemastore.org/component-detection-manifest.json", "Registrations": [ { "Component": { @@ -115,7 +116,7 @@ "Type": "nuget", "Nuget": { "Name": "Microsoft.Extensions.ObjectPool", - "Version": "8.0.19" + "Version": "8.0.21" } }, "DevelopmentDependency": false @@ -155,7 +156,7 @@ "Type": "nuget", "Nuget": { "Name": "Microsoft.Win32.Registry.AccessControl", - "Version": "9.0.8" + "Version": "9.0.10" } }, "DevelopmentDependency": false @@ -165,7 +166,7 @@ "Type": "nuget", "Nuget": { "Name": "Microsoft.Win32.SystemEvents", - "Version": "9.0.8" + "Version": "9.0.10" } }, "DevelopmentDependency": false @@ -175,7 +176,7 @@ "Type": "nuget", "Nuget": { "Name": "Microsoft.Windows.Compatibility", - "Version": "9.0.8" + "Version": "9.0.10" } }, "DevelopmentDependency": false @@ -185,7 +186,7 @@ "Type": "nuget", "Nuget": { "Name": "Newtonsoft.Json", - "Version": "13.0.3" + "Version": "13.0.4" } }, "DevelopmentDependency": false @@ -195,7 +196,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.android-arm.runtime.native.System.IO.Ports", - "Version": "9.0.8" + "Version": "9.0.10" } }, "DevelopmentDependency": false @@ -205,7 +206,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.android-arm64.runtime.native.System.IO.Ports", - "Version": "9.0.8" + "Version": "9.0.10" } }, "DevelopmentDependency": false @@ -215,7 +216,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.android-x64.runtime.native.System.IO.Ports", - "Version": "9.0.8" + "Version": "9.0.10" } }, "DevelopmentDependency": false @@ -225,7 +226,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.android-x86.runtime.native.System.IO.Ports", - "Version": "9.0.8" + "Version": "9.0.10" } }, "DevelopmentDependency": false @@ -235,7 +236,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.linux-arm.runtime.native.System.IO.Ports", - "Version": "9.0.8" + "Version": "9.0.10" } }, "DevelopmentDependency": false @@ -245,7 +246,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.linux-arm64.runtime.native.System.IO.Ports", - "Version": "9.0.8" + "Version": "9.0.10" } }, "DevelopmentDependency": false @@ -255,7 +256,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.linux-bionic-arm64.runtime.native.System.IO.Ports", - "Version": "9.0.8" + "Version": "9.0.10" } }, "DevelopmentDependency": false @@ -265,7 +266,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.linux-bionic-x64.runtime.native.System.IO.Ports", - "Version": "9.0.8" + "Version": "9.0.10" } }, "DevelopmentDependency": false @@ -275,7 +276,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.linux-musl-arm.runtime.native.System.IO.Ports", - "Version": "9.0.8" + "Version": "9.0.10" } }, "DevelopmentDependency": false @@ -285,7 +286,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.linux-musl-arm64.runtime.native.System.IO.Ports", - "Version": "9.0.8" + "Version": "9.0.10" } }, "DevelopmentDependency": false @@ -295,7 +296,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.linux-musl-x64.runtime.native.System.IO.Ports", - "Version": "9.0.8" + "Version": "9.0.10" } }, "DevelopmentDependency": false @@ -305,7 +306,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.linux-x64.runtime.native.System.IO.Ports", - "Version": "9.0.8" + "Version": "9.0.10" } }, "DevelopmentDependency": false @@ -315,7 +316,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.maccatalyst-arm64.runtime.native.System.IO.Ports", - "Version": "9.0.8" + "Version": "9.0.10" } }, "DevelopmentDependency": false @@ -325,7 +326,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.maccatalyst-x64.runtime.native.System.IO.Ports", - "Version": "9.0.8" + "Version": "9.0.10" } }, "DevelopmentDependency": false @@ -345,7 +346,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.native.System.IO.Ports", - "Version": "9.0.8" + "Version": "9.0.10" } }, "DevelopmentDependency": false @@ -355,7 +356,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.osx-arm64.runtime.native.System.IO.Ports", - "Version": "9.0.8" + "Version": "9.0.10" } }, "DevelopmentDependency": false @@ -365,7 +366,7 @@ "Type": "nuget", "Nuget": { "Name": "runtime.osx-x64.runtime.native.System.IO.Ports", - "Version": "9.0.8" + "Version": "9.0.10" } }, "DevelopmentDependency": false @@ -425,7 +426,7 @@ "Type": "nuget", "Nuget": { "Name": "System.CodeDom", - "Version": "9.0.8" + "Version": "9.0.10" } }, "DevelopmentDependency": false @@ -445,7 +446,7 @@ "Type": "nuget", "Nuget": { "Name": "System.ComponentModel.Composition.Registration", - "Version": "9.0.8" + "Version": "9.0.10" } }, "DevelopmentDependency": false @@ -455,7 +456,7 @@ "Type": "nuget", "Nuget": { "Name": "System.ComponentModel.Composition", - "Version": "9.0.8" + "Version": "9.0.10" } }, "DevelopmentDependency": false @@ -465,7 +466,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Configuration.ConfigurationManager", - "Version": "9.0.8" + "Version": "9.0.10" } }, "DevelopmentDependency": false @@ -475,7 +476,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Data.Odbc", - "Version": "9.0.8" + "Version": "9.0.10" } }, "DevelopmentDependency": false @@ -485,7 +486,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Data.OleDb", - "Version": "9.0.8" + "Version": "9.0.10" } }, "DevelopmentDependency": false @@ -505,7 +506,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Diagnostics.DiagnosticSource", - "Version": "9.0.8" + "Version": "9.0.10" } }, "DevelopmentDependency": false @@ -515,7 +516,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Diagnostics.EventLog", - "Version": "9.0.8" + "Version": "9.0.10" } }, "DevelopmentDependency": false @@ -525,7 +526,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Diagnostics.PerformanceCounter", - "Version": "9.0.8" + "Version": "9.0.10" } }, "DevelopmentDependency": false @@ -535,7 +536,7 @@ "Type": "nuget", "Nuget": { "Name": "System.DirectoryServices.AccountManagement", - "Version": "9.0.8" + "Version": "9.0.10" } }, "DevelopmentDependency": false @@ -545,7 +546,7 @@ "Type": "nuget", "Nuget": { "Name": "System.DirectoryServices.Protocols", - "Version": "9.0.8" + "Version": "9.0.10" } }, "DevelopmentDependency": false @@ -555,7 +556,7 @@ "Type": "nuget", "Nuget": { "Name": "System.DirectoryServices", - "Version": "9.0.8" + "Version": "9.0.10" } }, "DevelopmentDependency": false @@ -565,7 +566,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Drawing.Common", - "Version": "9.0.8" + "Version": "9.0.10" } }, "DevelopmentDependency": false @@ -575,7 +576,7 @@ "Type": "nuget", "Nuget": { "Name": "System.IO.Packaging", - "Version": "9.0.8" + "Version": "9.0.10" } }, "DevelopmentDependency": false @@ -585,7 +586,7 @@ "Type": "nuget", "Nuget": { "Name": "System.IO.Ports", - "Version": "9.0.8" + "Version": "9.0.10" } }, "DevelopmentDependency": false @@ -595,7 +596,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Management", - "Version": "9.0.8" + "Version": "9.0.10" } }, "DevelopmentDependency": false @@ -605,7 +606,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Net.Http.WinHttpHandler", - "Version": "9.0.8" + "Version": "9.0.10" } }, "DevelopmentDependency": false @@ -635,7 +636,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Reflection.Context", - "Version": "9.0.8" + "Version": "9.0.10" } }, "DevelopmentDependency": false @@ -665,7 +666,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Runtime.Caching", - "Version": "9.0.8" + "Version": "9.0.10" } }, "DevelopmentDependency": false @@ -685,7 +686,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Security.Cryptography.Pkcs", - "Version": "9.0.8" + "Version": "9.0.10" } }, "DevelopmentDependency": false @@ -695,7 +696,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Security.Cryptography.ProtectedData", - "Version": "9.0.8" + "Version": "9.0.10" } }, "DevelopmentDependency": false @@ -705,7 +706,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Security.Cryptography.Xml", - "Version": "9.0.8" + "Version": "9.0.10" } }, "DevelopmentDependency": false @@ -715,7 +716,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Security.Permissions", - "Version": "9.0.8" + "Version": "9.0.10" } }, "DevelopmentDependency": false @@ -785,7 +786,7 @@ "Type": "nuget", "Nuget": { "Name": "System.ServiceModel.Syndication", - "Version": "9.0.8" + "Version": "9.0.10" } }, "DevelopmentDependency": false @@ -795,7 +796,7 @@ "Type": "nuget", "Nuget": { "Name": "System.ServiceProcess.ServiceController", - "Version": "9.0.8" + "Version": "9.0.10" } }, "DevelopmentDependency": false @@ -805,7 +806,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Speech", - "Version": "9.0.8" + "Version": "9.0.10" } }, "DevelopmentDependency": false @@ -815,7 +816,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Text.Encoding.CodePages", - "Version": "9.0.8" + "Version": "9.0.10" } }, "DevelopmentDependency": false @@ -825,7 +826,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Text.Encodings.Web", - "Version": "9.0.8" + "Version": "9.0.10" } }, "DevelopmentDependency": false @@ -835,7 +836,7 @@ "Type": "nuget", "Nuget": { "Name": "System.Threading.AccessControl", - "Version": "9.0.8" + "Version": "9.0.10" } }, "DevelopmentDependency": false @@ -855,11 +856,10 @@ "Type": "nuget", "Nuget": { "Name": "System.Windows.Extensions", - "Version": "9.0.8" + "Version": "9.0.10" } }, "DevelopmentDependency": false } - ], - "$schema": "https://json.schemastore.org/component-detection-manifest.json" + ] } From 83c94d32ca99606817ccac00e727a8d9e518506f Mon Sep 17 00:00:00 2001 From: PowerShell Team Bot <69177312+pwshBot@users.noreply.github.com> Date: Thu, 16 Oct 2025 13:37:00 -0700 Subject: [PATCH 168/173] [release/v7.5] Update vPack name (#26221) --- .pipelines/PowerShell-vPack-Official.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.pipelines/PowerShell-vPack-Official.yml b/.pipelines/PowerShell-vPack-Official.yml index f110ff0366a..3b151127cb1 100644 --- a/.pipelines/PowerShell-vPack-Official.yml +++ b/.pipelines/PowerShell-vPack-Official.yml @@ -11,8 +11,9 @@ parameters: # parameters are shown up in ADO UI in a build queue time - name: vPackName type: string displayName: 'VPack Name:' - default: 'PowerShell' + default: 'PowerShell.BuildTool' values: + - PowerShell.BuildTool - PowerShell - PowerShellDoNotUse - name: 'ReleaseTagVar' From ce09a42fc8f7a3ff1bc35cd86a437f79bbfb8433 Mon Sep 17 00:00:00 2001 From: Travis Plunk Date: Wed, 5 Nov 2025 10:53:59 -0800 Subject: [PATCH 169/173] [release/v7.5] Github Workflow cleanup (#26389) --- .github/workflows/AssignPrs.yml | 30 -------------- .github/workflows/createReminders.yml | 21 ---------- .github/workflows/markdownLink.yml | 52 ------------------------- .github/workflows/markdownLinkDaily.yml | 33 ---------------- .github/workflows/processReminders.yml | 21 ---------- tools/download.sh | 4 +- tools/install-powershell.sh | 6 ++- 7 files changed, 7 insertions(+), 160 deletions(-) delete mode 100644 .github/workflows/AssignPrs.yml delete mode 100644 .github/workflows/createReminders.yml delete mode 100644 .github/workflows/markdownLink.yml delete mode 100644 .github/workflows/markdownLinkDaily.yml delete mode 100644 .github/workflows/processReminders.yml diff --git a/.github/workflows/AssignPrs.yml b/.github/workflows/AssignPrs.yml deleted file mode 100644 index a01c0bb0950..00000000000 --- a/.github/workflows/AssignPrs.yml +++ /dev/null @@ -1,30 +0,0 @@ -name: Auto Assign PR Maintainer -on: - issues: - types: [opened, edited] -permissions: - contents: read - -jobs: - run: - if: github.repository_owner == 'PowerShell' - runs-on: ubuntu-latest - permissions: - issues: write - pull-requests: write - steps: - - uses: wow-actions/auto-assign@67fafa03df61d7e5f201734a2fa60d1ab111880d # v3.0.2 - if: github.event.issue.pull_request - with: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - # using the `org/team_slug` or `/team_slug` syntax to add git team as reviewers - assignees: | - TravisEz13 - daxian-dbw - adityapatwardhan - iSazonov - SeeminglyScience - skipDraft: true - skipKeywords: wip, draft - addReviewers: false - numberOfAssignees: 1 diff --git a/.github/workflows/createReminders.yml b/.github/workflows/createReminders.yml deleted file mode 100644 index 0333b635d59..00000000000 --- a/.github/workflows/createReminders.yml +++ /dev/null @@ -1,21 +0,0 @@ -name: 'Create reminder' - -on: - issue_comment: - types: [created, edited] - -permissions: - contents: read - -jobs: - reminder: - if: github.repository_owner == 'PowerShell' - - permissions: - issues: write # for agrc/create-reminder-action to set reminders on issues - pull-requests: write # for agrc/create-reminder-action to set reminders on PRs - runs-on: ubuntu-latest - - steps: - - name: check for reminder - uses: agrc/create-reminder-action@ffa4363460fe5fff73b2b58e66fa7eb01f7465a0 # v1.1.15 diff --git a/.github/workflows/markdownLink.yml b/.github/workflows/markdownLink.yml deleted file mode 100644 index 85b9f51a742..00000000000 --- a/.github/workflows/markdownLink.yml +++ /dev/null @@ -1,52 +0,0 @@ -on: - pull_request: - branches: - - master - - 'release/**' - -name: Check modified markdown files -permissions: - contents: read - -jobs: - markdown-link-check: - runs-on: ubuntu-latest - if: github.repository_owner == 'PowerShell' - - steps: - - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 - - uses: gaurav-nelson/github-action-markdown-link-check@5c5dfc0ac2e225883c0e5f03a85311ec2830d368 # v1 - with: - use-quiet-mode: 'yes' - use-verbose-mode: 'yes' - check-modified-files-only: 'yes' - config-file: .github/workflows/markdown-link/config.json - markdown-lint: - permissions: - contents: read - packages: read - statuses: write - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 - with: - # Full git history is needed to get a proper - # list of changed files within `super-linter` - fetch-depth: 0 - - name: Load super-linter configuration - # Use grep inverse matching to exclude eventual comments in the .env file - # because the GitHub Actions command to set environment variables doesn't - # support comments. - # Ref: https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/workflow-commands-for-github-actions#setting-an-environment-variable - run: grep -v '^#' tools/super-linter/config/super-linter.env >> "$GITHUB_ENV" - - name: Lint Markdown - uses: super-linter/super-linter@b4515bd4ad9d0aa4681960e053916ab991bdbe96 # v6.8.0 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - name: Super-Linter correction instructions - if: failure() - uses: actions/github-script@v7.0.1 - with: - script: | - const message = "Super-Linter found issues in the changed files. Please check the logs for details. You can run the linter locally using the command: `./tools/super-lister/super-lister.ps1`."; - core.setFailed(message); diff --git a/.github/workflows/markdownLinkDaily.yml b/.github/workflows/markdownLinkDaily.yml deleted file mode 100644 index 7434bfd852b..00000000000 --- a/.github/workflows/markdownLinkDaily.yml +++ /dev/null @@ -1,33 +0,0 @@ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT license. - -name: PowerShell Daily Markdown Link Verification - -on: - workflow_dispatch: - schedule: - # At 13:00 UTC every day. - - cron: '0 13 * * *' - -permissions: - contents: read - -jobs: - markdown-link-check: - runs-on: ubuntu-latest - if: github.repository == 'PowerShell/PowerShell' - steps: - - name: Checkout - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 - - name: Check Links - uses: gaurav-nelson/github-action-markdown-link-check@5c5dfc0ac2e225883c0e5f03a85311ec2830d368 # v1 - with: - use-quiet-mode: 'yes' - use-verbose-mode: 'yes' - config-file: .github/workflows/markdown-link/config.json - - name: Microsoft Teams Notifier - uses: skitionek/notify-microsoft-teams@77cc88b484449e2318245a54c115c5dca0eae4ef # master - if: failure() - with: - webhook_url: ${{ secrets.PS_BUILD_TEAMS_CHANNEL }} - overwrite: "{title: `Failure in .github/markdownLinkDaily.yml validating links. Look at ${workflow_link}`}" diff --git a/.github/workflows/processReminders.yml b/.github/workflows/processReminders.yml deleted file mode 100644 index a2d5b4dbd93..00000000000 --- a/.github/workflows/processReminders.yml +++ /dev/null @@ -1,21 +0,0 @@ -name: 'Process reminders' - -on: - schedule: - - cron: '*/15 * * * *' - workflow_dispatch: - -permissions: - contents: read - -jobs: - reminder: - if: github.repository_owner == 'PowerShell' - permissions: - issues: write # for agrc/reminder-action to set reminders on issues - pull-requests: write # for agrc/reminder-action to set reminders on PRs - runs-on: ubuntu-latest - - steps: - - name: check reminders and notify - uses: agrc/reminder-action@b5cc06580b6a711baddf6a947131f85a422fa263 # v1.0.14 diff --git a/tools/download.sh b/tools/download.sh index 6a6c6436b4b..f1e8c42cdc3 100644 --- a/tools/download.sh +++ b/tools/download.sh @@ -1 +1,3 @@ -bash <(curl -s https://raw.githubusercontent.com/PowerShell/PowerShell/master/tools/install-powershell.sh) +# Pin to specific commit for security (OpenSSF Scorecard requirement) +# Pinned commit: 26bb188c8 - "Improve ValidateLength error message consistency and refactor validation tests" (2025-10-12) +bash <(curl -s https://raw.githubusercontent.com/PowerShell/PowerShell/26bb188c8be0cda6cb548ce1a12840ebf67e1331/tools/install-powershell.sh) diff --git a/tools/install-powershell.sh b/tools/install-powershell.sh index 128f5664483..91425c183a8 100755 --- a/tools/install-powershell.sh +++ b/tools/install-powershell.sh @@ -26,7 +26,9 @@ install(){ #gitrepo paths are overrideable to run from your own fork or branch for testing or private distribution local VERSION="1.2.0" - local gitreposubpath="PowerShell/PowerShell/master" + # Pin to specific commit for security (OpenSSF Scorecard requirement) + # Pinned commit: 26bb188c8 - "Improve ValidateLength error message consistency and refactor validation tests" (2025-10-12) + local gitreposubpath="PowerShell/PowerShell/26bb188c8be0cda6cb548ce1a12840ebf67e1331" local gitreposcriptroot="https://raw.githubusercontent.com/$gitreposubpath/tools" local gitscriptname="install-powershell.psh" @@ -125,7 +127,7 @@ install(){ if [[ $osname = *SUSE* ]]; then DistroBasedOn='suse' REV=$(source /etc/os-release; echo $VERSION_ID) - fi + fi OS=$(lowercase $OS) DistroBasedOn=$(lowercase $DistroBasedOn) fi From 053db9864eec7c1b99fe3892f12c3c1594b87cc0 Mon Sep 17 00:00:00 2001 From: Travis Plunk Date: Wed, 5 Nov 2025 11:36:21 -0800 Subject: [PATCH 170/173] [release/v7.5] Integrate Windows packaging into windows-ci workflow using reusable workflow (#26390) Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com> Co-authored-by: TravisEz13 <10873629+TravisEz13@users.noreply.github.com> --- .../infrastructure/path-filters/action.yml | 17 ++++ .github/workflows/windows-ci.yml | 10 +++ .../workflows/windows-packaging-reusable.yml | 88 +++++++++++++++++++ 3 files changed, 115 insertions(+) create mode 100644 .github/workflows/windows-packaging-reusable.yml diff --git a/.github/actions/infrastructure/path-filters/action.yml b/.github/actions/infrastructure/path-filters/action.yml index 78426bdff03..fd48e8091d6 100644 --- a/.github/actions/infrastructure/path-filters/action.yml +++ b/.github/actions/infrastructure/path-filters/action.yml @@ -26,6 +26,9 @@ outputs: buildModuleChanged: description: 'Build module changes' value: ${{ steps.filter.outputs.buildModuleChanged }} + packagingChanged: + description: 'Packaging related changes' + value: ${{ steps.filter.outputs.packagingChanged }} runs: using: composite steps: @@ -83,6 +86,18 @@ runs: const buildModuleChanged = files.some(file => file.filename.startsWith('build.psm1')); + const packagingChanged = files.some(file => + file.filename === '.github/workflows/windows-ci.yml' || + file.filename.startsWith('assets/wix/') || + file.filename === 'PowerShell.Common.props' || + file.filename.match(/^src\/.*\.csproj$/) || + file.filename.startsWith('test/packaging/windows/') || + file.filename.startsWith('tools/packaging/') || + file.filename.startsWith('tools/wix/') + ) || + buildModuleChanged || + toolsCiPsm1Changed; + const source = mainSourceChanged || toolsChanged || githubChanged || propsChanged || testsChanged; core.setOutput('toolsChanged', toolsChanged); @@ -91,6 +106,7 @@ runs: core.setOutput('testsChanged', testsChanged); core.setOutput('mainSourceChanged', mainSourceChanged); core.setOutput('buildModuleChanged', buildModuleChanged); + core.setOutput('packagingChanged', packagingChanged); core.setOutput('source', source); - name: Capture outputs @@ -102,4 +118,5 @@ runs: Write-Verbose -Verbose "tests: ${{ steps.filter.outputs.testsChanged }}" Write-Verbose -Verbose "mainSource: ${{ steps.filter.outputs.mainSourceChanged }}" Write-Verbose -Verbose "buildModule: ${{ steps.filter.outputs.buildModuleChanged }}" + Write-Verbose -Verbose "packaging: ${{ steps.filter.outputs.packagingChanged }}" shell: pwsh diff --git a/.github/workflows/windows-ci.yml b/.github/workflows/windows-ci.yml index 2e392987cb0..e960c0c255f 100644 --- a/.github/workflows/windows-ci.yml +++ b/.github/workflows/windows-ci.yml @@ -39,6 +39,8 @@ env: POWERSHELL_TELEMETRY_OPTOUT: 1 __SuppressAnsiEscapeSequences: 1 nugetMultiFeedWarnLevel: none + SYSTEM_ARTIFACTSDIRECTORY: ${{ github.workspace }}/artifacts + BUILD_ARTIFACTSTAGINGDIRECTORY: ${{ github.workspace }}/artifacts jobs: changes: name: Change Detection @@ -52,6 +54,7 @@ jobs: # Set job outputs to values from filter step outputs: source: ${{ steps.filter.outputs.source }} + packagingChanged: ${{ steps.filter.outputs.packagingChanged }} steps: - name: checkout uses: actions/checkout@v4.1.0 @@ -156,6 +159,12 @@ jobs: fetch-depth: 1000 - name: Verify xUnit test results uses: "./.github/actions/test/verify_xunit" + windows_packaging: + name: Windows Packaging + needs: + - changes + if: ${{ needs.changes.outputs.packagingChanged == 'true' }} + uses: ./.github/workflows/windows-packaging-reusable.yml ready_to_merge: name: windows ready to merge needs: @@ -164,6 +173,7 @@ jobs: - windows_test_elevated_others - windows_test_unelevated_ci - windows_test_unelevated_others + - windows_packaging if: always() uses: PowerShell/compliance/.github/workflows/ready-to-merge.yml@v1.0.0 with: diff --git a/.github/workflows/windows-packaging-reusable.yml b/.github/workflows/windows-packaging-reusable.yml new file mode 100644 index 00000000000..5a763544c62 --- /dev/null +++ b/.github/workflows/windows-packaging-reusable.yml @@ -0,0 +1,88 @@ +name: Windows Packaging (Reusable) + +on: + workflow_call: + +env: + GIT_CONFIG_PARAMETERS: "'core.autocrlf=false'" + DOTNET_CLI_TELEMETRY_OPTOUT: 1 + POWERSHELL_TELEMETRY_OPTOUT: 1 + DOTNET_NOLOGO: 1 + __SuppressAnsiEscapeSequences: 1 + nugetMultiFeedWarnLevel: none + SYSTEM_ARTIFACTSDIRECTORY: ${{ github.workspace }}/artifacts + BUILD_ARTIFACTSTAGINGDIRECTORY: ${{ github.workspace }}/artifacts + +jobs: + package: + name: ${{ matrix.architecture }} - ${{ matrix.channel }} + runs-on: windows-latest + strategy: + fail-fast: false + matrix: + include: + - architecture: x64 + channel: preview + runtimePrefix: win7 + - architecture: x86 + channel: stable + runtimePrefix: win7 + - architecture: x86 + channel: preview + runtimePrefix: win7 + - architecture: arm64 + channel: preview + runtimePrefix: win + + steps: + - name: Checkout + uses: actions/checkout@v5 + with: + fetch-depth: 1000 + + - name: Capture Environment + if: success() || failure() + run: | + Get-ChildItem -Path env: | Out-String -width 9999 -Stream | write-Verbose -Verbose + shell: pwsh + + - name: Capture PowerShell Version Table + if: success() || failure() + run: | + $PSVersionTable + shell: pwsh + + - name: Switch to Public Feeds + if: success() + run: | + Import-Module .\tools\ci.psm1 + Switch-PSNugetConfig -Source Public + shell: pwsh + + - name: Setup .NET + uses: actions/setup-dotnet@v4 + with: + global-json-file: ./global.json + + - name: Bootstrap + if: success() + run: | + Import-Module .\tools\ci.psm1 + Invoke-CIInstall -SkipUser + shell: pwsh + + - name: Build and Package + run: | + Import-Module .\tools\ci.psm1 + New-CodeCoverageAndTestPackage + Invoke-CIFinish -Runtime ${{ matrix.runtimePrefix }}-${{ matrix.architecture }} -channel ${{ matrix.channel }} + shell: pwsh + + - name: Upload Build Artifacts + if: always() + uses: actions/upload-artifact@v4 + with: + name: windows-packaging-${{ matrix.architecture }}-${{ matrix.channel }} + path: | + ${{ github.workspace }}/artifacts/**/* + !${{ github.workspace }}/artifacts/**/*.pdb From dcf85e02004377c11d1a867826d96f03f4c1eb87 Mon Sep 17 00:00:00 2001 From: Travis Plunk Date: Wed, 5 Nov 2025 11:40:42 -0800 Subject: [PATCH 171/173] [release/v7.5] Convert Azure DevOps Linux Packaging pipeline to GitHub Actions workflow (#26391) Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com> Co-authored-by: TravisEz13 <10873629+TravisEz13@users.noreply.github.com> --- .../actions/test/linux-packaging/action.yml | 112 +++++++++--------- .github/workflows/linux-ci.yml | 32 +++-- build.psm1 | 2 +- 3 files changed, 73 insertions(+), 73 deletions(-) diff --git a/.github/actions/test/linux-packaging/action.yml b/.github/actions/test/linux-packaging/action.yml index b4a9c3b55c0..736bddfa7a7 100644 --- a/.github/actions/test/linux-packaging/action.yml +++ b/.github/actions/test/linux-packaging/action.yml @@ -1,12 +1,5 @@ name: linux_packaging -description: 'Test very basic Linux packaging' - -# This isn't working yet -# It fails with - -# ERROR: While executing gem ... (Gem::FilePermissionError) -# You don't have write permissions for the /var/lib/gems/2.7.0 directory. -# WARNING: Installation of gem dotenv 2.8.1 failed! Must resolve manually. +description: 'Linux packaging for PowerShell' runs: using: composite @@ -15,58 +8,64 @@ runs: if: success() || failure() run: 'Get-ChildItem -Path env: | Out-String -width 9999 -Stream | write-Verbose -Verbose' shell: pwsh + + - uses: actions/setup-dotnet@v5 + with: + global-json-file: ./global.json + - name: Download Build Artifacts uses: actions/download-artifact@v4 with: - path: "${{ github.workspace }}" + name: build + path: "${{ runner.workspace }}/build" + - name: Capture Artifacts Directory continue-on-error: true - run: Get-ChildItem "${{ github.workspace }}/build/*" -Recurse + run: Get-ChildItem "${{ runner.workspace }}/build/*" -Recurse shell: pwsh - name: Bootstrap run: |- Import-Module ./build.psm1 Start-PSBootstrap -Scenario Package + Write-Verbose -Verbose "Start Sync-PSTags" + Sync-PSTags -AddRemoteIfMissing + Write-Verbose -Verbose "End Sync-PSTags" shell: pwsh - - name: Capture Artifacts Directory - continue-on-error: true - run: Import-Module ./build.psm1 + + - name: Extract Build ZIP + run: |- + $destinationFolder = "${{ runner.workspace }}/bins" + $archiveFile = "${{ runner.workspace }}/build/build.zip" + + Write-Verbose "Extracting $archiveFile to $destinationFolder" -Verbose + New-Item -ItemType Directory -Path $destinationFolder -Force | Out-Null + Expand-Archive -Path $archiveFile -DestinationPath $destinationFolder -Force shell: pwsh - - name: Extract Files - uses: actions/github-script@v7.0.0 - env: - DESTINATION_FOLDER: "${{ github.workspace }}/bins" - ARCHIVE_FILE_PATTERNS: "${{ github.workspace }}/build/build.zip" - with: - script: |- - const fs = require('fs').promises - const path = require('path') - const target = path.resolve(process.env.DESTINATION_FOLDER) - const patterns = process.env.ARCHIVE_FILE_PATTERNS - const globber = await glob.create(patterns) - await io.mkdirP(path.dirname(target)) - for await (const file of globber.globGenerator()) { - if ((await fs.lstat(file)).isDirectory()) continue - await exec.exec(`7z x ${file} -o${target} -aoa`) - } + - name: Fix permissions continue-on-error: true run: |- - find "${{ github.workspace }}/bins" -type d -exec chmod +rwx {} \; - find "${{ github.workspace }}/bins" -type f -exec chmod +rw {} \; + find "${{ runner.workspace }}/bins" -type d -exec chmod +rwx {} \; + find "${{ runner.workspace }}/bins" -type f -exec chmod +rw {} \; shell: bash + - name: Capture Extracted Build ZIP continue-on-error: true - run: Get-ChildItem "${{ github.workspace }}/bins/*" -Recurse -ErrorAction SilentlyContinue + run: Get-ChildItem "${{ runner.workspace }}/bins/*" -Recurse -ErrorAction SilentlyContinue shell: pwsh - - name: Packaging Tests - if: success() + + - name: Create Packages + env: + BUILD_ARTIFACTSTAGINGDIRECTORY: ${{ runner.workspace }}/packages run: |- + # Create the artifacts staging directory + New-Item -ItemType Directory -Path "$env:BUILD_ARTIFACTSTAGINGDIRECTORY" -Force | Out-Null + Import-Module ./tools/ci.psm1 - Restore-PSOptions -PSOptionsPath '${{ github.workspace }}/build/psoptions.json' + Restore-PSOptions -PSOptionsPath '${{ runner.workspace }}/build/psoptions.json' $options = (Get-PSOptions) - $rootPath = '${{ github.workspace }}/bins' + $rootPath = '${{ runner.workspace }}/bins' $originalRootPath = Split-Path -path $options.Output $path = Join-Path -path $rootPath -ChildPath (split-path -leaf -path $originalRootPath) $pwshPath = Join-Path -path $path -ChildPath 'pwsh' @@ -75,21 +74,24 @@ runs: Set-PSOptions $options Invoke-CIFinish shell: pwsh - - name: Upload packages - run: |- - Get-ChildItem "${env:BUILD_ARTIFACTSTAGINGDIRECTORY}/*.deb" -Recurse | ForEach-Object { - $packagePath = $_.FullName - Write-Host "Uploading $packagePath" - Write-Host "##vso[artifact.upload containerfolder=deb;artifactname=deb]$packagePath" - } - Get-ChildItem "${env:BUILD_ARTIFACTSTAGINGDIRECTORY}/*.rpm" -Recurse | ForEach-Object { - $packagePath = $_.FullName - Write-Host "Uploading $packagePath" - Write-Host "##vso[artifact.upload containerfolder=rpm;artifactname=rpm]$packagePath" - } - Get-ChildItem "${env:BUILD_ARTIFACTSTAGINGDIRECTORY}/*.tar.gz" -Recurse | ForEach-Object { - $packagePath = $_.FullName - Write-Host "Uploading $packagePath" - Write-Host "##vso[artifact.upload containerfolder=rpm;artifactname=rpm]$packagePath" - } - shell: pwsh + + - name: Upload deb packages + uses: actions/upload-artifact@v4 + with: + name: packages-deb + path: ${{ runner.workspace }}/packages/*.deb + if-no-files-found: ignore + + - name: Upload rpm packages + uses: actions/upload-artifact@v4 + with: + name: packages-rpm + path: ${{ runner.workspace }}/packages/*.rpm + if-no-files-found: ignore + + - name: Upload tar.gz packages + uses: actions/upload-artifact@v4 + with: + name: packages-tar + path: ${{ runner.workspace }}/packages/*.tar.gz + if-no-files-found: ignore diff --git a/.github/workflows/linux-ci.yml b/.github/workflows/linux-ci.yml index 2bf61ca3e48..6cf1e4c67b3 100644 --- a/.github/workflows/linux-ci.yml +++ b/.github/workflows/linux-ci.yml @@ -227,24 +227,22 @@ jobs: - linux_test_unelevated_ci - linux_test_unelevated_others - analyze + - linux_packaging if: always() uses: PowerShell/compliance/.github/workflows/ready-to-merge.yml@v1.0.0 with: needs_context: ${{ toJson(needs) }} - # TODO: Enable this when we have a Linux packaging workflow - - # ERROR: While executing gem ... (Gem::FilePermissionError) - # You don't have write permissions for the /var/lib/gems/2.7.0 directory. - # WARNING: Installation of gem dotenv 2.8.1 failed! Must resolve manually. - - # linux_packaging: - # name: Attempt Linux Packaging - # needs: ci_build - # runs-on: ubuntu-20.04 - # steps: - # - name: checkout - # uses: actions/checkout@v4.1.0 - # with: - # fetch-depth: 1000 - # - name: Verify xUnit test results - # uses: "./.github/actions/test/linux-packaging" + linux_packaging: + name: Linux Packaging + needs: + - ci_build + - changes + if: ${{ needs.changes.outputs.source == 'true' }} + runs-on: ubuntu-latest + steps: + - name: checkout + uses: actions/checkout@v5 + with: + fetch-depth: 0 + - name: Linux Packaging + uses: "./.github/actions/test/linux-packaging" diff --git a/build.psm1 b/build.psm1 index aa49b6061c3..45705e53fa6 100644 --- a/build.psm1 +++ b/build.psm1 @@ -2241,7 +2241,7 @@ function Install-GlobalGem { # We cannot guess if the user wants to run gem install as root on linux and windows, # but macOs usually requires sudo $gemsudo = '' - if($environment.IsMacOS -or $env:TF_BUILD) { + if($environment.IsMacOS -or $env:TF_BUILD -or $env:GITHUB_ACTIONS) { $gemsudo = $sudo } From 9e56e70e67fa9c463131af7500c1798359cc97a7 Mon Sep 17 00:00:00 2001 From: Travis Plunk Date: Wed, 5 Nov 2025 13:21:22 -0800 Subject: [PATCH 172/173] [release/v7.5] Add network isolation policy parameter to vPack pipeline (#26393) Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .pipelines/PowerShell-vPack-Official.yml | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/.pipelines/PowerShell-vPack-Official.yml b/.pipelines/PowerShell-vPack-Official.yml index 3b151127cb1..7ba92f4eda9 100644 --- a/.pipelines/PowerShell-vPack-Official.yml +++ b/.pipelines/PowerShell-vPack-Official.yml @@ -24,6 +24,14 @@ parameters: # parameters are shown up in ADO UI in a build queue time displayName: 'Enable debug output' type: boolean default: false +- name: netiso + displayName: "Network Isolation Policy" + type: string + values: + - KS4 + - R1 + - Netlock + default: "R1" name: vPack_$(Build.SourceBranchName)_Prod.${{ parameters.OfficialBuild }}_Create.${{ parameters.createVPack }}_Name.${{ parameters.vPackName}}_$(date:yyyyMMdd).$(rev:rr) @@ -54,6 +62,8 @@ variables: value: ${{ iif ( parameters.OfficialBuild, 'v2/Microsoft.Official.yml@onebranchTemplates', 'v2/Microsoft.NonOfficial.yml@onebranchTemplates' ) }} - group: DotNetPrivateBuildAccess - group: certificate_logical_to_actual + - name: netiso + value: ${{ parameters.netiso }} # We shouldn't be using PATs anymore # - group: mscodehub-feed-read-general @@ -70,6 +80,11 @@ extends: platform: name: 'windows_undocked' # windows undocked + featureFlags: + WindowsHostVersion: + Version: 2022 + Network: ${{ variables.netiso }} + cloudvault: enabled: false From 20b207d4c0211094da814c779dee346993cd288f Mon Sep 17 00:00:00 2001 From: Dongbo Wang Date: Mon, 12 Jan 2026 10:48:25 -0800 Subject: [PATCH 173/173] Update a few packages to use the right version corresponding to .NET 9 (#26671) --- .../Microsoft.PowerShell.Commands.Utility.csproj | 2 +- src/Microsoft.PowerShell.SDK/Microsoft.PowerShell.SDK.csproj | 4 ++-- .../PSVersionInfoGenerator/PSVersionInfoGenerator.csproj | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Microsoft.PowerShell.Commands.Utility/Microsoft.PowerShell.Commands.Utility.csproj b/src/Microsoft.PowerShell.Commands.Utility/Microsoft.PowerShell.Commands.Utility.csproj index 1bb01e109e2..3edc422be02 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/Microsoft.PowerShell.Commands.Utility.csproj +++ b/src/Microsoft.PowerShell.Commands.Utility/Microsoft.PowerShell.Commands.Utility.csproj @@ -14,7 +14,7 @@ all - + diff --git a/src/Microsoft.PowerShell.SDK/Microsoft.PowerShell.SDK.csproj b/src/Microsoft.PowerShell.SDK/Microsoft.PowerShell.SDK.csproj index bd6c95cedd0..8cb31a949bb 100644 --- a/src/Microsoft.PowerShell.SDK/Microsoft.PowerShell.SDK.csproj +++ b/src/Microsoft.PowerShell.SDK/Microsoft.PowerShell.SDK.csproj @@ -16,8 +16,8 @@ - - + + diff --git a/src/System.Management.Automation/SourceGenerators/PSVersionInfoGenerator/PSVersionInfoGenerator.csproj b/src/System.Management.Automation/SourceGenerators/PSVersionInfoGenerator/PSVersionInfoGenerator.csproj index 9de256a3ba1..7c2fd6a1a2c 100644 --- a/src/System.Management.Automation/SourceGenerators/PSVersionInfoGenerator/PSVersionInfoGenerator.csproj +++ b/src/System.Management.Automation/SourceGenerators/PSVersionInfoGenerator/PSVersionInfoGenerator.csproj @@ -17,7 +17,7 @@ - - + +