Skip to content

Commit

Permalink
feat(stageconfig): Download stage config from github release (#180)
Browse files Browse the repository at this point in the history
* feat: download stage config from releases

* Update dist

* Fix linting issues

* Fix linting issues

* Fix test

* Fix

* Fix test

* Clean up
  • Loading branch information
vstarostin authored Apr 11, 2024
1 parent c0eae9f commit ee7d736
Show file tree
Hide file tree
Showing 10 changed files with 138 additions and 164 deletions.
101 changes: 45 additions & 56 deletions dist/index.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion dist/index.js.map

Large diffs are not rendered by default.

38 changes: 23 additions & 15 deletions src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,13 @@ import { debug, exportVariable, info } from '@actions/core'
import * as artifact from '@actions/artifact'
import { type UploadResponse } from '@actions/artifact'
import { executePiper } from './execute'
import { downloadFileFromGitHub, getHost } from './github'
import { getHost } from './github'
import {
ENTERPRISE_DEFAULTS_FILENAME,
ENTERPRISE_STAGE_CONFIG_FILENAME,
getEnterpriseDefaultsUrl,
getEnterpriseStageConfigUrl
DEFAULT_CONFIG,
STAGE_CONFIG,
getEnterpriseConfigUrl
} from './enterprise'
import { internalActionVariables } from './piper'

Expand Down Expand Up @@ -44,7 +45,7 @@ export async function getDefaultConfig (server: string, apiURL: string, version:
export async function downloadDefaultConfig (server: string, apiURL: string, version: string, token: string, owner: string, repository: string, customDefaultsPaths: string): Promise<UploadResponse> {
let defaultsPaths: string[] = []

const enterpriseDefaultsURL = await getEnterpriseDefaultsUrl(apiURL, version, token, owner, repository)
const enterpriseDefaultsURL = await getEnterpriseConfigUrl(DEFAULT_CONFIG, apiURL, version, token, owner, repository)
if (enterpriseDefaultsURL !== '') {
defaultsPaths = defaultsPaths.concat([enterpriseDefaultsURL])
}
Expand Down Expand Up @@ -93,21 +94,28 @@ export function saveDefaultConfigs (defaultConfigs: any[]): string[] {
}
}

export async function downloadStageConfig (token: string, owner: string, repository: string): Promise<void> {
await downloadFileFromGitHub(getEnterpriseStageConfigUrl(owner, repository), token)
.then(response => {
const stageConfig = Buffer.from(response.data.content, 'base64').toString('binary')
fs.writeFileSync(path.join(CONFIG_DIR, ENTERPRISE_STAGE_CONFIG_FILENAME), stageConfig)
})
.catch(err => {
throw new Error(`downloading stage configuration failed: ${err as string}`)
})
export async function downloadStageConfig (server: string, apiURL: string, version: string, token: string, owner: string, repository: string): Promise<void> {
const stageConfigURL = await getEnterpriseConfigUrl(STAGE_CONFIG, apiURL, version, token, owner, repository)
if (stageConfigURL === '') {
throw new Error('Can\'t download stage config: failed to get URL!')
}

const piperPath = internalActionVariables.piperBinPath
if (piperPath === undefined) {
throw new Error('Can\'t download stage config: piperPath not defined!')
}
const flags: string[] = ['--useV1']
flags.push('--defaultsFile', stageConfigURL)
flags.push('--gitHubTokens', `${getHost(server)}:${token}`)
const piperExec = await executePiper('getDefaults', flags)
const config = JSON.parse(piperExec.output)
fs.writeFileSync(path.join(CONFIG_DIR, ENTERPRISE_STAGE_CONFIG_FILENAME), config.content)
}

export async function createCheckIfStepActiveMaps (token: string, owner: string, repository: string): Promise<void> {
export async function createCheckIfStepActiveMaps (server: string, apiURL: string, version: string, token: string, owner: string, repository: string): Promise<void> {
info('creating maps with active stages and steps with checkIfStepActive')

await downloadStageConfig(token, owner, repository)
await downloadStageConfig(server, apiURL, version, token, owner, repository)
.then(async () => await checkIfStepActive('_', '_', true))
.catch(err => {
info(`checkIfStepActive failed: ${err as string}`)
Expand Down
34 changes: 20 additions & 14 deletions src/enterprise.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { GITHUB_COM_SERVER_URL, getReleaseAssetUrl } from './github'

export const DEFAULT_CONFIG = 'DefaultConfig'
export const STAGE_CONFIG = 'StageConfig'
export const ENTERPRISE_DEFAULTS_FILENAME = 'piper-defaults.yml'
export const ENTERPRISE_DEFAULTS_FILENAME_ON_RELEASE = 'piper-defaults-github.yml'
export const ENTERPRISE_STAGE_CONFIG_FILENAME = 'github-stage-config.yml'

export const ENTERPRISE_STAGE_CONFIG_FILENAME = 'piper-stage-config.yml'
const ENTERPRISE_STEPNAME_PREFIX = 'sap'

export function isEnterpriseStep (stepName: string): boolean {
Expand All @@ -18,18 +19,23 @@ export function onGitHubEnterprise (): boolean {
return process.env.GITHUB_SERVER_URL !== GITHUB_COM_SERVER_URL
}

// deprecated, keep for backwards compatibility
export async function getEnterpriseDefaultsUrl (apiURL: string, version: string, token: string, owner: string, repository: string): Promise<string> {
// get URL of defaults from the release (gh api, authenticated)
const [enterpriseDefaultsURL] = await getReleaseAssetUrl(ENTERPRISE_DEFAULTS_FILENAME_ON_RELEASE, version, apiURL, token, owner, repository)
if (enterpriseDefaultsURL !== '') return enterpriseDefaultsURL
// fallback to get URL of defaults in the repository (unauthenticated)
return `${process.env.GITHUB_API_URL}/repos/${owner}/${repository}/contents/resources/${ENTERPRISE_DEFAULTS_FILENAME}`
}
export async function getEnterpriseConfigUrl (configType: string, apiURL: string, version: string, token: string, owner: string, repository: string): Promise<string> {
let assetname: string = ''
let filename: string = ''

export function getEnterpriseStageConfigUrl (owner: string, repository: string): string {
if (onGitHubEnterprise() && owner !== '' && repository !== '') {
return `${process.env.GITHUB_API_URL}/repos/${owner}/${repository}/contents/resources/${ENTERPRISE_STAGE_CONFIG_FILENAME}`
if (configType === DEFAULT_CONFIG) {
assetname = ENTERPRISE_DEFAULTS_FILENAME_ON_RELEASE
filename = ENTERPRISE_DEFAULTS_FILENAME
} else if (configType === STAGE_CONFIG) {
assetname = ENTERPRISE_STAGE_CONFIG_FILENAME
filename = ENTERPRISE_STAGE_CONFIG_FILENAME
} else {
return ''
}
return ''

// get URL of defaults from the release (gh api, authenticated)
const [url] = await getReleaseAssetUrl(assetname, version, apiURL, token, owner, repository)
if (url !== '') return url
// fallback to get URL of defaults in the repository (unauthenticated)
return `${process.env.GITHUB_API_URL}/repos/${owner}/${repository}/contents/resources/${filename}`
}
26 changes: 0 additions & 26 deletions src/github.ts
Original file line number Diff line number Diff line change
Expand Up @@ -178,29 +178,3 @@ function getTag (forAPICall: boolean, version: string | undefined): string {
if (version === '' || version === 'master' || version === 'latest') return 'latest'
return `${forAPICall ? 'tags' : 'tag'}/${version}`
}

// Expects a URL in API form:
// https://<host>/api/v3/repos/<org>/<repo>/contents/<folder>/<filename>
// TODO: remove this function after stage-config file is migrated to release assets
export async function downloadFileFromGitHub (url: string, token: string): Promise<OctokitResponse<any>> {
const host = url.substring(0, url.indexOf('/repos'))
const apiRequest = url.substring(url.indexOf('/repos'))

const options: OctokitOptions = {}
options.baseUrl = host
if (token !== '') {
options.auth = token
} else {
throw new Error('token is not provided')
}
const octokit = new Octokit(options)

const response = await octokit.request(
`GET ${apiRequest}`
)
if (response.status !== 200) {
throw new Error(`can't get file: ${response.status}`)
}

return response
}
13 changes: 10 additions & 3 deletions src/piper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,16 @@ export async function run (): Promise<void> {
actionCfg.sapPiperRepo,
actionCfg.customDefaultsPaths
)
}
if (actionCfg.createCheckIfStepActiveMaps) {
await createCheckIfStepActiveMaps(actionCfg.gitHubEnterpriseToken, actionCfg.sapPiperOwner, actionCfg.sapPiperRepo)
if (actionCfg.createCheckIfStepActiveMaps) {
await createCheckIfStepActiveMaps(
actionCfg.gitHubEnterpriseServer,
actionCfg.gitHubEnterpriseApi,
actionCfg.sapPiperVersion,
actionCfg.gitHubEnterpriseToken,
actionCfg.sapPiperOwner,
actionCfg.sapPiperRepo
)
}
}
if (actionCfg.stepName !== '') {
const flags = actionCfg.flags.split(' ')
Expand Down
Loading

0 comments on commit ee7d736

Please sign in to comment.