[{"data":1,"prerenderedAt":5670},["Reactive",2],{"navigation":3,"aAII9Cz3yR":204,"tags-package manager":397},[4,192,200],{"title":5,"_path":6,"children":7,"icon":191},"Blog","/posts",[8,11,14,17,20,23,26,29,32,35,38,41,44,47,50,53,56,59,62,65,68,71,74,77,80,83,86,89,92,95,98,101,104,107,110,113,116,119,122,125,128,131,134,137,140,143,146,149,152,155,158,161,164,167,170,173,176,179,182,185,188],{"title":9,"_path":10},"Testing your API with REST Client","/posts/testing-your-api-with-rest-client",{"title":12,"_path":13},"HTML templating in Xamarin","/posts/html-templating-in-xamarin",{"title":15,"_path":16},"Goodbye Azure Portal, Welcome Azure CLI","/posts/welcome-azure-cli",{"title":18,"_path":19},"Coming across Gitpod","/posts/gitpod",{"title":21,"_path":22},"Handle token retrieval while querying an API","/posts/delegating-handler",{"title":24,"_path":25},"Clean up your local git branches.","/posts/cleaning-git-branches",{"title":27,"_path":28},"Automate configuration of Teams Tab SSO with PowerShell.","/posts/teams-sso-powershell",{"title":30,"_path":31},"How to do a technology watch? - Part 1","/posts/technology-watch-part1",{"title":33,"_path":34},"How to do a technology watch? - Part 2","/posts/technology-watch-part2",{"title":36,"_path":37},"You almost no longer need Key Vault references for Azure Functions.","/posts/azure-functions-custom-configuration",{"title":39,"_path":40},"How to do a technology watch? - Part 3","/posts/technology-watch-part3",{"title":42,"_path":43},"Forget DevOps, the future is already here!","/posts/devops-future",{"title":45,"_path":46},"Week 9, 2021 - Tips I learned this week","/posts/w09-2021-tips-learned-this-week",{"title":48,"_path":49},"Week 12, 2021 - Tips I learned this week","/posts/w12-2021-tips-learned-this-week",{"title":51,"_path":52},"Week 14, 2021 - Tips I learned this week","/posts/w14-2021-tips-learned-this-week",{"title":54,"_path":55},"Once upon a time in .NET","/posts/once-upon-a-time-in-dotnet",{"title":57,"_path":58},"Install your applications with winget","/posts/winget-import",{"title":60,"_path":61},"Customize your applications when installing them with winget","/posts/winget-override",{"title":63,"_path":64},"Week 22, 2021 - Tips I learned this week","/posts/w22-2021-tips-learned-this-week",{"title":66,"_path":67},"How to connect to an Azure SQL Database from C# using Azure AD","/posts/sqlclient-active-directory-authent",{"title":69,"_path":70},"Producing packages for Windows Package Manager","/posts/wingetcreate",{"title":72,"_path":73},"4 tips about GitHub Actions environment variables and contexts","/posts/github-actions-var-and-context",{"title":75,"_path":76},"AzureWebJobsStorage, the secret you don't need in your Function App.","/posts/azure-functions-without-azurewebjobsstorage",{"title":78,"_path":79},"ASP.NET Core - Lost in configuration","/posts/lost-in-configuration",{"title":81,"_path":82},"Week 39, 2021 - Tips I learned this week","/posts/w39-2021-tips-learned-this-week",{"title":84,"_path":85},"Week 41, 2021 - Tips I learned this week","/posts/w41-2021-tips-learned-this-week",{"title":87,"_path":88},"Migrating and open-sourcing my blog","/posts/migrating-blog",{"title":90,"_path":91},"Week 45, 2021 - Tips I learned this week","/posts/w45-2021-tips-learned-this-week",{"title":93,"_path":94},"Organize your GitHub stars with Astral","/posts/astral",{"title":96,"_path":97},"Pulumi with an Azure Blob Storage backend","/posts/pulumi-azure-backend",{"title":99,"_path":100},"IaC Hot Reload with Pulumi Watch","/posts/pulumi-watch",{"title":102,"_path":103},"Week 2, 2022 - Tips I learned this week","/posts/w02-2022-tips-learned-this-week",{"title":105,"_path":106},"Week 3, 2022 - Tips I learned this week","/posts/w03-2022-tips-learned-this-week",{"title":108,"_path":109},"Week 5, 2022 - Tips I learned this week","/posts/w05-2022-tips-learned-this-week",{"title":111,"_path":112},"How to provision an Azure SQL Database with Active Directory authentication","/posts/sqldatabase-active-directory-authent",{"title":114,"_path":115},"Why will I choose Pulumi over Terraform for my next project?","/posts/pulumi-vs-terraform",{"title":117,"_path":118},"Week 19, 2022 - Tips I learned this week","/posts/w19-2022-tips-learned-this-week",{"title":120,"_path":121},"Week 20, 2022 - Tips I learned this week","/posts/w20-2022-tips-learned-this-week",{"title":123,"_path":124},"Keeping secrets secure when using API Clients","/posts/http-clients-secrets",{"title":126,"_path":127},"What made me want to be a developer?","/posts/be-a-developer",{"title":129,"_path":130},"What can we do when stuck with a programming problem?","/posts/get-unstuck",{"title":132,"_path":133},"How did I automate the setup of my developer Windows laptop?","/posts/automate-developer-machine",{"title":135,"_path":136},"Discussion about API clients","/posts/http-clients",{"title":138,"_path":139},"Week 46, 2022 - Tips I learned this week","/posts/w46-2022-tips-learned-this-week",{"title":141,"_path":142},"When Pulumi met Nuke: a .NET love story","/posts/when-pulumi-met-nuke",{"title":144,"_path":145},"A year of learning and sharing - Dev Retro 2022","/posts/2022-retro",{"title":147,"_path":148},"Perform Dynamic Execution of an npm Package","/posts/pnpm-dlx",{"title":150,"_path":151},"Manage multiple Node.js versions","/posts/pnpm-env",{"title":153,"_path":154},"Introducing the Vue.js CI/CD series","/posts/vuecicd-introduction",{"title":156,"_path":157},"Execute commands using your project dependencies","/posts/pnpm-exec",{"title":159,"_path":160},"Vue.js CI/CD: Continuous Integration","/posts/vuecicd-ci",{"title":162,"_path":163},"Who is using pnpm?","/posts/pnpm-who-is-using",{"title":165,"_path":166},"Create an Azure-Ready GitHub Repository using Pulumi","/posts/azure-ready-github-repository",{"title":168,"_path":169},"Deploying to Azure from Azure DevOps without secrets","/posts/ado-workload-identity-federation",{"title":171,"_path":172},"Effortlessly Configure GitHub Repositories for Azure Deployment via OIDC","/posts/scripting-azure-ready-github-repository",{"title":174,"_path":175},"Playing with the .NET 8 Web API template","/posts/playing-with-dotnet8",{"title":177,"_path":178},"Another year of sharing and learning - Dev Retro 2023","/posts/2023-retro",{"title":180,"_path":181},"Week 4, 2024 - Tips I learned this week","/posts/w04-2024-tips-learned-this-week",{"title":183,"_path":184},"Using dependency injection with Azure .NET SDK","/posts/azure-sdk-di",{"title":186,"_path":187},"Having Fun With IT Event Calendars","/posts/it-event-calendars",{"title":189,"_path":190},"Call your Azure AD B2C protected API with authenticated HTTP requests from your JetBrains IDE","/posts/http-clients-oauth2","i-heroicons-newspaper",{"title":193,"_path":194,"children":195,"icon":199},"Goodies","/goodies",[196],{"title":197,"_path":198},"My Git Cheat Sheet","/goodies/gitcheatsheet","i-heroicons-gift-solid",{"title":201,"_path":202,"icon":203},"About","/about","i-heroicons-user-circle-solid",[205,207,209,211,214,217,220,223,226,229,231,234,237,240,242,244,247,250,253,255,258,261,264,267,270,273,276,279,282,285,287,289,292,294,297,300,303,305,308,310,313,316,319,322,325,327,329,332,335,338,341,344,347,350,353,356,359,361,363,366,369,372,375,377,380,383,385,388,391,394],[206,206],"tooling",[208,208],"vscode",[210,210],"rest",[212,213],"http","HTTP",[215,216],"razor","Razor",[218,219],"xamarin","Xamarin",[221,222],"templating","Templating",[224,225],"azure-cli","Azure CLI",[227,228],"azure","Azure",[230,230],"shell",[232,233],"github","GitHub",[235,236],"asp-net-core","ASP.NET Core",[238,239],"net",".NET",[241,241],"git",[243,243],"nushell",[245,246],"microsoft-teams","Microsoft Teams",[248,249],"powershell","PowerShell",[251,252],"azure-active-directory","Azure Active Directory",[254,254],"learning",[256,257],"azure-functions","Azure Functions",[259,260],"azure-key-vault","Azure Key Vault",[262,263],"configuration","Configuration",[265,266],"devops","DevOps",[268,269],"it","IT",[271,272],"tips-learned-this-week","tips learned this week",[274,275],"windows-terminal","Windows Terminal",[277,278],"azure-pipelines","Azure Pipelines",[280,281],"application-insights","Application Insights",[283,284],"azure-iot","Azure IoT",[286,286],"records",[288,288],"refit",[290,291],"development-box-setup","development box setup",[293,293],"winget",[295,296],"package-manager","package manager",[298,299],"azure-sql-database","Azure SQL Database",[301,302],"azure-sdk","Azure SDK",[304,304],"wingetcreate",[306,307],"github-actions","GitHub Actions",[309,309],"jq",[311,312],"pulumi","Pulumi",[314,315],"iac","IaC",[317,318],"azure-storage","Azure Storage",[320,321],"azure-signalr","Azure SignalR",[323,324],"visio","Visio",[326,326],"csharp",[328,328],"jest",[330,331],"statiq","Statiq",[333,334],"open-source","open source",[336,337],"visual-studio","Visual Studio",[339,340],"vue-js","Vue.js",[342,343],"azure-devops","Azure DevOps",[345,346],"vite","Vite",[348,349],"code-analysis","Code analysis",[351,352],"diagram","Diagram",[354,355],"terraform","Terraform",[357,358],"typescript","TypeScript",[360,360],"thoughts",[362,362],"pnpm",[364,365],"nuke","Nuke",[367,368],"pipelines","Pipelines",[370,371],"cicd","CI/CD",[373,374],"openid-connect","OpenID Connect",[376,376],"security",[378,379],"github-cli","GitHub CLI",[381,382],"microsoft-entra-id","Microsoft Entra ID",[384,384],"advent",[386,387],"finops","FinOps",[389,390],"anglesharp","AngleSharp",[392,393],"oauth2","OAuth2",[395,396],"azure-ad-b2c","Azure AD B2C",[398,633,823,1001,1196,1453,2995,4346,4574],{"_path":163,"_dir":399,"_draft":400,"_partial":400,"_locale":401,"title":162,"description":402,"lead":403,"date":404,"badge":405,"image":407,"tags":409,"canonical":410,"body":411,"_type":628,"_id":629,"_source":630,"_file":631,"_extension":632},"posts",false,"","You may have come across pnpm through discussions with fellow developers, reading blog posts, watching videos, or attending developer conferences. You have probably heard its praises: it's fast, disk-space efficient, and great for monorepos.","Discussion about pnpm usage and popularity.","2023-07-06T00:00:00.000Z",{"label":406},"Tooling",{"src":408},"/images/pnpm.png",[362,296,206],"https://bordeauxcoders.com/who-is-using-pnpm",{"type":412,"children":413,"toc":621},"root",[414,421,426,433,438,450,455,467,472,478,483,492,497,506,512,517,522,532,537,577,582,590,596,601,606,611,616],{"type":415,"tag":416,"props":417,"children":418},"element","p",{},[419],{"type":420,"value":402},"text",{"type":415,"tag":416,"props":422,"children":423},{},[424],{"type":420,"value":425},"However, you might wonder: who is actually using pnpm?",{"type":415,"tag":427,"props":428,"children":430},"h2",{"id":429},"a-growing-popularity",[431],{"type":420,"value":432},"A growing popularity",{"type":415,"tag":416,"props":434,"children":435},{},[436],{"type":420,"value":437},"At the time of writing, pnpm has over 24k stars on GitHub, and this number is rapidly increasing. The pnpm Twitter account maintains a thread that tracks the number of stars. Each time the GitHub repository gains 1k stars, a new tweet is posted. For quite some time now, it has been growing by 1K every two months.",{"type":415,"tag":439,"props":440,"children":444},"div",{"className":441},[442,443],"flex","justify-center",[445],{"type":415,"tag":446,"props":447,"children":449},"tweet",{"id":448},"1666004997840986116",[],{"type":415,"tag":416,"props":451,"children":452},{},[453],{"type":420,"value":454},"Another indicator of its growing popularity is its number of downloads. If you go to npm stats you can see how this number evolved compared to npm and yarn.",{"type":415,"tag":416,"props":456,"children":457},{},[458],{"type":415,"tag":459,"props":460,"children":466},"img",{"alt":461,"className":462,"src":465},"npm vs yarn vs pnpm downloads per day",[463,464],"rounded-lg","mx-auto","/posts/images/pnpm101_whouses_stats.webp",[],{"type":415,"tag":416,"props":468,"children":469},{},[470],{"type":420,"value":471},"I believe this diagram speaks for itself 🚀.",{"type":415,"tag":427,"props":473,"children":475},{"id":474},"which-companies-are-using-pnpm",[476],{"type":420,"value":477},"Which companies are using pnpm?",{"type":415,"tag":416,"props":479,"children":480},{},[481],{"type":420,"value":482},"There is a page on pnpm's documentation about well-known companies using pnpm.",{"type":415,"tag":416,"props":484,"children":485},{},[486],{"type":415,"tag":459,"props":487,"children":491},{"alt":488,"className":489,"src":490},"Screeshot of the documentation showing companies using pnpm",[463,464],"/posts/images/pnpm101_whouses_companies.webp",[],{"type":415,"tag":416,"props":493,"children":494},{},[495],{"type":420,"value":496},"You can also see some other companies on the StackShare website (but it seems not many companies took the time to fill in the fact that they were using pnpm in their stack).",{"type":415,"tag":416,"props":498,"children":499},{},[500],{"type":415,"tag":459,"props":501,"children":505},{"alt":502,"className":503,"src":504},"Screeshot of the StackShare page showing companies using pnpm",[463,464],"/posts/images/pnpm101_whouses_companies_2.webp",[],{"type":415,"tag":427,"props":507,"children":509},{"id":508},"which-popular-open-source-projects-are-using-pnpm",[510],{"type":420,"value":511},"Which popular open-source projects are using pnpm?",{"type":415,"tag":416,"props":513,"children":514},{},[515],{"type":420,"value":516},"If you see a pnpm-lock.yaml or a pnpm-workspace.yaml file in a GitHub repository, then that project is definitively using pnpm to manage its dependencies. You can use this technique to find GitHub projects using pnpm by querying them with GitHub code search.",{"type":415,"tag":416,"props":518,"children":519},{},[520],{"type":420,"value":521},"I thought it would be interesting to explore which package managers are utilized in the development of popular JavaScript framework projects. And guess what? Many JavaScript frameworks are developed using pnpm 💖.",{"type":415,"tag":523,"props":524,"children":526},"callout",{"icon":525},"i-heroicons-light-bulb",[527],{"type":415,"tag":416,"props":528,"children":529},{},[530],{"type":420,"value":531},"To check that these projects were using pnpm, I not only verify the presence of pnpm specific files but also checked their continuous integration pipelines (contained in the .github folder) to see what they were using to manage their dependencies.",{"type":415,"tag":416,"props":533,"children":534},{},[535],{"type":420,"value":536},"Here is a non-exhaustive list of popular JavaScript web frameworks that use pnpm as their package manager:",{"type":415,"tag":538,"props":539,"children":540},"ul",{},[541,547,552,557,562,567,572],{"type":415,"tag":542,"props":543,"children":544},"li",{},[545],{"type":420,"value":546},"Vue",{"type":415,"tag":542,"props":548,"children":549},{},[550],{"type":420,"value":551},"Nuxt",{"type":415,"tag":542,"props":553,"children":554},{},[555],{"type":420,"value":556},"Next.js",{"type":415,"tag":542,"props":558,"children":559},{},[560],{"type":420,"value":561},"SvelteKit",{"type":415,"tag":542,"props":563,"children":564},{},[565],{"type":420,"value":566},"SolidStart",{"type":415,"tag":542,"props":568,"children":569},{},[570],{"type":420,"value":571},"Astro",{"type":415,"tag":542,"props":573,"children":574},{},[575],{"type":420,"value":576},"Qwik",{"type":415,"tag":416,"props":578,"children":579},{},[580],{"type":420,"value":581},"That's quite an impressive list: most modern JavaScript web frameworks seem to have chosen pnpm. That's also the case for popular frontend tooling projects like Vite or Turbo.",{"type":415,"tag":523,"props":583,"children":584},{"icon":525},[585],{"type":415,"tag":416,"props":586,"children":587},{},[588],{"type":420,"value":589},"The fact that pnpm is utilized by maintainers for internal development of these frameworks does not imply that these frameworks can only be used with pnpm. Typically, JavaScript frameworks are \"package manager\" agnostic, allowing you to use your preferred package manager when developing a project with one of these frameworks.",{"type":415,"tag":427,"props":591,"children":593},{"id":592},"should-you-use-pnpm-because-others-do",[594],{"type":420,"value":595},"Should you use pnpm because others do?",{"type":415,"tag":416,"props":597,"children":598},{},[599],{"type":420,"value":600},"Short answer: no.",{"type":415,"tag":416,"props":602,"children":603},{},[604],{"type":420,"value":605},"Choosing a technology solely based on its popularity is not advisable. While popularity is a factor to consider, it should not be the only determining aspect. Thus, you should not use pnpm because well-known companies or popular open-source projects use it.",{"type":415,"tag":416,"props":607,"children":608},{},[609],{"type":420,"value":610},"However (and here's the long answer 😉), you should consider exploring pnpm, as there must be a reason why all these intelligent individuals have chosen it over npm or yarn. Investigate the issues pnpm resolves for them; perhaps you face similar challenges in your projects. See what problems pnpm solves for them, maybe you have the same problems in your projects. You might not even be aware of certain problems (such as lengthy CI due to time-consuming package installations, excessive space occupied by node modules, or issues with hoisted node modules), but pnpm could potentially make some things easier. Nevertheless, if you are satisfied with your current package manager, there is no need to switch just to imitate the popular frameworks projects.",{"type":415,"tag":416,"props":612,"children":613},{},[614],{"type":420,"value":615},"I believe people are familiar with npm since it is the default package manager for Node.js projects. They might also know about yarn because it was initially developed by Facebook (who created React) and addressed some issues with npm. However, people recognize and utilize pnpm due to its performance and ability to resolve the problems they might encounter with npm package management. That's also why I use pnpm; it does the job, and it does it quickly.",{"type":415,"tag":416,"props":617,"children":618},{},[619],{"type":420,"value":620},"Now you know that you're not alone in using pnpm; from renowned companies to popular open-source projects, many people are utilizing it.",{"title":401,"searchDepth":622,"depth":622,"links":623},2,[624,625,626,627],{"id":429,"depth":622,"text":432},{"id":474,"depth":622,"text":477},{"id":508,"depth":622,"text":511},{"id":592,"depth":622,"text":595},"markdown","content:1.posts:52.pnpm-who-is-using.md","content","1.posts/52.pnpm-who-is-using.md","md",{"_path":157,"_dir":399,"_draft":400,"_partial":400,"_locale":401,"title":156,"description":634,"lead":635,"date":636,"image":637,"badge":638,"tags":639,"canonical":640,"body":641,"_type":628,"_id":821,"_source":630,"_file":822,"_extension":632},"You have a dependency in your project and want to execute a command using it? The pnpm exec command can help you with that.","pnpm exec","2023-06-15T00:00:00.000Z",{"src":408},{"label":406},[362,296,206],"https://bordeauxcoders.com/execute-commands-using-your-project-dependencies",{"type":412,"children":642,"toc":816},[643,658,664,713,725,731,757,763,768,798,810],{"type":415,"tag":416,"props":644,"children":645},{},[646,648,656],{"type":420,"value":647},"You have a dependency in your project and want to execute a command using it? The ",{"type":415,"tag":649,"props":650,"children":654},"a",{"href":651,"rel":652},"https://pnpm.io/cli/exec",[653],"nofollow",[655],{"type":420,"value":635},{"type":420,"value":657}," command can help you with that.",{"type":415,"tag":427,"props":659,"children":661},{"id":660},"an-example",[662],{"type":420,"value":663},"An example",{"type":415,"tag":665,"props":666,"children":670},"pre",{"className":667,"code":668,"language":669,"meta":401,"style":401},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight"," pnpm exec eslint . --ext .ts\n","bash",[671],{"type":415,"tag":672,"props":673,"children":674},"code",{"__ignoreMap":401},[675],{"type":415,"tag":676,"props":677,"children":680},"span",{"class":678,"line":679},"line",1,[681,687,693,698,703,708],{"type":415,"tag":676,"props":682,"children":684},{"style":683},"--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B",[685],{"type":420,"value":686}," pnpm",{"type":415,"tag":676,"props":688,"children":690},{"style":689},"--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D",[691],{"type":420,"value":692}," exec",{"type":415,"tag":676,"props":694,"children":695},{"style":689},[696],{"type":420,"value":697}," eslint",{"type":415,"tag":676,"props":699,"children":700},{"style":689},[701],{"type":420,"value":702}," .",{"type":415,"tag":676,"props":704,"children":705},{"style":689},[706],{"type":420,"value":707}," --ext",{"type":415,"tag":676,"props":709,"children":710},{"style":689},[711],{"type":420,"value":712}," .ts\n",{"type":415,"tag":416,"props":714,"children":715},{},[716,718,723],{"type":420,"value":717},"Given that ESLint is a project dependency, this example shows how to use the ",{"type":415,"tag":672,"props":719,"children":721},{"className":720},[],[722],{"type":420,"value":635},{"type":420,"value":724}," command to run the ESLint tool on all TypeScript files within the project.",{"type":415,"tag":427,"props":726,"children":728},{"id":727},"some-use-cases",[729],{"type":420,"value":730},"Some use cases",{"type":415,"tag":538,"props":732,"children":733},{},[734,739,744],{"type":415,"tag":542,"props":735,"children":736},{},[737],{"type":420,"value":738},"You need to do a specific command that is not part of your npm scripts",{"type":415,"tag":542,"props":740,"children":741},{},[742],{"type":420,"value":743},"You want to execute a tool that is a dependency of your project without having to install it globally",{"type":415,"tag":542,"props":745,"children":746},{},[747,749,755],{"type":420,"value":748},"You need to execute a CLI package command in a CI pipeline, and this package is already included in the ",{"type":415,"tag":672,"props":750,"children":752},{"className":751},[],[753],{"type":420,"value":754},"devDependencies",{"type":420,"value":756}," of your project.",{"type":415,"tag":427,"props":758,"children":760},{"id":759},"good-to-know",[761],{"type":420,"value":762},"Good to know",{"type":415,"tag":416,"props":764,"children":765},{},[766],{"type":420,"value":767},"If the command you are using does not conflict with a built-in pnpm command, there is no need to specify 'exec'. Referring to the previous example, you can simply run:",{"type":415,"tag":665,"props":769,"children":771},{"className":667,"code":770,"language":669,"meta":401,"style":401}," pnpm eslint . --ext .ts\n",[772],{"type":415,"tag":672,"props":773,"children":774},{"__ignoreMap":401},[775],{"type":415,"tag":676,"props":776,"children":777},{"class":678,"line":679},[778,782,786,790,794],{"type":415,"tag":676,"props":779,"children":780},{"style":683},[781],{"type":420,"value":686},{"type":415,"tag":676,"props":783,"children":784},{"style":689},[785],{"type":420,"value":697},{"type":415,"tag":676,"props":787,"children":788},{"style":689},[789],{"type":420,"value":702},{"type":415,"tag":676,"props":791,"children":792},{"style":689},[793],{"type":420,"value":707},{"type":415,"tag":676,"props":795,"children":796},{"style":689},[797],{"type":420,"value":712},{"type":415,"tag":416,"props":799,"children":800},{},[801,803,808],{"type":420,"value":802},"It's one of the small details that make using ",{"type":415,"tag":672,"props":804,"children":806},{"className":805},[],[807],{"type":420,"value":362},{"type":420,"value":809}," so pleasant.",{"type":415,"tag":811,"props":812,"children":813},"style",{},[814],{"type":420,"value":815},"html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":401,"searchDepth":622,"depth":622,"links":817},[818,819,820],{"id":660,"depth":622,"text":663},{"id":727,"depth":622,"text":730},{"id":759,"depth":622,"text":762},"content:1.posts:50.pnpm-exec.md","1.posts/50.pnpm-exec.md",{"_path":151,"_dir":399,"_draft":400,"_partial":400,"_locale":401,"title":150,"description":824,"lead":825,"date":826,"image":827,"badge":828,"tags":829,"canonical":830,"body":831,"_type":628,"_id":999,"_source":630,"_file":1000,"_extension":632},"If you are working on various projects, you have likely encountered situations where you need to have multiple versions of Node.js installed on your computer.","pnpm env","2023-05-25T00:00:00.000Z",{"src":408},{"label":406},[362,296,206],"https://bordeauxcoders.com/manage-multiple-nodejs-versions",{"type":412,"children":832,"toc":994},[833,837,854,858,892,897,902,908,913,927,931,964,990],{"type":415,"tag":416,"props":834,"children":835},{},[836],{"type":420,"value":824},{"type":415,"tag":416,"props":838,"children":839},{},[840,842,852],{"type":420,"value":841},"You might not know it, but managing multiple Node.js versions is something you can do with pnpm, using the ",{"type":415,"tag":649,"props":843,"children":846},{"href":844,"rel":845},"https://pnpm.io/fr/cli/env",[653],[847],{"type":415,"tag":672,"props":848,"children":850},{"className":849},[],[851],{"type":420,"value":825},{"type":420,"value":853}," command.",{"type":415,"tag":427,"props":855,"children":856},{"id":660},[857],{"type":420,"value":663},{"type":415,"tag":665,"props":859,"children":861},{"className":667,"code":860,"language":669,"meta":401,"style":401},"pnpm env use -g lts \n",[862],{"type":415,"tag":672,"props":863,"children":864},{"__ignoreMap":401},[865],{"type":415,"tag":676,"props":866,"children":867},{"class":678,"line":679},[868,872,877,882,887],{"type":415,"tag":676,"props":869,"children":870},{"style":683},[871],{"type":420,"value":362},{"type":415,"tag":676,"props":873,"children":874},{"style":689},[875],{"type":420,"value":876}," env",{"type":415,"tag":676,"props":878,"children":879},{"style":689},[880],{"type":420,"value":881}," use",{"type":415,"tag":676,"props":883,"children":884},{"style":689},[885],{"type":420,"value":886}," -g",{"type":415,"tag":676,"props":888,"children":889},{"style":689},[890],{"type":420,"value":891}," lts\n",{"type":415,"tag":416,"props":893,"children":894},{},[895],{"type":420,"value":896},"This example demonstrates how to install the LTS version of Node.js.",{"type":415,"tag":416,"props":898,"children":899},{},[900],{"type":420,"value":901},"Additionally, you can install specific versions of Node.js, view the versions already present on your computer, or remove one.",{"type":415,"tag":427,"props":903,"children":905},{"id":904},"why-use-pnpm-as-your-node-version-manager",[906],{"type":420,"value":907},"Why use pnpm as your Node version manager?",{"type":415,"tag":416,"props":909,"children":910},{},[911],{"type":420,"value":912},"Because managing your Node.js version is built into pnpm: if you already use pnpm as your npm package manager, you don't need to install another tool.",{"type":415,"tag":416,"props":914,"children":915},{},[916,918,925],{"type":420,"value":917},"But there is absolutely nothing wrong with using another Node version manager if you prefer. I was using ",{"type":415,"tag":649,"props":919,"children":922},{"href":920,"rel":921},"https://github.com/coreybutler/nvm-windows",[653],[923],{"type":420,"value":924},"nvm-windows",{"type":420,"value":926}," before and I was happy with it. I just don't see the point of installing it anymore as similar functionality is already available in pnpm.",{"type":415,"tag":427,"props":928,"children":929},{"id":759},[930],{"type":420,"value":762},{"type":415,"tag":416,"props":932,"children":933},{},[934,936,947,949,955,962],{"type":420,"value":935},"To specify a Node.js version to use in a project/folder, you can add an ",{"type":415,"tag":649,"props":937,"children":940},{"href":938,"rel":939},"https://pnpm.io/fr/npmrc",[653],[941],{"type":415,"tag":672,"props":942,"children":944},{"className":943},[],[945],{"type":420,"value":946},".npmrc",{"type":420,"value":948}," file ",{"type":415,"tag":672,"props":950,"children":952},{"className":951},[],[953],{"type":420,"value":954},"use-node-version",{"type":415,"tag":649,"props":956,"children":959},{"href":957,"rel":958},"https://pnpm.io/fr/npmrc#use-node-version",[653],[960],{"type":420,"value":961},"​",{"type":420,"value":963}," setting, like that:",{"type":415,"tag":665,"props":965,"children":967},{"className":667,"code":966,"language":669,"meta":401,"style":401},"use-node-version=16.16.0\n",[968],{"type":415,"tag":672,"props":969,"children":970},{"__ignoreMap":401},[971],{"type":415,"tag":676,"props":972,"children":973},{"class":678,"line":679},[974,979,985],{"type":415,"tag":676,"props":975,"children":977},{"style":976},"--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8",[978],{"type":420,"value":954},{"type":415,"tag":676,"props":980,"children":982},{"style":981},"--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF",[983],{"type":420,"value":984},"=",{"type":415,"tag":676,"props":986,"children":987},{"style":689},[988],{"type":420,"value":989},"16.16.0\n",{"type":415,"tag":811,"props":991,"children":992},{},[993],{"type":420,"value":815},{"title":401,"searchDepth":622,"depth":622,"links":995},[996,997,998],{"id":660,"depth":622,"text":663},{"id":904,"depth":622,"text":907},{"id":759,"depth":622,"text":762},"content:1.posts:48.pnpm-env.md","1.posts/48.pnpm-env.md",{"_path":148,"_dir":399,"_draft":400,"_partial":400,"_locale":401,"title":147,"description":1002,"lead":1003,"date":1004,"image":1005,"badge":1006,"tags":1007,"canonical":1008,"body":1009,"_type":628,"_id":1194,"_source":630,"_file":1195,"_extension":632},"Sometimes, all you want to do is grab an npm package and execute a command with it, without having to install it (whether globally or as a dependency).","pnpm dlx","2023-05-18T00:00:00.000Z",{"src":408},{"label":406},[362,296,206],"https://bordeauxcoders.com/perform-dynamic-execution-of-an-npm-package",{"type":412,"children":1010,"toc":1189},[1011,1015,1032,1036,1065,1085,1098,1102,1141,1145,1185],{"type":415,"tag":416,"props":1012,"children":1013},{},[1014],{"type":420,"value":1002},{"type":415,"tag":416,"props":1016,"children":1017},{},[1018,1020,1030],{"type":420,"value":1019},"That's what you can do with ",{"type":415,"tag":649,"props":1021,"children":1024},{"href":1022,"rel":1023},"https://pnpm.io/cli/dlx",[653],[1025],{"type":415,"tag":672,"props":1026,"children":1028},{"className":1027},[],[1029],{"type":420,"value":1003},{"type":420,"value":1031},".",{"type":415,"tag":427,"props":1033,"children":1034},{"id":660},[1035],{"type":420,"value":663},{"type":415,"tag":665,"props":1037,"children":1039},{"className":667,"code":1038,"language":669,"meta":401,"style":401},"pnpm dlx vercel deploy\n",[1040],{"type":415,"tag":672,"props":1041,"children":1042},{"__ignoreMap":401},[1043],{"type":415,"tag":676,"props":1044,"children":1045},{"class":678,"line":679},[1046,1050,1055,1060],{"type":415,"tag":676,"props":1047,"children":1048},{"style":683},[1049],{"type":420,"value":362},{"type":415,"tag":676,"props":1051,"children":1052},{"style":689},[1053],{"type":420,"value":1054}," dlx",{"type":415,"tag":676,"props":1056,"children":1057},{"style":689},[1058],{"type":420,"value":1059}," vercel",{"type":415,"tag":676,"props":1061,"children":1062},{"style":689},[1063],{"type":420,"value":1064}," deploy\n",{"type":415,"tag":416,"props":1066,"children":1067},{},[1068,1070,1077,1079,1084],{"type":420,"value":1069},"This example shows how to use the ",{"type":415,"tag":649,"props":1071,"children":1074},{"href":1072,"rel":1073},"https://vercel.com/docs/cli",[653],[1075],{"type":420,"value":1076},"vercel CLI package",{"type":420,"value":1078}," without having to install it thanks to ",{"type":415,"tag":672,"props":1080,"children":1082},{"className":1081},[],[1083],{"type":420,"value":1003},{"type":420,"value":1031},{"type":415,"tag":416,"props":1086,"children":1087},{},[1088,1090,1096],{"type":420,"value":1089},"In this example, pnpm downloads the vercel package, and executes it with the command ",{"type":415,"tag":672,"props":1091,"children":1093},{"className":1092},[],[1094],{"type":420,"value":1095},"deploy",{"type":420,"value":1097}," (that deploys a project to the Vercel platform).",{"type":415,"tag":427,"props":1099,"children":1100},{"id":727},[1101],{"type":420,"value":730},{"type":415,"tag":538,"props":1103,"children":1104},{},[1105,1110,1115,1120],{"type":415,"tag":542,"props":1106,"children":1107},{},[1108],{"type":420,"value":1109},"You don't want to install globally a package because you only need to execute its binary script once",{"type":415,"tag":542,"props":1111,"children":1112},{},[1113],{"type":420,"value":1114},"You don't want a package to be a dev dependency of your project, or you are not using it in the context of a Node project",{"type":415,"tag":542,"props":1116,"children":1117},{},[1118],{"type":420,"value":1119},"You need to execute a CLI package command from a CI pipeline",{"type":415,"tag":542,"props":1121,"children":1122},{},[1123,1125,1131,1133,1139],{"type":420,"value":1124},"You want to ensure you use the latest version of a package (useful for starter kits like ",{"type":415,"tag":672,"props":1126,"children":1128},{"className":1127},[],[1129],{"type":420,"value":1130},"create-vite",{"type":420,"value":1132},", or ",{"type":415,"tag":672,"props":1134,"children":1136},{"className":1135},[],[1137],{"type":420,"value":1138},"create-vue",{"type":420,"value":1140},")",{"type":415,"tag":427,"props":1142,"children":1143},{"id":759},[1144],{"type":420,"value":762},{"type":415,"tag":416,"props":1146,"children":1147},{},[1148,1150,1161,1163,1168,1170,1176,1178,1184],{"type":420,"value":1149},"For starter kits, you can use ",{"type":415,"tag":649,"props":1151,"children":1154},{"href":1152,"rel":1153},"https://pnpm.io/cli/create",[653],[1155],{"type":415,"tag":672,"props":1156,"children":1158},{"className":1157},[],[1159],{"type":420,"value":1160},"pnpm create",{"type":420,"value":1162}," instead of ",{"type":415,"tag":672,"props":1164,"children":1166},{"className":1165},[],[1167],{"type":420,"value":1003},{"type":420,"value":1169},". For instance, executing ",{"type":415,"tag":672,"props":1171,"children":1173},{"className":1172},[],[1174],{"type":420,"value":1175},"pnpm create vue",{"type":420,"value":1177}," is equivalent to executing ",{"type":415,"tag":672,"props":1179,"children":1181},{"className":1180},[],[1182],{"type":420,"value":1183},"pnpm dlx create-vue",{"type":420,"value":1031},{"type":415,"tag":811,"props":1186,"children":1187},{},[1188],{"type":420,"value":815},{"title":401,"searchDepth":622,"depth":622,"links":1190},[1191,1192,1193],{"id":660,"depth":622,"text":663},{"id":727,"depth":622,"text":730},{"id":759,"depth":622,"text":762},"content:1.posts:47.pnpm-dlx.md","1.posts/47.pnpm-dlx.md",{"_path":139,"_dir":399,"_draft":400,"_partial":400,"_locale":401,"title":138,"description":1197,"lead":1197,"date":1198,"image":1199,"badge":1201,"tags":1203,"body":1204,"_type":628,"_id":1451,"_source":630,"_file":1452,"_extension":632},"Some tips about .NET, pnpm, and Azure DevOps.","2022-11-20T00:00:00.000Z",{"src":1200},"/images/surface_1.jpg",{"label":1202},"Tips",[272,239,293,362,296,208,343,206],{"type":412,"children":1205,"toc":1446},[1206,1212,1226,1248,1271,1277,1308,1313,1322,1334,1343,1351,1356,1366,1375,1389,1395,1400,1410,1428,1437,1442],{"type":415,"tag":427,"props":1207,"children":1209},{"id":1208},"net-tip-of-the-week-install-net-7-using-winget",[1210],{"type":420,"value":1211},".NET tip of the week: install .NET 7 using winget",{"type":415,"tag":416,"props":1213,"children":1214},{},[1215,1217,1224],{"type":420,"value":1216},"This week, I installed .NET 7 on my laptop and I used ",{"type":415,"tag":649,"props":1218,"children":1221},{"href":1219,"rel":1220},"https://learn.microsoft.com/en-us/windows/package-manager/",[653],[1222],{"type":420,"value":1223},"Windows Package Manager",{"type":420,"value":1225}," for that:",{"type":415,"tag":665,"props":1227,"children":1230},{"className":1228,"code":1229,"language":248,"meta":401,"style":401},"language-powershell shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","winget install Microsoft.DotNet.SDK.7\n",[1231],{"type":415,"tag":672,"props":1232,"children":1233},{"__ignoreMap":401},[1234],{"type":415,"tag":676,"props":1235,"children":1236},{"class":678,"line":679},[1237,1242],{"type":415,"tag":676,"props":1238,"children":1239},{"style":976},[1240],{"type":420,"value":1241},"winget install Microsoft.DotNet.SDK.",{"type":415,"tag":676,"props":1243,"children":1245},{"style":1244},"--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C",[1246],{"type":420,"value":1247},"7\n",{"type":415,"tag":416,"props":1249,"children":1250},{},[1251,1253,1260,1262,1269],{"type":420,"value":1252},"I like winget, I have already written a few articles about it (you can find them ",{"type":415,"tag":649,"props":1254,"children":1257},{"href":1255,"rel":1256},"https://www.techwatching.dev/tags/winget/",[653],[1258],{"type":420,"value":1259},"here",{"type":420,"value":1261},") so I am really glad to see that we can now use winget to install .NET (whether it be the SDKs or the runtimes). You can check ",{"type":415,"tag":649,"props":1263,"children":1266},{"href":1264,"rel":1265},"https://devblogs.microsoft.com/dotnet/dotnet-now-on-windows-package-manager/",[653],[1267],{"type":420,"value":1268},"Microsoft's article",{"type":420,"value":1270}," announcing it for more information.",{"type":415,"tag":427,"props":1272,"children":1274},{"id":1273},"tool-of-the-week-pnpm",[1275],{"type":420,"value":1276},"Tool of the week: pnpm",{"type":415,"tag":416,"props":1278,"children":1279},{},[1280,1282,1288,1290,1297,1299,1306],{"type":420,"value":1281},"I don't know which JavaScript package manager you are using but since I tried ",{"type":415,"tag":649,"props":1283,"children":1286},{"href":1284,"rel":1285},"https://pnpm.io/",[653],[1287],{"type":420,"value":362},{"type":420,"value":1289}," I don't want to use anything else because it's so fast! If you are interested to know why it's so fast and better than npm for instance, you can watch the talk ",{"type":415,"tag":649,"props":1291,"children":1294},{"href":1292,"rel":1293},"https://viteconf.org/2022/replay/pnpm",[653],[1295],{"type":420,"value":1296},"\"What makes pnpm performant\"",{"type":420,"value":1298}," that Zoltan Kochan gave at Vite Conf. Many ",{"type":415,"tag":649,"props":1300,"children":1303},{"href":1301,"rel":1302},"https://pnpm.io/workspaces#usage-examples",[653],[1304],{"type":420,"value":1305},"popular open-source projects",{"type":420,"value":1307}," like Vite and Vue are using pnpm.",{"type":415,"tag":416,"props":1309,"children":1310},{},[1311],{"type":420,"value":1312},"Here are some tips about pnpm:",{"type":415,"tag":1314,"props":1315,"children":1316},"ol",{},[1317],{"type":415,"tag":542,"props":1318,"children":1319},{},[1320],{"type":420,"value":1321},"You can use pnpm to manage Node.js versions on your machine",{"type":415,"tag":416,"props":1323,"children":1324},{},[1325,1327,1332],{"type":420,"value":1326},"Previously, I was using ",{"type":415,"tag":649,"props":1328,"children":1330},{"href":920,"rel":1329},[653],[1331],{"type":420,"value":924},{"type":420,"value":1333}," to manage multiple installation of Node.js on my laptop and it worked fine. Yet I can now do that directly using pnpm env command:",{"type":415,"tag":416,"props":1335,"children":1336},{},[1337],{"type":415,"tag":459,"props":1338,"children":1342},{"alt":1339,"className":1340,"src":1341},"Output of the pnpm env command in a terminal.",[463,464],"/posts/images/w462022tips_pnpm_env.png",[],{"type":415,"tag":1314,"props":1344,"children":1345},{"start":622},[1346],{"type":415,"tag":542,"props":1347,"children":1348},{},[1349],{"type":420,"value":1350},"You can configure vscode to run npm scripts using pnpm",{"type":415,"tag":416,"props":1352,"children":1353},{},[1354],{"type":420,"value":1355},"A lot of the people I know don't use the scripts explorer of vscode to run the scripts contained in the package.json file of the project opened in vscode. It's a pity because it is an handy feature. And you can configure it in your settings to run scripts using a specific package manager, pnpm in my case.",{"type":415,"tag":416,"props":1357,"children":1358},{},[1359],{"type":415,"tag":459,"props":1360,"children":1365},{"alt":1361,"className":1362,"src":1363,"width":1364},"Npm scripts view in vscode editor.",[463,464],"/posts/images/w462022tips_pnpm_scripts.png",600,[],{"type":415,"tag":1314,"props":1367,"children":1369},{"start":1368},3,[1370],{"type":415,"tag":542,"props":1371,"children":1372},{},[1373],{"type":420,"value":1374},"With pnpm, you can use aliases for packages you install",{"type":415,"tag":416,"props":1376,"children":1377},{},[1378,1380,1387],{"type":420,"value":1379},"Check the ",{"type":415,"tag":649,"props":1381,"children":1384},{"href":1382,"rel":1383},"https://pnpm.io/aliases",[653],[1385],{"type":420,"value":1386},"documentation",{"type":420,"value":1388}," to see why and how to use this feature.",{"type":415,"tag":427,"props":1390,"children":1392},{"id":1391},"the-gitlensazure-devops-tip-you-did-not-know-about-autolinks",[1393],{"type":420,"value":1394},"The GitLens/Azure DevOps tip you did not know about: autolinks",{"type":415,"tag":416,"props":1396,"children":1397},{},[1398],{"type":420,"value":1399},"GitLens, the awesome extension for vscode has a nice feature called \"autolinks\" that can make external references in your commit messages clickable links.",{"type":415,"tag":416,"props":1401,"children":1402},{},[1403],{"type":415,"tag":459,"props":1404,"children":1409},{"alt":1405,"className":1406,"src":1407,"width":1408},"Autolinks GitLens settings view in vscode.",[463,464],"/posts/images/w462022tips_gitlens_autolink_1.png",1000,[],{"type":415,"tag":416,"props":1411,"children":1412},{},[1413,1415,1422],{"type":420,"value":1414},"If you are using Azure DevOps, this feature can become very handy for you commit messages that contain references to work items (usually an hasjtag followed by the work item number). You just have to configure # as the prefix and ",{"type":415,"tag":649,"props":1416,"children":1419},{"href":1417,"rel":1418},"https://dev.azure.com/%7BorganizationName%7D/%7BprojectName%7D/_workitems/edit/",[653],[1420],{"type":420,"value":1421},"https://dev.azure.com/{organizationName}/{projectName}/_workitems/edit/",{"type":415,"tag":1423,"props":1424,"children":1425},"num",{},[1426],{"type":420,"value":1427}," as the URL) to make it work.",{"type":415,"tag":416,"props":1429,"children":1430},{},[1431],{"type":415,"tag":459,"props":1432,"children":1436},{"alt":1433,"className":1434,"src":1435,"width":1408},"A commit GitLens popin in vscode with an Azure DevOps link.",[463,464],"/posts/images/w462022tips_gitlens_autolink_2.png",[],{"type":415,"tag":416,"props":1438,"children":1439},{},[1440],{"type":420,"value":1441},"And that's it for this week, happy learning!",{"type":415,"tag":811,"props":1443,"children":1444},{},[1445],{"type":420,"value":815},{"title":401,"searchDepth":622,"depth":622,"links":1447},[1448,1449,1450],{"id":1208,"depth":622,"text":1211},{"id":1273,"depth":622,"text":1276},{"id":1391,"depth":622,"text":1394},"content:1.posts:44.w46-2022-tips-learned-this-week.md","1.posts/44.w46-2022-tips-learned-this-week.md",{"_path":133,"_dir":399,"_draft":400,"_partial":400,"_locale":401,"title":132,"description":1454,"lead":1455,"date":1456,"badge":1457,"image":1458,"tags":1460,"body":1461,"_type":628,"_id":2993,"_source":630,"_file":2994,"_extension":632},"In this article, I talked about my latest project: how I built a script to automate the setup of my developer machine using Boxstarter, Chocolatey, Winget, and PowerShell... and how I learned a few things along the way.","A git repository, 2 packages managers, a little bit of scripting, and here is my new environment ready","2022-09-02T00:00:00.000Z",{"label":406},{"src":1459},"/images/laptop_2.jpg",[291,249,293,296,206],{"type":412,"children":1462,"toc":2980},[1463,1467,1473,1478,1483,1492,1497,1520,1526,1531,1554,1586,1601,1630,1639,1648,1668,1673,1798,1810,1816,1823,1844,1849,1864,1870,1875,1884,1889,1894,1977,1985,1990,2004,2018,2024,2044,2082,2087,2357,2380,2385,2433,2441,2447,2452,2643,2663,2669,2674,2683,2688,2738,2750,2827,2832,2837,2843,2848,2870,2884,2889,2916,2930,2936,2948,2953,2958,2971,2976],{"type":415,"tag":416,"props":1464,"children":1465},{},[1466],{"type":420,"value":1454},{"type":415,"tag":427,"props":1468,"children":1470},{"id":1469},"context",[1471],{"type":420,"value":1472},"Context",{"type":415,"tag":416,"props":1474,"children":1475},{},[1476],{"type":420,"value":1477},"You have probably already faced this situation when you get a new personal or professional laptop, and you have to reinstall all the software you are using daily on this machine. Usually, you lose a few hours to a day to set up your developer environment and not everything is exactly as it was on your previous laptop because you always forget some things.",{"type":415,"tag":416,"props":1479,"children":1480},{},[1481],{"type":420,"value":1482},"It's not even only about installing software but also configuring your environment to meet your habits. And that's important because a properly configured developer environment with the right tools is what makes you productive in your everyday developer life.",{"type":415,"tag":416,"props":1484,"children":1485},{},[1486],{"type":415,"tag":459,"props":1487,"children":1491},{"alt":1488,"className":1489,"src":1490},"A collection of office supplies laid out on a table.",[463,464],"/posts/images/automate_developer_machine_tool.jpg",[],{"type":415,"tag":416,"props":1493,"children":1494},{},[1495],{"type":420,"value":1496},"A lot of people have solved this issue by scripting their developer environment setup, and I decided it was time for me to do the same. And believe me, it was not for the beauty of having everything automatically installed but to stop wasting my time each time I change or reinstall my laptop.",{"type":415,"tag":416,"props":1498,"children":1499},{},[1500,1502,1509,1511,1518],{"type":420,"value":1501},"Please note that what I did to setup my developer machine was inspired by the ",{"type":415,"tag":649,"props":1503,"children":1506},{"href":1504,"rel":1505},"https://github.com/Microsoft/windows-dev-box-setup-scripts",[653],[1507],{"type":420,"value":1508},"Windows Dev Box setup scripts",{"type":420,"value":1510}," GitHub repository and other repositories using boxstarter (check ",{"type":415,"tag":649,"props":1512,"children":1515},{"href":1513,"rel":1514},"https://github.com/laurentkempe/Cacao",[653],[1516],{"type":420,"value":1517},"Laurent Kempé's repository",{"type":420,"value":1519}," for instance) to install their Windows environment.",{"type":415,"tag":427,"props":1521,"children":1523},{"id":1522},"how-does-it-work",[1524],{"type":420,"value":1525},"How does it work?",{"type":415,"tag":416,"props":1527,"children":1528},{},[1529],{"type":420,"value":1530},"There are many ways to automate the setup of a developer machine. Before choosing one, I had a few requirements/preferences:",{"type":415,"tag":538,"props":1532,"children":1533},{},[1534,1539,1544,1549],{"type":415,"tag":542,"props":1535,"children":1536},{},[1537],{"type":420,"value":1538},"installation of my machine should be simple to script and run",{"type":415,"tag":542,"props":1540,"children":1541},{},[1542],{"type":420,"value":1543},"no need to pre-install some software before launching the installation of my environment",{"type":415,"tag":542,"props":1545,"children":1546},{},[1547],{"type":420,"value":1548},"avoid manual steps or user interaction during the installation",{"type":415,"tag":542,"props":1550,"children":1551},{},[1552],{"type":420,"value":1553},"be able easily to share some software configurations between laptops",{"type":415,"tag":416,"props":1555,"children":1556},{},[1557,1559,1566,1568,1575,1577,1584],{"type":420,"value":1558},"Because of these requirements, I chose to use ",{"type":415,"tag":649,"props":1560,"children":1563},{"href":1561,"rel":1562},"https://boxstarter.org/",[653],[1564],{"type":420,"value":1565},"Boxstarter",{"type":420,"value":1567},". It has several interesting features (check the ",{"type":415,"tag":649,"props":1569,"children":1572},{"href":1570,"rel":1571},"https://boxstarter.org/whyboxstarter",[653],[1573],{"type":420,"value":1574},"website",{"type":420,"value":1576},") but the one I like the most is you can launch your installation process directly by ",{"type":415,"tag":649,"props":1578,"children":1581},{"href":1579,"rel":1580},"https://boxstarter.org/weblauncher",[653],[1582],{"type":420,"value":1583},"clicking on a link",{"type":420,"value":1585},". You just need an URL like this one:",{"type":415,"tag":665,"props":1587,"children":1590},{"className":1588,"code":1589,"language":212,"meta":401,"style":401},"language-http shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","https://boxstarter.org/package/nr/url?{urlToYourInstallationScript}\n",[1591],{"type":415,"tag":672,"props":1592,"children":1593},{"__ignoreMap":401},[1594],{"type":415,"tag":676,"props":1595,"children":1596},{"class":678,"line":679},[1597],{"type":415,"tag":676,"props":1598,"children":1599},{"style":976},[1600],{"type":420,"value":1589},{"type":415,"tag":416,"props":1602,"children":1603},{},[1604,1606,1612,1614,1621,1623,1629],{"type":420,"value":1605},"The ",{"type":415,"tag":672,"props":1607,"children":1609},{"className":1608},[],[1610],{"type":420,"value":1611},"{urlToYourInstallationScript}",{"type":420,"value":1613}," part is the URL where is stored your installation script. I put mine in a ",{"type":415,"tag":649,"props":1615,"children":1618},{"href":1616,"rel":1617},"https://github.com/TechWatching/dotfiles/blob/main/boxstarter.ps1",[653],[1619],{"type":420,"value":1620},"public GitHub repository",{"type":420,"value":1622}," called ",{"type":415,"tag":672,"props":1624,"children":1626},{"className":1625},[],[1627],{"type":420,"value":1628},"dotfiles",{"type":420,"value":1031},{"type":415,"tag":416,"props":1631,"children":1632},{},[1633],{"type":415,"tag":459,"props":1634,"children":1638},{"alt":1635,"className":1636,"src":1637},"Boxstarter website.",[463,464],"/posts/images/automate_developer_machine_boxstarter.png",[],{"type":415,"tag":523,"props":1640,"children":1642},{"icon":1641},"i-heroicons-chat-bubble-left-20-solid",[1643],{"type":415,"tag":416,"props":1644,"children":1645},{},[1646],{"type":420,"value":1647},"Boxstarter was a nice discovery, I barely scratched the surface but it can do interesting things like remote installations.",{"type":415,"tag":416,"props":1649,"children":1650},{},[1651,1653,1659,1661,1666],{"type":420,"value":1652},"In this repository, I also put different scripts (to separate the different steps instead of having one big installation script file), some config files I wanted to use in my setup (my ",{"type":415,"tag":672,"props":1654,"children":1656},{"className":1655},[],[1657],{"type":420,"value":1658},".gitconfig",{"type":420,"value":1660}," file for instance), and a readme with some explanations and the link to launch the installation. I did not reinvent the wheel as it's more or less how the ",{"type":415,"tag":649,"props":1662,"children":1664},{"href":1504,"rel":1663},[653],[1665],{"type":420,"value":1508},{"type":420,"value":1667}," work.",{"type":415,"tag":416,"props":1669,"children":1670},{},[1671],{"type":420,"value":1672},"Because I wanted to share some software configurations between laptops (or between installations), using a GitHub repository is interesting. The first thing my setup script does is to install Git, then it clones this repository to have access to the other scripts and configuration files.",{"type":415,"tag":665,"props":1674,"children":1676},{"className":1228,"code":1675,"language":248,"meta":401,"style":401},"# Install git and clone repository containing scripts and config files\nchoco install -y git --params \"/GitOnlyOnPath /NoShellIntegration /WindowsTerminal\"\nRefreshEnv\ngit clone https://github.com/TechWatching/dotfiles.git \"$env:USERPROFILE\\dotfiles\"\n",[1677],{"type":415,"tag":672,"props":1678,"children":1679},{"__ignoreMap":401},[1680,1689,1732,1740],{"type":415,"tag":676,"props":1681,"children":1682},{"class":678,"line":679},[1683],{"type":415,"tag":676,"props":1684,"children":1686},{"style":1685},"--shiki-light:#90A4AE;--shiki-default:#546E7A;--shiki-dark:#676E95;--shiki-light-font-style:italic;--shiki-default-font-style:italic;--shiki-dark-font-style:italic",[1687],{"type":420,"value":1688},"# Install git and clone repository containing scripts and config files\n",{"type":415,"tag":676,"props":1690,"children":1691},{"class":678,"line":622},[1692,1697,1702,1707,1712,1717,1722,1727],{"type":415,"tag":676,"props":1693,"children":1694},{"style":976},[1695],{"type":420,"value":1696},"choco install ",{"type":415,"tag":676,"props":1698,"children":1699},{"style":981},[1700],{"type":420,"value":1701},"-",{"type":415,"tag":676,"props":1703,"children":1704},{"style":976},[1705],{"type":420,"value":1706},"y git ",{"type":415,"tag":676,"props":1708,"children":1709},{"style":981},[1710],{"type":420,"value":1711},"--",{"type":415,"tag":676,"props":1713,"children":1714},{"style":976},[1715],{"type":420,"value":1716},"params ",{"type":415,"tag":676,"props":1718,"children":1719},{"style":981},[1720],{"type":420,"value":1721},"\"",{"type":415,"tag":676,"props":1723,"children":1724},{"style":689},[1725],{"type":420,"value":1726},"/GitOnlyOnPath /NoShellIntegration /WindowsTerminal",{"type":415,"tag":676,"props":1728,"children":1729},{"style":981},[1730],{"type":420,"value":1731},"\"\n",{"type":415,"tag":676,"props":1733,"children":1734},{"class":678,"line":1368},[1735],{"type":415,"tag":676,"props":1736,"children":1737},{"style":976},[1738],{"type":420,"value":1739},"RefreshEnv\n",{"type":415,"tag":676,"props":1741,"children":1743},{"class":678,"line":1742},4,[1744,1749,1754,1760,1765,1770,1774,1779,1784,1789,1794],{"type":415,"tag":676,"props":1745,"children":1746},{"style":976},[1747],{"type":420,"value":1748},"git clone https:",{"type":415,"tag":676,"props":1750,"children":1751},{"style":981},[1752],{"type":420,"value":1753},"//",{"type":415,"tag":676,"props":1755,"children":1757},{"style":1756},"--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF",[1758],{"type":420,"value":1759},"github.com",{"type":415,"tag":676,"props":1761,"children":1762},{"style":981},[1763],{"type":420,"value":1764},"/",{"type":415,"tag":676,"props":1766,"children":1767},{"style":976},[1768],{"type":420,"value":1769},"TechWatching",{"type":415,"tag":676,"props":1771,"children":1772},{"style":981},[1773],{"type":420,"value":1764},{"type":415,"tag":676,"props":1775,"children":1776},{"style":976},[1777],{"type":420,"value":1778},"dotfiles.git ",{"type":415,"tag":676,"props":1780,"children":1781},{"style":981},[1782],{"type":420,"value":1783},"\"$",{"type":415,"tag":676,"props":1785,"children":1786},{"style":976},[1787],{"type":420,"value":1788},"env:USERPROFILE",{"type":415,"tag":676,"props":1790,"children":1791},{"style":689},[1792],{"type":420,"value":1793},"\\dotfiles",{"type":415,"tag":676,"props":1795,"children":1796},{"style":981},[1797],{"type":420,"value":1731},{"type":415,"tag":416,"props":1799,"children":1800},{},[1801,1803,1809],{"type":420,"value":1802},"The scripts are written in ",{"type":415,"tag":649,"props":1804,"children":1807},{"href":1805,"rel":1806},"https://docs.microsoft.com/en-us/powershell/",[653],[1808],{"type":420,"value":249},{"type":420,"value":1031},{"type":415,"tag":427,"props":1811,"children":1813},{"id":1812},"installing-software",[1814],{"type":420,"value":1815},"Installing software",{"type":415,"tag":1817,"props":1818,"children":1820},"h3",{"id":1819},"package-managers",[1821],{"type":420,"value":1822},"Package managers",{"type":415,"tag":416,"props":1824,"children":1825},{},[1826,1828,1834,1836,1843],{"type":420,"value":1827},"The easiest way to automate installing, upgrading, and configuring software is to use package managers. There are several available on Windows but I chose to use ",{"type":415,"tag":649,"props":1829,"children":1832},{"href":1830,"rel":1831},"https://docs.microsoft.com/en-us/windows/package-manager/",[653],[1833],{"type":420,"value":1223},{"type":420,"value":1835}," and ",{"type":415,"tag":649,"props":1837,"children":1840},{"href":1838,"rel":1839},"https://chocolatey.org/",[653],[1841],{"type":420,"value":1842},"Chocolatey",{"type":420,"value":1031},{"type":415,"tag":416,"props":1845,"children":1846},{},[1847],{"type":420,"value":1848},"Windows Package Manager (aka winget) is relatively new so has fewer features and packages available than other package managers like Chocolatey. However it's very promising, it's getting better every day, it's built-in Windows, and above all, it supports installing Microsoft Store apps. So I chose to use winget by default and fallback to Chocolatey when a package I needed was not available or not up-to-date in winget.",{"type":415,"tag":523,"props":1850,"children":1851},{"icon":1641},[1852],{"type":415,"tag":416,"props":1853,"children":1854},{},[1855,1857,1862],{"type":420,"value":1856},"I learned a few things about winget while starting to use it. You can find my articles talking about it ",{"type":415,"tag":649,"props":1858,"children":1860},{"href":1255,"rel":1859},[653],[1861],{"type":420,"value":1259},{"type":420,"value":1863}," if you are interested.",{"type":415,"tag":1817,"props":1865,"children":1867},{"id":1866},"installing-integrated-development-environments-ides",[1868],{"type":420,"value":1869},"Installing Integrated Development Environments (IDEs)",{"type":415,"tag":416,"props":1871,"children":1872},{},[1873],{"type":420,"value":1874},"Visual Studio has been my main IDE for a while, but I have been started recently to use more and more Rider as well. Both are nice IDEs with many features particularly well suited for .NET development which is what I mostly do. I have been a Visual Studio Code long-time user too, mostly using it as a text editor or for front development. I also use vscode to work with Azure because it has nice extensions for a lot of Azure services.",{"type":415,"tag":416,"props":1876,"children":1877},{},[1878],{"type":415,"tag":459,"props":1879,"children":1883},{"alt":1880,"className":1881,"src":1882},"Visual Studio logo.",[463,464],"/posts/images/automate_developer_machine_visualstudio.jpg",[],{"type":415,"tag":416,"props":1885,"children":1886},{},[1887],{"type":420,"value":1888},"You probably want to customize your Visual Studio installation to only include the workloads, components, and language packs you are using. You can specify them as parameters in the winget or chocolatey install command but that's a bit cumbersome. The easiest way is to export your configuration from the Visual Studio installer.",{"type":415,"tag":416,"props":1890,"children":1891},{},[1892],{"type":420,"value":1893},"You can then install Visual Studio with this kind of command:",{"type":415,"tag":665,"props":1895,"children":1897},{"className":1228,"code":1896,"language":248,"meta":401,"style":401},"winget install -e -h --id Microsoft.VisualStudio.2022.Enterprise --silent --override \"--wait --quiet --addProductLang En-us --config .vsconfig\"\n",[1898],{"type":415,"tag":672,"props":1899,"children":1900},{"__ignoreMap":401},[1901],{"type":415,"tag":676,"props":1902,"children":1903},{"class":678,"line":679},[1904,1909,1913,1918,1922,1927,1931,1936,1941,1946,1950,1955,1959,1964,1968,1973],{"type":415,"tag":676,"props":1905,"children":1906},{"style":976},[1907],{"type":420,"value":1908},"winget install ",{"type":415,"tag":676,"props":1910,"children":1911},{"style":981},[1912],{"type":420,"value":1701},{"type":415,"tag":676,"props":1914,"children":1915},{"style":976},[1916],{"type":420,"value":1917},"e ",{"type":415,"tag":676,"props":1919,"children":1920},{"style":981},[1921],{"type":420,"value":1701},{"type":415,"tag":676,"props":1923,"children":1924},{"style":976},[1925],{"type":420,"value":1926},"h ",{"type":415,"tag":676,"props":1928,"children":1929},{"style":981},[1930],{"type":420,"value":1711},{"type":415,"tag":676,"props":1932,"children":1933},{"style":976},[1934],{"type":420,"value":1935},"id Microsoft.VisualStudio.",{"type":415,"tag":676,"props":1937,"children":1938},{"style":1244},[1939],{"type":420,"value":1940},"2022.",{"type":415,"tag":676,"props":1942,"children":1943},{"style":976},[1944],{"type":420,"value":1945},"Enterprise ",{"type":415,"tag":676,"props":1947,"children":1948},{"style":981},[1949],{"type":420,"value":1711},{"type":415,"tag":676,"props":1951,"children":1952},{"style":976},[1953],{"type":420,"value":1954},"silent ",{"type":415,"tag":676,"props":1956,"children":1957},{"style":981},[1958],{"type":420,"value":1711},{"type":415,"tag":676,"props":1960,"children":1961},{"style":976},[1962],{"type":420,"value":1963},"override ",{"type":415,"tag":676,"props":1965,"children":1966},{"style":981},[1967],{"type":420,"value":1721},{"type":415,"tag":676,"props":1969,"children":1970},{"style":689},[1971],{"type":420,"value":1972},"--wait --quiet --addProductLang En-us --config .vsconfig",{"type":415,"tag":676,"props":1974,"children":1975},{"style":981},[1976],{"type":420,"value":1731},{"type":415,"tag":523,"props":1978,"children":1979},{"icon":1641},[1980],{"type":415,"tag":416,"props":1981,"children":1982},{},[1983],{"type":420,"value":1984},"I did not know before trying to automate Visual Studio installation that you could specify parameters to its installer on the command line but that's very useful.",{"type":415,"tag":416,"props":1986,"children":1987},{},[1988],{"type":420,"value":1989},"I don't export Visual Studio settings or extensions as most of them can be synchronized through the personalization account (you just have to sign in to Visual Studio with the same account).",{"type":415,"tag":416,"props":1991,"children":1992},{},[1993,1995,2002],{"type":420,"value":1994},"In a similar way, I use ",{"type":415,"tag":649,"props":1996,"children":1999},{"href":1997,"rel":1998},"https://code.visualstudio.com/docs/editor/settings-sync",[653],[2000],{"type":420,"value":2001},"vscode built-in settings synchronization",{"type":420,"value":2003}," to share my setup (extensions, settings, keybindings) across machines so I don't have to do a custom installation.",{"type":415,"tag":416,"props":2005,"children":2006},{},[2007,2009,2016],{"type":420,"value":2008},"There is a Rider package available on chocolatey but it is not always up-to-date and I prefer to use the JetBrains ToolBox application to manage the installation and update of my JetBrains tools. Unfortunately, JetBrains ToolBox does not currently have a CLI to automate the installation of Rider and other useful .NET tools (there is an ",{"type":415,"tag":649,"props":2010,"children":2013},{"href":2011,"rel":2012},"https://youtrack.jetbrains.com/issue/TBX-653/toolbox-cli",[653],[2014],{"type":420,"value":2015},"issue",{"type":420,"value":2017}," opened though if you want to vote) so I only automated the installation of JetBrains ToolBox and will have to install it Rider manually from it.",{"type":415,"tag":1817,"props":2019,"children":2021},{"id":2020},"tools-i-need",[2022],{"type":420,"value":2023},"Tools I need",{"type":415,"tag":416,"props":2025,"children":2026},{},[2027,2029,2035,2037,2042],{"type":420,"value":2028},"Of course, git is a must-have. I use ",{"type":415,"tag":649,"props":2030,"children":2032},{"href":920,"rel":2031},[653],[2033],{"type":420,"value":2034},"NVM for windows",{"type":420,"value":2036}," to manage multiple installations of node.js on my laptop, and ",{"type":415,"tag":649,"props":2038,"children":2040},{"href":1284,"rel":2039},[653],[2041],{"type":420,"value":362},{"type":420,"value":2043}," is my preferred package manager for Node.js.",{"type":415,"tag":416,"props":2045,"children":2046},{},[2047,2049,2055,2056,2063,2065,2072,2074,2080],{"type":420,"value":2048},"There are 2 shells I like to use (both of them are cross-platform): ",{"type":415,"tag":649,"props":2050,"children":2053},{"href":2051,"rel":2052},"https://docs.microsoft.com/en-us/powershell/scripting/overview",[653],[2054],{"type":420,"value":249},{"type":420,"value":1835},{"type":415,"tag":649,"props":2057,"children":2060},{"href":2058,"rel":2059},"https://www.nushell.sh/",[653],[2061],{"type":420,"value":2062},"Nushell",{"type":420,"value":2064},". I use ",{"type":415,"tag":649,"props":2066,"children":2069},{"href":2067,"rel":2068},"https://ohmyposh.dev/",[653],[2070],{"type":420,"value":2071},"Oh My Posh",{"type":420,"value":2073}," to configure an enhanced prompt for both shells. ",{"type":415,"tag":649,"props":2075,"children":2078},{"href":2076,"rel":2077},"https://docs.microsoft.com/en-us/windows/terminal/",[653],[2079],{"type":420,"value":275},{"type":420,"value":2081}," is my go-to terminal.",{"type":415,"tag":416,"props":2083,"children":2084},{},[2085],{"type":420,"value":2086},"As I work mainly on cloud projects, there are some Azure tools I need on my laptop:",{"type":415,"tag":665,"props":2088,"children":2090},{"className":1228,"code":2089,"language":248,"meta":401,"style":401},"winget install -e -h --id Microsoft.AzureCLI\nwinget install -e -h --id Microsoft.AzureCosmosEmulator\nwinget install -e -h --id Microsoft.AzureDataStudio\nwinget install -e -h --id Microsoft.azure-iot-explorer\nwinget install -e -h --id Microsoft.AzureStorageExplorer\nwinget install -e -h --id Pulumi.Pulumi\nwinget install -e -h --id Microsoft.AzureFunctionsCoreTools\n# Azurite can be installed through vscode extension or as a global npm package\n# pnpm add -g azurite\n",[2091],{"type":415,"tag":672,"props":2092,"children":2093},{"__ignoreMap":401},[2094,2126,2158,2190,2240,2273,2306,2339,2348],{"type":415,"tag":676,"props":2095,"children":2096},{"class":678,"line":679},[2097,2101,2105,2109,2113,2117,2121],{"type":415,"tag":676,"props":2098,"children":2099},{"style":976},[2100],{"type":420,"value":1908},{"type":415,"tag":676,"props":2102,"children":2103},{"style":981},[2104],{"type":420,"value":1701},{"type":415,"tag":676,"props":2106,"children":2107},{"style":976},[2108],{"type":420,"value":1917},{"type":415,"tag":676,"props":2110,"children":2111},{"style":981},[2112],{"type":420,"value":1701},{"type":415,"tag":676,"props":2114,"children":2115},{"style":976},[2116],{"type":420,"value":1926},{"type":415,"tag":676,"props":2118,"children":2119},{"style":981},[2120],{"type":420,"value":1711},{"type":415,"tag":676,"props":2122,"children":2123},{"style":976},[2124],{"type":420,"value":2125},"id Microsoft.AzureCLI\n",{"type":415,"tag":676,"props":2127,"children":2128},{"class":678,"line":622},[2129,2133,2137,2141,2145,2149,2153],{"type":415,"tag":676,"props":2130,"children":2131},{"style":976},[2132],{"type":420,"value":1908},{"type":415,"tag":676,"props":2134,"children":2135},{"style":981},[2136],{"type":420,"value":1701},{"type":415,"tag":676,"props":2138,"children":2139},{"style":976},[2140],{"type":420,"value":1917},{"type":415,"tag":676,"props":2142,"children":2143},{"style":981},[2144],{"type":420,"value":1701},{"type":415,"tag":676,"props":2146,"children":2147},{"style":976},[2148],{"type":420,"value":1926},{"type":415,"tag":676,"props":2150,"children":2151},{"style":981},[2152],{"type":420,"value":1711},{"type":415,"tag":676,"props":2154,"children":2155},{"style":976},[2156],{"type":420,"value":2157},"id Microsoft.AzureCosmosEmulator\n",{"type":415,"tag":676,"props":2159,"children":2160},{"class":678,"line":1368},[2161,2165,2169,2173,2177,2181,2185],{"type":415,"tag":676,"props":2162,"children":2163},{"style":976},[2164],{"type":420,"value":1908},{"type":415,"tag":676,"props":2166,"children":2167},{"style":981},[2168],{"type":420,"value":1701},{"type":415,"tag":676,"props":2170,"children":2171},{"style":976},[2172],{"type":420,"value":1917},{"type":415,"tag":676,"props":2174,"children":2175},{"style":981},[2176],{"type":420,"value":1701},{"type":415,"tag":676,"props":2178,"children":2179},{"style":976},[2180],{"type":420,"value":1926},{"type":415,"tag":676,"props":2182,"children":2183},{"style":981},[2184],{"type":420,"value":1711},{"type":415,"tag":676,"props":2186,"children":2187},{"style":976},[2188],{"type":420,"value":2189},"id Microsoft.AzureDataStudio\n",{"type":415,"tag":676,"props":2191,"children":2192},{"class":678,"line":1742},[2193,2197,2201,2205,2209,2213,2217,2222,2226,2231,2235],{"type":415,"tag":676,"props":2194,"children":2195},{"style":976},[2196],{"type":420,"value":1908},{"type":415,"tag":676,"props":2198,"children":2199},{"style":981},[2200],{"type":420,"value":1701},{"type":415,"tag":676,"props":2202,"children":2203},{"style":976},[2204],{"type":420,"value":1917},{"type":415,"tag":676,"props":2206,"children":2207},{"style":981},[2208],{"type":420,"value":1701},{"type":415,"tag":676,"props":2210,"children":2211},{"style":976},[2212],{"type":420,"value":1926},{"type":415,"tag":676,"props":2214,"children":2215},{"style":981},[2216],{"type":420,"value":1711},{"type":415,"tag":676,"props":2218,"children":2219},{"style":976},[2220],{"type":420,"value":2221},"id Microsoft.azure",{"type":415,"tag":676,"props":2223,"children":2224},{"style":981},[2225],{"type":420,"value":1701},{"type":415,"tag":676,"props":2227,"children":2228},{"style":976},[2229],{"type":420,"value":2230},"iot",{"type":415,"tag":676,"props":2232,"children":2233},{"style":981},[2234],{"type":420,"value":1701},{"type":415,"tag":676,"props":2236,"children":2237},{"style":976},[2238],{"type":420,"value":2239},"explorer\n",{"type":415,"tag":676,"props":2241,"children":2243},{"class":678,"line":2242},5,[2244,2248,2252,2256,2260,2264,2268],{"type":415,"tag":676,"props":2245,"children":2246},{"style":976},[2247],{"type":420,"value":1908},{"type":415,"tag":676,"props":2249,"children":2250},{"style":981},[2251],{"type":420,"value":1701},{"type":415,"tag":676,"props":2253,"children":2254},{"style":976},[2255],{"type":420,"value":1917},{"type":415,"tag":676,"props":2257,"children":2258},{"style":981},[2259],{"type":420,"value":1701},{"type":415,"tag":676,"props":2261,"children":2262},{"style":976},[2263],{"type":420,"value":1926},{"type":415,"tag":676,"props":2265,"children":2266},{"style":981},[2267],{"type":420,"value":1711},{"type":415,"tag":676,"props":2269,"children":2270},{"style":976},[2271],{"type":420,"value":2272},"id Microsoft.AzureStorageExplorer\n",{"type":415,"tag":676,"props":2274,"children":2276},{"class":678,"line":2275},6,[2277,2281,2285,2289,2293,2297,2301],{"type":415,"tag":676,"props":2278,"children":2279},{"style":976},[2280],{"type":420,"value":1908},{"type":415,"tag":676,"props":2282,"children":2283},{"style":981},[2284],{"type":420,"value":1701},{"type":415,"tag":676,"props":2286,"children":2287},{"style":976},[2288],{"type":420,"value":1917},{"type":415,"tag":676,"props":2290,"children":2291},{"style":981},[2292],{"type":420,"value":1701},{"type":415,"tag":676,"props":2294,"children":2295},{"style":976},[2296],{"type":420,"value":1926},{"type":415,"tag":676,"props":2298,"children":2299},{"style":981},[2300],{"type":420,"value":1711},{"type":415,"tag":676,"props":2302,"children":2303},{"style":976},[2304],{"type":420,"value":2305},"id Pulumi.Pulumi\n",{"type":415,"tag":676,"props":2307,"children":2309},{"class":678,"line":2308},7,[2310,2314,2318,2322,2326,2330,2334],{"type":415,"tag":676,"props":2311,"children":2312},{"style":976},[2313],{"type":420,"value":1908},{"type":415,"tag":676,"props":2315,"children":2316},{"style":981},[2317],{"type":420,"value":1701},{"type":415,"tag":676,"props":2319,"children":2320},{"style":976},[2321],{"type":420,"value":1917},{"type":415,"tag":676,"props":2323,"children":2324},{"style":981},[2325],{"type":420,"value":1701},{"type":415,"tag":676,"props":2327,"children":2328},{"style":976},[2329],{"type":420,"value":1926},{"type":415,"tag":676,"props":2331,"children":2332},{"style":981},[2333],{"type":420,"value":1711},{"type":415,"tag":676,"props":2335,"children":2336},{"style":976},[2337],{"type":420,"value":2338},"id Microsoft.AzureFunctionsCoreTools\n",{"type":415,"tag":676,"props":2340,"children":2342},{"class":678,"line":2341},8,[2343],{"type":415,"tag":676,"props":2344,"children":2345},{"style":1685},[2346],{"type":420,"value":2347},"# Azurite can be installed through vscode extension or as a global npm package\n",{"type":415,"tag":676,"props":2349,"children":2351},{"class":678,"line":2350},9,[2352],{"type":415,"tag":676,"props":2353,"children":2354},{"style":1685},[2355],{"type":420,"value":2356},"# pnpm add -g azurite\n",{"type":415,"tag":416,"props":2358,"children":2359},{},[2360,2362,2369,2371,2378],{"type":420,"value":2361},"My script also automates the installation of other tools, not related to software development but that I often use (like ",{"type":415,"tag":649,"props":2363,"children":2366},{"href":2364,"rel":2365},"https://www.7-zip.org/",[653],[2367],{"type":420,"value":2368},"7zip",{"type":420,"value":2370},", ",{"type":415,"tag":649,"props":2372,"children":2375},{"href":2373,"rel":2374},"https://docs.microsoft.com/en-us/windows/powertoys/",[653],[2376],{"type":420,"value":2377},"Microsoft Power Toys",{"type":420,"value":2379}," or just browsers).",{"type":415,"tag":416,"props":2381,"children":2382},{},[2383],{"type":420,"value":2384},"Generally, when the applications I want to install are available in the Microsoft Store, I specify winget to install them from there.",{"type":415,"tag":665,"props":2386,"children":2388},{"className":1228,"code":2387,"language":248,"meta":401,"style":401},"winget install -e -h --id Microsoft.WindowsTerminal -s msstore\n",[2389],{"type":415,"tag":672,"props":2390,"children":2391},{"__ignoreMap":401},[2392],{"type":415,"tag":676,"props":2393,"children":2394},{"class":678,"line":679},[2395,2399,2403,2407,2411,2415,2419,2424,2428],{"type":415,"tag":676,"props":2396,"children":2397},{"style":976},[2398],{"type":420,"value":1908},{"type":415,"tag":676,"props":2400,"children":2401},{"style":981},[2402],{"type":420,"value":1701},{"type":415,"tag":676,"props":2404,"children":2405},{"style":976},[2406],{"type":420,"value":1917},{"type":415,"tag":676,"props":2408,"children":2409},{"style":981},[2410],{"type":420,"value":1701},{"type":415,"tag":676,"props":2412,"children":2413},{"style":976},[2414],{"type":420,"value":1926},{"type":415,"tag":676,"props":2416,"children":2417},{"style":981},[2418],{"type":420,"value":1711},{"type":415,"tag":676,"props":2420,"children":2421},{"style":976},[2422],{"type":420,"value":2423},"id Microsoft.WindowsTerminal ",{"type":415,"tag":676,"props":2425,"children":2426},{"style":981},[2427],{"type":420,"value":1701},{"type":415,"tag":676,"props":2429,"children":2430},{"style":976},[2431],{"type":420,"value":2432},"s msstore\n",{"type":415,"tag":523,"props":2434,"children":2435},{"icon":1641},[2436],{"type":415,"tag":416,"props":2437,"children":2438},{},[2439],{"type":420,"value":2440},"Automating the installation of my developer machine was the opportunity to realize all the tools I was using daily, and which ones were really useful.",{"type":415,"tag":1817,"props":2442,"children":2444},{"id":2443},"tools-i-dont-need",[2445],{"type":420,"value":2446},"Tools I don't need",{"type":415,"tag":416,"props":2448,"children":2449},{},[2450],{"type":420,"value":2451},"Unnecessary applications that come with Windows out of the box are uninstalled using this function:",{"type":415,"tag":665,"props":2453,"children":2455},{"className":1228,"code":2454,"language":248,"meta":401,"style":401},"function removeApp {\n    Param ([string]$appName)\n    Write-Output \"Trying to remove $appName\"\n    Get-AppxPackage $appName -AllUsers | Remove-AppxPackage\n    Get-AppXProvisionedPackage -Online | Where DisplayName -like $appName | Remove-AppxProvisionedPackage -Online\n",[2456],{"type":415,"tag":672,"props":2457,"children":2458},{"__ignoreMap":401},[2459,2478,2512,2543,2580],{"type":415,"tag":676,"props":2460,"children":2461},{"class":678,"line":679},[2462,2468,2473],{"type":415,"tag":676,"props":2463,"children":2465},{"style":2464},"--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA",[2466],{"type":420,"value":2467},"function",{"type":415,"tag":676,"props":2469,"children":2470},{"style":1756},[2471],{"type":420,"value":2472}," removeApp",{"type":415,"tag":676,"props":2474,"children":2475},{"style":981},[2476],{"type":420,"value":2477}," {\n",{"type":415,"tag":676,"props":2479,"children":2480},{"class":678,"line":622},[2481,2487,2492,2497,2502,2507],{"type":415,"tag":676,"props":2482,"children":2484},{"style":2483},"--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF;--shiki-light-font-style:italic;--shiki-default-font-style:italic;--shiki-dark-font-style:italic",[2485],{"type":420,"value":2486},"    Param",{"type":415,"tag":676,"props":2488,"children":2489},{"style":981},[2490],{"type":420,"value":2491}," ([",{"type":415,"tag":676,"props":2493,"children":2494},{"style":2464},[2495],{"type":420,"value":2496},"string",{"type":415,"tag":676,"props":2498,"children":2499},{"style":981},[2500],{"type":420,"value":2501},"]$",{"type":415,"tag":676,"props":2503,"children":2504},{"style":976},[2505],{"type":420,"value":2506},"appName",{"type":415,"tag":676,"props":2508,"children":2509},{"style":981},[2510],{"type":420,"value":2511},")\n",{"type":415,"tag":676,"props":2513,"children":2514},{"class":678,"line":1368},[2515,2520,2525,2530,2535,2539],{"type":415,"tag":676,"props":2516,"children":2517},{"style":1756},[2518],{"type":420,"value":2519},"    Write-Output",{"type":415,"tag":676,"props":2521,"children":2522},{"style":981},[2523],{"type":420,"value":2524}," \"",{"type":415,"tag":676,"props":2526,"children":2527},{"style":689},[2528],{"type":420,"value":2529},"Trying to remove ",{"type":415,"tag":676,"props":2531,"children":2532},{"style":981},[2533],{"type":420,"value":2534},"$",{"type":415,"tag":676,"props":2536,"children":2537},{"style":976},[2538],{"type":420,"value":2506},{"type":415,"tag":676,"props":2540,"children":2541},{"style":981},[2542],{"type":420,"value":1731},{"type":415,"tag":676,"props":2544,"children":2545},{"class":678,"line":1742},[2546,2551,2556,2561,2565,2570,2575],{"type":415,"tag":676,"props":2547,"children":2548},{"style":1756},[2549],{"type":420,"value":2550},"    Get-AppxPackage",{"type":415,"tag":676,"props":2552,"children":2553},{"style":981},[2554],{"type":420,"value":2555}," $",{"type":415,"tag":676,"props":2557,"children":2558},{"style":976},[2559],{"type":420,"value":2560},"appName ",{"type":415,"tag":676,"props":2562,"children":2563},{"style":981},[2564],{"type":420,"value":1701},{"type":415,"tag":676,"props":2566,"children":2567},{"style":976},[2568],{"type":420,"value":2569},"AllUsers ",{"type":415,"tag":676,"props":2571,"children":2572},{"style":981},[2573],{"type":420,"value":2574},"|",{"type":415,"tag":676,"props":2576,"children":2577},{"style":1756},[2578],{"type":420,"value":2579}," Remove-AppxPackage\n",{"type":415,"tag":676,"props":2581,"children":2582},{"class":678,"line":2242},[2583,2588,2593,2598,2602,2607,2612,2617,2621,2625,2629,2634,2638],{"type":415,"tag":676,"props":2584,"children":2585},{"style":1756},[2586],{"type":420,"value":2587},"    Get-AppXProvisionedPackage",{"type":415,"tag":676,"props":2589,"children":2590},{"style":981},[2591],{"type":420,"value":2592}," -",{"type":415,"tag":676,"props":2594,"children":2595},{"style":976},[2596],{"type":420,"value":2597},"Online ",{"type":415,"tag":676,"props":2599,"children":2600},{"style":981},[2601],{"type":420,"value":2574},{"type":415,"tag":676,"props":2603,"children":2604},{"style":2483},[2605],{"type":420,"value":2606}," Where",{"type":415,"tag":676,"props":2608,"children":2609},{"style":976},[2610],{"type":420,"value":2611}," DisplayName ",{"type":415,"tag":676,"props":2613,"children":2614},{"style":981},[2615],{"type":420,"value":2616},"-like",{"type":415,"tag":676,"props":2618,"children":2619},{"style":981},[2620],{"type":420,"value":2555},{"type":415,"tag":676,"props":2622,"children":2623},{"style":976},[2624],{"type":420,"value":2560},{"type":415,"tag":676,"props":2626,"children":2627},{"style":981},[2628],{"type":420,"value":2574},{"type":415,"tag":676,"props":2630,"children":2631},{"style":1756},[2632],{"type":420,"value":2633}," Remove-AppxProvisionedPackage",{"type":415,"tag":676,"props":2635,"children":2636},{"style":981},[2637],{"type":420,"value":2592},{"type":415,"tag":676,"props":2639,"children":2640},{"style":976},[2641],{"type":420,"value":2642},"Online\n",{"type":415,"tag":416,"props":2644,"children":2645},{},[2646,2648,2654,2656,2662],{"type":420,"value":2647},"It allows me to get rid of pre-installed applications like ",{"type":415,"tag":672,"props":2649,"children":2651},{"className":2650},[],[2652],{"type":420,"value":2653},"Facebook",{"type":420,"value":2655},"or ",{"type":415,"tag":672,"props":2657,"children":2659},{"className":2658},[],[2660],{"type":420,"value":2661},"Bing News",{"type":420,"value":1031},{"type":415,"tag":427,"props":2664,"children":2666},{"id":2665},"configuring-software",[2667],{"type":420,"value":2668},"Configuring software",{"type":415,"tag":416,"props":2670,"children":2671},{},[2672],{"type":420,"value":2673},"Installing software is one part, but configuring it is another. As I previously mentioned, for some applications in which you sign in with an account, settings are synchronized so you don't need to transfer the application settings from your previous laptop. For the others, I decided to use symbolic links.",{"type":415,"tag":416,"props":2675,"children":2676},{},[2677],{"type":415,"tag":459,"props":2678,"children":2682},{"alt":2679,"className":2680,"src":2681},"A light bulb that is turned on.",[463,464],"/posts/images/automate_developer_machine_idea.jpg",[],{"type":415,"tag":416,"props":2684,"children":2685},{},[2686],{"type":420,"value":2687},"Here are some examples of settings I wanted to set up on a new laptop:",{"type":415,"tag":538,"props":2689,"children":2690},{},[2691,2703,2714,2725],{"type":415,"tag":542,"props":2692,"children":2693},{},[2694,2696],{"type":420,"value":2695},"my ",{"type":415,"tag":649,"props":2697,"children":2700},{"href":2698,"rel":2699},"https://github.com/TechWatching/dotfiles/blob/main/config/git/.gitconfig",[653],[2701],{"type":420,"value":2702},".gitconfig file",{"type":415,"tag":542,"props":2704,"children":2705},{},[2706,2707],{"type":420,"value":2695},{"type":415,"tag":649,"props":2708,"children":2711},{"href":2709,"rel":2710},"https://github.com/TechWatching/dotfiles/blob/main/config/windowsTerminal/settings.json",[653],[2712],{"type":420,"value":2713},"Windows Terminal settings",{"type":415,"tag":542,"props":2715,"children":2716},{},[2717,2718],{"type":420,"value":2695},{"type":415,"tag":649,"props":2719,"children":2722},{"href":2720,"rel":2721},"https://github.com/TechWatching/dotfiles/blob/main/config/powershell/Microsoft.PowerShell_profile.ps1",[653],[2723],{"type":420,"value":2724},"PowerShell profile",{"type":415,"tag":542,"props":2726,"children":2727},{},[2728,2729,2736],{"type":420,"value":2695},{"type":415,"tag":649,"props":2730,"children":2733},{"href":2731,"rel":2732},"https://github.com/TechWatching/dotfiles/blob/main/config/prompt/.oh-my-posh.omp.json",[653],[2734],{"type":420,"value":2735},"custom prompt configuration",{"type":420,"value":2737}," done using oh my posh",{"type":415,"tag":416,"props":2739,"children":2740},{},[2741,2743,2748],{"type":420,"value":2742},"To create a symbolic link at the Windows Terminal settings file pointing to the settings file in my ",{"type":415,"tag":672,"props":2744,"children":2746},{"className":2745},[],[2747],{"type":420,"value":1628},{"type":420,"value":2749}," cloned repository I can do the following command:",{"type":415,"tag":665,"props":2751,"children":2753},{"className":1228,"code":2752,"language":248,"meta":401,"style":401},"New-Item -ItemType SymbolicLink -Path \"$env:USERPROFILE\\AppData\\Local\\Packages\\Microsoft.WindowsTerminal_8wekyb3d8bbwe\\LocalState\\settings.json\" -Target \"$env:USERPROFILE\\dotfiles\\config\\windowsTerminal\\settings.json\"\"\n",[2754],{"type":415,"tag":672,"props":2755,"children":2756},{"__ignoreMap":401},[2757],{"type":415,"tag":676,"props":2758,"children":2759},{"class":678,"line":679},[2760,2765,2769,2774,2778,2783,2787,2791,2796,2800,2804,2809,2813,2817,2822],{"type":415,"tag":676,"props":2761,"children":2762},{"style":1756},[2763],{"type":420,"value":2764},"New-Item",{"type":415,"tag":676,"props":2766,"children":2767},{"style":981},[2768],{"type":420,"value":2592},{"type":415,"tag":676,"props":2770,"children":2771},{"style":976},[2772],{"type":420,"value":2773},"ItemType SymbolicLink ",{"type":415,"tag":676,"props":2775,"children":2776},{"style":981},[2777],{"type":420,"value":1701},{"type":415,"tag":676,"props":2779,"children":2780},{"style":976},[2781],{"type":420,"value":2782},"Path ",{"type":415,"tag":676,"props":2784,"children":2785},{"style":981},[2786],{"type":420,"value":1783},{"type":415,"tag":676,"props":2788,"children":2789},{"style":976},[2790],{"type":420,"value":1788},{"type":415,"tag":676,"props":2792,"children":2793},{"style":689},[2794],{"type":420,"value":2795},"\\AppData\\Local\\Packages\\Microsoft.WindowsTerminal_8wekyb3d8bbwe\\LocalState\\settings.json",{"type":415,"tag":676,"props":2797,"children":2798},{"style":981},[2799],{"type":420,"value":1721},{"type":415,"tag":676,"props":2801,"children":2802},{"style":981},[2803],{"type":420,"value":2592},{"type":415,"tag":676,"props":2805,"children":2806},{"style":976},[2807],{"type":420,"value":2808},"Target ",{"type":415,"tag":676,"props":2810,"children":2811},{"style":981},[2812],{"type":420,"value":1783},{"type":415,"tag":676,"props":2814,"children":2815},{"style":976},[2816],{"type":420,"value":1788},{"type":415,"tag":676,"props":2818,"children":2819},{"style":689},[2820],{"type":420,"value":2821},"\\dotfiles\\config\\windowsTerminal\\settings.json",{"type":415,"tag":676,"props":2823,"children":2824},{"style":976},[2825],{"type":420,"value":2826},"\"\"\n",{"type":415,"tag":416,"props":2828,"children":2829},{},[2830],{"type":420,"value":2831},"Because I use symbolic links, when I modify the configuration of my Windows Terminal (event through the UI), the settings file in my git repository is the one being modified so I can commit it and push it so that my other machines have the latest version. And it's the same for all my settings files.",{"type":415,"tag":416,"props":2833,"children":2834},{},[2835],{"type":420,"value":2836},"There are others settings in my repository and I will probably continue to add some later.",{"type":415,"tag":427,"props":2838,"children":2840},{"id":2839},"what-i-did-not-automate-yet",[2841],{"type":420,"value":2842},"What I did not automate ... yet!",{"type":415,"tag":416,"props":2844,"children":2845},{},[2846],{"type":420,"value":2847},"There are many things I did not automate yet and that I will do bit by bit.  Nevertheless, I am happy with the current setup. There is much room for improvement but I've already won some time last time I changed my laptop, and that was the goal.",{"type":415,"tag":416,"props":2849,"children":2850},{},[2851,2853,2860,2862,2868],{"type":420,"value":2852},"As I've just said, there are other configurations I would probably need to store in my repository. ",{"type":415,"tag":649,"props":2854,"children":2857},{"href":2855,"rel":2856},"https://docs.microsoft.com/en-us/windows/powertoys",[653],[2858],{"type":420,"value":2859},"Power Toys",{"type":420,"value":2861}," settings might be one of them unless they add a settings sync (issue already opened ",{"type":415,"tag":649,"props":2863,"children":2866},{"href":2864,"rel":2865},"https://github.com/microsoft/PowerToys/issues/3381",[653],[2867],{"type":420,"value":1259},{"type":420,"value":2869},"). It would be better because there are many settings files so only using symbolic links could be cumbersome.",{"type":415,"tag":416,"props":2871,"children":2872},{},[2873,2875,2882],{"type":420,"value":2874},"Most of the software I need is installed by my setup script. One exception is JetBrains products but I hope it will be possible soon. I have some commented lines in my installation script about automating the setup of ",{"type":415,"tag":649,"props":2876,"children":2879},{"href":2877,"rel":2878},"https://docs.microsoft.com/en-us/windows/wsl/install",[653],[2880],{"type":420,"value":2881},"WSL2",{"type":420,"value":2883}," and docker (well installation of Rancher Desktop to be more precise as a replacement of Docker Desktop due to its new license model) that required some windows features to be installed.  I think these lines should work with some adjustments, it's just that I did that manually last time and did not take the time to test the corresponding commands properly.",{"type":415,"tag":416,"props":2885,"children":2886},{},[2887],{"type":420,"value":2888},"There are also some limitations to my current approach to installing my developer machine:",{"type":415,"tag":538,"props":2890,"children":2891},{},[2892,2906,2911],{"type":415,"tag":542,"props":2893,"children":2894},{},[2895,2897,2904],{"type":420,"value":2896},"As everything is contained in a public GitHub repository, I can't keep some files or secrets private obviously (it could be useful to configure a new machine to ",{"type":415,"tag":649,"props":2898,"children":2901},{"href":2899,"rel":2900},"https://docs.github.com/en/authentication/managing-commit-signature-verification/signing-commits",[653],[2902],{"type":420,"value":2903},"sign commits",{"type":420,"value":2905}," for instance)",{"type":415,"tag":542,"props":2907,"children":2908},{},[2909],{"type":420,"value":2910},"The installation script is not idempotent so it will try to re-install and re-configure everything if I re-run it (not a big deal as I mainly use it to install a new machine, but it would be nice to be able to just re-run it to get on an existing installation all the latest improvements I made on another laptop)",{"type":415,"tag":542,"props":2912,"children":2913},{},[2914],{"type":420,"value":2915},"I did not set up anything to handle multiple configurations (one for my personal laptop and one for my professional laptop for example)",{"type":415,"tag":416,"props":2917,"children":2918},{},[2919,2921,2928],{"type":420,"value":2920},"I think the tool ",{"type":415,"tag":649,"props":2922,"children":2925},{"href":2923,"rel":2924},"https://www.chezmoi.io/",[653],[2926],{"type":420,"value":2927},"chezmoi",{"type":420,"value":2929}," might help to solve some of these limitations. Maybe one day I'll take the time to dig a little deeper to see if I can improve the whole process.",{"type":415,"tag":427,"props":2931,"children":2933},{"id":2932},"to-conclude",[2934],{"type":420,"value":2935},"To conclude",{"type":415,"tag":416,"props":2937,"children":2938},{},[2939,2941,2947],{"type":420,"value":2940},"You can find the repository with all the code I use to automate my installation ",{"type":415,"tag":649,"props":2942,"children":2945},{"href":2943,"rel":2944},"https://github.com/TechWatching/dotfiles",[653],[2946],{"type":420,"value":1259},{"type":420,"value":1031},{"type":415,"tag":416,"props":2949,"children":2950},{},[2951],{"type":420,"value":2952},"Automating my machine installation was not that fun, but I learned lots of things while doing it about package managers, windows, symbolic links, PowerShell... And in the end, it is very satisfying when everything starts to install automatically and you find a familiar environment on a new laptop.",{"type":415,"tag":416,"props":2954,"children":2955},{},[2956],{"type":420,"value":2957},"Whether you adopt this approach or another to automate the setup of your development machine, I think it's an important thing to do. It does not have to be complex, and you don't need to automate everything. But you should probably at least use a package manager for your software installations, have a list somewhere of the most useful tools you need, and keep a copy of the configuration files of your most important tools.",{"type":415,"tag":416,"props":2959,"children":2960},{},[2961,2963,2970],{"type":420,"value":2962},"This article is part of the ",{"type":415,"tag":649,"props":2964,"children":2967},{"href":2965,"rel":2966},"https://townhall.hashnode.com/4-articles-in-4-weeks-hashnode-writing-contest",[653],[2968],{"type":420,"value":2969},"4 articles in 4 weeks Hashnode writing contest",{"type":420,"value":1031},{"type":415,"tag":416,"props":2972,"children":2973},{},[2974],{"type":420,"value":2975},"Happy learning.",{"type":415,"tag":811,"props":2977,"children":2978},{},[2979],{"type":420,"value":815},{"title":401,"searchDepth":622,"depth":622,"links":2981},[2982,2983,2984,2990,2991,2992],{"id":1469,"depth":622,"text":1472},{"id":1522,"depth":622,"text":1525},{"id":1812,"depth":622,"text":1815,"children":2985},[2986,2987,2988,2989],{"id":1819,"depth":1368,"text":1822},{"id":1866,"depth":1368,"text":1869},{"id":2020,"depth":1368,"text":2023},{"id":2443,"depth":1368,"text":2446},{"id":2665,"depth":622,"text":2668},{"id":2839,"depth":622,"text":2842},{"id":2932,"depth":622,"text":2935},"content:1.posts:42.automate-developer-machine.md","1.posts/42.automate-developer-machine.md",{"_path":70,"_dir":399,"_draft":400,"_partial":400,"_locale":401,"title":69,"description":2996,"lead":2997,"date":2998,"image":2999,"badge":3001,"tags":3003,"body":3004,"_type":628,"_id":4344,"_source":630,"_file":4345,"_extension":632},"In my previous articles about winget I talked about installing packages but I did not talk about producing packages for Windows Package Manager. So let's set things right.","Automate the upgrade of a winget package with GitHub Actions and Winget Create.","2021-08-25T00:00:00.000Z",{"src":3000},"/images/surface_2.jpg",{"label":3002},"Development",[293,304,296,206,243,307],{"type":412,"children":3005,"toc":4322},[3006,3020,3026,3040,3049,3060,3065,3071,3077,3105,3134,3146,3159,3170,3183,3194,3199,3205,3219,3224,3230,3236,3245,3250,3255,3261,3271,3285,3294,3308,3317,3330,3336,3356,3374,3379,3530,3535,3548,3553,3621,3641,3740,3752,3807,3812,3958,3967,3986,3995,4000,4009,4015,4028,4257,4262,4271,4277,4282,4287,4318],{"type":415,"tag":416,"props":3007,"children":3008},{},[3009,3011,3018],{"type":420,"value":3010},"In my ",{"type":415,"tag":649,"props":3012,"children":3015},{"href":3013,"rel":3014},"https://www.techwatching.dev/tags/winget",[653],[3016],{"type":420,"value":3017},"previous articles about winget",{"type":420,"value":3019}," I talked about installing packages but I did not talk about producing packages for Windows Package Manager. So let's set things right.",{"type":415,"tag":427,"props":3021,"children":3023},{"id":3022},"about-winget-packages",[3024],{"type":420,"value":3025},"About winget packages",{"type":415,"tag":416,"props":3027,"children":3028},{},[3029,3031,3038],{"type":420,"value":3030},"Windows Package Manager allows you to search and install applications that are referenced by the sources you have configured to be used by the winget tool. Sources are repositories that list applications that can be installed by winget and the data needed for them to be installed (in the form of a manifest file containing information such as the installer location of a package for instance). The default source is the ",{"type":415,"tag":649,"props":3032,"children":3035},{"href":3033,"rel":3034},"https://github.com/microsoft/winget-pkgs",[653],[3036],{"type":420,"value":3037},"Windows Package Manager Community Repository",{"type":420,"value":3039}," which is a public GitHub repository where everyone can submit their application package manifest to make an application available for installation to Windows Package Manager users.",{"type":415,"tag":416,"props":3041,"children":3042},{},[3043],{"type":415,"tag":459,"props":3044,"children":3048},{"alt":3045,"className":3046,"src":3047},"Windows Package Manager Community repository readme.",[463,464],"/posts/images/wingetcreate_package_repository.png",[],{"type":415,"tag":416,"props":3050,"children":3051},{},[3052,3054],{"type":420,"value":3053},"Once you know that, if you are the developer of an application you want to distribute on Windows through the Windows Package Manager you have to create a manifest for your application and publish it through a Pull Request on the Windows Package Manager Community Repository. And each time you release a new version of your application, you have to update your app manifest with the information of your new package version (new version number, new installer location...) and create a PR to the Windows Package Manager Community Repository with this updated version of your manifest. For more details, you can have a look at the official ",{"type":415,"tag":649,"props":3055,"children":3058},{"href":3056,"rel":3057},"https://docs.microsoft.com/en-us/windows/package-manager/package/",[653],[3059],{"type":420,"value":1386},{"type":415,"tag":416,"props":3061,"children":3062},{},[3063],{"type":420,"value":3064},"As a package creator, you probably do not want to create and update this app manifest manually. Luckily for you, there is a tool to do that for you.",{"type":415,"tag":427,"props":3066,"children":3068},{"id":3067},"wingetcreate-to-the-rescue",[3069],{"type":420,"value":3070},"WingetCreate to the rescue",{"type":415,"tag":1817,"props":3072,"children":3074},{"id":3073},"introducing-wingetcreate",[3075],{"type":420,"value":3076},"Introducing WingetCreate",{"type":415,"tag":416,"props":3078,"children":3079},{},[3080,3087,3089,3096,3098,3104],{"type":415,"tag":649,"props":3081,"children":3084},{"href":3082,"rel":3083},"https://github.com/microsoft/winget-create",[653],[3085],{"type":420,"value":3086},"Windows Package Manager Manifest Creator",{"type":420,"value":3088}," aka WingetCreate is a tool \"designed to help generate or update manifest files for the Community repo\" (quoting the readme of WingetCreate repository). At the time of writing it is still in preview but you can already use it to help you with your manifest files. You can download the installer from ",{"type":415,"tag":649,"props":3090,"children":3093},{"href":3091,"rel":3092},"https://aka.ms/wingetcreate/latest",[653],[3094],{"type":420,"value":3095},"this link",{"type":420,"value":3097}," but of course, it is available from winget: ",{"type":415,"tag":672,"props":3099,"children":3101},{"className":3100},[],[3102],{"type":420,"value":3103},"winget install wingetcreate",{"type":420,"value":1031},{"type":415,"tag":416,"props":3106,"children":3107},{},[3108,3110,3117,3118,3125,3126,3133],{"type":420,"value":3109},"The main commands are ",{"type":415,"tag":649,"props":3111,"children":3114},{"href":3112,"rel":3113},"https://github.com/microsoft/winget-create/blob/main/doc/new.md",[653],[3115],{"type":420,"value":3116},"New",{"type":420,"value":2370},{"type":415,"tag":649,"props":3119,"children":3122},{"href":3120,"rel":3121},"https://github.com/microsoft/winget-create/blob/main/doc/update.md",[653],[3123],{"type":420,"value":3124},"Update",{"type":420,"value":1835},{"type":415,"tag":649,"props":3127,"children":3130},{"href":3128,"rel":3129},"https://github.com/microsoft/winget-create/blob/main/doc/submit.md",[653],[3131],{"type":420,"value":3132},"Submit",{"type":420,"value":1031},{"type":415,"tag":1817,"props":3135,"children":3137},{"id":3136},"the-new-command",[3138,3139,3144],{"type":420,"value":1605},{"type":415,"tag":672,"props":3140,"children":3142},{"className":3141},[],[3143],{"type":420,"value":3116},{"type":420,"value":3145}," command",{"type":415,"tag":416,"props":3147,"children":3148},{},[3149,3151,3157],{"type":420,"value":3150},"It allows you to create a new manifest from scratch. If you don't know where to start to deal with manifest files it is a nice way of getting started. Yet having a look at existing manifests in the ",{"type":415,"tag":649,"props":3152,"children":3154},{"href":3033,"rel":3153},[653],[3155],{"type":420,"value":3156},"winget community repository",{"type":420,"value":3158}," can be sometimes more efficient.",{"type":415,"tag":1817,"props":3160,"children":3162},{"id":3161},"the-update-command",[3163,3164,3169],{"type":420,"value":1605},{"type":415,"tag":672,"props":3165,"children":3167},{"className":3166},[],[3168],{"type":420,"value":3124},{"type":420,"value":3145},{"type":415,"tag":416,"props":3171,"children":3172},{},[3173,3175,3181],{"type":420,"value":3174},"It allows you to update an existing manifest, that is to say, to create an updated version of your manifest when you have released a new version of your application (so new version number and new installer URL). You can use this command to ",{"type":415,"tag":672,"props":3176,"children":3178},{"className":3177},[],[3179],{"type":420,"value":3180},"submit",{"type":420,"value":3182}," your updated package to the Windows Package Manager Community Repository. In my opinion, it is the most useful command from WingetCreate as it can be easily be integrated into a build pipeline to publish your installer.",{"type":415,"tag":1817,"props":3184,"children":3186},{"id":3185},"the-submit-command",[3187,3188,3193],{"type":420,"value":1605},{"type":415,"tag":672,"props":3189,"children":3191},{"className":3190},[],[3192],{"type":420,"value":3132},{"type":420,"value":3145},{"type":415,"tag":416,"props":3195,"children":3196},{},[3197],{"type":420,"value":3198},"It allows you to submit an existing manifest (you created earlier on disk with the create or update command) to the Windows Package Manager Community Repository automatically. Basically, what it does is that it uses the GitHub personal access token you give it to create a Pull Request with your manifest in this repository.",{"type":415,"tag":1817,"props":3200,"children":3202},{"id":3201},"what-else",[3203],{"type":420,"value":3204},"What else?",{"type":415,"tag":416,"props":3206,"children":3207},{},[3208,3210,3217],{"type":420,"value":3209},"If you look at the ",{"type":415,"tag":649,"props":3211,"children":3214},{"href":3212,"rel":3213},"https://github.com/microsoft/winget-create/blob/main/doc/settings.md",[653],[3215],{"type":420,"value":3216},"settings command",{"type":420,"value":3218}," you will see that you can specify the name of the GitHub repository to target for your package submission. This is interesting if you want to host a private source for winget available to your organization only where you will publish applications related to your business needs and that you don't want to make available publicly.",{"type":415,"tag":416,"props":3220,"children":3221},{},[3222],{"type":420,"value":3223},"WingetCreate is a really helpful tool to create, update and validate a manifest for your winget package. Still, you probably don't want to manually run WingetCreate each time you release a new package version. So let's see how to automate that with GitHub Actions.",{"type":415,"tag":427,"props":3225,"children":3227},{"id":3226},"automating-your-app-manifest-upgrade-with-github-actions",[3228],{"type":420,"value":3229},"Automating your app manifest upgrade with GitHub Actions",{"type":415,"tag":1817,"props":3231,"children":3233},{"id":3232},"why-using-github-actions-to-demonstrate-the-automation-of-app-manifests-upgrades",[3234],{"type":420,"value":3235},"Why using GitHub Actions to demonstrate the automation of app manifests upgrades?",{"type":415,"tag":416,"props":3237,"children":3238},{},[3239],{"type":415,"tag":459,"props":3240,"children":3244},{"alt":3241,"className":3242,"src":3243},"GitHub Actions documentation.",[463,464],"/posts/images/wingetcreate_githubactions.png",[],{"type":415,"tag":416,"props":3246,"children":3247},{},[3248],{"type":420,"value":3249},"In my daily work, Azure Pipelines are the pipelines I used to do CI/CD and they are great. Currently, they offer more functionalities than GitHub Actions and as the code I develop is hosted in Azure Repos it makes more sense to use the Azure DevOps built-in CI/CD tool than something else (although Azure DevOps does not enforce at all you to choose their tools). However there is already in WingetCreate's readme a section with a link to an example about using WingetCreate with Azure Pipelines, but there is no example with GitHub Actions.",{"type":415,"tag":416,"props":3251,"children":3252},{},[3253],{"type":420,"value":3254},"Moreover, I think many applications that are available or will want to be available as a winget package are open source applications whose code are hosted in a GitHub repository and that are already using GitHub Actions for their CI/CD. So I thought it could be useful to have an example of using WingetCreate with GitHub Actions, especially as GitHub has this concept of \"releases\".",{"type":415,"tag":1817,"props":3256,"children":3258},{"id":3257},"an-interesting-use-case-for-with-nushell",[3259],{"type":420,"value":3260},"An interesting use case for with Nushell",{"type":415,"tag":416,"props":3262,"children":3263},{},[3264,3269],{"type":415,"tag":649,"props":3265,"children":3267},{"href":2058,"rel":3266},[653],[3268],{"type":420,"value":2062},{"type":420,"value":3270}," is a cross-platform shell written in Rust. Nushell's developers took the best of existing shells (like the structured data approach from PowerShell) and created a shell that feels modern, easy-to-use, and very useful in my opinion.",{"type":415,"tag":416,"props":3272,"children":3273},{},[3274,3276,3283],{"type":420,"value":3275},"There was a ",{"type":415,"tag":649,"props":3277,"children":3280},{"href":3278,"rel":3279},"https://github.com/nushell/nushell/issues/1859",[653],[3281],{"type":420,"value":3282},"GitHub issue",{"type":420,"value":3284}," to support the new official Windows package manager so I though it was the opportunity to contribute to Nushell. Contributing to this project was something that I had not been able to do yet because I did not know Rust, writing CI/CD pipelines however is something I can do.",{"type":415,"tag":416,"props":3286,"children":3287},{},[3288],{"type":415,"tag":459,"props":3289,"children":3293},{"alt":3290,"className":3291,"src":3292},"Nushell documentation page.",[463,464],"/posts/images/wingetcreate_nushell.png",[],{"type":415,"tag":416,"props":3295,"children":3296},{},[3297,3299,3306],{"type":420,"value":3298},"Nushell already uses GitHub Actions for its continuous integration and to create releases. If you are not familiar with GitHub releases you can read the ",{"type":415,"tag":649,"props":3300,"children":3303},{"href":3301,"rel":3302},"https://docs.github.com/en/github/administering-a-repository/releasing-projects-on-github/about-releases",[653],[3304],{"type":420,"value":3305},"official documentation",{"type":420,"value":3307}," but basically a release is a version of your software (corresponding to a git tag in your repository) that you make available with release notes and binaries files.",{"type":415,"tag":416,"props":3309,"children":3310},{},[3311],{"type":415,"tag":459,"props":3312,"children":3316},{"alt":3313,"className":3314,"src":3315},"Nushell release page in GitHub.",[463,464],"/posts/images/wingetcreate_release.png",[],{"type":415,"tag":416,"props":3318,"children":3319},{},[3320,3322,3328],{"type":420,"value":3321},"Therefore, the idea was to update Nushell manifest with the latest version of Nushell using ",{"type":415,"tag":672,"props":3323,"children":3325},{"className":3324},[],[3326],{"type":420,"value":3327},"WingetCreate",{"type":420,"value":3329}," each time a new release of Nushell is published.",{"type":415,"tag":1817,"props":3331,"children":3333},{"id":3332},"triggering-a-new-workflow-from-a-release-event",[3334],{"type":420,"value":3335},"Triggering a new workflow from a release event",{"type":415,"tag":416,"props":3337,"children":3338},{},[3339,3341,3347,3349,3354],{"type":420,"value":3340},"Automating the app manifest upgrade of Nushell just meant creating a ",{"type":415,"tag":672,"props":3342,"children":3344},{"className":3343},[],[3345],{"type":420,"value":3346},"job",{"type":420,"value":3348}," in a GitHub Actions workflow that would call ",{"type":415,"tag":672,"props":3350,"children":3352},{"className":3351},[],[3353],{"type":420,"value":3327},{"type":420,"value":3355}," with the new version number and the new installer URL.",{"type":415,"tag":416,"props":3357,"children":3358},{},[3359,3361,3366,3368,3373],{"type":420,"value":3360},"I first wanted to modify the existing Nushell GitHub Actions workflow that was creating the releases by adding a new ",{"type":415,"tag":672,"props":3362,"children":3364},{"className":3363},[],[3365],{"type":420,"value":3346},{"type":420,"value":3367}," at the end of the workflow just after the release was created. Well this is was a bad idea, I pushed this change and during the next release of Nushell the workflow failed because I did not pay attention that the workflow was creating releases in draft, so the installer URL of the new version did not exist when my job called ",{"type":415,"tag":672,"props":3369,"children":3371},{"className":3370},[],[3372],{"type":420,"value":3327},{"type":420,"value":1031},{"type":415,"tag":416,"props":3375,"children":3376},{},[3377],{"type":420,"value":3378},"Because of that, I decided to create a separate workflow that would be triggered each time a Nushell release is published. In Nushell this is done manually (passing from draft to release) but even if it were done automatically by the release workflow I think it is a better idea to have a specific workflow triggered by the publication of a release.",{"type":415,"tag":665,"props":3380,"children":3384},{"className":3381,"code":3382,"language":3383,"meta":401,"style":401},"language-yml shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","name: Submit Nushell package to Windows Package Manager Community Repository \n\non:\n  release:\n    types: [published]\n\njobs:\n\n  winget:\n    name: Publish winget package\n","yml",[3385],{"type":415,"tag":672,"props":3386,"children":3387},{"__ignoreMap":401},[3388,3412,3421,3435,3447,3474,3481,3493,3500,3512],{"type":415,"tag":676,"props":3389,"children":3390},{"class":678,"line":679},[3391,3397,3402,3407],{"type":415,"tag":676,"props":3392,"children":3394},{"style":3393},"--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178",[3395],{"type":420,"value":3396},"name",{"type":415,"tag":676,"props":3398,"children":3399},{"style":981},[3400],{"type":420,"value":3401},":",{"type":415,"tag":676,"props":3403,"children":3404},{"style":689},[3405],{"type":420,"value":3406}," Submit Nushell package to Windows Package Manager Community Repository",{"type":415,"tag":676,"props":3408,"children":3409},{"style":976},[3410],{"type":420,"value":3411}," \n",{"type":415,"tag":676,"props":3413,"children":3414},{"class":678,"line":622},[3415],{"type":415,"tag":676,"props":3416,"children":3418},{"emptyLinePlaceholder":3417},true,[3419],{"type":420,"value":3420},"\n",{"type":415,"tag":676,"props":3422,"children":3423},{"class":678,"line":1368},[3424,3430],{"type":415,"tag":676,"props":3425,"children":3427},{"style":3426},"--shiki-light:#FF5370;--shiki-default:#FF9CAC;--shiki-dark:#FF9CAC",[3428],{"type":420,"value":3429},"on",{"type":415,"tag":676,"props":3431,"children":3432},{"style":981},[3433],{"type":420,"value":3434},":\n",{"type":415,"tag":676,"props":3436,"children":3437},{"class":678,"line":1742},[3438,3443],{"type":415,"tag":676,"props":3439,"children":3440},{"style":3393},[3441],{"type":420,"value":3442},"  release",{"type":415,"tag":676,"props":3444,"children":3445},{"style":981},[3446],{"type":420,"value":3434},{"type":415,"tag":676,"props":3448,"children":3449},{"class":678,"line":2242},[3450,3455,3459,3464,3469],{"type":415,"tag":676,"props":3451,"children":3452},{"style":3393},[3453],{"type":420,"value":3454},"    types",{"type":415,"tag":676,"props":3456,"children":3457},{"style":981},[3458],{"type":420,"value":3401},{"type":415,"tag":676,"props":3460,"children":3461},{"style":981},[3462],{"type":420,"value":3463}," [",{"type":415,"tag":676,"props":3465,"children":3466},{"style":689},[3467],{"type":420,"value":3468},"published",{"type":415,"tag":676,"props":3470,"children":3471},{"style":981},[3472],{"type":420,"value":3473},"]\n",{"type":415,"tag":676,"props":3475,"children":3476},{"class":678,"line":2275},[3477],{"type":415,"tag":676,"props":3478,"children":3479},{"emptyLinePlaceholder":3417},[3480],{"type":420,"value":3420},{"type":415,"tag":676,"props":3482,"children":3483},{"class":678,"line":2308},[3484,3489],{"type":415,"tag":676,"props":3485,"children":3486},{"style":3393},[3487],{"type":420,"value":3488},"jobs",{"type":415,"tag":676,"props":3490,"children":3491},{"style":981},[3492],{"type":420,"value":3434},{"type":415,"tag":676,"props":3494,"children":3495},{"class":678,"line":2341},[3496],{"type":415,"tag":676,"props":3497,"children":3498},{"emptyLinePlaceholder":3417},[3499],{"type":420,"value":3420},{"type":415,"tag":676,"props":3501,"children":3502},{"class":678,"line":2350},[3503,3508],{"type":415,"tag":676,"props":3504,"children":3505},{"style":3393},[3506],{"type":420,"value":3507},"  winget",{"type":415,"tag":676,"props":3509,"children":3510},{"style":981},[3511],{"type":420,"value":3434},{"type":415,"tag":676,"props":3513,"children":3515},{"class":678,"line":3514},10,[3516,3521,3525],{"type":415,"tag":676,"props":3517,"children":3518},{"style":3393},[3519],{"type":420,"value":3520},"    name",{"type":415,"tag":676,"props":3522,"children":3523},{"style":981},[3524],{"type":420,"value":3401},{"type":415,"tag":676,"props":3526,"children":3527},{"style":689},[3528],{"type":420,"value":3529}," Publish winget package\n",{"type":415,"tag":416,"props":3531,"children":3532},{},[3533],{"type":420,"value":3534},"I like how it is possible with GitHub Actions to trigger on many different GitHub events. It is something that seems more limited in Azure Pipelines.",{"type":415,"tag":1817,"props":3536,"children":3538},{"id":3537},"calling-wingetcreate-from-a-github-actions-workflow",[3539,3541,3546],{"type":420,"value":3540},"Calling ",{"type":415,"tag":672,"props":3542,"children":3544},{"className":3543},[],[3545],{"type":420,"value":3327},{"type":420,"value":3547}," from a GitHub Actions workflow.",{"type":415,"tag":416,"props":3549,"children":3550},{},[3551],{"type":420,"value":3552},"Windows Package Manager Manifest Creator needs to be run in windows so we need to specify that in the job that will submit a new version of Nushell package to Windows Package Manager Community Repository:",{"type":415,"tag":665,"props":3554,"children":3556},{"className":3381,"code":3555,"language":3383,"meta":401,"style":401},"jobs:\n\n  winget:\n    name: Publish winget package\n    runs-on: windows-latest\n",[3557],{"type":415,"tag":672,"props":3558,"children":3559},{"__ignoreMap":401},[3560,3571,3578,3589,3604],{"type":415,"tag":676,"props":3561,"children":3562},{"class":678,"line":679},[3563,3567],{"type":415,"tag":676,"props":3564,"children":3565},{"style":3393},[3566],{"type":420,"value":3488},{"type":415,"tag":676,"props":3568,"children":3569},{"style":981},[3570],{"type":420,"value":3434},{"type":415,"tag":676,"props":3572,"children":3573},{"class":678,"line":622},[3574],{"type":415,"tag":676,"props":3575,"children":3576},{"emptyLinePlaceholder":3417},[3577],{"type":420,"value":3420},{"type":415,"tag":676,"props":3579,"children":3580},{"class":678,"line":1368},[3581,3585],{"type":415,"tag":676,"props":3582,"children":3583},{"style":3393},[3584],{"type":420,"value":3507},{"type":415,"tag":676,"props":3586,"children":3587},{"style":981},[3588],{"type":420,"value":3434},{"type":415,"tag":676,"props":3590,"children":3591},{"class":678,"line":1742},[3592,3596,3600],{"type":415,"tag":676,"props":3593,"children":3594},{"style":3393},[3595],{"type":420,"value":3520},{"type":415,"tag":676,"props":3597,"children":3598},{"style":981},[3599],{"type":420,"value":3401},{"type":415,"tag":676,"props":3601,"children":3602},{"style":689},[3603],{"type":420,"value":3529},{"type":415,"tag":676,"props":3605,"children":3606},{"class":678,"line":2242},[3607,3612,3616],{"type":415,"tag":676,"props":3608,"children":3609},{"style":3393},[3610],{"type":420,"value":3611},"    runs-on",{"type":415,"tag":676,"props":3613,"children":3614},{"style":981},[3615],{"type":420,"value":3401},{"type":415,"tag":676,"props":3617,"children":3618},{"style":689},[3619],{"type":420,"value":3620}," windows-latest\n",{"type":415,"tag":416,"props":3622,"children":3623},{},[3624,3626,3631,3633,3639],{"type":420,"value":3625},"This job will only contain one step that is the execution of the commands to call ",{"type":415,"tag":672,"props":3627,"children":3629},{"className":3628},[],[3630],{"type":420,"value":3327},{"type":420,"value":3632},". These commands will be in PowerShell as this is the default runner (",{"type":415,"tag":672,"props":3634,"children":3636},{"className":3635},[],[3637],{"type":420,"value":3638},"pwsh",{"type":420,"value":3640},") in a windows job.",{"type":415,"tag":665,"props":3642,"children":3644},{"className":3381,"code":3643,"language":3383,"meta":401,"style":401},"  winget:\n    name: Publish winget package\n    runs-on: windows-latest\n    steps:\n      - name: Submit package to Windows Package Manager Community Repository\n        run: |\n\n",[3645],{"type":415,"tag":672,"props":3646,"children":3647},{"__ignoreMap":401},[3648,3659,3674,3689,3701,3723],{"type":415,"tag":676,"props":3649,"children":3650},{"class":678,"line":679},[3651,3655],{"type":415,"tag":676,"props":3652,"children":3653},{"style":3393},[3654],{"type":420,"value":3507},{"type":415,"tag":676,"props":3656,"children":3657},{"style":981},[3658],{"type":420,"value":3434},{"type":415,"tag":676,"props":3660,"children":3661},{"class":678,"line":622},[3662,3666,3670],{"type":415,"tag":676,"props":3663,"children":3664},{"style":3393},[3665],{"type":420,"value":3520},{"type":415,"tag":676,"props":3667,"children":3668},{"style":981},[3669],{"type":420,"value":3401},{"type":415,"tag":676,"props":3671,"children":3672},{"style":689},[3673],{"type":420,"value":3529},{"type":415,"tag":676,"props":3675,"children":3676},{"class":678,"line":1368},[3677,3681,3685],{"type":415,"tag":676,"props":3678,"children":3679},{"style":3393},[3680],{"type":420,"value":3611},{"type":415,"tag":676,"props":3682,"children":3683},{"style":981},[3684],{"type":420,"value":3401},{"type":415,"tag":676,"props":3686,"children":3687},{"style":689},[3688],{"type":420,"value":3620},{"type":415,"tag":676,"props":3690,"children":3691},{"class":678,"line":1742},[3692,3697],{"type":415,"tag":676,"props":3693,"children":3694},{"style":3393},[3695],{"type":420,"value":3696},"    steps",{"type":415,"tag":676,"props":3698,"children":3699},{"style":981},[3700],{"type":420,"value":3434},{"type":415,"tag":676,"props":3702,"children":3703},{"class":678,"line":2242},[3704,3709,3714,3718],{"type":415,"tag":676,"props":3705,"children":3706},{"style":981},[3707],{"type":420,"value":3708},"      -",{"type":415,"tag":676,"props":3710,"children":3711},{"style":3393},[3712],{"type":420,"value":3713}," name",{"type":415,"tag":676,"props":3715,"children":3716},{"style":981},[3717],{"type":420,"value":3401},{"type":415,"tag":676,"props":3719,"children":3720},{"style":689},[3721],{"type":420,"value":3722}," Submit package to Windows Package Manager Community Repository\n",{"type":415,"tag":676,"props":3724,"children":3725},{"class":678,"line":2275},[3726,3731,3735],{"type":415,"tag":676,"props":3727,"children":3728},{"style":3393},[3729],{"type":420,"value":3730},"        run",{"type":415,"tag":676,"props":3732,"children":3733},{"style":981},[3734],{"type":420,"value":3401},{"type":415,"tag":676,"props":3736,"children":3737},{"style":2483},[3738],{"type":420,"value":3739}," |\n",{"type":415,"tag":416,"props":3741,"children":3742},{},[3743,3745,3750],{"type":420,"value":3744},"First, we need to download the latest version of ",{"type":415,"tag":672,"props":3746,"children":3748},{"className":3747},[],[3749],{"type":420,"value":3327},{"type":420,"value":3751}," by using the following command :",{"type":415,"tag":665,"props":3753,"children":3755},{"className":1228,"code":3754,"language":248,"meta":401,"style":401},"iwr https://aka.ms/wingetcreate/latest -OutFile wingetcreate.exe\n",[3756],{"type":415,"tag":672,"props":3757,"children":3758},{"__ignoreMap":401},[3759],{"type":415,"tag":676,"props":3760,"children":3761},{"class":678,"line":679},[3762,3767,3771,3776,3780,3784,3788,3793,3797,3802],{"type":415,"tag":676,"props":3763,"children":3764},{"style":976},[3765],{"type":420,"value":3766},"iwr https:",{"type":415,"tag":676,"props":3768,"children":3769},{"style":981},[3770],{"type":420,"value":1753},{"type":415,"tag":676,"props":3772,"children":3773},{"style":976},[3774],{"type":420,"value":3775},"aka.ms",{"type":415,"tag":676,"props":3777,"children":3778},{"style":981},[3779],{"type":420,"value":1764},{"type":415,"tag":676,"props":3781,"children":3782},{"style":976},[3783],{"type":420,"value":304},{"type":415,"tag":676,"props":3785,"children":3786},{"style":981},[3787],{"type":420,"value":1764},{"type":415,"tag":676,"props":3789,"children":3790},{"style":976},[3791],{"type":420,"value":3792},"latest ",{"type":415,"tag":676,"props":3794,"children":3795},{"style":981},[3796],{"type":420,"value":1701},{"type":415,"tag":676,"props":3798,"children":3799},{"style":976},[3800],{"type":420,"value":3801},"OutFile ",{"type":415,"tag":676,"props":3803,"children":3804},{"style":1756},[3805],{"type":420,"value":3806},"wingetcreate.exe\n",{"type":415,"tag":416,"props":3808,"children":3809},{},[3810],{"type":420,"value":3811},"Second, we want to retrieve the version number and the installer URL of the new package. These 2 pieces of information will be needed as parameters to the WingetCreate update command. We can find these in the GitHub context which contains the release event that triggered the workflow. We are using these 2 lines of PowerShell to get assets associated with the release and filter on the msi file which is the Windows installer of Nushell.",{"type":415,"tag":665,"props":3813,"children":3815},{"className":1228,"code":3814,"language":248,"meta":401,"style":401},"$github = Get-Content '${{ github.event_path }}' | ConvertFrom-Json\n$installerUrl = $github.release.assets | Where-Object -Property name -match 'windows.msi' | Select -ExpandProperty browser_download_url -First 1\n",[3816],{"type":415,"tag":672,"props":3817,"children":3818},{"__ignoreMap":401},[3819,3865],{"type":415,"tag":676,"props":3820,"children":3821},{"class":678,"line":679},[3822,3826,3831,3835,3840,3845,3850,3855,3860],{"type":415,"tag":676,"props":3823,"children":3824},{"style":981},[3825],{"type":420,"value":2534},{"type":415,"tag":676,"props":3827,"children":3828},{"style":976},[3829],{"type":420,"value":3830},"github ",{"type":415,"tag":676,"props":3832,"children":3833},{"style":981},[3834],{"type":420,"value":984},{"type":415,"tag":676,"props":3836,"children":3837},{"style":1756},[3838],{"type":420,"value":3839}," Get-Content",{"type":415,"tag":676,"props":3841,"children":3842},{"style":981},[3843],{"type":420,"value":3844}," '",{"type":415,"tag":676,"props":3846,"children":3847},{"style":689},[3848],{"type":420,"value":3849},"${{ github.event_path }}",{"type":415,"tag":676,"props":3851,"children":3852},{"style":981},[3853],{"type":420,"value":3854},"'",{"type":415,"tag":676,"props":3856,"children":3857},{"style":981},[3858],{"type":420,"value":3859}," |",{"type":415,"tag":676,"props":3861,"children":3862},{"style":1756},[3863],{"type":420,"value":3864}," ConvertFrom-Json\n",{"type":415,"tag":676,"props":3866,"children":3867},{"class":678,"line":622},[3868,3872,3877,3881,3885,3890,3894,3899,3903,3908,3913,3917,3922,3926,3930,3935,3939,3944,3948,3953],{"type":415,"tag":676,"props":3869,"children":3870},{"style":981},[3871],{"type":420,"value":2534},{"type":415,"tag":676,"props":3873,"children":3874},{"style":976},[3875],{"type":420,"value":3876},"installerUrl ",{"type":415,"tag":676,"props":3878,"children":3879},{"style":981},[3880],{"type":420,"value":984},{"type":415,"tag":676,"props":3882,"children":3883},{"style":981},[3884],{"type":420,"value":2555},{"type":415,"tag":676,"props":3886,"children":3887},{"style":976},[3888],{"type":420,"value":3889},"github.release.assets ",{"type":415,"tag":676,"props":3891,"children":3892},{"style":981},[3893],{"type":420,"value":2574},{"type":415,"tag":676,"props":3895,"children":3896},{"style":1756},[3897],{"type":420,"value":3898}," Where-Object",{"type":415,"tag":676,"props":3900,"children":3901},{"style":981},[3902],{"type":420,"value":2592},{"type":415,"tag":676,"props":3904,"children":3905},{"style":976},[3906],{"type":420,"value":3907},"Property name ",{"type":415,"tag":676,"props":3909,"children":3910},{"style":981},[3911],{"type":420,"value":3912},"-match",{"type":415,"tag":676,"props":3914,"children":3915},{"style":981},[3916],{"type":420,"value":3844},{"type":415,"tag":676,"props":3918,"children":3919},{"style":689},[3920],{"type":420,"value":3921},"windows.msi",{"type":415,"tag":676,"props":3923,"children":3924},{"style":981},[3925],{"type":420,"value":3854},{"type":415,"tag":676,"props":3927,"children":3928},{"style":981},[3929],{"type":420,"value":3859},{"type":415,"tag":676,"props":3931,"children":3932},{"style":976},[3933],{"type":420,"value":3934}," Select ",{"type":415,"tag":676,"props":3936,"children":3937},{"style":981},[3938],{"type":420,"value":1701},{"type":415,"tag":676,"props":3940,"children":3941},{"style":976},[3942],{"type":420,"value":3943},"ExpandProperty browser_download_url ",{"type":415,"tag":676,"props":3945,"children":3946},{"style":981},[3947],{"type":420,"value":1701},{"type":415,"tag":676,"props":3949,"children":3950},{"style":976},[3951],{"type":420,"value":3952},"First ",{"type":415,"tag":676,"props":3954,"children":3955},{"style":1244},[3956],{"type":420,"value":3957},"1\n",{"type":415,"tag":3959,"props":3960,"children":3961},"blockquote",{},[3962],{"type":415,"tag":416,"props":3963,"children":3964},{},[3965],{"type":420,"value":3966},"💡 I just thought that instead of doing this in PowerShell we could have done this in Nushell, which would have been fun 'using Nushell to provide a new version of Nushell' but as it is not installed by default on windows agents it would mean a loss of time each time the workflow runs.",{"type":415,"tag":416,"props":3968,"children":3969},{},[3970,3972,3977,3979,3984],{"type":420,"value":3971},"Third, we can call the ",{"type":415,"tag":672,"props":3973,"children":3975},{"className":3974},[],[3976],{"type":420,"value":3327},{"type":420,"value":3978}," update command by specifying the version, the URL of the installer, and a Personal Access Token that will be used by ",{"type":415,"tag":672,"props":3980,"children":3982},{"className":3981},[],[3983],{"type":420,"value":3327},{"type":420,"value":3985}," to make the Pull Request in the Windows Package Manager Community Repository. This PAT needs to be created by a maintainer of the repository with permission and added to the secrets of the project.",{"type":415,"tag":416,"props":3987,"children":3988},{},[3989],{"type":415,"tag":459,"props":3990,"children":3994},{"alt":3991,"className":3992,"src":3993},"Screen to define Personal Access Tokens.",[463,464],"/posts/images/wingetcreate_pat.png",[],{"type":415,"tag":416,"props":3996,"children":3997},{},[3998],{"type":420,"value":3999},"Here you can see a run of the workflow in GitHub:",{"type":415,"tag":416,"props":4001,"children":4002},{},[4003],{"type":415,"tag":459,"props":4004,"children":4008},{"alt":4005,"className":4006,"src":4007},"GitHub Actions workflow running.",[463,464],"/posts/images/wingetcreate_wokflow_1.png",[],{"type":415,"tag":427,"props":4010,"children":4012},{"id":4011},"overview-of-the-created-workflow",[4013],{"type":420,"value":4014},"Overview of the created workflow",{"type":415,"tag":416,"props":4016,"children":4017},{},[4018,4020,4026],{"type":420,"value":4019},"You can find the complete workflow below and ",{"type":415,"tag":649,"props":4021,"children":4024},{"href":4022,"rel":4023},"https://github.com/nushell/nushell/blob/main/.github/workflows/winget-submission.yml",[653],[4025],{"type":420,"value":1259},{"type":420,"value":4027}," in the Nushell repository.",{"type":415,"tag":665,"props":4029,"children":4031},{"className":3381,"code":4030,"language":3383,"meta":401,"style":401},"name: Submit Nushell package to Windows Package Manager Community Repository \n\non:\n  release:\n    types: [published]\n\njobs:\n\n  winget:\n    name: Publish winget package\n    runs-on: windows-latest\n    steps:\n      - name: Submit package to Windows Package Manager Community Repository\n        run: |\n          iwr https://aka.ms/wingetcreate/latest -OutFile wingetcreate.exe\n          $github = Get-Content '${{ github.event_path }}' | ConvertFrom-Json\n          $installerUrl = $github.release.assets | Where-Object -Property name -match 'windows.msi' | Select -ExpandProperty browser_download_url -First 1\n          .\\wingetcreate.exe update Nushell.Nushell -s -v $github.release.tag_name -u $installerUrl -t ${{ secrets.NUSHELL_PAT }}\n",[4032],{"type":415,"tag":672,"props":4033,"children":4034},{"__ignoreMap":401},[4035,4054,4061,4072,4083,4106,4113,4124,4131,4142,4157,4173,4185,4205,4221,4230,4239,4248],{"type":415,"tag":676,"props":4036,"children":4037},{"class":678,"line":679},[4038,4042,4046,4050],{"type":415,"tag":676,"props":4039,"children":4040},{"style":3393},[4041],{"type":420,"value":3396},{"type":415,"tag":676,"props":4043,"children":4044},{"style":981},[4045],{"type":420,"value":3401},{"type":415,"tag":676,"props":4047,"children":4048},{"style":689},[4049],{"type":420,"value":3406},{"type":415,"tag":676,"props":4051,"children":4052},{"style":976},[4053],{"type":420,"value":3411},{"type":415,"tag":676,"props":4055,"children":4056},{"class":678,"line":622},[4057],{"type":415,"tag":676,"props":4058,"children":4059},{"emptyLinePlaceholder":3417},[4060],{"type":420,"value":3420},{"type":415,"tag":676,"props":4062,"children":4063},{"class":678,"line":1368},[4064,4068],{"type":415,"tag":676,"props":4065,"children":4066},{"style":3426},[4067],{"type":420,"value":3429},{"type":415,"tag":676,"props":4069,"children":4070},{"style":981},[4071],{"type":420,"value":3434},{"type":415,"tag":676,"props":4073,"children":4074},{"class":678,"line":1742},[4075,4079],{"type":415,"tag":676,"props":4076,"children":4077},{"style":3393},[4078],{"type":420,"value":3442},{"type":415,"tag":676,"props":4080,"children":4081},{"style":981},[4082],{"type":420,"value":3434},{"type":415,"tag":676,"props":4084,"children":4085},{"class":678,"line":2242},[4086,4090,4094,4098,4102],{"type":415,"tag":676,"props":4087,"children":4088},{"style":3393},[4089],{"type":420,"value":3454},{"type":415,"tag":676,"props":4091,"children":4092},{"style":981},[4093],{"type":420,"value":3401},{"type":415,"tag":676,"props":4095,"children":4096},{"style":981},[4097],{"type":420,"value":3463},{"type":415,"tag":676,"props":4099,"children":4100},{"style":689},[4101],{"type":420,"value":3468},{"type":415,"tag":676,"props":4103,"children":4104},{"style":981},[4105],{"type":420,"value":3473},{"type":415,"tag":676,"props":4107,"children":4108},{"class":678,"line":2275},[4109],{"type":415,"tag":676,"props":4110,"children":4111},{"emptyLinePlaceholder":3417},[4112],{"type":420,"value":3420},{"type":415,"tag":676,"props":4114,"children":4115},{"class":678,"line":2308},[4116,4120],{"type":415,"tag":676,"props":4117,"children":4118},{"style":3393},[4119],{"type":420,"value":3488},{"type":415,"tag":676,"props":4121,"children":4122},{"style":981},[4123],{"type":420,"value":3434},{"type":415,"tag":676,"props":4125,"children":4126},{"class":678,"line":2341},[4127],{"type":415,"tag":676,"props":4128,"children":4129},{"emptyLinePlaceholder":3417},[4130],{"type":420,"value":3420},{"type":415,"tag":676,"props":4132,"children":4133},{"class":678,"line":2350},[4134,4138],{"type":415,"tag":676,"props":4135,"children":4136},{"style":3393},[4137],{"type":420,"value":3507},{"type":415,"tag":676,"props":4139,"children":4140},{"style":981},[4141],{"type":420,"value":3434},{"type":415,"tag":676,"props":4143,"children":4144},{"class":678,"line":3514},[4145,4149,4153],{"type":415,"tag":676,"props":4146,"children":4147},{"style":3393},[4148],{"type":420,"value":3520},{"type":415,"tag":676,"props":4150,"children":4151},{"style":981},[4152],{"type":420,"value":3401},{"type":415,"tag":676,"props":4154,"children":4155},{"style":689},[4156],{"type":420,"value":3529},{"type":415,"tag":676,"props":4158,"children":4160},{"class":678,"line":4159},11,[4161,4165,4169],{"type":415,"tag":676,"props":4162,"children":4163},{"style":3393},[4164],{"type":420,"value":3611},{"type":415,"tag":676,"props":4166,"children":4167},{"style":981},[4168],{"type":420,"value":3401},{"type":415,"tag":676,"props":4170,"children":4171},{"style":689},[4172],{"type":420,"value":3620},{"type":415,"tag":676,"props":4174,"children":4176},{"class":678,"line":4175},12,[4177,4181],{"type":415,"tag":676,"props":4178,"children":4179},{"style":3393},[4180],{"type":420,"value":3696},{"type":415,"tag":676,"props":4182,"children":4183},{"style":981},[4184],{"type":420,"value":3434},{"type":415,"tag":676,"props":4186,"children":4188},{"class":678,"line":4187},13,[4189,4193,4197,4201],{"type":415,"tag":676,"props":4190,"children":4191},{"style":981},[4192],{"type":420,"value":3708},{"type":415,"tag":676,"props":4194,"children":4195},{"style":3393},[4196],{"type":420,"value":3713},{"type":415,"tag":676,"props":4198,"children":4199},{"style":981},[4200],{"type":420,"value":3401},{"type":415,"tag":676,"props":4202,"children":4203},{"style":689},[4204],{"type":420,"value":3722},{"type":415,"tag":676,"props":4206,"children":4208},{"class":678,"line":4207},14,[4209,4213,4217],{"type":415,"tag":676,"props":4210,"children":4211},{"style":3393},[4212],{"type":420,"value":3730},{"type":415,"tag":676,"props":4214,"children":4215},{"style":981},[4216],{"type":420,"value":3401},{"type":415,"tag":676,"props":4218,"children":4219},{"style":2483},[4220],{"type":420,"value":3739},{"type":415,"tag":676,"props":4222,"children":4224},{"class":678,"line":4223},15,[4225],{"type":415,"tag":676,"props":4226,"children":4227},{"style":689},[4228],{"type":420,"value":4229},"          iwr https://aka.ms/wingetcreate/latest -OutFile wingetcreate.exe\n",{"type":415,"tag":676,"props":4231,"children":4233},{"class":678,"line":4232},16,[4234],{"type":415,"tag":676,"props":4235,"children":4236},{"style":689},[4237],{"type":420,"value":4238},"          $github = Get-Content '${{ github.event_path }}' | ConvertFrom-Json\n",{"type":415,"tag":676,"props":4240,"children":4242},{"class":678,"line":4241},17,[4243],{"type":415,"tag":676,"props":4244,"children":4245},{"style":689},[4246],{"type":420,"value":4247},"          $installerUrl = $github.release.assets | Where-Object -Property name -match 'windows.msi' | Select -ExpandProperty browser_download_url -First 1\n",{"type":415,"tag":676,"props":4249,"children":4251},{"class":678,"line":4250},18,[4252],{"type":415,"tag":676,"props":4253,"children":4254},{"style":689},[4255],{"type":420,"value":4256},"          .\\wingetcreate.exe update Nushell.Nushell -s -v $github.release.tag_name -u $installerUrl -t ${{ secrets.NUSHELL_PAT }}\n",{"type":415,"tag":416,"props":4258,"children":4259},{},[4260],{"type":420,"value":4261},"Here is what a Pull Request generated by the GitHub Actions workflow looks like:",{"type":415,"tag":416,"props":4263,"children":4264},{},[4265],{"type":415,"tag":459,"props":4266,"children":4270},{"alt":4267,"className":4268,"src":4269},"Pull Request in the winget-pkgs repository.",[463,464],"/posts/images/wingetcreate_pr.png",[],{"type":415,"tag":427,"props":4272,"children":4274},{"id":4273},"to-summarize",[4275],{"type":420,"value":4276},"To summarize",{"type":415,"tag":416,"props":4278,"children":4279},{},[4280],{"type":420,"value":4281},"We have introduced the notion of source for winget packages and in particular, the Windows Package Manager Community Repository where we can open PR to submit a new application or new versions of an existing application. We have seen how Windows Package Manager Manifest Creator could help us do that and how it could be automated from a GitHub Actions workflow like it was done for the Nushell project.",{"type":415,"tag":416,"props":4283,"children":4284},{},[4285],{"type":420,"value":4286},"Do not hesitate to copy some of the GitHub Actions workflows I showed you. I hope this will inspire you to do the same to distribute your applications through winget.",{"type":415,"tag":416,"props":4288,"children":4289},{},[4290,4292,4299,4301,4308,4309,4316],{"type":420,"value":4291},"A big thank you to ",{"type":415,"tag":649,"props":4293,"children":4296},{"href":4294,"rel":4295},"https://twitter.com/ethomson",[653],[4297],{"type":420,"value":4298},"Edward Thomson",{"type":420,"value":4300}," who explained to me how to retrieve GitHub Actions contexts in PowerShell. Thanks also to ",{"type":415,"tag":649,"props":4302,"children":4305},{"href":4303,"rel":4304},"https://twitter.com/fdncred",[653],[4306],{"type":420,"value":4307},"Darren Schroeder",{"type":420,"value":1835},{"type":415,"tag":649,"props":4310,"children":4313},{"href":4311,"rel":4312},"https://twitter.com/jntrnr",[653],[4314],{"type":420,"value":4315},"Jonathan Turner",{"type":420,"value":4317}," who supported me to set up a workflow that publishes new releases of Nushell in winget.",{"type":415,"tag":811,"props":4319,"children":4320},{},[4321],{"type":420,"value":815},{"title":401,"searchDepth":622,"depth":622,"links":4323},[4324,4325,4335,4342,4343],{"id":3022,"depth":622,"text":3025},{"id":3067,"depth":622,"text":3070,"children":4326},[4327,4328,4330,4332,4334],{"id":3073,"depth":1368,"text":3076},{"id":3136,"depth":1368,"text":4329},"The New command",{"id":3161,"depth":1368,"text":4331},"The Update command",{"id":3185,"depth":1368,"text":4333},"The Submit command",{"id":3201,"depth":1368,"text":3204},{"id":3226,"depth":622,"text":3229,"children":4336},[4337,4338,4339,4340],{"id":3232,"depth":1368,"text":3235},{"id":3257,"depth":1368,"text":3260},{"id":3332,"depth":1368,"text":3335},{"id":3537,"depth":1368,"text":4341},"Calling WingetCreate from a GitHub Actions workflow.",{"id":4011,"depth":622,"text":4014},{"id":4273,"depth":622,"text":4276},"content:1.posts:21.wingetcreate.md","1.posts/21.wingetcreate.md",{"_path":61,"_dir":399,"_draft":400,"_partial":400,"_locale":401,"title":60,"description":4347,"lead":4348,"date":4349,"image":4350,"badge":4351,"tags":4352,"body":4353,"_type":628,"_id":4572,"_source":630,"_file":4573,"_extension":632},"In my last article about Windows Package Manager, I said that with winget I was missing \"being able to specify some parameters for a package installation (like the workload and components to install for Visual Studio 2019)\". Well, that was before I went through a few GitHub issues of the winget-cli repository that mentioned the override option.","The override option of winget install command","2021-05-31T00:00:00.000Z",{"src":3000},{"label":406},[291,293,296,206],{"type":412,"children":4354,"toc":4565},[4355,4376,4382,4415,4426,4432,4437,4490,4502,4515,4543,4549,4561],{"type":415,"tag":416,"props":4356,"children":4357},{},[4358,4360,4366,4368,4374],{"type":420,"value":4359},"In my last article about Windows Package Manager, I said that with winget I was missing \"",{"type":415,"tag":4361,"props":4362,"children":4363},"em",{},[4364],{"type":420,"value":4365},"being able to specify some parameters for a package installation (like the workload and components to install for Visual Studio 2019)",{"type":420,"value":4367},"\". Well, that was before I went through a few GitHub issues of the winget-cli repository that mentioned the ",{"type":415,"tag":672,"props":4369,"children":4371},{"className":4370},[],[4372],{"type":420,"value":4373},"override",{"type":420,"value":4375}," option.",{"type":415,"tag":427,"props":4377,"children":4379},{"id":4378},"about-the-override-option",[4380],{"type":420,"value":4381},"About the override option",{"type":415,"tag":416,"props":4383,"children":4384},{},[4385,4391,4393,4398,4400,4406,4408,4413],{"type":415,"tag":672,"props":4386,"children":4388},{"className":4387},[],[4389],{"type":420,"value":4390},"winget install",{"type":420,"value":4392}," official documentation says the ",{"type":415,"tag":672,"props":4394,"children":4396},{"className":4395},[],[4397],{"type":420,"value":4373},{"type":420,"value":4399}," option to the ",{"type":415,"tag":672,"props":4401,"children":4403},{"className":4402},[],[4404],{"type":420,"value":4405},"install",{"type":420,"value":4407}," command can be used to provide a \"",{"type":415,"tag":4361,"props":4409,"children":4410},{},[4411],{"type":420,"value":4412},"string that will be passed directly to the installer",{"type":420,"value":4414},"\". What does that mean exactly?",{"type":415,"tag":416,"props":4416,"children":4417},{},[4418,4420,4425],{"type":420,"value":4419},"When you install a program on your laptop, the installer GUI often prompts you to configure some parameters for the program. For instance, Git installer lets you choose how you want to handle CRLF. Each installer has its own parameters that you can specify on the command line if you run the installer exe in your terminal. When using winget CLI, you can also specify these parameters by passing them as the value of the option ",{"type":415,"tag":672,"props":4421,"children":4423},{"className":4422},[],[4424],{"type":420,"value":4373},{"type":420,"value":1031},{"type":415,"tag":427,"props":4427,"children":4429},{"id":4428},"an-example-with-visual-studio-2019-installation",[4430],{"type":420,"value":4431},"An example with Visual Studio 2019 installation",{"type":415,"tag":416,"props":4433,"children":4434},{},[4435],{"type":420,"value":4436},"If we take the example of Visual Studio 2019, let's say we want to install it with the English language pack and the Azure workload. To do that we can run the following command:",{"type":415,"tag":665,"props":4438,"children":4440},{"className":1228,"code":4439,"language":248,"meta":401,"style":401},"winget install Microsoft.VisualStudio.2019.Enterprise --silent --override \"--wait --quiet --addProductLang En-us --add Microsoft.VisualStudio.Workload.Azure\"\n",[4441],{"type":415,"tag":672,"props":4442,"children":4443},{"__ignoreMap":401},[4444],{"type":415,"tag":676,"props":4445,"children":4446},{"class":678,"line":679},[4447,4452,4457,4461,4465,4469,4473,4477,4481,4486],{"type":415,"tag":676,"props":4448,"children":4449},{"style":976},[4450],{"type":420,"value":4451},"winget install Microsoft.VisualStudio.",{"type":415,"tag":676,"props":4453,"children":4454},{"style":1244},[4455],{"type":420,"value":4456},"2019.",{"type":415,"tag":676,"props":4458,"children":4459},{"style":976},[4460],{"type":420,"value":1945},{"type":415,"tag":676,"props":4462,"children":4463},{"style":981},[4464],{"type":420,"value":1711},{"type":415,"tag":676,"props":4466,"children":4467},{"style":976},[4468],{"type":420,"value":1954},{"type":415,"tag":676,"props":4470,"children":4471},{"style":981},[4472],{"type":420,"value":1711},{"type":415,"tag":676,"props":4474,"children":4475},{"style":976},[4476],{"type":420,"value":1963},{"type":415,"tag":676,"props":4478,"children":4479},{"style":981},[4480],{"type":420,"value":1721},{"type":415,"tag":676,"props":4482,"children":4483},{"style":689},[4484],{"type":420,"value":4485},"--wait --quiet --addProductLang En-us --add Microsoft.VisualStudio.Workload.Azure",{"type":415,"tag":676,"props":4487,"children":4488},{"style":981},[4489],{"type":420,"value":1731},{"type":415,"tag":416,"props":4491,"children":4492},{},[4493,4495,4501],{"type":420,"value":4494},"You can find the documentation of the visual studio installer with the parameters I used ",{"type":415,"tag":649,"props":4496,"children":4499},{"href":4497,"rel":4498},"https://docs.microsoft.com/en-us/visualstudio/install/use-command-line-parameters-to-install-visual-studio?view=vs-2019#bootstrapper-commands-and-command-line-parameters",[653],[4500],{"type":420,"value":1259},{"type":420,"value":1031},{"type":415,"tag":427,"props":4503,"children":4505},{"id":4504},"why-override",[4506,4508,4513],{"type":420,"value":4507},"Why ",{"type":415,"tag":672,"props":4509,"children":4511},{"className":4510},[],[4512],{"type":420,"value":4373},{"type":420,"value":4514},"?",{"type":415,"tag":416,"props":4516,"children":4517},{},[4518,4520,4525,4527,4532,4534,4541],{"type":420,"value":4519},"So ",{"type":415,"tag":672,"props":4521,"children":4523},{"className":4522},[],[4524],{"type":420,"value":4373},{"type":420,"value":4526}," is a really useful option because it allows us to customize our program installations. The name ",{"type":415,"tag":672,"props":4528,"children":4530},{"className":4529},[],[4531],{"type":420,"value":4373},{"type":420,"value":4533}," could seem a bit strange but it is to indicate that we override the default parameters that could have been specified in the manifest of the package you are installing. By the way, the packages and their manifests can be found in ",{"type":415,"tag":649,"props":4535,"children":4538},{"href":4536,"rel":4537},"https://github.com/microsoft/winget-pkgs/",[653],[4539],{"type":420,"value":4540},"this GitHub repository",{"type":420,"value":4542},". If you look at some of them you will see what parameters they use by default and be able to know if you need to override them to fit your needs.",{"type":415,"tag":427,"props":4544,"children":4546},{"id":4545},"pros-and-cons",[4547],{"type":420,"value":4548},"Pros and cons",{"type":415,"tag":416,"props":4550,"children":4551},{},[4552,4554,4559],{"type":420,"value":4553},"As we said, each installer has its own parameters so if we want to customize our installations we will have to look at the documentation of each installer which can be quite tiresome. If we compare to Chocolatey it is more or less the same but on Chocolatey site, each package has a page with most of the time the parameters documentation or at least a link to the documentation of the installer. Winget clearly lacks that. Yet, even if it requires a bit of effort to find the parameters of a package, thanks to the ",{"type":415,"tag":672,"props":4555,"children":4557},{"className":4556},[],[4558],{"type":420,"value":4373},{"type":420,"value":4560}," option we can fully customize its installation and that's great.",{"type":415,"tag":811,"props":4562,"children":4563},{},[4564],{"type":420,"value":815},{"title":401,"searchDepth":622,"depth":622,"links":4566},[4567,4568,4569,4571],{"id":4378,"depth":622,"text":4381},{"id":4428,"depth":622,"text":4431},{"id":4504,"depth":622,"text":4570},"Why override?",{"id":4545,"depth":622,"text":4548},"content:1.posts:18.winget-override.md","1.posts/18.winget-override.md",{"_path":58,"_dir":399,"_draft":400,"_partial":400,"_locale":401,"title":57,"description":4575,"lead":4576,"date":4577,"image":4578,"badge":4579,"tags":4580,"body":4581,"_type":628,"_id":5668,"_source":630,"_file":5669,"_extension":632},"Using Windows Package Manager import to install multiple applications.","Winget import a promising feature","2021-05-26T00:00:00.000Z",{"src":3000},{"label":406},[291,293,296,206],{"type":412,"children":4582,"toc":5662},[4583,4589,4608,4613,4627,4646,4652,4679,4696,4705,4711,4738,4743,5607,5619,5635,5640,5646,5658],{"type":415,"tag":427,"props":4584,"children":4586},{"id":4585},"about-windows-package-manager",[4587],{"type":420,"value":4588},"About Windows Package Manager",{"type":415,"tag":416,"props":4590,"children":4591},{},[4592,4594,4599,4601,4606],{"type":420,"value":4593},"You probably have already heard of the new ",{"type":415,"tag":649,"props":4595,"children":4597},{"href":1830,"rel":4596},[653],[4598],{"type":420,"value":1223},{"type":420,"value":4600}," and its command-line tool ",{"type":415,"tag":672,"props":4602,"children":4604},{"className":4603},[],[4605],{"type":420,"value":293},{"type":420,"value":4607}," that allows you to automate installing and upgrading software on your Windows 10 computer.",{"type":415,"tag":416,"props":4609,"children":4610},{},[4611],{"type":420,"value":4612},"With winget you can install an application very easily simply by executing in your terminal a command like this one which installs PowerToys:",{"type":415,"tag":665,"props":4614,"children":4616},{"className":1228,"code":4615,"language":248,"meta":401,"style":401},"winget install powertoys\n",[4617],{"type":415,"tag":672,"props":4618,"children":4619},{"__ignoreMap":401},[4620],{"type":415,"tag":676,"props":4621,"children":4622},{"class":678,"line":679},[4623],{"type":415,"tag":676,"props":4624,"children":4625},{"style":976},[4626],{"type":420,"value":4615},{"type":415,"tag":416,"props":4628,"children":4629},{},[4630,4632,4637,4639,4644],{"type":420,"value":4631},"Currently, Windows Package Manager only offers basic features and has far fewer packages compared to other package managers like ",{"type":415,"tag":649,"props":4633,"children":4635},{"href":1838,"rel":4634},[653],[4636],{"type":420,"value":1842},{"type":420,"value":4638},". However, even if ",{"type":415,"tag":672,"props":4640,"children":4642},{"className":4641},[],[4643],{"type":420,"value":293},{"type":420,"value":4645}," is still in its early days, there are some promising features that make it a tool to consider when setting up a Windows 10 machine.",{"type":415,"tag":427,"props":4647,"children":4649},{"id":4648},"installing-microsoft-store-applications",[4650],{"type":420,"value":4651},"Installing Microsoft Store applications",{"type":415,"tag":416,"props":4653,"children":4654},{},[4655,4657,4662,4664,4669,4671,4677],{"type":420,"value":4656},"First, winget can install Microsoft Store applications. Most of the software you use as a developer probably does not come from Microsoft Store, but there are still some applications that it is handy to get from it. For instance, the new Windows Terminal is available as a Microsoft Store application. As far as I know, apart from ",{"type":415,"tag":672,"props":4658,"children":4660},{"className":4659},[],[4661],{"type":420,"value":293},{"type":420,"value":4663},", there is no other easy way to install a Microsoft Store application from the command line. With ",{"type":415,"tag":672,"props":4665,"children":4667},{"className":4666},[],[4668],{"type":420,"value":293},{"type":420,"value":4670}," you can just do: ",{"type":415,"tag":672,"props":4672,"children":4674},{"className":4673},[],[4675],{"type":420,"value":4676},"winget install Microsoft.WindowsTerminal -s msstore",{"type":420,"value":4678}," to install the new WindowsTerminal application from Microsoft Store.",{"type":415,"tag":523,"props":4680,"children":4682},{"icon":4681},"i-fluent-emoji-flat-pushpin",[4683],{"type":415,"tag":416,"props":4684,"children":4685},{},[4686,4688,4694],{"type":420,"value":4687},"Please note that at the time of writing, installing store applications from winget is an experimental feature that you have to enable in ",{"type":415,"tag":672,"props":4689,"children":4691},{"className":4690},[],[4692],{"type":420,"value":4693},"winget settings",{"type":420,"value":4695}," and that only a subset of Microsoft Store applications can be installed.",{"type":415,"tag":416,"props":4697,"children":4698},{},[4699],{"type":415,"tag":459,"props":4700,"children":4704},{"alt":4701,"className":4702,"src":4703},"Winget configuration file.",[463,464],"/posts/images/winget_import_1.png",[],{"type":415,"tag":427,"props":4706,"children":4708},{"id":4707},"installing-several-packages-with-the-import-command",[4709],{"type":420,"value":4710},"Installing several packages with the import command",{"type":415,"tag":416,"props":4712,"children":4713},{},[4714,4716,4722,4724,4730,4732],{"type":420,"value":4715},"Second, winget has an ",{"type":415,"tag":672,"props":4717,"children":4719},{"className":4718},[],[4720],{"type":420,"value":4721},"import",{"type":420,"value":4723}," command that allows you installing all the package specified in a JSON file you pass in parameter. It means that instead of writing a script with many install commands for each of the packages you want to install, you can write a ",{"type":415,"tag":672,"props":4725,"children":4727},{"className":4726},[],[4728],{"type":420,"value":4729},"package.json",{"type":420,"value":4731}," file that will contain all the packages you want to install, their version, the source of the package (place to find them, msstore for Microsoft Store applications), ... and you will be able to install the software with one command: ",{"type":415,"tag":672,"props":4733,"children":4735},{"className":4734},[],[4736],{"type":420,"value":4737},"winget import packages.json",{"type":415,"tag":416,"props":4739,"children":4740},{},[4741],{"type":420,"value":4742},"Here is an example of such a file:",{"type":415,"tag":665,"props":4744,"children":4748},{"className":4745,"code":4746,"language":4747,"meta":401,"style":401},"language-json shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","{\n    \"$schema\" : \"https://aka.ms/winget-packages.schema.2.0.json\",\n    \"CreationDate\" : \"2021-05-23T14:41:38.200-00:00\",\n    \"Sources\" : \n    [\n        {\n            \"Packages\" : \n            [\n                {\n                    \"PackageIdentifier\" : \"Microsoft.Whiteboard\"\n                },\n                {\n                    \"PackageIdentifier\" : \"Microsoft.WindowsTerminal\"   \n                }\n            ],\n            \"SourceDetails\" : \n            {\n                \"Argument\" : \"https://winget.azureedge.net/msstore\",\n                \"Identifier\" : \"Microsoft.Winget.MSStore.Source_8wekyb3d8bbwe\",\n                \"Name\" : \"msstore\",\n                \"Type\" : \"Microsoft.PreIndexed.Package\"\n            }\n        },\n        {\n            \"Packages\" : \n            [\n                {\n                    \"PackageIdentifier\": \"Microsoft.AzureCLI\"\n                },\n                {\n                    \"PackageIdentifier\" : \"Microsoft.PowerToys\"\n                }\n            ],\n            \"SourceDetails\" : \n            {\n                \"Argument\" : \"https://winget.azureedge.net/cache\",\n                \"Identifier\" : \"Microsoft.Winget.Source_8wekyb3d8bbwe\",\n                \"Name\" : \"winget\",\n                \"Type\" : \"Microsoft.PreIndexed.Package\"\n            }\n        }\n    ],\n    \"WinGetVersion\" : \"0.4.11391\"\n}\n","json",[4749],{"type":415,"tag":672,"props":4750,"children":4751},{"__ignoreMap":401},[4752,4760,4800,4837,4861,4869,4877,4902,4910,4918,4952,4960,4967,5004,5012,5020,5044,5052,5090,5128,5166,5200,5209,5218,5226,5250,5258,5266,5299,5307,5315,5348,5356,5364,5388,5396,5433,5470,5506,5538,5546,5555,5564,5598],{"type":415,"tag":676,"props":4753,"children":4754},{"class":678,"line":679},[4755],{"type":415,"tag":676,"props":4756,"children":4757},{"style":981},[4758],{"type":420,"value":4759},"{\n",{"type":415,"tag":676,"props":4761,"children":4762},{"class":678,"line":622},[4763,4768,4773,4777,4782,4786,4791,4795],{"type":415,"tag":676,"props":4764,"children":4765},{"style":981},[4766],{"type":420,"value":4767},"    \"",{"type":415,"tag":676,"props":4769,"children":4770},{"style":2464},[4771],{"type":420,"value":4772},"$schema",{"type":415,"tag":676,"props":4774,"children":4775},{"style":981},[4776],{"type":420,"value":1721},{"type":415,"tag":676,"props":4778,"children":4779},{"style":981},[4780],{"type":420,"value":4781}," :",{"type":415,"tag":676,"props":4783,"children":4784},{"style":981},[4785],{"type":420,"value":2524},{"type":415,"tag":676,"props":4787,"children":4788},{"style":689},[4789],{"type":420,"value":4790},"https://aka.ms/winget-packages.schema.2.0.json",{"type":415,"tag":676,"props":4792,"children":4793},{"style":981},[4794],{"type":420,"value":1721},{"type":415,"tag":676,"props":4796,"children":4797},{"style":981},[4798],{"type":420,"value":4799},",\n",{"type":415,"tag":676,"props":4801,"children":4802},{"class":678,"line":1368},[4803,4807,4812,4816,4820,4824,4829,4833],{"type":415,"tag":676,"props":4804,"children":4805},{"style":981},[4806],{"type":420,"value":4767},{"type":415,"tag":676,"props":4808,"children":4809},{"style":2464},[4810],{"type":420,"value":4811},"CreationDate",{"type":415,"tag":676,"props":4813,"children":4814},{"style":981},[4815],{"type":420,"value":1721},{"type":415,"tag":676,"props":4817,"children":4818},{"style":981},[4819],{"type":420,"value":4781},{"type":415,"tag":676,"props":4821,"children":4822},{"style":981},[4823],{"type":420,"value":2524},{"type":415,"tag":676,"props":4825,"children":4826},{"style":689},[4827],{"type":420,"value":4828},"2021-05-23T14:41:38.200-00:00",{"type":415,"tag":676,"props":4830,"children":4831},{"style":981},[4832],{"type":420,"value":1721},{"type":415,"tag":676,"props":4834,"children":4835},{"style":981},[4836],{"type":420,"value":4799},{"type":415,"tag":676,"props":4838,"children":4839},{"class":678,"line":1742},[4840,4844,4849,4853,4857],{"type":415,"tag":676,"props":4841,"children":4842},{"style":981},[4843],{"type":420,"value":4767},{"type":415,"tag":676,"props":4845,"children":4846},{"style":2464},[4847],{"type":420,"value":4848},"Sources",{"type":415,"tag":676,"props":4850,"children":4851},{"style":981},[4852],{"type":420,"value":1721},{"type":415,"tag":676,"props":4854,"children":4855},{"style":981},[4856],{"type":420,"value":4781},{"type":415,"tag":676,"props":4858,"children":4859},{"style":976},[4860],{"type":420,"value":3411},{"type":415,"tag":676,"props":4862,"children":4863},{"class":678,"line":2242},[4864],{"type":415,"tag":676,"props":4865,"children":4866},{"style":981},[4867],{"type":420,"value":4868},"    [\n",{"type":415,"tag":676,"props":4870,"children":4871},{"class":678,"line":2275},[4872],{"type":415,"tag":676,"props":4873,"children":4874},{"style":981},[4875],{"type":420,"value":4876},"        {\n",{"type":415,"tag":676,"props":4878,"children":4879},{"class":678,"line":2308},[4880,4885,4890,4894,4898],{"type":415,"tag":676,"props":4881,"children":4882},{"style":981},[4883],{"type":420,"value":4884},"            \"",{"type":415,"tag":676,"props":4886,"children":4887},{"style":683},[4888],{"type":420,"value":4889},"Packages",{"type":415,"tag":676,"props":4891,"children":4892},{"style":981},[4893],{"type":420,"value":1721},{"type":415,"tag":676,"props":4895,"children":4896},{"style":981},[4897],{"type":420,"value":4781},{"type":415,"tag":676,"props":4899,"children":4900},{"style":976},[4901],{"type":420,"value":3411},{"type":415,"tag":676,"props":4903,"children":4904},{"class":678,"line":2341},[4905],{"type":415,"tag":676,"props":4906,"children":4907},{"style":981},[4908],{"type":420,"value":4909},"            [\n",{"type":415,"tag":676,"props":4911,"children":4912},{"class":678,"line":2350},[4913],{"type":415,"tag":676,"props":4914,"children":4915},{"style":981},[4916],{"type":420,"value":4917},"                {\n",{"type":415,"tag":676,"props":4919,"children":4920},{"class":678,"line":3514},[4921,4926,4931,4935,4939,4943,4948],{"type":415,"tag":676,"props":4922,"children":4923},{"style":981},[4924],{"type":420,"value":4925},"                    \"",{"type":415,"tag":676,"props":4927,"children":4928},{"style":1244},[4929],{"type":420,"value":4930},"PackageIdentifier",{"type":415,"tag":676,"props":4932,"children":4933},{"style":981},[4934],{"type":420,"value":1721},{"type":415,"tag":676,"props":4936,"children":4937},{"style":981},[4938],{"type":420,"value":4781},{"type":415,"tag":676,"props":4940,"children":4941},{"style":981},[4942],{"type":420,"value":2524},{"type":415,"tag":676,"props":4944,"children":4945},{"style":689},[4946],{"type":420,"value":4947},"Microsoft.Whiteboard",{"type":415,"tag":676,"props":4949,"children":4950},{"style":981},[4951],{"type":420,"value":1731},{"type":415,"tag":676,"props":4953,"children":4954},{"class":678,"line":4159},[4955],{"type":415,"tag":676,"props":4956,"children":4957},{"style":981},[4958],{"type":420,"value":4959},"                },\n",{"type":415,"tag":676,"props":4961,"children":4962},{"class":678,"line":4175},[4963],{"type":415,"tag":676,"props":4964,"children":4965},{"style":981},[4966],{"type":420,"value":4917},{"type":415,"tag":676,"props":4968,"children":4969},{"class":678,"line":4187},[4970,4974,4978,4982,4986,4990,4995,4999],{"type":415,"tag":676,"props":4971,"children":4972},{"style":981},[4973],{"type":420,"value":4925},{"type":415,"tag":676,"props":4975,"children":4976},{"style":1244},[4977],{"type":420,"value":4930},{"type":415,"tag":676,"props":4979,"children":4980},{"style":981},[4981],{"type":420,"value":1721},{"type":415,"tag":676,"props":4983,"children":4984},{"style":981},[4985],{"type":420,"value":4781},{"type":415,"tag":676,"props":4987,"children":4988},{"style":981},[4989],{"type":420,"value":2524},{"type":415,"tag":676,"props":4991,"children":4992},{"style":689},[4993],{"type":420,"value":4994},"Microsoft.WindowsTerminal",{"type":415,"tag":676,"props":4996,"children":4997},{"style":981},[4998],{"type":420,"value":1721},{"type":415,"tag":676,"props":5000,"children":5001},{"style":976},[5002],{"type":420,"value":5003},"   \n",{"type":415,"tag":676,"props":5005,"children":5006},{"class":678,"line":4207},[5007],{"type":415,"tag":676,"props":5008,"children":5009},{"style":981},[5010],{"type":420,"value":5011},"                }\n",{"type":415,"tag":676,"props":5013,"children":5014},{"class":678,"line":4223},[5015],{"type":415,"tag":676,"props":5016,"children":5017},{"style":981},[5018],{"type":420,"value":5019},"            ],\n",{"type":415,"tag":676,"props":5021,"children":5022},{"class":678,"line":4232},[5023,5027,5032,5036,5040],{"type":415,"tag":676,"props":5024,"children":5025},{"style":981},[5026],{"type":420,"value":4884},{"type":415,"tag":676,"props":5028,"children":5029},{"style":683},[5030],{"type":420,"value":5031},"SourceDetails",{"type":415,"tag":676,"props":5033,"children":5034},{"style":981},[5035],{"type":420,"value":1721},{"type":415,"tag":676,"props":5037,"children":5038},{"style":981},[5039],{"type":420,"value":4781},{"type":415,"tag":676,"props":5041,"children":5042},{"style":976},[5043],{"type":420,"value":3411},{"type":415,"tag":676,"props":5045,"children":5046},{"class":678,"line":4241},[5047],{"type":415,"tag":676,"props":5048,"children":5049},{"style":981},[5050],{"type":420,"value":5051},"            {\n",{"type":415,"tag":676,"props":5053,"children":5054},{"class":678,"line":4250},[5055,5060,5065,5069,5073,5077,5082,5086],{"type":415,"tag":676,"props":5056,"children":5057},{"style":981},[5058],{"type":420,"value":5059},"                \"",{"type":415,"tag":676,"props":5061,"children":5062},{"style":1244},[5063],{"type":420,"value":5064},"Argument",{"type":415,"tag":676,"props":5066,"children":5067},{"style":981},[5068],{"type":420,"value":1721},{"type":415,"tag":676,"props":5070,"children":5071},{"style":981},[5072],{"type":420,"value":4781},{"type":415,"tag":676,"props":5074,"children":5075},{"style":981},[5076],{"type":420,"value":2524},{"type":415,"tag":676,"props":5078,"children":5079},{"style":689},[5080],{"type":420,"value":5081},"https://winget.azureedge.net/msstore",{"type":415,"tag":676,"props":5083,"children":5084},{"style":981},[5085],{"type":420,"value":1721},{"type":415,"tag":676,"props":5087,"children":5088},{"style":981},[5089],{"type":420,"value":4799},{"type":415,"tag":676,"props":5091,"children":5093},{"class":678,"line":5092},19,[5094,5098,5103,5107,5111,5115,5120,5124],{"type":415,"tag":676,"props":5095,"children":5096},{"style":981},[5097],{"type":420,"value":5059},{"type":415,"tag":676,"props":5099,"children":5100},{"style":1244},[5101],{"type":420,"value":5102},"Identifier",{"type":415,"tag":676,"props":5104,"children":5105},{"style":981},[5106],{"type":420,"value":1721},{"type":415,"tag":676,"props":5108,"children":5109},{"style":981},[5110],{"type":420,"value":4781},{"type":415,"tag":676,"props":5112,"children":5113},{"style":981},[5114],{"type":420,"value":2524},{"type":415,"tag":676,"props":5116,"children":5117},{"style":689},[5118],{"type":420,"value":5119},"Microsoft.Winget.MSStore.Source_8wekyb3d8bbwe",{"type":415,"tag":676,"props":5121,"children":5122},{"style":981},[5123],{"type":420,"value":1721},{"type":415,"tag":676,"props":5125,"children":5126},{"style":981},[5127],{"type":420,"value":4799},{"type":415,"tag":676,"props":5129,"children":5131},{"class":678,"line":5130},20,[5132,5136,5141,5145,5149,5153,5158,5162],{"type":415,"tag":676,"props":5133,"children":5134},{"style":981},[5135],{"type":420,"value":5059},{"type":415,"tag":676,"props":5137,"children":5138},{"style":1244},[5139],{"type":420,"value":5140},"Name",{"type":415,"tag":676,"props":5142,"children":5143},{"style":981},[5144],{"type":420,"value":1721},{"type":415,"tag":676,"props":5146,"children":5147},{"style":981},[5148],{"type":420,"value":4781},{"type":415,"tag":676,"props":5150,"children":5151},{"style":981},[5152],{"type":420,"value":2524},{"type":415,"tag":676,"props":5154,"children":5155},{"style":689},[5156],{"type":420,"value":5157},"msstore",{"type":415,"tag":676,"props":5159,"children":5160},{"style":981},[5161],{"type":420,"value":1721},{"type":415,"tag":676,"props":5163,"children":5164},{"style":981},[5165],{"type":420,"value":4799},{"type":415,"tag":676,"props":5167,"children":5169},{"class":678,"line":5168},21,[5170,5174,5179,5183,5187,5191,5196],{"type":415,"tag":676,"props":5171,"children":5172},{"style":981},[5173],{"type":420,"value":5059},{"type":415,"tag":676,"props":5175,"children":5176},{"style":1244},[5177],{"type":420,"value":5178},"Type",{"type":415,"tag":676,"props":5180,"children":5181},{"style":981},[5182],{"type":420,"value":1721},{"type":415,"tag":676,"props":5184,"children":5185},{"style":981},[5186],{"type":420,"value":4781},{"type":415,"tag":676,"props":5188,"children":5189},{"style":981},[5190],{"type":420,"value":2524},{"type":415,"tag":676,"props":5192,"children":5193},{"style":689},[5194],{"type":420,"value":5195},"Microsoft.PreIndexed.Package",{"type":415,"tag":676,"props":5197,"children":5198},{"style":981},[5199],{"type":420,"value":1731},{"type":415,"tag":676,"props":5201,"children":5203},{"class":678,"line":5202},22,[5204],{"type":415,"tag":676,"props":5205,"children":5206},{"style":981},[5207],{"type":420,"value":5208},"            }\n",{"type":415,"tag":676,"props":5210,"children":5212},{"class":678,"line":5211},23,[5213],{"type":415,"tag":676,"props":5214,"children":5215},{"style":981},[5216],{"type":420,"value":5217},"        },\n",{"type":415,"tag":676,"props":5219,"children":5221},{"class":678,"line":5220},24,[5222],{"type":415,"tag":676,"props":5223,"children":5224},{"style":981},[5225],{"type":420,"value":4876},{"type":415,"tag":676,"props":5227,"children":5229},{"class":678,"line":5228},25,[5230,5234,5238,5242,5246],{"type":415,"tag":676,"props":5231,"children":5232},{"style":981},[5233],{"type":420,"value":4884},{"type":415,"tag":676,"props":5235,"children":5236},{"style":683},[5237],{"type":420,"value":4889},{"type":415,"tag":676,"props":5239,"children":5240},{"style":981},[5241],{"type":420,"value":1721},{"type":415,"tag":676,"props":5243,"children":5244},{"style":981},[5245],{"type":420,"value":4781},{"type":415,"tag":676,"props":5247,"children":5248},{"style":976},[5249],{"type":420,"value":3411},{"type":415,"tag":676,"props":5251,"children":5253},{"class":678,"line":5252},26,[5254],{"type":415,"tag":676,"props":5255,"children":5256},{"style":981},[5257],{"type":420,"value":4909},{"type":415,"tag":676,"props":5259,"children":5261},{"class":678,"line":5260},27,[5262],{"type":415,"tag":676,"props":5263,"children":5264},{"style":981},[5265],{"type":420,"value":4917},{"type":415,"tag":676,"props":5267,"children":5269},{"class":678,"line":5268},28,[5270,5274,5278,5282,5286,5290,5295],{"type":415,"tag":676,"props":5271,"children":5272},{"style":981},[5273],{"type":420,"value":4925},{"type":415,"tag":676,"props":5275,"children":5276},{"style":1244},[5277],{"type":420,"value":4930},{"type":415,"tag":676,"props":5279,"children":5280},{"style":981},[5281],{"type":420,"value":1721},{"type":415,"tag":676,"props":5283,"children":5284},{"style":981},[5285],{"type":420,"value":3401},{"type":415,"tag":676,"props":5287,"children":5288},{"style":981},[5289],{"type":420,"value":2524},{"type":415,"tag":676,"props":5291,"children":5292},{"style":689},[5293],{"type":420,"value":5294},"Microsoft.AzureCLI",{"type":415,"tag":676,"props":5296,"children":5297},{"style":981},[5298],{"type":420,"value":1731},{"type":415,"tag":676,"props":5300,"children":5302},{"class":678,"line":5301},29,[5303],{"type":415,"tag":676,"props":5304,"children":5305},{"style":981},[5306],{"type":420,"value":4959},{"type":415,"tag":676,"props":5308,"children":5310},{"class":678,"line":5309},30,[5311],{"type":415,"tag":676,"props":5312,"children":5313},{"style":981},[5314],{"type":420,"value":4917},{"type":415,"tag":676,"props":5316,"children":5318},{"class":678,"line":5317},31,[5319,5323,5327,5331,5335,5339,5344],{"type":415,"tag":676,"props":5320,"children":5321},{"style":981},[5322],{"type":420,"value":4925},{"type":415,"tag":676,"props":5324,"children":5325},{"style":1244},[5326],{"type":420,"value":4930},{"type":415,"tag":676,"props":5328,"children":5329},{"style":981},[5330],{"type":420,"value":1721},{"type":415,"tag":676,"props":5332,"children":5333},{"style":981},[5334],{"type":420,"value":4781},{"type":415,"tag":676,"props":5336,"children":5337},{"style":981},[5338],{"type":420,"value":2524},{"type":415,"tag":676,"props":5340,"children":5341},{"style":689},[5342],{"type":420,"value":5343},"Microsoft.PowerToys",{"type":415,"tag":676,"props":5345,"children":5346},{"style":981},[5347],{"type":420,"value":1731},{"type":415,"tag":676,"props":5349,"children":5351},{"class":678,"line":5350},32,[5352],{"type":415,"tag":676,"props":5353,"children":5354},{"style":981},[5355],{"type":420,"value":5011},{"type":415,"tag":676,"props":5357,"children":5359},{"class":678,"line":5358},33,[5360],{"type":415,"tag":676,"props":5361,"children":5362},{"style":981},[5363],{"type":420,"value":5019},{"type":415,"tag":676,"props":5365,"children":5367},{"class":678,"line":5366},34,[5368,5372,5376,5380,5384],{"type":415,"tag":676,"props":5369,"children":5370},{"style":981},[5371],{"type":420,"value":4884},{"type":415,"tag":676,"props":5373,"children":5374},{"style":683},[5375],{"type":420,"value":5031},{"type":415,"tag":676,"props":5377,"children":5378},{"style":981},[5379],{"type":420,"value":1721},{"type":415,"tag":676,"props":5381,"children":5382},{"style":981},[5383],{"type":420,"value":4781},{"type":415,"tag":676,"props":5385,"children":5386},{"style":976},[5387],{"type":420,"value":3411},{"type":415,"tag":676,"props":5389,"children":5391},{"class":678,"line":5390},35,[5392],{"type":415,"tag":676,"props":5393,"children":5394},{"style":981},[5395],{"type":420,"value":5051},{"type":415,"tag":676,"props":5397,"children":5399},{"class":678,"line":5398},36,[5400,5404,5408,5412,5416,5420,5425,5429],{"type":415,"tag":676,"props":5401,"children":5402},{"style":981},[5403],{"type":420,"value":5059},{"type":415,"tag":676,"props":5405,"children":5406},{"style":1244},[5407],{"type":420,"value":5064},{"type":415,"tag":676,"props":5409,"children":5410},{"style":981},[5411],{"type":420,"value":1721},{"type":415,"tag":676,"props":5413,"children":5414},{"style":981},[5415],{"type":420,"value":4781},{"type":415,"tag":676,"props":5417,"children":5418},{"style":981},[5419],{"type":420,"value":2524},{"type":415,"tag":676,"props":5421,"children":5422},{"style":689},[5423],{"type":420,"value":5424},"https://winget.azureedge.net/cache",{"type":415,"tag":676,"props":5426,"children":5427},{"style":981},[5428],{"type":420,"value":1721},{"type":415,"tag":676,"props":5430,"children":5431},{"style":981},[5432],{"type":420,"value":4799},{"type":415,"tag":676,"props":5434,"children":5436},{"class":678,"line":5435},37,[5437,5441,5445,5449,5453,5457,5462,5466],{"type":415,"tag":676,"props":5438,"children":5439},{"style":981},[5440],{"type":420,"value":5059},{"type":415,"tag":676,"props":5442,"children":5443},{"style":1244},[5444],{"type":420,"value":5102},{"type":415,"tag":676,"props":5446,"children":5447},{"style":981},[5448],{"type":420,"value":1721},{"type":415,"tag":676,"props":5450,"children":5451},{"style":981},[5452],{"type":420,"value":4781},{"type":415,"tag":676,"props":5454,"children":5455},{"style":981},[5456],{"type":420,"value":2524},{"type":415,"tag":676,"props":5458,"children":5459},{"style":689},[5460],{"type":420,"value":5461},"Microsoft.Winget.Source_8wekyb3d8bbwe",{"type":415,"tag":676,"props":5463,"children":5464},{"style":981},[5465],{"type":420,"value":1721},{"type":415,"tag":676,"props":5467,"children":5468},{"style":981},[5469],{"type":420,"value":4799},{"type":415,"tag":676,"props":5471,"children":5473},{"class":678,"line":5472},38,[5474,5478,5482,5486,5490,5494,5498,5502],{"type":415,"tag":676,"props":5475,"children":5476},{"style":981},[5477],{"type":420,"value":5059},{"type":415,"tag":676,"props":5479,"children":5480},{"style":1244},[5481],{"type":420,"value":5140},{"type":415,"tag":676,"props":5483,"children":5484},{"style":981},[5485],{"type":420,"value":1721},{"type":415,"tag":676,"props":5487,"children":5488},{"style":981},[5489],{"type":420,"value":4781},{"type":415,"tag":676,"props":5491,"children":5492},{"style":981},[5493],{"type":420,"value":2524},{"type":415,"tag":676,"props":5495,"children":5496},{"style":689},[5497],{"type":420,"value":293},{"type":415,"tag":676,"props":5499,"children":5500},{"style":981},[5501],{"type":420,"value":1721},{"type":415,"tag":676,"props":5503,"children":5504},{"style":981},[5505],{"type":420,"value":4799},{"type":415,"tag":676,"props":5507,"children":5509},{"class":678,"line":5508},39,[5510,5514,5518,5522,5526,5530,5534],{"type":415,"tag":676,"props":5511,"children":5512},{"style":981},[5513],{"type":420,"value":5059},{"type":415,"tag":676,"props":5515,"children":5516},{"style":1244},[5517],{"type":420,"value":5178},{"type":415,"tag":676,"props":5519,"children":5520},{"style":981},[5521],{"type":420,"value":1721},{"type":415,"tag":676,"props":5523,"children":5524},{"style":981},[5525],{"type":420,"value":4781},{"type":415,"tag":676,"props":5527,"children":5528},{"style":981},[5529],{"type":420,"value":2524},{"type":415,"tag":676,"props":5531,"children":5532},{"style":689},[5533],{"type":420,"value":5195},{"type":415,"tag":676,"props":5535,"children":5536},{"style":981},[5537],{"type":420,"value":1731},{"type":415,"tag":676,"props":5539,"children":5541},{"class":678,"line":5540},40,[5542],{"type":415,"tag":676,"props":5543,"children":5544},{"style":981},[5545],{"type":420,"value":5208},{"type":415,"tag":676,"props":5547,"children":5549},{"class":678,"line":5548},41,[5550],{"type":415,"tag":676,"props":5551,"children":5552},{"style":981},[5553],{"type":420,"value":5554},"        }\n",{"type":415,"tag":676,"props":5556,"children":5558},{"class":678,"line":5557},42,[5559],{"type":415,"tag":676,"props":5560,"children":5561},{"style":981},[5562],{"type":420,"value":5563},"    ],\n",{"type":415,"tag":676,"props":5565,"children":5567},{"class":678,"line":5566},43,[5568,5572,5577,5581,5585,5589,5594],{"type":415,"tag":676,"props":5569,"children":5570},{"style":981},[5571],{"type":420,"value":4767},{"type":415,"tag":676,"props":5573,"children":5574},{"style":2464},[5575],{"type":420,"value":5576},"WinGetVersion",{"type":415,"tag":676,"props":5578,"children":5579},{"style":981},[5580],{"type":420,"value":1721},{"type":415,"tag":676,"props":5582,"children":5583},{"style":981},[5584],{"type":420,"value":4781},{"type":415,"tag":676,"props":5586,"children":5587},{"style":981},[5588],{"type":420,"value":2524},{"type":415,"tag":676,"props":5590,"children":5591},{"style":689},[5592],{"type":420,"value":5593},"0.4.11391",{"type":415,"tag":676,"props":5595,"children":5596},{"style":981},[5597],{"type":420,"value":1731},{"type":415,"tag":676,"props":5599,"children":5601},{"class":678,"line":5600},44,[5602],{"type":415,"tag":676,"props":5603,"children":5604},{"style":981},[5605],{"type":420,"value":5606},"}\n",{"type":415,"tag":416,"props":5608,"children":5609},{},[5610,5612,5617],{"type":420,"value":5611},"It contains packages from Microsoft Store and packages from the ",{"type":415,"tag":672,"props":5613,"children":5615},{"className":5614},[],[5616],{"type":420,"value":293},{"type":420,"value":5618}," package repository hence the 2 arrays of packages (one by each source).",{"type":415,"tag":523,"props":5620,"children":5621},{"icon":4681},[5622],{"type":415,"tag":416,"props":5623,"children":5624},{},[5625,5627,5633],{"type":420,"value":5626},"You can easily edit this JSON in vscode with autocompletion thanks to the link to the JSON ",{"type":415,"tag":672,"props":5628,"children":5630},{"className":5629},[],[5631],{"type":420,"value":5632},"schema",{"type":420,"value":5634}," at the beginning of the JSON.",{"type":415,"tag":416,"props":5636,"children":5637},{},[5638],{"type":420,"value":5639},"Import is great but there are still things missing like the ability to silently install the applications which is possible with the install command.",{"type":415,"tag":427,"props":5641,"children":5643},{"id":5642},"final-thoughts",[5644],{"type":420,"value":5645},"Final thoughts",{"type":415,"tag":416,"props":5647,"children":5648},{},[5649,5651,5656],{"type":420,"value":5650},"Chocolatey will continue to be my main package manager for now: on the one hand for the number of packages available and on the other hand for being able to specify some parameters for a package installation (like the workload and components to install for Visual Studio 2019). Yet, ",{"type":415,"tag":672,"props":5652,"children":5654},{"className":5653},[],[5655],{"type":420,"value":293},{"type":420,"value":5657}," will be part of my toolbox as well to install some packages (including Microsoft Store applications) and I expect it to continue to get better and better.",{"type":415,"tag":811,"props":5659,"children":5660},{},[5661],{"type":420,"value":815},{"title":401,"searchDepth":622,"depth":622,"links":5663},[5664,5665,5666,5667],{"id":4585,"depth":622,"text":4588},{"id":4648,"depth":622,"text":4651},{"id":4707,"depth":622,"text":4710},{"id":5642,"depth":622,"text":5645},"content:1.posts:17.winget-import.md","1.posts/17.winget-import.md",1716749600594]