'GitHub Actions: How to dynamically set environment url based on deployment step output?

I found out about a really nice GitHub Actions Feature called Environments. Using the appropriate syntax a Environment could also be created inside a GitHub Action workflow.yml like this:

environment:
  name: test_environment
  url: https://your-apps-url-here.com

As the docs state thats a valid way to create GitHub Action Environments:

Running a workflow that references an environment that does not exist will create an environment with the referenced name.

But inside my current GitHub Action workflow is there a way I dynamically set the url based on a deployment step output? I have a dynamic URL resulting from the deployment process to AWS which I can't define up-front.



Solution 1:[1]

The job workflow docs tell us that there's also a way of using expressions inside the url field:

environment:
  name: test_environment
  url: ${{ steps.step_name.outputs.url_output }}

Now imagine a ci.yml workflow file that uses AWS CLI to deploy a static website to S3, where we used a tool like Pulumi to dynamically create a S3 Bucket inside our AWS account. We can read the dynamically created S3 url using the following command pulumi stack output bucketName. The deploy step inside the ci.yml could then look like this:

  - name: Deploy Nuxt.js generated static site to S3 Bucket via AWS CLI
    id: aws-sync
    run: |
      aws s3 sync ../dist/ s3://$(pulumi stack output bucketName) --acl public-read
      echo "::set-output name=s3_url::http://$(pulumi stack output bucketUrl)"
    working-directory: ./deployment

There are 2 crucial points here: First we should use id inside the deployment step to define a step name we could easily access via step_name inside our environment:url. Second we need to define a step output using echo "::set-output name=s3_url::http://$(pulumi stack output bucketUrl)". In this example I create a variable s3_url. You could replace the pulumi stack output bucketUrl with any other command you'd like or tool you use, which responds with your dynamic environment url.

Be also sure to add a http:// or https:// in order to prevent an error message like this:

Environment URL 'microservice-ui-nuxt-js-hosting-bucket-bc75fce.s3-website.eu-central-1.amazonaws.com' is not a valid http(s) URL, so it will not be shown as a link in the workflow graph.

Now the environment definition at the top of our ci.yml can access the s3_url output variable from our deployment step like this:

jobs:
  ci:
    runs-on: ubuntu-latest

    environment:
      name: microservice-ui-nuxt-js-deployment
      url: ${{ steps.aws-sync.outputs.s3_url }}

    steps:
      - name: Checkout
        ...

Using steps.aws-sync we reference the deployment step directly, since we defined it with the id. The appended .outputs.s3_url then directly references the variable containing our S3 url. If you defined everything correctly the GitHub Actions UI will render the environment URL directly below the finished job:

enter image description here

Here's also a fully working workflow embedded inside a example project.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1