Skip to content

Commit

Permalink
Merge branch 'jeremy-daley-kr-main'
Browse files Browse the repository at this point in the history
  • Loading branch information
JamesMGreene committed Feb 16, 2023
2 parents 2396801 + 83d8e1a commit fc89b04
Show file tree
Hide file tree
Showing 9 changed files with 13,859 additions and 14,146 deletions.
26,743 changes: 13,016 additions & 13,727 deletions dist/index.js

Large diffs are not rendered by default.

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

Large diffs are not rendered by default.

604 changes: 443 additions & 161 deletions dist/licenses.txt

Large diffs are not rendered by default.

483 changes: 327 additions & 156 deletions package-lock.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
"homepage": "https://github.com/actions/configure-pages#readme",
"dependencies": {
"@actions/core": "^1.10.0",
"axios": "^1.3.3",
"@actions/github": "^5.1.1",
"espree": "^9.4.1"
},
"devDependencies": {
Expand Down
48 changes: 18 additions & 30 deletions src/api-client.js
Original file line number Diff line number Diff line change
@@ -1,25 +1,15 @@
const axios = require('axios')
const core = require('@actions/core')
const github = require('@actions/github')

function getApiBaseUrl() {
return process.env.GITHUB_API_URL || 'https://api.github.com'
}

async function enablePagesSite({ repositoryNwo, githubToken }) {
const pagesEndpoint = `${getApiBaseUrl()}/repos/${repositoryNwo}/pages`
async function enablePagesSite({ githubToken }) {
const octokit = github.getOctokit(githubToken)

try {
const response = await axios.post(
pagesEndpoint,
{ build_type: 'workflow' },
{
headers: {
Accept: 'application/vnd.github.v3+json',
Authorization: `Bearer ${githubToken}`,
'Content-type': 'application/json'
}
}
)
const response = await octokit.rest.repos.createPagesSite({
owner: github.context.repo.owner,
repo: github.context.repo.repo,
build_type: 'workflow'
})

const pageObject = response.data
return pageObject
Expand All @@ -32,26 +22,24 @@ async function enablePagesSite({ repositoryNwo, githubToken }) {
}
}

async function getPagesSite({ repositoryNwo, githubToken }) {
const pagesEndpoint = `${getApiBaseUrl()}/repos/${repositoryNwo}/pages`
async function getPagesSite({ githubToken }) {
const octokit = github.getOctokit(githubToken)

const response = await axios.get(pagesEndpoint, {
headers: {
Accept: 'application/vnd.github.v3+json',
Authorization: `Bearer ${githubToken}`
}
const response = await octokit.rest.repos.getPages({
owner: github.context.repo.owner,
repo: github.context.repo.repo
})

const pageObject = response.data
return pageObject
}

async function findOrCreatePagesSite({ repositoryNwo, githubToken, enablement = true }) {
async function findOrCreatePagesSite({ githubToken, enablement = true }) {
let pageObject

// Try to find an existing Pages site first
try {
pageObject = await getPagesSite({ repositoryNwo, githubToken })
pageObject = await getPagesSite({ githubToken })
} catch (error) {
if (!enablement) {
core.error('Get Pages site failed', error)
Expand All @@ -63,7 +51,7 @@ async function findOrCreatePagesSite({ repositoryNwo, githubToken, enablement =
if (!pageObject && enablement) {
// Create a new Pages site if one doesn't exist
try {
pageObject = await enablePagesSite({ repositoryNwo, githubToken })
pageObject = await enablePagesSite({ githubToken })
} catch (error) {
core.error('Create Pages site failed', error)
throw error
Expand All @@ -73,7 +61,7 @@ async function findOrCreatePagesSite({ repositoryNwo, githubToken, enablement =
// Try one more time for this extreme edge case!
if (pageObject == null) {
try {
pageObject = await getPagesSite({ repositoryNwo, githubToken })
pageObject = await getPagesSite({ githubToken })
} catch (error) {
core.error('Get Pages site still failed', error)
throw error
Expand All @@ -84,4 +72,4 @@ async function findOrCreatePagesSite({ repositoryNwo, githubToken, enablement =
return pageObject
}

module.exports = { findOrCreatePagesSite, enablePagesSite, getPagesSite, getApiBaseUrl }
module.exports = { findOrCreatePagesSite, enablePagesSite, getPagesSite }
118 changes: 51 additions & 67 deletions src/api-client.test.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,34 @@
const core = require('@actions/core')
const axios = require('axios')

const apiClient = require('./api-client')

const mockGetPages = jest.fn()
const mockCreatePagesSite = jest.fn()

jest.mock('@actions/github', () => ({
context: {
repo: {
owner: 'actions',
repo: 'is-awesome'
}
},
getOctokit: () => ({
rest: {
repos: {
getPages: mockGetPages,
createPagesSite: mockCreatePagesSite
}
}
})
}))

describe('apiClient', () => {
const GITHUB_REPOSITORY = 'actions/is-awesome'
const GITHUB_TOKEN = 'gha-token'
const PAGE_OBJECT = { html_url: 'https://actions.github.io/is-awesome/' }

beforeEach(() => {
jest.restoreAllMocks()
jest.clearAllMocks()
jest.resetAllMocks()

// Mock error/warning/info/debug
jest.spyOn(core, 'error').mockImplementation(jest.fn())
Expand All @@ -18,59 +37,33 @@ describe('apiClient', () => {
jest.spyOn(core, 'debug').mockImplementation(jest.fn())
})

describe('getApiBaseUrl', () => {
it('returns GITHUB_API_URL environment variable when set', async () => {
const expectedBaseUrl = 'https://api.ghe.com'
process.env.GITHUB_API_URL = expectedBaseUrl
const result = apiClient.getApiBaseUrl()
delete process.env.GITHUB_API_URL
expect(result).toEqual(expectedBaseUrl)
})

it('defaults to GitHub API if GITHUB_API_URL environment variable is empty', async () => {
process.env.GITHUB_API_URL = ''
const result = apiClient.getApiBaseUrl()
delete process.env.GITHUB_API_URL
expect(result).toEqual('https://api.github.com')
})

it('defaults to GitHub API if GITHUB_API_URL environment variable is not set', async () => {
delete process.env.GITHUB_API_URL
const result = apiClient.getApiBaseUrl()
expect(result).toEqual('https://api.github.com')
})
})

describe('enablePagesSite', () => {
it('makes a request to create a page', async () => {
jest.spyOn(axios, 'post').mockImplementationOnce(() => Promise.resolve({ status: 201, data: PAGE_OBJECT }))
mockCreatePagesSite.mockImplementationOnce(() => Promise.resolve({ status: 201, data: PAGE_OBJECT }))

const result = await apiClient.enablePagesSite({
repositoryNwo: GITHUB_REPOSITORY,
githubToken: GITHUB_TOKEN
})
expect(result).toEqual(PAGE_OBJECT)
})

it('handles a 409 response when the page already exists', async () => {
jest.spyOn(axios, 'post').mockImplementationOnce(() => Promise.reject({ response: { status: 409 } }))
mockCreatePagesSite.mockImplementationOnce(() => Promise.reject({ response: { status: 409 } }))

// Simply assert that no error is raised
const result = await apiClient.enablePagesSite({
repositoryNwo: GITHUB_REPOSITORY,
githubToken: GITHUB_TOKEN
})

expect(result).toBe(null)
})

it('re-raises errors on failure status codes', async () => {
jest.spyOn(axios, 'post').mockImplementationOnce(() => Promise.reject({ response: { status: 404 } }))
mockCreatePagesSite.mockImplementationOnce(() => Promise.reject({ response: { status: 404 } }))

let erred = false
try {
await apiClient.enablePagesSite({
repositoryNwo: GITHUB_REPOSITORY,
githubToken: GITHUB_TOKEN
})
} catch (error) {
Expand All @@ -84,22 +77,20 @@ describe('apiClient', () => {
describe('getPagesSite', () => {
it('makes a request to get a page', async () => {
const PAGE_OBJECT = { html_url: 'https://actions.github.io/is-awesome/' }
jest.spyOn(axios, 'get').mockImplementationOnce(() => Promise.resolve({ status: 200, data: PAGE_OBJECT }))
mockGetPages.mockImplementationOnce(() => Promise.resolve({ status: 200, data: PAGE_OBJECT }))

const result = await apiClient.getPagesSite({
repositoryNwo: GITHUB_REPOSITORY,
githubToken: GITHUB_TOKEN
})
expect(result).toEqual(PAGE_OBJECT)
})

it('re-raises errors on failure status codes', async () => {
jest.spyOn(axios, 'get').mockImplementationOnce(() => Promise.reject({ response: { status: 404 } }))
mockGetPages.mockImplementationOnce(() => Promise.reject({ response: { status: 404 } }))

let erred = false
try {
await apiClient.getPagesSite({
repositoryNwo: GITHUB_REPOSITORY,
githubToken: GITHUB_TOKEN
})
} catch (error) {
Expand All @@ -113,55 +104,51 @@ describe('apiClient', () => {
describe('findOrCreatePagesSite', () => {
it('does not make a request to create a page if it already exists', async () => {
const PAGE_OBJECT = { html_url: 'https://actions.github.io/is-awesome/' }
jest.spyOn(axios, 'get').mockImplementationOnce(() => Promise.resolve({ status: 200, data: PAGE_OBJECT }))
jest.spyOn(axios, 'post').mockImplementationOnce(() => Promise.reject({ response: { status: 404 } }))
mockGetPages.mockImplementationOnce(() => Promise.resolve({ status: 200, data: PAGE_OBJECT }))
mockCreatePagesSite.mockImplementationOnce(() => Promise.reject({ response: { status: 404 } }))

const result = await apiClient.findOrCreatePagesSite({
repositoryNwo: GITHUB_REPOSITORY,
githubToken: GITHUB_TOKEN
})
expect(result).toEqual(PAGE_OBJECT)
expect(axios.get).toHaveBeenCalledTimes(1)
expect(axios.post).toHaveBeenCalledTimes(0)
expect(mockGetPages).toHaveBeenCalledTimes(1)
expect(mockCreatePagesSite).toHaveBeenCalledTimes(0)
})

it('makes request to create a page by default if it does not exist', async () => {
const PAGE_OBJECT = { html_url: 'https://actions.github.io/is-awesome/' }
jest.spyOn(axios, 'get').mockImplementationOnce(() => Promise.reject({ response: { status: 404 } }))
jest.spyOn(axios, 'post').mockImplementationOnce(() => Promise.resolve({ status: 201, data: PAGE_OBJECT }))
mockGetPages.mockImplementationOnce(() => Promise.reject({ response: { status: 404 } }))
mockCreatePagesSite.mockImplementationOnce(() => Promise.resolve({ status: 201, data: PAGE_OBJECT }))

const result = await apiClient.findOrCreatePagesSite({
repositoryNwo: GITHUB_REPOSITORY,
githubToken: GITHUB_TOKEN
})
expect(result).toEqual(PAGE_OBJECT)
expect(axios.get).toHaveBeenCalledTimes(1)
expect(axios.post).toHaveBeenCalledTimes(1)
expect(mockGetPages).toHaveBeenCalledTimes(1)
expect(mockCreatePagesSite).toHaveBeenCalledTimes(1)
})

it('makes a request to create a page when explicitly enabled if it does not exist', async () => {
const PAGE_OBJECT = { html_url: 'https://actions.github.io/is-awesome/' }
jest.spyOn(axios, 'get').mockImplementationOnce(() => Promise.reject({ response: { status: 404 } }))
jest.spyOn(axios, 'post').mockImplementationOnce(() => Promise.resolve({ status: 201, data: PAGE_OBJECT }))
mockGetPages.mockImplementationOnce(() => Promise.reject({ response: { status: 404 } }))
mockCreatePagesSite.mockImplementationOnce(() => Promise.resolve({ status: 201, data: PAGE_OBJECT }))

const result = await apiClient.findOrCreatePagesSite({
repositoryNwo: GITHUB_REPOSITORY,
githubToken: GITHUB_TOKEN,
enablement: true
})
expect(result).toEqual(PAGE_OBJECT)
expect(axios.get).toHaveBeenCalledTimes(1)
expect(axios.post).toHaveBeenCalledTimes(1)
expect(mockGetPages).toHaveBeenCalledTimes(1)
expect(mockCreatePagesSite).toHaveBeenCalledTimes(1)
})

it('does not make a request to create a page when explicitly disabled even if it does not exist', async () => {
jest.spyOn(axios, 'get').mockImplementationOnce(() => Promise.reject({ response: { status: 404 } }))
jest.spyOn(axios, 'post').mockImplementationOnce(() => Promise.reject({ response: { status: 500 } })) // just so they both aren't 404
mockGetPages.mockImplementationOnce(() => Promise.reject({ response: { status: 404 } }))
mockCreatePagesSite.mockImplementationOnce(() => Promise.reject({ response: { status: 500 } })) // just so they both aren't 404

let erred = false
try {
await apiClient.findOrCreatePagesSite({
repositoryNwo: GITHUB_REPOSITORY,
githubToken: GITHUB_TOKEN,
enablement: false
})
Expand All @@ -171,18 +158,17 @@ describe('apiClient', () => {
expect(error.response.status).toEqual(404)
}
expect(erred).toBe(true)
expect(axios.get).toHaveBeenCalledTimes(1)
expect(axios.post).toHaveBeenCalledTimes(0)
expect(mockGetPages).toHaveBeenCalledTimes(1)
expect(mockCreatePagesSite).toHaveBeenCalledTimes(0)
})

it('does not make a second request to get page if create fails for reason other than existence', async () => {
jest.spyOn(axios, 'get').mockImplementationOnce(() => Promise.reject({ response: { status: 404 } }))
jest.spyOn(axios, 'post').mockImplementationOnce(() => Promise.reject({ response: { status: 500 } })) // just so they both aren't 404
mockGetPages.mockImplementationOnce(() => Promise.reject({ response: { status: 404 } }))
mockCreatePagesSite.mockImplementationOnce(() => Promise.reject({ response: { status: 500 } })) // just so they both aren't 404

let erred = false
try {
await apiClient.findOrCreatePagesSite({
repositoryNwo: GITHUB_REPOSITORY,
githubToken: GITHUB_TOKEN
})
} catch (error) {
Expand All @@ -191,25 +177,23 @@ describe('apiClient', () => {
expect(error.response.status).toEqual(500)
}
expect(erred).toBe(true)
expect(axios.get).toHaveBeenCalledTimes(1)
expect(axios.post).toHaveBeenCalledTimes(1)
expect(mockGetPages).toHaveBeenCalledTimes(1)
expect(mockCreatePagesSite).toHaveBeenCalledTimes(1)
})

it('makes second request to get page if create fails because of existence', async () => {
const PAGE_OBJECT = { html_url: 'https://actions.github.io/is-awesome/' }
jest
.spyOn(axios, 'get')
mockGetPages
.mockImplementationOnce(() => Promise.reject({ response: { status: 404 } }))
.mockImplementationOnce(() => Promise.resolve({ status: 200, data: PAGE_OBJECT }))
jest.spyOn(axios, 'post').mockImplementationOnce(() => Promise.reject({ response: { status: 409 } }))
mockCreatePagesSite.mockImplementationOnce(() => Promise.reject({ response: { status: 409 } }))

const result = await apiClient.findOrCreatePagesSite({
repositoryNwo: GITHUB_REPOSITORY,
githubToken: GITHUB_TOKEN
})
expect(result).toEqual(PAGE_OBJECT)
expect(axios.get).toHaveBeenCalledTimes(2)
expect(axios.post).toHaveBeenCalledTimes(1)
expect(mockGetPages).toHaveBeenCalledTimes(2)
expect(mockCreatePagesSite).toHaveBeenCalledTimes(1)
})
})
})
1 change: 0 additions & 1 deletion src/context.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ const core = require('@actions/core')
// Load variables from Actions runtime
function getRequiredVars() {
return {
repositoryNwo: process.env.GITHUB_REPOSITORY,
githubToken: core.getInput('token'),
staticSiteGenerator: core.getInput('static_site_generator'),
generatorConfigFile: core.getInput('generator_config_file'),
Expand Down
4 changes: 2 additions & 2 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ const outputPagesBaseUrl = require('./output-pages-base-url')

async function main() {
try {
const { repositoryNwo, githubToken, enablement, staticSiteGenerator, generatorConfigFile } = getContext()
const { githubToken, enablement, staticSiteGenerator, generatorConfigFile } = getContext()

const pageObject = await findOrCreatePagesSite({ repositoryNwo, githubToken, enablement })
const pageObject = await findOrCreatePagesSite({ githubToken, enablement })
const siteUrl = new URL(pageObject.html_url)

if (staticSiteGenerator) {
Expand Down

0 comments on commit fc89b04

Please sign in to comment.