[{"data":1,"prerenderedAt":923},["Reactive",2],{"navigation":3,"/posts/github-actions-var-and-context":204,"/posts/github-actions-var-and-context-surround":891},[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",{"_path":73,"_dir":205,"_draft":206,"_partial":206,"_locale":207,"title":72,"description":208,"date":209,"image":210,"badge":212,"tags":214,"body":218,"_type":886,"_id":887,"_source":888,"_file":889,"_extension":890},"posts",false,"","I recently played a bit with GitHub Actions and as I have spent some time running, again and again, my workflows to understand what was going wrong I thought it could be interesting to share what I have learned especially concerning environment variables and contexts.","2021-09-06T00:00:00.000Z",{"src":211},"/images/github-figurine_1.jpg",{"label":213},"Tips",[215,216,217],"PowerShell","GitHub Actions","jq",{"type":219,"children":220,"toc":879},"root",[221,228,238,245,259,264,276,303,317,331,343,358,372,381,393,407,413,418,431,445,459,489,502,514,526,536,643,651,801,823,829,834,855,864,868,873],{"type":222,"tag":223,"props":224,"children":225},"element","p",{},[226],{"type":227,"value":208},"text",{"type":222,"tag":229,"props":230,"children":232},"callout",{"icon":231},"i-heroicons-chat-bubble-left-20-solid",[233],{"type":222,"tag":223,"props":234,"children":235},{},[236],{"type":227,"value":237},"Disclaimer: Although I have some experience with Azure Pipelines, I am still learning GitHub Actions so I do not pretend to know everything about them nor do I never make mistakes when writing about them. Feel free to correct me in the comments if you think I am wrong about something or if something that I show can be done more effectively.",{"type":222,"tag":239,"props":240,"children":242},"h2",{"id":241},"tip-n1-environment-variables-syntax-depends-on-the-shell-you-are-using-in-your-job",[243],{"type":227,"value":244},"Tip n°1: Environment variables syntax depends on the shell you are using in your job",{"type":222,"tag":223,"props":246,"children":247},{},[248,250,257],{"type":227,"value":249},"As you know a GitHub Actions workflow is composed of different jobs where each job is a set of steps that execute on the same runner. As a runner can be hosted Ubuntu, Windows, macOS, or even another operating system (if you host your own runner) the shell that will execute your commands will not be the same by default depending on the runner you choose. For instance, if you are on a Ubuntu GitHub-hosted runner, by default the shell will be bash whereas on a Windows GitHub-hosted runner it will be PowerShell (I think we don't say PowerShell Core anymore but I am speaking of ",{"type":222,"tag":251,"props":252,"children":254},"code",{"className":253},[],[255],{"type":227,"value":256},"pwsh",{"type":227,"value":258},", not the old Windows PowerShell of course).",{"type":222,"tag":223,"props":260,"children":261},{},[262],{"type":227,"value":263},"This is really important to know because depending on the shell used, the syntax to use an environment variable in a script is different as you can see on the documentation screenshot below:",{"type":222,"tag":223,"props":265,"children":266},{},[267],{"type":222,"tag":268,"props":269,"children":275},"img",{"alt":270,"className":271,"src":274},"GitHub Actions' documentation of running a script.",[272,273],"rounded-lg","mx-auto","/posts/images/githubactions_envvar_1.png",[],{"type":222,"tag":229,"props":277,"children":278},{"icon":231},[279],{"type":222,"tag":223,"props":280,"children":281},{},[282,284,293,295,301],{"type":227,"value":283},"When I am talking about environment variables here I am referring to GitHub ",{"type":222,"tag":285,"props":286,"children":290},"a",{"href":287,"rel":288},"https://docs.github.com/en/actions/reference/environment-variables",[289],"nofollow",[291],{"type":227,"value":292},"default environment variables",{"type":227,"value":294}," (for instance ",{"type":222,"tag":251,"props":296,"children":298},{"className":297},[],[299],{"type":227,"value":300},"GITHUB_EVENT_NAME",{"type":227,"value":302}," which is the name of the webhook event that triggered the workflow) and to custom variables you set in a workflow. The syntax for environment variables you just create and use in a shell script does not change of course.",{"type":222,"tag":223,"props":304,"children":305},{},[306,308,315],{"type":227,"value":307},"The documentation briefly explains the syntax to use depending on the shell ",{"type":222,"tag":285,"props":309,"children":312},{"href":310,"rel":311},"https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions#using-a-specific-shell",[289],[313],{"type":227,"value":314},"here",{"type":227,"value":316}," but you can easily miss it as I did. In fact, most of the GitHub Actions examples you can find are in bash so if you use them as-is without paying attention to the shell you are using, you will probably get it wrong. I lost a lot of time trying to figure out why my scripts were not working on a Windows runner so I hope knowing that you will avoid doing the same.",{"type":222,"tag":239,"props":318,"children":320},{"id":319},"tip-n2-do-not-use-your-repository-github_token-in-tasks-that-need-to-trigger-another-workflow",[321,323,329],{"type":227,"value":322},"Tip n°2: Do not use your repository ",{"type":222,"tag":251,"props":324,"children":326},{"className":325},[],[327],{"type":227,"value":328},"GITHUB_TOKEN",{"type":227,"value":330}," in tasks that need to trigger another workflow.",{"type":222,"tag":223,"props":332,"children":333},{},[334,336,341],{"type":227,"value":335},"The ",{"type":222,"tag":251,"props":337,"children":339},{"className":338},[],[340],{"type":227,"value":328},{"type":227,"value":342}," is a secret you can use in your workflow to do some actions on your GitHub repository like pushing a tag, creating a new release, creating an issue... It is very convenient because it allows you to automate in your workflow many things for your GitHub repository using built-in actions or the GitHub REST API.",{"type":222,"tag":229,"props":344,"children":345},{"icon":231},[346],{"type":222,"tag":223,"props":347,"children":348},{},[349,351,356],{"type":227,"value":350},"Be aware that internally GitHub Actions is a GitHub App that is installed on your repository when you start creating GitHub Actions workflows for this repository. That means the token represented by ",{"type":222,"tag":251,"props":352,"children":354},{"className":353},[],[355],{"type":227,"value":328},{"type":227,"value":357}," in your workflow is a GitHub App installation token that will only work on your repository workflow and that will have a limited set of permissions (but you can grant more permissions directly in your workflow if you want).",{"type":222,"tag":223,"props":359,"children":360},{},[361,363,370],{"type":227,"value":362},"If you want to know about authentication in a workflow, there is a dedicated ",{"type":222,"tag":285,"props":364,"children":367},{"href":365,"rel":366},"https://docs.github.com/en/actions/reference/authentication-in-a-workflow",[289],[368],{"type":227,"value":369},"page",{"type":227,"value":371}," on the topic in the GitHub documentation. However, if you read it quickly you may miss an important piece of information:",{"type":222,"tag":373,"props":374,"children":375},"blockquote",{},[376],{"type":222,"tag":223,"props":377,"children":378},{},[379],{"type":227,"value":380},"\"events triggered by the GITHUB_TOKEN will not create a new workflow run\"",{"type":222,"tag":223,"props":382,"children":383},{},[384,386,391],{"type":227,"value":385},"What does this mean? It means that if you have 2 workflows and that the first one uses the ",{"type":222,"tag":251,"props":387,"children":389},{"className":388},[],[390],{"type":227,"value":328},{"type":227,"value":392}," for an action that should trigger the second one, then the second workflow will never be triggered. The aim is to prevent you from making an infinite loop of workflows runs triggering each other.",{"type":222,"tag":223,"props":394,"children":395},{},[396,398,405],{"type":227,"value":397},"So imagine you want to implement a workflow that publishes a release when a new tag is pushed on a repository and another workflow that automatically tweets about your new release once it is published, how can you do that? You just have to ",{"type":222,"tag":285,"props":399,"children":402},{"href":400,"rel":401},"https://docs.github.com/en/github/authenticating-to-github/keeping-your-account-and-data-secure/creating-a-personal-access-token",[289],[403],{"type":227,"value":404},"create a GitHub Personal Access Token",{"type":227,"value":406},", add it as a secret in your repository, and use it in your first workflow to create your release. This way, the second workflow will run fine when the release is published.",{"type":222,"tag":239,"props":408,"children":410},{"id":409},"tip-n3-assign-information-from-the-event-triggering-a-github-actions-workflow-to-a-powershell-variable",[411],{"type":227,"value":412},"Tip n°3: Assign information from the event triggering a GitHub Actions workflow to a PowerShell variable.",{"type":222,"tag":223,"props":414,"children":415},{},[416],{"type":227,"value":417},"Sometimes, in a GitHub Actions workflow, we want to execute some PowerShell to do specific actions depending on information from the event that triggered the workflow. Hence having a PowerShell variable with this data could be useful. For instance, if we have a workflow triggered by the publication of a release, maybe we need to retrieve the URLs of the binaries of this release which can be done easily if the event data is in a PowerShell variable.",{"type":222,"tag":223,"props":419,"children":420},{},[421,423,429],{"type":227,"value":422},"The webhook payload corresponding to the event that triggered a workflow is part of the properties of the ",{"type":222,"tag":251,"props":424,"children":426},{"className":425},[],[427],{"type":227,"value":428},"github",{"type":227,"value":430}," context.",{"type":222,"tag":229,"props":432,"children":433},{"icon":231},[434],{"type":222,"tag":223,"props":435,"children":436},{},[437,439],{"type":227,"value":438},"If you are not familiar with contexts in GitHub Actions, they are objects that contain information about the current workflow, job, runner, or things like that. Contexts are often used in expressions to determine whether or not a step of the workflow should be executed or to set some variables as you can see in the sample below.\n",{"type":222,"tag":268,"props":440,"children":444},{"alt":441,"className":442,"src":443},"GitHub Actions sample to create a draft release.",[272,273],"/posts/images/githubactions_context_1.png",[],{"type":222,"tag":223,"props":446,"children":447},{},[448,450,457],{"type":227,"value":449},"As you can read in the ",{"type":222,"tag":285,"props":451,"children":454},{"href":452,"rel":453},"https://docs.github.com/en/actions/reference/context-and-expression-syntax-for-github-actions",[289],[455],{"type":227,"value":456},"documentation",{"type":227,"value":458},", the event property is of type object which makes it difficult to query it and to assign it to a PowerShell variable. Fortunately, there are ways to do that which are based on the fact that GitHub event data is persisted in a JSON file on the runner file system.",{"type":222,"tag":223,"props":460,"children":461},{},[462,464,474,476,487],{"type":227,"value":463},"The first one is to use the tool ",{"type":222,"tag":285,"props":465,"children":468},{"href":466,"rel":467},"https://stedolan.github.io/jq/",[289],[469],{"type":222,"tag":251,"props":470,"children":472},{"className":471},[],[473],{"type":227,"value":217},{"type":227,"value":475}," which is already installed on GitHub's runners and allows you to process JSON data. Edward Thomson has a blog post that explains how you can use jq with GitHub Actions to do that: ",{"type":222,"tag":285,"props":477,"children":480},{"href":478,"rel":479},"https://www.edwardthomson.com/blog/github_actions_12_information_about_your_workflow.html",[289],[481],{"type":222,"tag":251,"props":482,"children":484},{"className":483},[],[485],{"type":227,"value":486},"GitHub Actions Day 12: Information about your Workflow",{"type":227,"value":488},".",{"type":222,"tag":223,"props":490,"children":491},{},[492,494,500],{"type":227,"value":493},"The second one is to directly use PowerShell to grab the GitHub context like this: ",{"type":222,"tag":251,"props":495,"children":497},{"className":496},[],[498],{"type":227,"value":499},"$github = Get-Content '${{ github.event_path }}' | ConvertFrom-Json",{"type":227,"value":501},". Thanks a lot Edward Thomson for helping me with this tip 😀.",{"type":222,"tag":503,"props":504,"children":508},"div",{"className":505},[506,507],"flex","justify-center",[509],{"type":222,"tag":510,"props":511,"children":513},"tweet",{"id":512},"1417509550786322440",[],{"type":222,"tag":223,"props":515,"children":516},{},[517,519,524],{"type":227,"value":518},"To illustrate that, here are a sample of using these two ways to assign the URL of the binary published by a release to a PowerShell variable using the event property of the ",{"type":222,"tag":251,"props":520,"children":522},{"className":521},[],[523],{"type":227,"value":428},{"type":227,"value":525}," context:",{"type":222,"tag":527,"props":528,"children":529},"ul",{},[530],{"type":222,"tag":531,"props":532,"children":533},"li",{},[534],{"type":227,"value":535},"using jq:",{"type":222,"tag":537,"props":538,"children":542},"pre",{"className":539,"code":540,"language":541,"meta":207,"style":207},"language-powershell shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","$installerUrl = $(jq --raw-output '.release.assets[].browser_download_url | select(contains(\\\"windows.msi\\\"))' \"${{ github.event_path }}\")\n","powershell",[543],{"type":222,"tag":251,"props":544,"children":545},{"__ignoreMap":207},[546],{"type":222,"tag":547,"props":548,"children":551},"span",{"class":549,"line":550},"line",1,[552,558,564,569,574,579,584,589,594,599,604,610,614,619,624,629,633,638],{"type":222,"tag":547,"props":553,"children":555},{"style":554},"--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF",[556],{"type":227,"value":557},"$",{"type":222,"tag":547,"props":559,"children":561},{"style":560},"--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8",[562],{"type":227,"value":563},"installerUrl ",{"type":222,"tag":547,"props":565,"children":566},{"style":554},[567],{"type":227,"value":568},"=",{"type":222,"tag":547,"props":570,"children":571},{"style":554},[572],{"type":227,"value":573}," $(",{"type":222,"tag":547,"props":575,"children":576},{"style":560},[577],{"type":227,"value":578},"jq ",{"type":222,"tag":547,"props":580,"children":581},{"style":554},[582],{"type":227,"value":583},"--",{"type":222,"tag":547,"props":585,"children":586},{"style":560},[587],{"type":227,"value":588},"raw",{"type":222,"tag":547,"props":590,"children":591},{"style":554},[592],{"type":227,"value":593},"-",{"type":222,"tag":547,"props":595,"children":596},{"style":560},[597],{"type":227,"value":598},"output ",{"type":222,"tag":547,"props":600,"children":601},{"style":554},[602],{"type":227,"value":603},"'",{"type":222,"tag":547,"props":605,"children":607},{"style":606},"--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D",[608],{"type":227,"value":609},".release.assets[].browser_download_url | select(contains(\\\"windows.msi\\\"))",{"type":222,"tag":547,"props":611,"children":612},{"style":554},[613],{"type":227,"value":603},{"type":222,"tag":547,"props":615,"children":616},{"style":554},[617],{"type":227,"value":618}," \"${",{"type":222,"tag":547,"props":620,"children":621},{"style":560},[622],{"type":227,"value":623},"{ github.event_path ",{"type":222,"tag":547,"props":625,"children":626},{"style":554},[627],{"type":227,"value":628},"}",{"type":222,"tag":547,"props":630,"children":631},{"style":606},[632],{"type":227,"value":628},{"type":222,"tag":547,"props":634,"children":635},{"style":554},[636],{"type":227,"value":637},"\"",{"type":222,"tag":547,"props":639,"children":640},{"style":554},[641],{"type":227,"value":642},")\n",{"type":222,"tag":527,"props":644,"children":645},{},[646],{"type":222,"tag":531,"props":647,"children":648},{},[649],{"type":227,"value":650},"using ConvertFrom-Json method in PowerShell:",{"type":222,"tag":537,"props":652,"children":654},{"className":539,"code":653,"language":541,"meta":207,"style":207},"$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",[655],{"type":222,"tag":251,"props":656,"children":657},{"__ignoreMap":207},[658,704],{"type":222,"tag":547,"props":659,"children":660},{"class":549,"line":550},[661,665,670,674,680,685,690,694,699],{"type":222,"tag":547,"props":662,"children":663},{"style":554},[664],{"type":227,"value":557},{"type":222,"tag":547,"props":666,"children":667},{"style":560},[668],{"type":227,"value":669},"github ",{"type":222,"tag":547,"props":671,"children":672},{"style":554},[673],{"type":227,"value":568},{"type":222,"tag":547,"props":675,"children":677},{"style":676},"--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF",[678],{"type":227,"value":679}," Get-Content",{"type":222,"tag":547,"props":681,"children":682},{"style":554},[683],{"type":227,"value":684}," '",{"type":222,"tag":547,"props":686,"children":687},{"style":606},[688],{"type":227,"value":689},"${{ github.event_path }}",{"type":222,"tag":547,"props":691,"children":692},{"style":554},[693],{"type":227,"value":603},{"type":222,"tag":547,"props":695,"children":696},{"style":554},[697],{"type":227,"value":698}," |",{"type":222,"tag":547,"props":700,"children":701},{"style":676},[702],{"type":227,"value":703}," ConvertFrom-Json\n",{"type":222,"tag":547,"props":705,"children":707},{"class":549,"line":706},2,[708,712,716,720,725,730,735,740,745,750,755,759,764,768,772,777,781,786,790,795],{"type":222,"tag":547,"props":709,"children":710},{"style":554},[711],{"type":227,"value":557},{"type":222,"tag":547,"props":713,"children":714},{"style":560},[715],{"type":227,"value":563},{"type":222,"tag":547,"props":717,"children":718},{"style":554},[719],{"type":227,"value":568},{"type":222,"tag":547,"props":721,"children":722},{"style":554},[723],{"type":227,"value":724}," $",{"type":222,"tag":547,"props":726,"children":727},{"style":560},[728],{"type":227,"value":729},"github.release.assets ",{"type":222,"tag":547,"props":731,"children":732},{"style":554},[733],{"type":227,"value":734},"|",{"type":222,"tag":547,"props":736,"children":737},{"style":676},[738],{"type":227,"value":739}," Where-Object",{"type":222,"tag":547,"props":741,"children":742},{"style":554},[743],{"type":227,"value":744}," -",{"type":222,"tag":547,"props":746,"children":747},{"style":560},[748],{"type":227,"value":749},"Property name ",{"type":222,"tag":547,"props":751,"children":752},{"style":554},[753],{"type":227,"value":754},"-match",{"type":222,"tag":547,"props":756,"children":757},{"style":554},[758],{"type":227,"value":684},{"type":222,"tag":547,"props":760,"children":761},{"style":606},[762],{"type":227,"value":763},"windows.msi",{"type":222,"tag":547,"props":765,"children":766},{"style":554},[767],{"type":227,"value":603},{"type":222,"tag":547,"props":769,"children":770},{"style":554},[771],{"type":227,"value":698},{"type":222,"tag":547,"props":773,"children":774},{"style":560},[775],{"type":227,"value":776}," Select ",{"type":222,"tag":547,"props":778,"children":779},{"style":554},[780],{"type":227,"value":593},{"type":222,"tag":547,"props":782,"children":783},{"style":560},[784],{"type":227,"value":785},"ExpandProperty browser_download_url ",{"type":222,"tag":547,"props":787,"children":788},{"style":554},[789],{"type":227,"value":593},{"type":222,"tag":547,"props":791,"children":792},{"style":560},[793],{"type":227,"value":794},"First ",{"type":222,"tag":547,"props":796,"children":798},{"style":797},"--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C",[799],{"type":227,"value":800},"1\n",{"type":222,"tag":223,"props":802,"children":803},{},[804,806,812,814,821],{"type":227,"value":805},"I did not know about jq but I find it is a nice tool although the syntax is not that straightforward. Yet, I prefer the PowerShell way because it allows to directly manipulate an object instead of a JSON string. It is what I did to automate the upgrade of the ",{"type":222,"tag":251,"props":807,"children":809},{"className":808},[],[810],{"type":227,"value":811},"Nushell",{"type":227,"value":813}," winget package using GitHub Actions when a new release is published (you can read more about it in this ",{"type":222,"tag":285,"props":815,"children":818},{"href":816,"rel":817},"https://www.techwatching.dev/posts/wingetcreate",[289],[819],{"type":227,"value":820},"article",{"type":227,"value":822},").",{"type":222,"tag":239,"props":824,"children":826},{"id":825},"tip-n4-enable-debugging-logs-to-help-you-understand-what-is-going-wrong-in-your-workflow",[827],{"type":227,"value":828},"Tip n°4: Enable debugging logs to help you understand what is going wrong in your workflow",{"type":222,"tag":223,"props":830,"children":831},{},[832],{"type":227,"value":833},"Like many CI / CD platforms, GitHub Actions has the disadvantage of not being testable locally which makes it hard to debug a workflow when something is not working properly. Moreover, by default, you won't see how some expressions/contexts are evaluated when the workflow run so logs will not help you figure out what is wrong in your workflow definition.",{"type":222,"tag":223,"props":835,"children":836},{},[837,839,845,847,853],{"type":227,"value":838},"Hopefully, you can enable debugging logs for all pipelines in your repository (unfortunately you can't specify it for a specific pipeline only) by setting the secret ",{"type":222,"tag":251,"props":840,"children":842},{"className":841},[],[843],{"type":227,"value":844},"ACTIONS_STEP_DEBUG",{"type":227,"value":846}," to true in your repository. You can read more about it in the ",{"type":222,"tag":285,"props":848,"children":851},{"href":849,"rel":850},"https://docs.github.com/en/actions/monitoring-and-troubleshooting-workflows/enabling-debug-logging",[289],[852],{"type":227,"value":456},{"type":227,"value":854}," but here is what it look likes in a workflow run:",{"type":222,"tag":223,"props":856,"children":857},{},[858],{"type":222,"tag":268,"props":859,"children":863},{"alt":860,"className":861,"src":862},"Debug logs of a Github workflow run.",[272,273],"/posts/images/githubactions_logs_1.png",[],{"type":222,"tag":865,"props":866,"children":867},"hr",{},[],{"type":222,"tag":223,"props":869,"children":870},{},[871],{"type":227,"value":872},"I hope these 4 tips will help you build awesome GitHub Actions workflows.",{"type":222,"tag":874,"props":875,"children":876},"style",{},[877],{"type":227,"value":878},"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":207,"searchDepth":706,"depth":706,"links":880},[881,882,884,885],{"id":241,"depth":706,"text":244},{"id":319,"depth":706,"text":883},"Tip n°2: Do not use your repository GITHUB_TOKEN in tasks that need to trigger another workflow.",{"id":409,"depth":706,"text":412},{"id":825,"depth":706,"text":828},"markdown","content:1.posts:22.github-actions-var-and-context.md","content","1.posts/22.github-actions-var-and-context.md","md",[892,907],{"_path":76,"_dir":205,"_draft":206,"_partial":206,"_locale":207,"title":75,"description":893,"date":894,"image":895,"badge":897,"tags":899,"_type":886,"_id":905,"_source":888,"_file":906,"_extension":890},"If you are using Azure Functions chances are you are using the setting AzureWebJobsStorage in your Function App configuration. And it is quite likely that the value of this setting which is a secret is stored in a non-secured way directly in your Function App configuration, available to anyone who has access to this configuration. But do not worry, we will see in this article how we can make your Function App more secure by removing this secret.","2021-09-15T00:00:00.000Z",{"src":896},"/images/lightning_2.jpg",{"label":898},"DevOps",[900,901,902,903,904],"Azure Functions","Pulumi","IaC","Azure Active Directory","Azure","content:1.posts:23.azure-functions-without-azurewebjobsstorage.md","1.posts/23.azure-functions-without-azurewebjobsstorage.md",{"_path":70,"_dir":205,"_draft":206,"_partial":206,"_locale":207,"title":69,"description":908,"lead":909,"date":910,"image":911,"badge":913,"tags":915,"_type":886,"_id":921,"_source":888,"_file":922,"_extension":890},"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":912},"/images/surface_2.jpg",{"label":914},"Development",[916,917,918,919,920,216],"winget","wingetcreate","package manager","tooling","nushell","content:1.posts:21.wingetcreate.md","1.posts/21.wingetcreate.md",1716749601631]