Skip to content

Commands: Add Set-GitHubEnvironmentUrl to report a deployment environment URL from a workflow job #635

Description

A common deployment pattern surfaces a "View deployment" link on the workflow run, the pull request, and the repository's Environments page, pointing at whatever was just deployed (a published documentation site, a web app, a preview environment). GitHub renders that link from a job's environment.url, which "maps to environment_url in the deployments API".

An existing documentation-publishing pipeline (written in Python) already does this: after publishing, it writes the published page URL to the GITHUB_OUTPUT file as a step output, and the job references it with url: ${{ steps.<id>.outputs.<name> }}. The result is a live link to the deployed content directly from the run.

Workflows written in PowerShell that consume this module have no first-class, discoverable way to do the same. Reporting the URL today means hand-writing a raw output line (or reaching for the generic Set-GitHubOutput), which is easy to get wrong and does not read as "report the deployment URL". There is also no documented answer to the natural follow-up: what else, beyond the URL, can be reported back to a deployment while a job runs?

Request

Desired capability

A command, callable from within a running GitHub Actions job, that reports the deployment environment URL so GitHub shows the View deployment link — the PowerShell analog of the Python pipeline's step-output approach. The command belongs in the module's Commands category, alongside Set-GitHubOutput, Set-GitHubStepSummary, and Set-GitHubEnvironmentVariable.

In addition, this issue should document what else can be reported back to a deployment during a run (deployment state, a log URL, a short description), so a workflow author knows which mechanism to reach for.

Acceptance criteria

  • A documented command reports the environment URL for the current job's deployment; after the run, the URL appears as the environment's View deployment link.
  • The command is intent-revealing (reporting a deployment URL), not a generic output write.
  • Documentation explains what else can be written back to a deployment (state, log URL, description) and which API/function provides it.
  • Behavior, help, and examples are consistent with the existing Commands functions.
  • No duplication of the deployments REST API work already tracked in Add deployments REST API and custom deployment protection rule functions [Changelog 2023-04-20] #622; the relationship is documented.

Technical decisions

Two mechanisms exist for surfacing a deployment's information; the choice drives the design.

Mechanism What it can set How Fits
Declarative environment.url from a step output The environment URL only Job declares environment: { name, url: ${{ steps.<id>.outputs.<name> }} }; a step writes <name>=<url> to GITHUB_OUTPUT. The runner creates the deployment and its statuses and records the URL as environment_url. The "write URL back" request; mirrors the Python pipeline
Deployment Statuses REST API state, environment_url, log_url, description, environment, auto_inactive POST /repos/{owner}/{repo}/deployments/{deployment_id}/statuses against a deployment Writing back more than the URL; owning the deployment lifecycle

Primary deliverable — Set-GitHubEnvironmentUrl (Commands). The only runtime lever for environment.url is a step output that the job's environment.url expression references (confirmed by the "Using output as URL" example in the workflow syntax docs). The new command writes that output, so it composes with the declarative environment: block and matches the Python pipeline exactly.

Placement: src/functions/public/Commands/Set-GitHubEnvironmentUrl.ps1, following the Set-GitHubOutput / Set-GitHubStepSummary pattern.

Naming: Set-GitHubEnvironmentUrl matches the domain terms environment.url (workflow syntax) and environment_url (deployments API). It sits in the Commands category and is distinct from Set-GitHubEnvironment in the Environments category (which creates/updates environment configuration via REST). Set-GitHubDeploymentUrl was considered; Environment was chosen to align with the Actions field name.

Behavior:

  • [CmdletBinding(SupportsShouldProcess)].
  • Parameters: -Url (mandatory, the environment URL), -Name (the step-output key that environment.url will reference; a sensible default such as environment-url), -Path (defaults to $env:GITHUB_OUTPUT, matching Set-GitHubOutput).
  • Delegates the output write to Set-GitHubOutput rather than re-implementing the output file format (including the GitHub-Script composite-action result accumulation that Set-GitHubOutput already handles).
  • Emits a ::notice:: via Write-GitHubNotice and appends a line to the job summary via Set-GitHubStepSummary, so the URL is visible in the log and on the run summary.
  • No-op-safe when GITHUB_OUTPUT is unset (outside Actions), consistent with the other Commands functions.

Note

The URL writeback is already achievable today with Set-GitHubOutput -Name environment-url -Value $url plus the environment.url wiring. A dedicated command does not remove the YAML wiring, but it is intent-revealing, fixes a consistent output name, and adds the notice/summary — improving discoverability and reducing foot-guns, matching why the module wraps other raw workflow commands.

Research — what else can be written back during a deployment. Beyond the URL, the Deployment Statuses API accepts, per status:

Field Purpose
state queued, pending, in_progress, success, failure, error, inactive — drives the deployment's status and colour
environment_url The View deployment link (same value as environment.url)
log_url Full URL to the deployment's output/logs (replaces the legacy target_url)
description Short summary, ≤ 140 characters
environment Target environment name (can change on a status)
auto_inactive Auto-marks prior non-transient deployments inactive

At the deployment level: ref, task, environment, description, payload, transient_environment, production_environment, auto_merge, required_contexts.

Relationship to existing issues (no duplication). Writing back more than the URL requires the Deployment Statuses REST API, which is not yet in the module and is already tracked by #622 (Add deployments REST API and custom deployment protection rule functions, which lists New-GitHubDeploymentStatus). This issue does not re-implement that surface. Recommended split:

Auth / permissions. Set-GitHubEnvironmentUrl writes a file and needs no token. The REST path in #622 needs a token with repo/repo_deployment and the job deployments: write permission — a note for #622, not this issue.

Testing. Unit tests in the existing tests/Actions.Tests.ps1 (or a Commands test file): given a temp GITHUB_OUTPUT, the command writes the expected name=url entry, honours -WhatIf, emits the notice and summary line, and is a no-op when GITHUB_OUTPUT is unset.


Implementation plan

Core

  • Add src/functions/public/Commands/Set-GitHubEnvironmentUrl.ps1 with [CmdletBinding(SupportsShouldProcess)] and parameters -Url, -Name (default environment-url), -Path (default $env:GITHUB_OUTPUT).
  • Delegate the output write to Set-GitHubOutput (reuse its GITHUB_OUTPUT / GitHub-Script handling).
  • Emit a ::notice:: via Write-GitHubNotice and append the URL to the job summary via Set-GitHubStepSummary.
  • Add comment-based help (.SYNOPSIS, .DESCRIPTION, .EXAMPLE, .LINK https://psmodule.io/GitHub/Functions/Commands/Set-GitHubEnvironmentUrl) with an example showing the environment.url: ${{ steps.<id>.outputs.environment-url }} wiring.

Documentation

Tests

  • Add unit tests (in tests/Actions.Tests.ps1) for: output written to a temp GITHUB_OUTPUT; -WhatIf writes nothing; notice + summary emitted; no-op when GITHUB_OUTPUT is unset.

Coordination

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    Status
    Todo

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions