Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 72 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -381,8 +381,80 @@ For more information about semantic versioning, see the [semver documentation](h

# Architecture to install (auto-detected if not specified)
architecture: 'x64'

# Base URL for downloading Go distributions (default: https://github.com)
go-download-site: 'https://github.com'

## Using Custom Download Sites

For environments with restricted internet access or when using internal mirrors/proxies, you can configure the action to download Go distributions from a custom location using the `go-download-site` input.

### Use Cases

- **GitHub Enterprise Server** - Access Go distributions through your internal server
- **Corporate Proxies** - Route downloads through approved proxy servers
- **Artifact Repositories** - Use internal artifact management systems (Artifactory, Nexus, etc.)
- **Air-Gapped Environments** - Download from pre-populated internal mirrors

### Configuration

```yaml
steps:
- uses: actions/checkout@v5
- uses: actions/setup-go@v6
with:
go-version: '1.21'
go-download-site: 'https://internal-artifactory.company.com/github-proxy'
- run: go version
```

**How it works:**

The action will replace the default `https://github.com` base URL with your custom download site. For example:

- **Default URL:**
```
https://github.com/actions/go-versions/releases/download/1.21.13-10277905115/go-1.21.13-linux-x64.tar.gz
```

- **Custom URL (with `go-download-site: 'https://internal-artifactory.company.com/github-proxy'`):**
```
https://internal-artifactory.company.com/github-proxy/actions/go-versions/releases/download/1.21.13-10277905115/go-1.21.13-linux-x64.tar.gz
```

Copy link

Copilot AI Nov 29, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The example URL https://internal-artifactory.company.com/github-proxy should clarify whether it should end with a trailing slash or not. The implementation uses simple string replacement, so the URL format must exactly match how GitHub structures its URLs. Consider adding a note:

"Important: The custom download site URL should not include a trailing slash, as it directly replaces https://github.com in the full download URL path."

Suggested change
**Important:** The custom download site URL should not include a trailing slash, as it directly replaces `https://github.com` in the full download URL path.

Copilot uses AI. Check for mistakes.
### Requirements

Your custom download site must:
1. Mirror the same directory structure as GitHub's go-versions repository
2. Host the pre-built Go distribution archives
3. Be accessible from your runners
Copy link

Copilot AI Nov 29, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] Consider adding a note about the manifest URL requirement. The action still fetches the versions manifest from https://raw.githubusercontent.com/actions/go-versions/main/versions-manifest.json (line 17 in installer.ts), which may not be accessible in restricted environments. Users may need to configure their proxy/mirror to also handle this manifest URL or ensure it's accessible through their network configuration.

Suggested change
3. Be accessible from your runners
3. Be accessible from your runners
4. Ensure that the versions manifest file (`https://raw.githubusercontent.com/actions/go-versions/main/versions-manifest.json`) is accessible from your runners.
- **Note:** The action always fetches the manifest from this public URL, even when using a custom download site. In restricted environments, you may need to mirror or proxy this manifest file, or configure your network to allow access.

Copilot uses AI. Check for mistakes.

### Example: Using with JFrog Artifactory

```yaml
steps:
- uses: actions/checkout@v5
- uses: actions/setup-go@v6
with:
go-version: '1.23'
go-download-site: 'https://artifactory.internal.company.com/artifactory/github-mirror'
- run: go version
```

### Example: Using with GitHub Enterprise Server Proxy

```yaml
steps:
- uses: actions/checkout@v5
- uses: actions/setup-go@v6
with:
go-version: '1.22'
go-download-site: 'https://ghes.company.com/github-com-proxy'
- run: go version
```

> **Note:** The `go-download-site` parameter only affects downloads from the go-versions repository. Direct downloads from go.dev (fallback mechanism) are not affected by this setting.
Copy link

Copilot AI Nov 29, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This note indicates that the go-download-site parameter doesn't affect fallback downloads from go.dev, but the implementation in installer.ts only modifies manifest-based downloads. Consider clarifying that:

  1. The parameter only affects downloads from the go-versions repository manifest
  2. When manifest downloads fail, the action falls back to go.dev without using the custom download site
  3. This limitation means truly air-gapped environments may still encounter issues if manifest downloads aren't available

This could be made clearer to help users understand when they might still need additional configuration for fully restricted environments.

Suggested change
> **Note:** The `go-download-site` parameter only affects downloads from the go-versions repository. Direct downloads from go.dev (fallback mechanism) are not affected by this setting.
> **Note:** The `go-download-site` parameter only affects downloads from the go-versions repository manifest. If manifest-based downloads fail, the action falls back to downloading directly from go.dev, and the custom download site is not used. This means that in truly air-gapped environments, you may still encounter issues if manifest downloads aren't available—additional configuration or pre-caching is required for fully restricted environments.

Copilot uses AI. Check for mistakes.

## Using setup-go on GHES

setup-go comes pre-installed on GHES when Actions is enabled. For dynamic Go version downloads, the action fetches distributions from the [go-versions repository](https://github.com/actions/go-versions/) on github.com (external to your appliance).
Expand Down
3 changes: 3 additions & 0 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ inputs:
description: 'Used to specify the path to a dependency file - go.sum'
architecture:
description: 'Target architecture for Go to use. Examples: x86, x64. Will use system architecture by default.'
go-download-site:
description: 'Base URL for downloading Go distributions. Useful for GitHub Enterprise or when using a proxy/mirror. Defaults to https://github.com'
default: 'https://github.com'
outputs:
go-version:
description: 'The installed Go version. Useful when given a version range as input.'
Expand Down
20 changes: 13 additions & 7 deletions src/installer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@ export async function getGo(
versionSpec: string,
checkLatest: boolean,
auth: string | undefined,
arch: Architecture = os.arch() as Architecture
arch: Architecture = os.arch() as Architecture,
goDownloadSite: string = 'https://github.com'
) {
let manifest: tc.IToolRelease[] | undefined;
const osPlat: string = os.platform();
Expand Down Expand Up @@ -80,7 +81,8 @@ export async function getGo(
true,
auth,
arch,
manifest
manifest,
goDownloadSite
);
if (resolvedVersion) {
versionSpec = resolvedVersion;
Expand All @@ -105,7 +107,7 @@ export async function getGo(
// Try download from internal distribution (popular versions only)
//
try {
info = await getInfoFromManifest(versionSpec, true, auth, arch, manifest);
info = await getInfoFromManifest(versionSpec, true, auth, arch, manifest, goDownloadSite);
if (info) {
downloadPath = await installGoVersion(info, auth, arch);
} else {
Expand Down Expand Up @@ -155,15 +157,17 @@ async function resolveVersionFromManifest(
stable: boolean,
auth: string | undefined,
arch: Architecture,
manifest: tc.IToolRelease[] | undefined
manifest: tc.IToolRelease[] | undefined,
goDownloadSite: string = 'https://github.com'
): Promise<string | undefined> {
try {
const info = await getInfoFromManifest(
versionSpec,
stable,
auth,
arch,
manifest
manifest,
goDownloadSite
);
return info?.resolvedVersion;
} catch (err) {
Expand Down Expand Up @@ -357,7 +361,8 @@ export async function getInfoFromManifest(
stable: boolean,
auth: string | undefined,
arch: Architecture = os.arch() as Architecture,
manifest?: tc.IToolRelease[] | undefined
manifest?: tc.IToolRelease[] | undefined,
goDownloadSite: string = 'https://github.com'
): Promise<IGoVersionInfo | null> {
let info: IGoVersionInfo | null = null;
if (!manifest) {
Expand All @@ -373,7 +378,8 @@ export async function getInfoFromManifest(
info = <IGoVersionInfo>{};
info.type = 'manifest';
info.resolvedVersion = rel.version;
info.downloadUrl = rel.files[0].download_url;
// Replace the default github.com URL with the custom download site
info.downloadUrl = rel.files[0].download_url.replace('https://github.com', goDownloadSite);
Copy link

Copilot AI Nov 29, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The URL replacement has two potential issues:

  1. String replace is not precise: Using replace() with a string will replace any occurrence of 'https://github.com' in the URL, not just at the beginning. Use a regex with ^ anchor for safety.

  2. No trailing slash handling: If goDownloadSite ends with a trailing slash, the result will have a double slash (e.g., https://example.com//actions/...).

Suggested fix:

const normalizedSite = goDownloadSite.replace(/\/$/, '');
info.downloadUrl = rel.files[0].download_url.replace(/^https:\/\/github\.com/, normalizedSite);

This ensures only the base URL is replaced and handles trailing slashes gracefully.

Suggested change
info.downloadUrl = rel.files[0].download_url.replace('https://github.com', goDownloadSite);
const normalizedSite = goDownloadSite.replace(/\/$/, '');
info.downloadUrl = rel.files[0].download_url.replace(/^https:\/\/github\.com/, normalizedSite);

Copilot uses AI. Check for mistakes.
info.fileName = rel.files[0].filename;
}

Expand Down
4 changes: 3 additions & 1 deletion src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,14 @@ export async function run() {
const auth = !token ? undefined : `token ${token}`;

const checkLatest = core.getBooleanInput('check-latest');
const goDownloadSite = core.getInput('go-download-site') || 'https://github.com';
Copy link

Copilot AI Nov 29, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] The fallback || 'https://github.com' is redundant since go-download-site has a default value in action.yml. The core.getInput() will return the default value from action.yml if not explicitly provided by the user. While this defensive approach doesn't cause issues, it could be simplified to just:

const goDownloadSite = core.getInput('go-download-site');

This makes the code cleaner and relies on the single source of truth for the default value in action.yml.

Suggested change
const goDownloadSite = core.getInput('go-download-site') || 'https://github.com';
const goDownloadSite = core.getInput('go-download-site');

Copilot uses AI. Check for mistakes.

const installDir = await installer.getGo(
versionSpec,
checkLatest,
auth,
arch
arch,
goDownloadSite
);

const installDirVersion = path.basename(path.dirname(installDir));
Expand Down