Adding Job Summary support to my GitHub Release Notes Action

A recent addition to GitHub Actions is the ability to create a custom job summary. Using a simple echo command in a script you can write to the job summary

steps:   - name: Adding markdown
  run: echo '### Hello world! :rocket:' >> $GITHUB_STEP_SUMMARY

Now, this got me thinking. I have a well-used custom release notes extension for Azure DevOps. It has a GitHub Action equivalent, but it does not seem to get as much usage. Would adding support for custom Job Summaries make it more useful?

Well, there was only one way to find out, I added it.

There is now an extra boolean parameter for the action writeToJobSummary. If this is set to true (default is false) the output of the release notes action is written as a custom job summary (as well as still being available as a markdown file as before).

So now using this feature you see something similar to the following. The summary is built using a Handlbars based template.

I hope people find this a useful means to format their release notes using handlebars as opposed to having to build them using a series of echo statements in a script or writing their own custom action.

Fix for cannot ‘TypeError: Cannot read property’ when Dependabot submits a PR to upgrade a Jest Module

GitHub’s Dependabot is a great tool to help keep your dependencies up to date, and most of the time the PR it generates just merges without a problem. However, sometimes there are issues with other related dependencies.

This was the case with a recent PR to update jest-circus to 28.x. The PR failed with the error

TypeError: Cannot read property ‘enableGlobally’ of undefined at jestAdapter (node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapter.js:39:25) at TestScheduler.scheduleTests (node_modules/@jest/core/build/TestScheduler.js:333:13) at runJest (node_modules/@jest/core/build/runJest.js:404:19) at _run10000 (node_modules/@jest/core/build/cli/index.js:320:7) at runCLI (node_modules/@jest/core/build/cli/index.js:173:3)

In the end, the fix was simple, make sure all the other Jest related packages were updated to 28.x versions. Once I did this, using a GitHub Codespace, the PR merged without a problem.

More examples of using custom variables in Azure DevOps multi-stage YML

I have blogged in the past ( here , here and here) about the complexities and possible areas of confusion with different types of Azure DevOps pipeline variables.

Well here is another example of how to use variables and what can trip you up.

The key in this example is the scope of a variable, whether it is available outside a job and the syntax to access it

Variables local to the Job

So, if you create your variable as shown below

write-host "##vso[task.setvariable variable=standardvar]$MyPowerShellVar"

It is only available in the current job in the form $(standardvar)

Variable with a wider scope

If you want it to be available in another job, or stage you have to declare it thus, adding ;isOutput=true

write-host "##vso[task.setvariable variable=stagevar;isOutput=true]$MyPowerShellVar"

But there is also a change in how you access it.

  • You need to give the script that declares the variable a name so it can be referenced
  • You need to add dependons associations between stages/jobs
  • And the syntax used to access the variable changes depending on whether you are in the same job, same stage but a different job or a completely different stage.

Below is a fully worked example

Updating the Azure Application client_secret used by Packer

As I have posted about previously, we create our Azure DevOps build agent images using the same Packer definitions as used by Microsoft. This time when I ran my Packer command to build an updated VHD I got the error

Build ‘vhd’ errored after 135 milliseconds 708 microseconds: adal: Refresh request failed. Status Code = ‘401’. Response body: {“error”:”invalid_client”,”error_description”:”AADSTS7000222: The provided client secret keys for app ‘6425416f-aa94-4c20-8395-XXXXXXX’ are expired. Visit the Azure portal to create new keys for your app: https://aka.ms/NewClientSecret, or consider using certificate credentials for added security: https://aka.ms/certCreds.\r\nTrace ID: 65a200cf-8423-4d52-af07-67bf26225200\r\nCorrelation ID: 0f86de87-33fa-443b-8186-4de3894972e1\r\nTimestamp: 2022-05-03 08:36:50Z”,”error_codes”:[7000222],”timestamp”:”2022-05-03 08:36:50Z”,”trace_id”:”65a200cf-8423-4d52-af07-67bf26225200″,”correlation_id”:”0f86de87-33fa-443b-8186-4de3894972e1″,”error_uri”:”https://login.microsoftonline.com/error?code=7000222″} Endpoint https://login.microsoftonline.com/545a7a95-3c4d-4e88-9890-baa86d5fdacb/oauth2/token==> Builds finished but no artifacts were created.

As the error message made clear, the client_secret had expired.

This value was originally set/generated when the Azure Service Prinicple was created. However, as I don’t want a new SP, this time I just wanted to update the secret via the Azure Portal (Home > AAD > Application Registration > [My Packer App].

The overview showed the old Secret had expired and I was able to create a new one on the Certificates and Secrets tab. However, when I update my Packer configuration file and re-ran the command it still failed.

It only worked after I deleted the expired secret. I am not sure if this is a requirement ( it is not something I have seen before) or just some propagation/cache delay.

But worth a blog post as a reminder to my future self and any other with a similar issue.

Fix for Azure DevOps deployment to an environment stuck in “Job is pending” state

Issue

I had an Azure DevOps YAML based pipeline that had been working but was now getting stuck with the message “Job is pending…” when trying to start a stage in which there is a deployment to an environment.

Looking at the logs and Azure DevOps UI it was not obvious what the issue was.

Solution

Turns out it was due to environment checks and approvals. There was a branch policy on the environment. This was set to only allow use of Azure DevOps Templates on a given branch. The edit that had been done to the YAML meant it was trying to extend a template in a branch that was not in the approved list.

As soon as the working branch was added to the proved list it all worked as expected.

So if you see “Job is pending” errors with no obvious reason, check the environment approvals and checks. Remember, any issues with these don’t show up in the build log

A workaround for not being able to access custom variables via stagedependencies if they are set in deployment jobs in Azure DevOps Pipelines

I have blogged in the past ( here and here) about the complexities and possible areas of confusion with different types of Azure DevOps pipeline variables. I have also seen issues raised over how to access custom variables across jobs and stages. Safe to say, this is an area where it is really easy to get it wrong and end up with a null value.

I have recently come across another edge case to add to the list of gotchas.

It seems you cannot use stagedependencies to access a variable declared in a deployment job i.e. when you are using an environment to get approval for a release.

The workaround is to add a job that is dependent on the deployment and set the custom variable within it. This variable can be accessed by a later stage as shown below

- stage: S1
  jobs:
  - deployment: D1
    strategy:
      runOnce:
        deploy:
          steps:
              - checkout: none
              - bash: echo "Can't access the variable if set in here"
  - job: J1
    dependsOn:
      D1
    steps:
      - checkout: none
      - bash: echo "##vso[task.setvariable variable=myvar;isOutput=true]True" 
        name: BashStep

- stage: S2
  condition: always()

  dependsOn: 
   - S1
  jobs:
   - job: Use_Variable
     variables: # add an alias for the var
       myvar: $[stagedependencies.S1.J1.outputs['BashStep.myvar']]
        steps:
          - checkout: none
          - dash: echo "Script gets run when myvar is true"
            condition: eq (variables['myvar'],'True')

The importance of blogging – or how to do your future self a favour

Yesterday, yet again, I was thankful for my past self taking time to blog about a technical solution I had found.

I had an error when trying to digitally sign a package. On searching on the error code I came across my own blog post with the solution. This was, as usual, one I had no recollection of writing.

I find this happens all the time. It is a little disturbing when you search for an issue and the only reference is to a post you made and have forgotten, so you are the defacto expert, nobody knows anymore on the subject, but better than having no solution.

Too often I ask people if they have documented the hints, tips and solutions they find and the response I get is ‘I will remember’. Trust me you won’t. Write something down where it is discoverable for your team and your future self. This can be any format that works for you: an Email, OneNote, a Wiki or the one I find most useful a blog. Just make sure it is easily searchable.

Your future self will thank you.