Skip to content

Commit

Permalink
Adding Forgejo support (#23)
Browse files Browse the repository at this point in the history
Signed-off-by: Janos Bonic <86970079+janosdebugs@users.noreply.github.com>
Co-authored-by: Bence Santha <bence@santha.eu>
  • Loading branch information
janosdebugs and bencurio committed Jan 30, 2024
1 parent 24b9f14 commit da3271e
Show file tree
Hide file tree
Showing 6 changed files with 36 additions and 17 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ A specific version of OpenTofu CLI can be installed:
steps:
- uses: opentofu/setup-opentofu@v1
with:
tofu_version: 1.6.0-alpha1
tofu_version: 1.6.0
```

Credentials for Terraform Cloud ([app.terraform.io](https://app.terraform.io/)) can be configured:
Expand Down Expand Up @@ -257,6 +257,7 @@ The action supports the following inputs:
- `tofu_wrapper` - (optional) Whether to install a wrapper to wrap subsequent calls of
the `tofu` binary and expose its STDOUT, STDERR, and exit code as outputs
named `stdout`, `stderr`, and `exitcode` respectively. Defaults to `true`.
- `github_token` - (optional) Override the GitHub token read from the environment variable. Defaults to the value of the `GITHUB_TOKEN` environment variable unless running on Forgejo or Gitea.

## Outputs

Expand Down
4 changes: 4 additions & 0 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ inputs:
description: 'Whether or not to install a wrapper to wrap subsequent calls of the `tofu` binary and expose its STDOUT, STDERR, and exit code as outputs named `stdout`, `stderr`, and `exitcode` respectively. Defaults to `true`.'
default: 'true'
required: false
github_token:
description: 'API token for GitHub to increase the rate limit. Defaults to the GITHUB_TOKEN environment variable unless running on Forgejo/Gitea.'
default: ''
required: false
outputs:
stdout:
description: 'The STDOUT stream of the call to the `tofu` binary.'
Expand Down
21 changes: 14 additions & 7 deletions dist/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,24 +33,24 @@ class Release {
*
* @return {Array<Release>} Releases.
*/
async function fetchReleases () {
async function fetchReleases (githubToken) {
const url = 'https://api.github.com/repos/opentofu/opentofu/releases';

const headers = {
Accept: 'application/vnd.github+json',
'X-GitHub-Api-Version': '2022-11-28'
};

if (process.env.GITHUB_TOKEN) {
headers.Authorization = `Bearer ${process.env.GITHUB_TOKEN}`;
if (githubToken) {
headers.Authorization = `Bearer ${githubToken}`;
}

const resp = await fetch(url, {
headers
});

if (!resp.ok) {
throw new Error('failed fetching releases');
throw new Error('failed fetching releases (' + resp.status + ')');
}

const releasesMeta = await resp.json();
Expand All @@ -72,18 +72,19 @@ async function findLatestVersionInRange (versions, range) {
* Fetches the release given the version.
*
* @param {string} version: Release version.
* @param {string} githubToken: GitHub token to use for working around rate limits.
* @param {function} fetchReleasesFn: Optional function to fetch releases.
* @return {Release} Release.
*/
async function getRelease (version, fetchReleasesFn = fetchReleases) {
async function getRelease (version, githubToken, fetchReleasesFn = fetchReleases) {
const latestVersionLabel = 'latest';

const versionsRange = semver.validRange(version, { prerelease: true, loose: true });
if (versionsRange === null && version !== latestVersionLabel) {
throw new Error('Input version cannot be used, see semver: https://semver.org/spec/v2.0.0.html');
}

const releases = await fetchReleasesFn();
const releases = await fetchReleasesFn(githubToken);

if (releases === null || releases.length === 0) {
throw new Error('No tofu releases found, please contact OpenTofu');
Expand Down Expand Up @@ -251,13 +252,19 @@ async function run () {
const credentialsHostname = core.getInput('cli_config_credentials_hostname');
const credentialsToken = core.getInput('cli_config_credentials_token');
const wrapper = core.getInput('tofu_wrapper') === 'true';
let githubToken = core.getInput('github_token');
if (githubToken === '' && !(process.env.FORGEJO_ACTIONS || process.env.GITEA_ACTIONS)) {
// Only default to the environment variable when running in GitHub Actions. Don't do this for other CI systems
// that may set the GITHUB_TOKEN environment variable.
githubToken = process.env.GITHUB_TOKEN;
}

// Gather OS details
const osPlatform = os.platform();
const osArch = os.arch();

core.debug(`Finding releases for OpenTofu version ${version}`);
const release = await releases.getRelease(version);
const release = await releases.getRelease(version, githubToken);
const platform = mapOS(osPlatform);
const arch = mapArch(osArch);
const build = release.getBuild(platform, arch);
Expand Down
13 changes: 7 additions & 6 deletions lib/releases.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,24 +27,24 @@ class Release {
*
* @return {Array<Release>} Releases.
*/
async function fetchReleases () {
async function fetchReleases (githubToken) {
const url = 'https://api.github.com/repos/opentofu/opentofu/releases';

const headers = {
Accept: 'application/vnd.github+json',
'X-GitHub-Api-Version': '2022-11-28'
};

if (process.env.GITHUB_TOKEN) {
headers.Authorization = `Bearer ${process.env.GITHUB_TOKEN}`;
if (githubToken) {
headers.Authorization = `Bearer ${githubToken}`;
}

const resp = await fetch(url, {
headers
});

if (!resp.ok) {
throw new Error('failed fetching releases');
throw new Error('failed fetching releases (' + resp.status + ')');
}

const releasesMeta = await resp.json();
Expand All @@ -66,18 +66,19 @@ async function findLatestVersionInRange (versions, range) {
* Fetches the release given the version.
*
* @param {string} version: Release version.
* @param {string} githubToken: GitHub token to use for working around rate limits.
* @param {function} fetchReleasesFn: Optional function to fetch releases.
* @return {Release} Release.
*/
async function getRelease (version, fetchReleasesFn = fetchReleases) {
async function getRelease (version, githubToken, fetchReleasesFn = fetchReleases) {
const latestVersionLabel = 'latest';

const versionsRange = semver.validRange(version, { prerelease: true, loose: true });
if (versionsRange === null && version !== latestVersionLabel) {
throw new Error('Input version cannot be used, see semver: https://semver.org/spec/v2.0.0.html');
}

const releases = await fetchReleasesFn();
const releases = await fetchReleasesFn(githubToken);

if (releases === null || releases.length === 0) {
throw new Error('No tofu releases found, please contact OpenTofu');
Expand Down
8 changes: 7 additions & 1 deletion lib/setup-tofu.js
Original file line number Diff line number Diff line change
Expand Up @@ -132,13 +132,19 @@ async function run () {
const credentialsHostname = core.getInput('cli_config_credentials_hostname');
const credentialsToken = core.getInput('cli_config_credentials_token');
const wrapper = core.getInput('tofu_wrapper') === 'true';
let githubToken = core.getInput('github_token');
if (githubToken === '' && !(process.env.FORGEJO_ACTIONS || process.env.GITEA_ACTIONS)) {
// Only default to the environment variable when running in GitHub Actions. Don't do this for other CI systems
// that may set the GITHUB_TOKEN environment variable.
githubToken = process.env.GITHUB_TOKEN;
}

// Gather OS details
const osPlatform = os.platform();
const osArch = os.arch();

core.debug(`Finding releases for OpenTofu version ${version}`);
const release = await releases.getRelease(version);
const release = await releases.getRelease(version, githubToken);
const platform = mapOS(osPlatform);
const arch = mapArch(osArch);
const build = release.getBuild(platform, arch);
Expand Down
4 changes: 2 additions & 2 deletions lib/test/releases.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ describe('getRelease', () => {
]
)('happy path: getRelease(\'%s\') -> \'%s\'', async (input, wantVersion) => {
const want = mockFetchReleases().find(el => el.version === wantVersion);
const gotRelease = await pkg.getRelease(input, mockFetchReleases);
const gotRelease = await pkg.getRelease(input, '', mockFetchReleases);
expect(gotRelease).toEqual(want);
});

Expand All @@ -210,7 +210,7 @@ describe('getRelease', () => {
]
)('unhappy path: getRelease(\'%s\') -> throw Error(\'%s\')', async (input, wantErrorMessage, mockFetchReleasesFn) => {
try {
await pkg.getRelease(input, mockFetchReleasesFn);
await pkg.getRelease(input, '', mockFetchReleasesFn);
expect(true).toBe(false);
} catch (e) {
expect(e.message).toBe(wantErrorMessage);
Expand Down

0 comments on commit da3271e

Please sign in to comment.