2024-03-01 16:45:32 +00:00
|
|
|
import * as core from '@actions/core'
|
|
|
|
|
import * as github from '@actions/github'
|
|
|
|
|
import * as cfg from '../src/config'
|
2024-03-25 17:44:45 +00:00
|
|
|
import * as apiClient from '../src/api-client'
|
2024-03-01 16:45:32 +00:00
|
|
|
|
|
|
|
|
let getContainerRegistryURLMock: jest.SpyInstance
|
2024-04-15 12:03:02 +01:00
|
|
|
let getRepositoryMetadataMock: jest.SpyInstance
|
2024-03-01 16:45:32 +00:00
|
|
|
let getInputMock: jest.SpyInstance
|
|
|
|
|
|
|
|
|
|
const ghcrUrl = new URL('https://ghcr.io')
|
|
|
|
|
|
|
|
|
|
describe('config.resolvePublishActionOptions', () => {
|
|
|
|
|
beforeEach(() => {
|
|
|
|
|
getContainerRegistryURLMock = jest
|
2024-03-25 17:44:45 +00:00
|
|
|
.spyOn(apiClient, 'getContainerRegistryURL')
|
2024-03-01 16:45:32 +00:00
|
|
|
.mockImplementation()
|
|
|
|
|
|
2024-04-15 12:03:02 +01:00
|
|
|
getRepositoryMetadataMock = jest
|
|
|
|
|
.spyOn(apiClient, 'getRepositoryMetadata')
|
|
|
|
|
.mockImplementation()
|
|
|
|
|
|
2024-03-01 16:45:32 +00:00
|
|
|
getInputMock = jest.spyOn(core, 'getInput').mockImplementation()
|
|
|
|
|
|
|
|
|
|
configureEventContext()
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
afterEach(() => {
|
|
|
|
|
jest.clearAllMocks()
|
|
|
|
|
clearEventContext()
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
it('throws an error when the token is not provided', async () => {
|
|
|
|
|
getInputMock.mockReturnValueOnce(undefined)
|
|
|
|
|
|
|
|
|
|
await expect(cfg.resolvePublishActionOptions()).rejects.toThrow(
|
|
|
|
|
'Could not find GITHUB_TOKEN.'
|
|
|
|
|
)
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
it('throws an error when the event is not provided', async () => {
|
|
|
|
|
getInputMock.mockReturnValueOnce('token')
|
|
|
|
|
github.context.eventName = ''
|
|
|
|
|
|
|
|
|
|
await expect(cfg.resolvePublishActionOptions()).rejects.toThrow(
|
|
|
|
|
'Could not find event name.'
|
|
|
|
|
)
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
it('throws an error when the ref is not provided', async () => {
|
|
|
|
|
getInputMock.mockReturnValueOnce('token')
|
2024-08-28 12:10:13 +01:00
|
|
|
github.context.ref = ''
|
2024-03-01 16:45:32 +00:00
|
|
|
|
|
|
|
|
await expect(cfg.resolvePublishActionOptions()).rejects.toThrow(
|
|
|
|
|
'Could not find GITHUB_REF.'
|
|
|
|
|
)
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
it('throws an error when the workspaceDir is not provided', async () => {
|
|
|
|
|
getInputMock.mockReturnValueOnce('token')
|
|
|
|
|
process.env.GITHUB_WORKSPACE = ''
|
|
|
|
|
|
|
|
|
|
await expect(cfg.resolvePublishActionOptions()).rejects.toThrow(
|
|
|
|
|
'Could not find GITHUB_WORKSPACE.'
|
|
|
|
|
)
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
it('throws an error when the repository is not provided', async () => {
|
|
|
|
|
getInputMock.mockReturnValueOnce('token')
|
2024-08-28 12:10:13 +01:00
|
|
|
github.context.payload.repository = undefined
|
2024-03-01 16:45:32 +00:00
|
|
|
|
|
|
|
|
await expect(cfg.resolvePublishActionOptions()).rejects.toThrow(
|
|
|
|
|
'Could not find Repository.'
|
|
|
|
|
)
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
it('throws an error when the apiBaseUrl is not provided', async () => {
|
|
|
|
|
getInputMock.mockReturnValueOnce('token')
|
2024-08-28 12:10:13 +01:00
|
|
|
github.context.apiUrl = ''
|
2024-03-01 16:45:32 +00:00
|
|
|
|
|
|
|
|
await expect(cfg.resolvePublishActionOptions()).rejects.toThrow(
|
|
|
|
|
'Could not find GITHUB_API_URL.'
|
|
|
|
|
)
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
it('throws an error when the runnerTempDir is not provided', async () => {
|
|
|
|
|
getInputMock.mockReturnValueOnce('token')
|
|
|
|
|
process.env.RUNNER_TEMP = ''
|
|
|
|
|
|
|
|
|
|
await expect(cfg.resolvePublishActionOptions()).rejects.toThrow(
|
|
|
|
|
'Could not find RUNNER_TEMP.'
|
|
|
|
|
)
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
it('throws an error when the sha is not provided', async () => {
|
|
|
|
|
getInputMock.mockReturnValueOnce('token')
|
2024-08-28 12:10:13 +01:00
|
|
|
github.context.sha = ''
|
2024-03-01 16:45:32 +00:00
|
|
|
|
|
|
|
|
await expect(cfg.resolvePublishActionOptions()).rejects.toThrow(
|
|
|
|
|
'Could not find GITHUB_SHA.'
|
|
|
|
|
)
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
it('throws an error when the githubServerUrl is not provided', async () => {
|
|
|
|
|
getInputMock.mockReturnValueOnce('token')
|
2024-08-28 12:10:13 +01:00
|
|
|
github.context.serverUrl = ''
|
2024-03-01 16:45:32 +00:00
|
|
|
|
|
|
|
|
await expect(cfg.resolvePublishActionOptions()).rejects.toThrow(
|
|
|
|
|
'Could not find GITHUB_SERVER_URL.'
|
|
|
|
|
)
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
it('throws an error when the repositoryId is not provided', async () => {
|
|
|
|
|
getInputMock.mockReturnValueOnce('token')
|
|
|
|
|
process.env.GITHUB_REPOSITORY_ID = ''
|
|
|
|
|
|
|
|
|
|
await expect(cfg.resolvePublishActionOptions()).rejects.toThrow(
|
|
|
|
|
'Could not find GITHUB_REPOSITORY_ID.'
|
|
|
|
|
)
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
it('throws an error when the repositoryOwnerId is not provided', async () => {
|
|
|
|
|
getInputMock.mockReturnValueOnce('token')
|
|
|
|
|
process.env.GITHUB_REPOSITORY_OWNER_ID = ''
|
|
|
|
|
|
|
|
|
|
await expect(cfg.resolvePublishActionOptions()).rejects.toThrow(
|
|
|
|
|
'Could not find GITHUB_REPOSITORY_OWNER_ID.'
|
|
|
|
|
)
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
it('throws an error when getting the container registry URL fails', async () => {
|
|
|
|
|
getInputMock.mockReturnValueOnce('token')
|
|
|
|
|
getContainerRegistryURLMock.mockRejectedValue(
|
|
|
|
|
new Error('Failed to get container registry URL')
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
await expect(cfg.resolvePublishActionOptions()).rejects.toThrow(
|
|
|
|
|
'Failed to get container registry URL'
|
|
|
|
|
)
|
|
|
|
|
})
|
|
|
|
|
|
2024-04-15 12:03:02 +01:00
|
|
|
it('throws an error when getting the repository metadata fails', async () => {
|
|
|
|
|
getInputMock.mockReturnValueOnce('token')
|
|
|
|
|
getContainerRegistryURLMock.mockResolvedValue(ghcrUrl)
|
|
|
|
|
getRepositoryMetadataMock.mockRejectedValue(
|
|
|
|
|
new Error('Failed to get repository metadata')
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
await expect(cfg.resolvePublishActionOptions()).rejects.toThrow(
|
|
|
|
|
'Failed to get repository metadata'
|
|
|
|
|
)
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
it('throws an error when returned repository visibility is empty', async () => {
|
|
|
|
|
getInputMock.mockReturnValueOnce('token')
|
|
|
|
|
getContainerRegistryURLMock.mockResolvedValue(ghcrUrl)
|
|
|
|
|
getRepositoryMetadataMock.mockResolvedValue({
|
|
|
|
|
visibility: ''
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
await expect(cfg.resolvePublishActionOptions()).rejects.toThrow(
|
|
|
|
|
'Could not find repository visibility.'
|
|
|
|
|
)
|
|
|
|
|
})
|
|
|
|
|
|
2024-04-15 12:26:26 +01:00
|
|
|
it('throws an error when returned repository id does not match env var', async () => {
|
|
|
|
|
getInputMock.mockReturnValueOnce('token')
|
|
|
|
|
getContainerRegistryURLMock.mockResolvedValue(ghcrUrl)
|
|
|
|
|
getRepositoryMetadataMock.mockResolvedValue({
|
|
|
|
|
visibility: 'public',
|
|
|
|
|
ownerId: '12345',
|
|
|
|
|
repoId: '54321'
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
await expect(cfg.resolvePublishActionOptions()).rejects.toThrow(
|
|
|
|
|
'Repository ID mismatch.'
|
|
|
|
|
)
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
it('throws an error when returned repository owner id does not match env var', async () => {
|
|
|
|
|
getInputMock.mockReturnValueOnce('token')
|
|
|
|
|
getContainerRegistryURLMock.mockResolvedValue(ghcrUrl)
|
|
|
|
|
getRepositoryMetadataMock.mockResolvedValue({
|
|
|
|
|
visibility: 'public',
|
|
|
|
|
ownerId: '123124',
|
|
|
|
|
repoId: 'repositoryId'
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
await expect(cfg.resolvePublishActionOptions()).rejects.toThrow(
|
|
|
|
|
'Repository Owner ID mismatch.'
|
|
|
|
|
)
|
|
|
|
|
})
|
|
|
|
|
|
2024-03-01 16:45:32 +00:00
|
|
|
it('returns options when all values are present', async () => {
|
|
|
|
|
getInputMock.mockImplementation((name: string) => {
|
|
|
|
|
expect(name).toBe('github-token')
|
|
|
|
|
return 'token'
|
|
|
|
|
})
|
|
|
|
|
getContainerRegistryURLMock.mockResolvedValue(ghcrUrl)
|
|
|
|
|
|
2024-04-15 12:03:02 +01:00
|
|
|
getRepositoryMetadataMock.mockResolvedValue({
|
2024-04-15 12:26:26 +01:00
|
|
|
visibility: 'public',
|
|
|
|
|
repoId: 'repositoryId',
|
|
|
|
|
ownerId: 'repositoryOwnerId'
|
2024-04-15 12:03:02 +01:00
|
|
|
})
|
|
|
|
|
|
2024-03-01 16:45:32 +00:00
|
|
|
const options = await cfg.resolvePublishActionOptions()
|
|
|
|
|
|
|
|
|
|
expect(options).toEqual({
|
|
|
|
|
nameWithOwner: 'nameWithOwner',
|
|
|
|
|
ref: 'ref',
|
|
|
|
|
workspaceDir: 'workspaceDir',
|
|
|
|
|
event: 'release',
|
|
|
|
|
apiBaseUrl: 'apiBaseUrl',
|
|
|
|
|
runnerTempDir: 'runnerTempDir',
|
|
|
|
|
sha: 'sha',
|
2024-04-15 12:03:02 +01:00
|
|
|
repositoryVisibility: 'public',
|
2024-03-01 16:45:32 +00:00
|
|
|
repositoryId: 'repositoryId',
|
|
|
|
|
repositoryOwnerId: 'repositoryOwnerId',
|
|
|
|
|
isEnterprise: false,
|
|
|
|
|
containerRegistryUrl: ghcrUrl,
|
|
|
|
|
token: 'token'
|
|
|
|
|
})
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
it('sets enterprise to true when the server URL is not github.com or ghe.com', async () => {
|
|
|
|
|
getInputMock.mockImplementation((name: string) => {
|
|
|
|
|
expect(name).toBe('github-token')
|
|
|
|
|
return 'token'
|
|
|
|
|
})
|
|
|
|
|
getContainerRegistryURLMock.mockResolvedValue(ghcrUrl)
|
2024-04-15 12:26:26 +01:00
|
|
|
|
2024-04-15 12:03:02 +01:00
|
|
|
getRepositoryMetadataMock.mockResolvedValue({
|
2024-04-15 12:26:26 +01:00
|
|
|
visibility: 'public',
|
|
|
|
|
repoId: 'repositoryId',
|
|
|
|
|
ownerId: 'repositoryOwnerId'
|
2024-04-15 12:03:02 +01:00
|
|
|
})
|
2024-03-01 16:45:32 +00:00
|
|
|
|
2024-08-28 12:10:13 +01:00
|
|
|
github.context.serverUrl = 'https://github-enterprise.com'
|
2024-03-01 16:45:32 +00:00
|
|
|
|
|
|
|
|
const options = await cfg.resolvePublishActionOptions()
|
|
|
|
|
|
|
|
|
|
expect(options).toEqual({
|
|
|
|
|
nameWithOwner: 'nameWithOwner',
|
|
|
|
|
ref: 'ref',
|
|
|
|
|
workspaceDir: 'workspaceDir',
|
|
|
|
|
event: 'release',
|
|
|
|
|
apiBaseUrl: 'apiBaseUrl',
|
|
|
|
|
runnerTempDir: 'runnerTempDir',
|
|
|
|
|
sha: 'sha',
|
|
|
|
|
repositoryId: 'repositoryId',
|
|
|
|
|
repositoryOwnerId: 'repositoryOwnerId',
|
|
|
|
|
isEnterprise: true,
|
|
|
|
|
containerRegistryUrl: ghcrUrl,
|
2024-04-15 12:03:02 +01:00
|
|
|
token: 'token',
|
|
|
|
|
repositoryVisibility: 'public'
|
2024-03-01 16:45:32 +00:00
|
|
|
})
|
|
|
|
|
})
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
describe('config.serializeOptions', () => {
|
|
|
|
|
it('serializes the options, ignoring internal keys', () => {
|
|
|
|
|
const options: cfg.PublishActionOptions = {
|
|
|
|
|
nameWithOwner: 'nameWithOwner',
|
|
|
|
|
ref: 'ref',
|
|
|
|
|
workspaceDir: 'workspaceDir',
|
|
|
|
|
event: 'release',
|
|
|
|
|
apiBaseUrl: 'apiBaseUrl',
|
|
|
|
|
runnerTempDir: 'runnerTempDir',
|
|
|
|
|
sha: 'sha',
|
|
|
|
|
repositoryId: 'repositoryId',
|
|
|
|
|
repositoryOwnerId: 'repositoryOwnerId',
|
|
|
|
|
isEnterprise: false,
|
|
|
|
|
containerRegistryUrl: ghcrUrl,
|
2024-04-15 12:03:02 +01:00
|
|
|
token: 'token',
|
|
|
|
|
repositoryVisibility: 'public'
|
2024-03-01 16:45:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const serialized = cfg.serializeOptions(options)
|
|
|
|
|
|
|
|
|
|
// Parse the JSON
|
|
|
|
|
const parsed = JSON.parse(serialized)
|
|
|
|
|
|
|
|
|
|
expect(parsed.nameWithOwner).toBe('nameWithOwner')
|
|
|
|
|
expect(parsed.ref).toBe('ref')
|
|
|
|
|
expect(parsed.workspaceDir).toBe('workspaceDir')
|
|
|
|
|
expect(parsed.event).toBe('release')
|
|
|
|
|
expect(parsed.apiBaseUrl).toBe('apiBaseUrl')
|
|
|
|
|
expect(parsed.sha).toBe('sha')
|
|
|
|
|
expect(parsed.isEnterprise).toBe(false)
|
|
|
|
|
expect(parsed.containerRegistryUrl).toBe(ghcrUrl.toString())
|
|
|
|
|
expect(parsed.token).toBeUndefined()
|
|
|
|
|
expect(parsed.repositoryId).toBeUndefined()
|
|
|
|
|
expect(parsed.repositoryOwnerId).toBeUndefined()
|
|
|
|
|
expect(parsed.runnerTempDir).toBeUndefined()
|
|
|
|
|
})
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
function configureEventContext(): void {
|
2024-08-28 12:10:13 +01:00
|
|
|
github.context.ref = 'ref'
|
|
|
|
|
github.context.eventName = 'release'
|
|
|
|
|
github.context.apiUrl = 'apiBaseUrl'
|
|
|
|
|
github.context.sha = 'sha'
|
|
|
|
|
github.context.serverUrl = 'https://github.com/'
|
|
|
|
|
github.context.payload = {
|
|
|
|
|
repository: {
|
|
|
|
|
full_name: 'nameWithOwner',
|
|
|
|
|
name: 'name',
|
|
|
|
|
owner: {
|
|
|
|
|
login: 'owner'
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-01 16:45:32 +00:00
|
|
|
process.env.RUNNER_TEMP = 'runnerTempDir'
|
2024-08-28 12:10:13 +01:00
|
|
|
process.env.GITHUB_WORKSPACE = 'workspaceDir'
|
2024-03-01 16:45:32 +00:00
|
|
|
process.env.GITHUB_REPOSITORY_ID = 'repositoryId'
|
|
|
|
|
process.env.GITHUB_REPOSITORY_OWNER_ID = 'repositoryOwnerId'
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function clearEventContext(): void {
|
2024-08-28 12:10:13 +01:00
|
|
|
github.context.ref = ''
|
|
|
|
|
github.context.eventName = ''
|
|
|
|
|
github.context.apiUrl = ''
|
|
|
|
|
github.context.sha = ''
|
|
|
|
|
github.context.serverUrl = ''
|
|
|
|
|
github.context.payload = {}
|
2024-03-01 16:45:32 +00:00
|
|
|
process.env.RUNNER_TEMP = ''
|
2024-08-28 12:10:13 +01:00
|
|
|
process.env.GITHUB_WORKSPACE = ''
|
2024-03-01 16:45:32 +00:00
|
|
|
process.env.GITHUB_REPOSITORY_ID = ''
|
|
|
|
|
process.env.GITHUB_REPOSITORY_OWNER_ID = ''
|
|
|
|
|
}
|