GitHub Actions: How to dynamically set environment url based on deployment step output?
Asked Answered
P

2

13

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.

Penny answered 4/5, 2021 at 13:17 Comment(0)
P
17

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 "s3_url=http://$(pulumi stack output bucketUrl)" >> $GITHUB_OUTPUT
    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 "s3_url=http://$(pulumi stack output bucketUrl)" >> $GITHUB_OUTPUT. 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.

Update: The set-output name=VARNAME::VALUE notation is deprecated and produces the following output (thanks Rob for pointing that out!):

Warning: The `set-output` command is deprecated and will be disabled soon. Please upgrade to using Environment Files. For more information see: https://github.blog/changelog/2022-10-11-github-actions-deprecating-save-state-and-set-output-commands/
Penny answered 4/5, 2021 at 13:17 Comment(3)
"a fully working workflow embedded inside a example project." the link is brokenBarnet
Just fixed the link!Penny
That's a bummer that we still can't set it during the job execution. As for myself, the job that deploys to my environments also outputs the dynamically generated URL. Hence I must create an extra job just to set the URL which is not a viable solutionSteradian
S
0

Just as an addendum, if you run the accepted answer today (3/8/2023) you will get a deprecation warning. Set-output will be removed in the future. The accepted answer can be rewritten as

  - 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 "s3_url=http://$(pulumi stack output bucketUrl)" >> $GITHUB_OUTPUT
Strikebound answered 8/3, 2023 at 18:52 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.