commit
cab09437ea
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"plugins": ["jest", "@typescript-eslint"],
|
"plugins": ["jest", "@typescript-eslint"],
|
||||||
"extends": ["plugin:github/es6"],
|
"extends": ["plugin:github/recommended"],
|
||||||
"parser": "@typescript-eslint/parser",
|
"parser": "@typescript-eslint/parser",
|
||||||
"parserOptions": {
|
"parserOptions": {
|
||||||
"ecmaVersion": 9,
|
"ecmaVersion": 9,
|
||||||
|
@ -16,13 +16,9 @@
|
||||||
"@typescript-eslint/no-require-imports": "error",
|
"@typescript-eslint/no-require-imports": "error",
|
||||||
"@typescript-eslint/array-type": "error",
|
"@typescript-eslint/array-type": "error",
|
||||||
"@typescript-eslint/await-thenable": "error",
|
"@typescript-eslint/await-thenable": "error",
|
||||||
"@typescript-eslint/ban-ts-ignore": "error",
|
|
||||||
"camelcase": "off",
|
"camelcase": "off",
|
||||||
"@typescript-eslint/camelcase": "error",
|
|
||||||
"@typescript-eslint/class-name-casing": "error",
|
|
||||||
"@typescript-eslint/explicit-function-return-type": ["error", {"allowExpressions": true}],
|
"@typescript-eslint/explicit-function-return-type": ["error", {"allowExpressions": true}],
|
||||||
"@typescript-eslint/func-call-spacing": ["error", "never"],
|
"@typescript-eslint/func-call-spacing": ["error", "never"],
|
||||||
"@typescript-eslint/generic-type-naming": ["error", "^[A-Z][A-Za-z]*$"],
|
|
||||||
"@typescript-eslint/no-array-constructor": "error",
|
"@typescript-eslint/no-array-constructor": "error",
|
||||||
"@typescript-eslint/no-empty-interface": "error",
|
"@typescript-eslint/no-empty-interface": "error",
|
||||||
"@typescript-eslint/no-explicit-any": "error",
|
"@typescript-eslint/no-explicit-any": "error",
|
||||||
|
@ -33,7 +29,6 @@
|
||||||
"@typescript-eslint/no-misused-new": "error",
|
"@typescript-eslint/no-misused-new": "error",
|
||||||
"@typescript-eslint/no-namespace": "error",
|
"@typescript-eslint/no-namespace": "error",
|
||||||
"@typescript-eslint/no-non-null-assertion": "warn",
|
"@typescript-eslint/no-non-null-assertion": "warn",
|
||||||
"@typescript-eslint/no-object-literal-type-assertion": "error",
|
|
||||||
"@typescript-eslint/no-unnecessary-qualifier": "error",
|
"@typescript-eslint/no-unnecessary-qualifier": "error",
|
||||||
"@typescript-eslint/no-unnecessary-type-assertion": "error",
|
"@typescript-eslint/no-unnecessary-type-assertion": "error",
|
||||||
"@typescript-eslint/no-useless-constructor": "error",
|
"@typescript-eslint/no-useless-constructor": "error",
|
||||||
|
@ -41,7 +36,6 @@
|
||||||
"@typescript-eslint/prefer-for-of": "warn",
|
"@typescript-eslint/prefer-for-of": "warn",
|
||||||
"@typescript-eslint/prefer-function-type": "warn",
|
"@typescript-eslint/prefer-function-type": "warn",
|
||||||
"@typescript-eslint/prefer-includes": "error",
|
"@typescript-eslint/prefer-includes": "error",
|
||||||
"@typescript-eslint/prefer-interface": "error",
|
|
||||||
"@typescript-eslint/prefer-string-starts-ends-with": "error",
|
"@typescript-eslint/prefer-string-starts-ends-with": "error",
|
||||||
"@typescript-eslint/promise-function-async": "error",
|
"@typescript-eslint/promise-function-async": "error",
|
||||||
"@typescript-eslint/require-array-sort-compare": "error",
|
"@typescript-eslint/require-array-sort-compare": "error",
|
||||||
|
|
|
@ -0,0 +1,51 @@
|
||||||
|
# `dist/index.js` is a special file in Actions.
|
||||||
|
# When you reference an action with `uses:` in a workflow,
|
||||||
|
# `index.js` is the code that will run.
|
||||||
|
# For our project, we generate this file through a build process
|
||||||
|
# from other source files.
|
||||||
|
# We need to make sure the checked-in `index.js` actually matches what we expect it to be.
|
||||||
|
name: Check dist
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
paths-ignore:
|
||||||
|
- '**.md'
|
||||||
|
pull_request:
|
||||||
|
paths-ignore:
|
||||||
|
- '**.md'
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
check-dist:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
|
||||||
|
- name: Set Node.js 12.x
|
||||||
|
uses: actions/setup-node@v1
|
||||||
|
with:
|
||||||
|
node-version: 12.x
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
run: npm ci
|
||||||
|
|
||||||
|
- name: Rebuild the index.js file
|
||||||
|
run: npm run build
|
||||||
|
|
||||||
|
- name: Compare the expected and actual dist/ directories
|
||||||
|
run: |
|
||||||
|
if [ "$(git diff --ignore-space-at-eol dist/ | wc -l)" -gt "0" ]; then
|
||||||
|
echo "Detected uncommitted changes after build. See status below:"
|
||||||
|
git diff
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# If dist/ was different than expected, upload the expected version as an artifact
|
||||||
|
- uses: actions/upload-artifact@v2
|
||||||
|
if: ${{ failure() && steps.diff.conclusion == 'failure' }}
|
||||||
|
with:
|
||||||
|
name: dist
|
||||||
|
path: dist/
|
|
@ -0,0 +1,58 @@
|
||||||
|
# For most projects, this workflow file will not need changing; you simply need
|
||||||
|
# to commit it to your repository.
|
||||||
|
#
|
||||||
|
# You may wish to alter this file to override the set of languages analyzed,
|
||||||
|
# or to provide custom queries or build logic.
|
||||||
|
#
|
||||||
|
# ******** NOTE ********
|
||||||
|
# We have attempted to detect the languages in your repository. Please check
|
||||||
|
# the `language` matrix defined below to confirm you have the correct set of
|
||||||
|
# supported CodeQL languages.
|
||||||
|
#
|
||||||
|
name: "CodeQL"
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [ main ]
|
||||||
|
pull_request:
|
||||||
|
# The branches below must be a subset of the branches above
|
||||||
|
branches: [ main ]
|
||||||
|
schedule:
|
||||||
|
- cron: '28 9 * * 0'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
analyze:
|
||||||
|
name: Analyze
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
actions: read
|
||||||
|
contents: read
|
||||||
|
security-events: write
|
||||||
|
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
language: [ 'javascript' ]
|
||||||
|
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ]
|
||||||
|
# Learn more:
|
||||||
|
# https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
|
||||||
|
- name: Initialize CodeQL
|
||||||
|
uses: github/codeql-action/init@v1
|
||||||
|
with:
|
||||||
|
languages: ${{ matrix.language }}
|
||||||
|
# If you wish to specify custom queries, you can do so here or in a config file.
|
||||||
|
# By default, queries listed here will override any specified in a config file.
|
||||||
|
# Prefix the list here with "+" to use these queries and those in the config file.
|
||||||
|
# queries: ./path/to/local/query, your-org/your-repo/queries@main
|
||||||
|
|
||||||
|
- run: npm ci
|
||||||
|
- run: npm run build
|
||||||
|
- run: rm -rf dist # We want code scanning to analyze lib instead (individual .js files)
|
||||||
|
|
||||||
|
- name: Perform CodeQL Analysis
|
||||||
|
uses: github/codeql-action/analyze@v1
|
|
@ -11,10 +11,4 @@ jobs:
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
- run: npm ci
|
- run: npm ci
|
||||||
- name: Install licensed
|
- run: npm run licensed-check
|
||||||
run: |
|
|
||||||
cd $RUNNER_TEMP
|
|
||||||
curl -Lfs -o licensed.tar.gz https://github.com/github/licensed/releases/download/2.12.2/licensed-2.12.2-linux-x64.tar.gz
|
|
||||||
sudo tar -xzf licensed.tar.gz
|
|
||||||
sudo mv licensed /usr/local/bin/licensed
|
|
||||||
- run: licensed status
|
|
|
@ -1,3 +1,4 @@
|
||||||
__test__/_temp
|
__test__/_temp
|
||||||
|
_temp/
|
||||||
lib/
|
lib/
|
||||||
node_modules/
|
node_modules/
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -185,7 +185,7 @@ Refer [here](https://github.com/actions/checkout/blob/v1/README.md) for previous
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v2
|
||||||
with:
|
with:
|
||||||
repository: my-org/my-private-tools
|
repository: my-org/my-private-tools
|
||||||
token: ${{ secrets.GitHub_PAT }} # `GitHub_PAT` is a secret that contains your PAT
|
token: ${{ secrets.GH_PAT }} # `GH_PAT` is a secret that contains your PAT
|
||||||
path: my-tools
|
path: my-tools
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
|
@ -417,7 +417,7 @@ describe('git-auth-helper tests', () => {
|
||||||
`Did not expect file to exist: '${globalGitConfigPath}'`
|
`Did not expect file to exist: '${globalGitConfigPath}'`
|
||||||
)
|
)
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
if (err.code !== 'ENOENT') {
|
if ((err as any)?.code !== 'ENOENT') {
|
||||||
throw err
|
throw err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -518,12 +518,17 @@ describe('git-auth-helper tests', () => {
|
||||||
await authHelper.configureSubmoduleAuth()
|
await authHelper.configureSubmoduleAuth()
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
expect(mockSubmoduleForeach).toHaveBeenCalledTimes(3)
|
expect(mockSubmoduleForeach).toHaveBeenCalledTimes(4)
|
||||||
expect(mockSubmoduleForeach.mock.calls[0][0]).toMatch(
|
expect(mockSubmoduleForeach.mock.calls[0][0]).toMatch(
|
||||||
/unset-all.*insteadOf/
|
/unset-all.*insteadOf/
|
||||||
)
|
)
|
||||||
expect(mockSubmoduleForeach.mock.calls[1][0]).toMatch(/http.*extraheader/)
|
expect(mockSubmoduleForeach.mock.calls[1][0]).toMatch(/http.*extraheader/)
|
||||||
expect(mockSubmoduleForeach.mock.calls[2][0]).toMatch(/url.*insteadOf/)
|
expect(mockSubmoduleForeach.mock.calls[2][0]).toMatch(
|
||||||
|
/url.*insteadOf.*git@github.com:/
|
||||||
|
)
|
||||||
|
expect(mockSubmoduleForeach.mock.calls[3][0]).toMatch(
|
||||||
|
/url.*insteadOf.*org-123456@github.com:/
|
||||||
|
)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -601,7 +606,7 @@ describe('git-auth-helper tests', () => {
|
||||||
await fs.promises.stat(actualKeyPath)
|
await fs.promises.stat(actualKeyPath)
|
||||||
throw new Error('SSH key should have been deleted')
|
throw new Error('SSH key should have been deleted')
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
if (err.code !== 'ENOENT') {
|
if ((err as any)?.code !== 'ENOENT') {
|
||||||
throw err
|
throw err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -611,7 +616,7 @@ describe('git-auth-helper tests', () => {
|
||||||
await fs.promises.stat(actualKnownHostsPath)
|
await fs.promises.stat(actualKnownHostsPath)
|
||||||
throw new Error('SSH known hosts should have been deleted')
|
throw new Error('SSH known hosts should have been deleted')
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
if (err.code !== 'ENOENT') {
|
if ((err as any)?.code !== 'ENOENT') {
|
||||||
throw err
|
throw err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -658,7 +663,7 @@ describe('git-auth-helper tests', () => {
|
||||||
await fs.promises.stat(homeOverride)
|
await fs.promises.stat(homeOverride)
|
||||||
throw new Error(`Should have been deleted '${homeOverride}'`)
|
throw new Error(`Should have been deleted '${homeOverride}'`)
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
if (err.code !== 'ENOENT') {
|
if ((err as any)?.code !== 'ENOENT') {
|
||||||
throw err
|
throw err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -770,7 +775,8 @@ async function setup(testName: string): Promise<void> {
|
||||||
repositoryPath: '',
|
repositoryPath: '',
|
||||||
sshKey: sshPath ? 'some ssh private key' : '',
|
sshKey: sshPath ? 'some ssh private key' : '',
|
||||||
sshKnownHosts: '',
|
sshKnownHosts: '',
|
||||||
sshStrict: true
|
sshStrict: true,
|
||||||
|
workflowOrganizationId: 123456
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
import * as assert from 'assert'
|
|
||||||
import * as core from '@actions/core'
|
import * as core from '@actions/core'
|
||||||
import * as fsHelper from '../lib/fs-helper'
|
import * as fsHelper from '../lib/fs-helper'
|
||||||
import * as github from '@actions/github'
|
import * as github from '@actions/github'
|
||||||
import * as inputHelper from '../lib/input-helper'
|
import * as inputHelper from '../lib/input-helper'
|
||||||
import * as path from 'path'
|
import * as path from 'path'
|
||||||
|
import * as workflowContextHelper from '../lib/workflow-context-helper'
|
||||||
import {IGitSourceSettings} from '../lib/git-source-settings'
|
import {IGitSourceSettings} from '../lib/git-source-settings'
|
||||||
|
|
||||||
const originalGitHubWorkspace = process.env['GITHUB_WORKSPACE']
|
const originalGitHubWorkspace = process.env['GITHUB_WORKSPACE']
|
||||||
|
@ -43,6 +43,11 @@ describe('input-helper tests', () => {
|
||||||
.spyOn(fsHelper, 'directoryExistsSync')
|
.spyOn(fsHelper, 'directoryExistsSync')
|
||||||
.mockImplementation((path: string) => path == gitHubWorkspace)
|
.mockImplementation((path: string) => path == gitHubWorkspace)
|
||||||
|
|
||||||
|
// Mock ./workflowContextHelper getOrganizationId()
|
||||||
|
jest
|
||||||
|
.spyOn(workflowContextHelper, 'getOrganizationId')
|
||||||
|
.mockImplementation(() => Promise.resolve(123456))
|
||||||
|
|
||||||
// GitHub workspace
|
// GitHub workspace
|
||||||
process.env['GITHUB_WORKSPACE'] = gitHubWorkspace
|
process.env['GITHUB_WORKSPACE'] = gitHubWorkspace
|
||||||
})
|
})
|
||||||
|
@ -67,8 +72,8 @@ describe('input-helper tests', () => {
|
||||||
jest.restoreAllMocks()
|
jest.restoreAllMocks()
|
||||||
})
|
})
|
||||||
|
|
||||||
it('sets defaults', () => {
|
it('sets defaults', async () => {
|
||||||
const settings: IGitSourceSettings = inputHelper.getInputs()
|
const settings: IGitSourceSettings = await inputHelper.getInputs()
|
||||||
expect(settings).toBeTruthy()
|
expect(settings).toBeTruthy()
|
||||||
expect(settings.authToken).toBeFalsy()
|
expect(settings.authToken).toBeFalsy()
|
||||||
expect(settings.clean).toBe(true)
|
expect(settings.clean).toBe(true)
|
||||||
|
@ -82,11 +87,11 @@ describe('input-helper tests', () => {
|
||||||
expect(settings.repositoryPath).toBe(gitHubWorkspace)
|
expect(settings.repositoryPath).toBe(gitHubWorkspace)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('qualifies ref', () => {
|
it('qualifies ref', async () => {
|
||||||
let originalRef = github.context.ref
|
let originalRef = github.context.ref
|
||||||
try {
|
try {
|
||||||
github.context.ref = 'some-unqualified-ref'
|
github.context.ref = 'some-unqualified-ref'
|
||||||
const settings: IGitSourceSettings = inputHelper.getInputs()
|
const settings: IGitSourceSettings = await inputHelper.getInputs()
|
||||||
expect(settings).toBeTruthy()
|
expect(settings).toBeTruthy()
|
||||||
expect(settings.commit).toBe('1234567890123456789012345678901234567890')
|
expect(settings.commit).toBe('1234567890123456789012345678901234567890')
|
||||||
expect(settings.ref).toBe('refs/heads/some-unqualified-ref')
|
expect(settings.ref).toBe('refs/heads/some-unqualified-ref')
|
||||||
|
@ -95,32 +100,42 @@ describe('input-helper tests', () => {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
it('requires qualified repo', () => {
|
it('requires qualified repo', async () => {
|
||||||
inputs.repository = 'some-unqualified-repo'
|
inputs.repository = 'some-unqualified-repo'
|
||||||
assert.throws(() => {
|
try {
|
||||||
inputHelper.getInputs()
|
await inputHelper.getInputs()
|
||||||
}, /Invalid repository 'some-unqualified-repo'/)
|
throw 'should not reach here'
|
||||||
|
} catch (err) {
|
||||||
|
expect(`(${(err as any).message}`).toMatch(
|
||||||
|
"Invalid repository 'some-unqualified-repo'"
|
||||||
|
)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
it('roots path', () => {
|
it('roots path', async () => {
|
||||||
inputs.path = 'some-directory/some-subdirectory'
|
inputs.path = 'some-directory/some-subdirectory'
|
||||||
const settings: IGitSourceSettings = inputHelper.getInputs()
|
const settings: IGitSourceSettings = await inputHelper.getInputs()
|
||||||
expect(settings.repositoryPath).toBe(
|
expect(settings.repositoryPath).toBe(
|
||||||
path.join(gitHubWorkspace, 'some-directory', 'some-subdirectory')
|
path.join(gitHubWorkspace, 'some-directory', 'some-subdirectory')
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('sets ref to empty when explicit sha', () => {
|
it('sets ref to empty when explicit sha', async () => {
|
||||||
inputs.ref = '1111111111222222222233333333334444444444'
|
inputs.ref = '1111111111222222222233333333334444444444'
|
||||||
const settings: IGitSourceSettings = inputHelper.getInputs()
|
const settings: IGitSourceSettings = await inputHelper.getInputs()
|
||||||
expect(settings.ref).toBeFalsy()
|
expect(settings.ref).toBeFalsy()
|
||||||
expect(settings.commit).toBe('1111111111222222222233333333334444444444')
|
expect(settings.commit).toBe('1111111111222222222233333333334444444444')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('sets sha to empty when explicit ref', () => {
|
it('sets sha to empty when explicit ref', async () => {
|
||||||
inputs.ref = 'refs/heads/some-other-ref'
|
inputs.ref = 'refs/heads/some-other-ref'
|
||||||
const settings: IGitSourceSettings = inputHelper.getInputs()
|
const settings: IGitSourceSettings = await inputHelper.getInputs()
|
||||||
expect(settings.ref).toBe('refs/heads/some-other-ref')
|
expect(settings.ref).toBe('refs/heads/some-other-ref')
|
||||||
expect(settings.commit).toBeFalsy()
|
expect(settings.commit).toBeFalsy()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('sets workflow organization ID', async () => {
|
||||||
|
const settings: IGitSourceSettings = await inputHelper.getInputs()
|
||||||
|
expect(settings.workflowOrganizationId).toBe(123456)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
|
@ -16,7 +16,7 @@ describe('ref-helper tests', () => {
|
||||||
await refHelper.getCheckoutInfo(git, 'refs/heads/my/branch', commit)
|
await refHelper.getCheckoutInfo(git, 'refs/heads/my/branch', commit)
|
||||||
throw new Error('Should not reach here')
|
throw new Error('Should not reach here')
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
expect(err.message).toBe('Arg git cannot be empty')
|
expect((err as any)?.message).toBe('Arg git cannot be empty')
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -25,7 +25,9 @@ describe('ref-helper tests', () => {
|
||||||
await refHelper.getCheckoutInfo(git, '', '')
|
await refHelper.getCheckoutInfo(git, '', '')
|
||||||
throw new Error('Should not reach here')
|
throw new Error('Should not reach here')
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
expect(err.message).toBe('Args ref and commit cannot both be empty')
|
expect((err as any)?.message).toBe(
|
||||||
|
'Args ref and commit cannot both be empty'
|
||||||
|
)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -102,7 +104,7 @@ describe('ref-helper tests', () => {
|
||||||
await refHelper.getCheckoutInfo(git, 'my-ref', '')
|
await refHelper.getCheckoutInfo(git, 'my-ref', '')
|
||||||
throw new Error('Should not reach here')
|
throw new Error('Should not reach here')
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
expect(err.message).toBe(
|
expect((err as any)?.message).toBe(
|
||||||
"A branch or tag with the name 'my-ref' could not be found"
|
"A branch or tag with the name 'my-ref' could not be found"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -74,7 +74,7 @@ describe('retry-helper tests', () => {
|
||||||
throw new Error(`some error ${++attempts}`)
|
throw new Error(`some error ${++attempts}`)
|
||||||
})
|
})
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
error = err
|
error = err as Error
|
||||||
}
|
}
|
||||||
expect(error.message).toBe('some error 3')
|
expect(error.message).toBe('some error 3')
|
||||||
expect(attempts).toBe(3)
|
expect(attempts).toBe(3)
|
||||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
24
package.json
24
package.json
|
@ -8,7 +8,9 @@
|
||||||
"format": "prettier --write '**/*.ts'",
|
"format": "prettier --write '**/*.ts'",
|
||||||
"format-check": "prettier --check '**/*.ts'",
|
"format-check": "prettier --check '**/*.ts'",
|
||||||
"lint": "eslint src/**/*.ts",
|
"lint": "eslint src/**/*.ts",
|
||||||
"test": "jest"
|
"test": "jest",
|
||||||
|
"licensed-check": "src/misc/licensed-check.sh",
|
||||||
|
"licensed-generate": "src/misc/licensed-generate.sh"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
|
@ -26,7 +28,7 @@
|
||||||
},
|
},
|
||||||
"homepage": "https://github.com/actions/checkout#readme",
|
"homepage": "https://github.com/actions/checkout#readme",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@actions/core": "^1.1.3",
|
"@actions/core": "^1.2.6",
|
||||||
"@actions/exec": "^1.0.1",
|
"@actions/exec": "^1.0.1",
|
||||||
"@actions/github": "^2.2.0",
|
"@actions/github": "^2.2.0",
|
||||||
"@actions/io": "^1.0.1",
|
"@actions/io": "^1.0.1",
|
||||||
|
@ -34,19 +36,19 @@
|
||||||
"uuid": "^3.3.3"
|
"uuid": "^3.3.3"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/jest": "^24.0.23",
|
"@types/jest": "^27.0.2",
|
||||||
"@types/node": "^12.7.12",
|
"@types/node": "^12.7.12",
|
||||||
"@types/uuid": "^3.4.6",
|
"@types/uuid": "^3.4.6",
|
||||||
"@typescript-eslint/parser": "^2.8.0",
|
"@typescript-eslint/parser": "^5.1.0",
|
||||||
"@zeit/ncc": "^0.20.5",
|
"@zeit/ncc": "^0.20.5",
|
||||||
"eslint": "^5.16.0",
|
"eslint": "^7.32.0",
|
||||||
"eslint-plugin-github": "^2.0.0",
|
"eslint-plugin-github": "^4.3.2",
|
||||||
"eslint-plugin-jest": "^22.21.0",
|
"eslint-plugin-jest": "^25.2.2",
|
||||||
"jest": "^24.9.0",
|
"jest": "^27.3.0",
|
||||||
"jest-circus": "^24.9.0",
|
"jest-circus": "^27.3.0",
|
||||||
"js-yaml": "^3.13.1",
|
"js-yaml": "^3.13.1",
|
||||||
"prettier": "^1.19.1",
|
"prettier": "^1.19.1",
|
||||||
"ts-jest": "^24.2.0",
|
"ts-jest": "^27.0.7",
|
||||||
"typescript": "^3.6.4"
|
"typescript": "^4.4.4"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@ export function directoryExistsSync(path: string, required?: boolean): boolean {
|
||||||
try {
|
try {
|
||||||
stats = fs.statSync(path)
|
stats = fs.statSync(path)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (error.code === 'ENOENT') {
|
if ((error as any)?.code === 'ENOENT') {
|
||||||
if (!required) {
|
if (!required) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
@ -18,7 +18,8 @@ export function directoryExistsSync(path: string, required?: boolean): boolean {
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`Encountered an error when checking whether path '${path}' exists: ${error.message}`
|
`Encountered an error when checking whether path '${path}' exists: ${(error as any)
|
||||||
|
?.message ?? error}`
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,12 +40,13 @@ export function existsSync(path: string): boolean {
|
||||||
try {
|
try {
|
||||||
fs.statSync(path)
|
fs.statSync(path)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (error.code === 'ENOENT') {
|
if ((error as any)?.code === 'ENOENT') {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`Encountered an error when checking whether path '${path}' exists: ${error.message}`
|
`Encountered an error when checking whether path '${path}' exists: ${(error as any)
|
||||||
|
?.message ?? error}`
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,12 +62,13 @@ export function fileExistsSync(path: string): boolean {
|
||||||
try {
|
try {
|
||||||
stats = fs.statSync(path)
|
stats = fs.statSync(path)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (error.code === 'ENOENT') {
|
if ((error as any)?.code === 'ENOENT') {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`Encountered an error when checking whether path '${path}' exists: ${error.message}`
|
`Encountered an error when checking whether path '${path}' exists: ${(error as any)
|
||||||
|
?.message ?? error}`
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -37,7 +37,7 @@ class GitAuthHelper {
|
||||||
private readonly tokenConfigValue: string
|
private readonly tokenConfigValue: string
|
||||||
private readonly tokenPlaceholderConfigValue: string
|
private readonly tokenPlaceholderConfigValue: string
|
||||||
private readonly insteadOfKey: string
|
private readonly insteadOfKey: string
|
||||||
private readonly insteadOfValue: string
|
private readonly insteadOfValues: string[] = []
|
||||||
private sshCommand = ''
|
private sshCommand = ''
|
||||||
private sshKeyPath = ''
|
private sshKeyPath = ''
|
||||||
private sshKnownHostsPath = ''
|
private sshKnownHostsPath = ''
|
||||||
|
@ -45,7 +45,7 @@ class GitAuthHelper {
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
gitCommandManager: IGitCommandManager,
|
gitCommandManager: IGitCommandManager,
|
||||||
gitSourceSettings?: IGitSourceSettings
|
gitSourceSettings: IGitSourceSettings | undefined
|
||||||
) {
|
) {
|
||||||
this.git = gitCommandManager
|
this.git = gitCommandManager
|
||||||
this.settings = gitSourceSettings || (({} as unknown) as IGitSourceSettings)
|
this.settings = gitSourceSettings || (({} as unknown) as IGitSourceSettings)
|
||||||
|
@ -63,7 +63,12 @@ class GitAuthHelper {
|
||||||
|
|
||||||
// Instead of SSH URL
|
// Instead of SSH URL
|
||||||
this.insteadOfKey = `url.${serverUrl.origin}/.insteadOf` // "origin" is SCHEME://HOSTNAME[:PORT]
|
this.insteadOfKey = `url.${serverUrl.origin}/.insteadOf` // "origin" is SCHEME://HOSTNAME[:PORT]
|
||||||
this.insteadOfValue = `git@${serverUrl.hostname}:`
|
this.insteadOfValues.push(`git@${serverUrl.hostname}:`)
|
||||||
|
if (this.settings.workflowOrganizationId) {
|
||||||
|
this.insteadOfValues.push(
|
||||||
|
`org-${this.settings.workflowOrganizationId}@github.com:`
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async configureAuth(): Promise<void> {
|
async configureAuth(): Promise<void> {
|
||||||
|
@ -94,7 +99,7 @@ class GitAuthHelper {
|
||||||
await fs.promises.stat(gitConfigPath)
|
await fs.promises.stat(gitConfigPath)
|
||||||
configExists = true
|
configExists = true
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
if (err.code !== 'ENOENT') {
|
if ((err as any)?.code !== 'ENOENT') {
|
||||||
throw err
|
throw err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -118,7 +123,9 @@ class GitAuthHelper {
|
||||||
// Configure HTTPS instead of SSH
|
// Configure HTTPS instead of SSH
|
||||||
await this.git.tryConfigUnset(this.insteadOfKey, true)
|
await this.git.tryConfigUnset(this.insteadOfKey, true)
|
||||||
if (!this.settings.sshKey) {
|
if (!this.settings.sshKey) {
|
||||||
await this.git.config(this.insteadOfKey, this.insteadOfValue, true)
|
for (const insteadOfValue of this.insteadOfValues) {
|
||||||
|
await this.git.config(this.insteadOfKey, insteadOfValue, true, true)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
// Unset in case somehow written to the real global config
|
// Unset in case somehow written to the real global config
|
||||||
|
@ -159,10 +166,12 @@ class GitAuthHelper {
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
// Configure HTTPS instead of SSH
|
// Configure HTTPS instead of SSH
|
||||||
await this.git.submoduleForeach(
|
for (const insteadOfValue of this.insteadOfValues) {
|
||||||
`git config --local '${this.insteadOfKey}' '${this.insteadOfValue}'`,
|
await this.git.submoduleForeach(
|
||||||
this.settings.nestedSubmodules
|
`git config --local --add '${this.insteadOfKey}' '${insteadOfValue}'`,
|
||||||
)
|
this.settings.nestedSubmodules
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -213,7 +222,7 @@ class GitAuthHelper {
|
||||||
await fs.promises.readFile(userKnownHostsPath)
|
await fs.promises.readFile(userKnownHostsPath)
|
||||||
).toString()
|
).toString()
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
if (err.code !== 'ENOENT') {
|
if ((err as any)?.code !== 'ENOENT') {
|
||||||
throw err
|
throw err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -302,7 +311,7 @@ class GitAuthHelper {
|
||||||
try {
|
try {
|
||||||
await io.rmRF(keyPath)
|
await io.rmRF(keyPath)
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
core.debug(err.message)
|
core.debug(`${(err as any)?.message ?? err}`)
|
||||||
core.warning(`Failed to remove SSH key '${keyPath}'`)
|
core.warning(`Failed to remove SSH key '${keyPath}'`)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,8 @@ export interface IGitCommandManager {
|
||||||
config(
|
config(
|
||||||
configKey: string,
|
configKey: string,
|
||||||
configValue: string,
|
configValue: string,
|
||||||
globalConfig?: boolean
|
globalConfig?: boolean,
|
||||||
|
add?: boolean
|
||||||
): Promise<void>
|
): Promise<void>
|
||||||
configExists(configKey: string, globalConfig?: boolean): Promise<boolean>
|
configExists(configKey: string, globalConfig?: boolean): Promise<boolean>
|
||||||
fetch(refSpec: string[], fetchDepth?: number): Promise<void>
|
fetch(refSpec: string[], fetchDepth?: number): Promise<void>
|
||||||
|
@ -140,14 +141,15 @@ class GitCommandManager {
|
||||||
async config(
|
async config(
|
||||||
configKey: string,
|
configKey: string,
|
||||||
configValue: string,
|
configValue: string,
|
||||||
globalConfig?: boolean
|
globalConfig?: boolean,
|
||||||
|
add?: boolean
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
await this.execGit([
|
const args: string[] = ['config', globalConfig ? '--global' : '--local']
|
||||||
'config',
|
if (add) {
|
||||||
globalConfig ? '--global' : '--local',
|
args.push('--add')
|
||||||
configKey,
|
}
|
||||||
configValue
|
args.push(...[configKey, configValue])
|
||||||
])
|
await this.execGit(args)
|
||||||
}
|
}
|
||||||
|
|
||||||
async configExists(
|
async configExists(
|
||||||
|
|
|
@ -39,7 +39,9 @@ export async function prepareExistingDirectory(
|
||||||
try {
|
try {
|
||||||
await io.rmRF(lockPath)
|
await io.rmRF(lockPath)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
core.debug(`Unable to delete '${lockPath}'. ${error.message}`)
|
core.debug(
|
||||||
|
`Unable to delete '${lockPath}'. ${(error as any)?.message ?? error}`
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -73,4 +73,9 @@ export interface IGitSourceSettings {
|
||||||
* Indicates whether to persist the credentials on disk to enable scripting authenticated git commands
|
* Indicates whether to persist the credentials on disk to enable scripting authenticated git commands
|
||||||
*/
|
*/
|
||||||
persistCredentials: boolean
|
persistCredentials: boolean
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Organization ID for the currently running workflow (used for auth settings)
|
||||||
|
*/
|
||||||
|
workflowOrganizationId: number | undefined
|
||||||
}
|
}
|
||||||
|
|
|
@ -92,7 +92,10 @@ export async function getDefaultBranch(
|
||||||
assert.ok(result, 'default_branch cannot be empty')
|
assert.ok(result, 'default_branch cannot be empty')
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
// Handle .wiki repo
|
// Handle .wiki repo
|
||||||
if (err['status'] === 404 && repo.toUpperCase().endsWith('.WIKI')) {
|
if (
|
||||||
|
(err as any)?.status === 404 &&
|
||||||
|
repo.toUpperCase().endsWith('.WIKI')
|
||||||
|
) {
|
||||||
result = 'master'
|
result = 'master'
|
||||||
}
|
}
|
||||||
// Otherwise error
|
// Otherwise error
|
||||||
|
|
|
@ -2,9 +2,10 @@ import * as core from '@actions/core'
|
||||||
import * as fsHelper from './fs-helper'
|
import * as fsHelper from './fs-helper'
|
||||||
import * as github from '@actions/github'
|
import * as github from '@actions/github'
|
||||||
import * as path from 'path'
|
import * as path from 'path'
|
||||||
|
import * as workflowContextHelper from './workflow-context-helper'
|
||||||
import {IGitSourceSettings} from './git-source-settings'
|
import {IGitSourceSettings} from './git-source-settings'
|
||||||
|
|
||||||
export function getInputs(): IGitSourceSettings {
|
export async function getInputs(): Promise<IGitSourceSettings> {
|
||||||
const result = ({} as unknown) as IGitSourceSettings
|
const result = ({} as unknown) as IGitSourceSettings
|
||||||
|
|
||||||
// GitHub workspace
|
// GitHub workspace
|
||||||
|
@ -118,5 +119,8 @@ export function getInputs(): IGitSourceSettings {
|
||||||
result.persistCredentials =
|
result.persistCredentials =
|
||||||
(core.getInput('persist-credentials') || 'false').toUpperCase() === 'TRUE'
|
(core.getInput('persist-credentials') || 'false').toUpperCase() === 'TRUE'
|
||||||
|
|
||||||
|
// Workflow organization ID
|
||||||
|
result.workflowOrganizationId = await workflowContextHelper.getOrganizationId()
|
||||||
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ import * as stateHelper from './state-helper'
|
||||||
|
|
||||||
async function run(): Promise<void> {
|
async function run(): Promise<void> {
|
||||||
try {
|
try {
|
||||||
const sourceSettings = inputHelper.getInputs()
|
const sourceSettings = await inputHelper.getInputs()
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Register problem matcher
|
// Register problem matcher
|
||||||
|
@ -26,7 +26,7 @@ async function run(): Promise<void> {
|
||||||
coreCommand.issueCommand('remove-matcher', {owner: 'checkout-git'}, '')
|
coreCommand.issueCommand('remove-matcher', {owner: 'checkout-git'}, '')
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
core.setFailed(error.message)
|
core.setFailed(`${(error as any)?.message ?? error}`)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,7 +34,7 @@ async function cleanup(): Promise<void> {
|
||||||
try {
|
try {
|
||||||
await gitSourceProvider.cleanup(stateHelper.RepositoryPath)
|
await gitSourceProvider.cleanup(stateHelper.RepositoryPath)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
core.warning(error.message)
|
core.warning(`${(error as any)?.message ?? error}`)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,10 +10,10 @@ import * as yaml from 'js-yaml'
|
||||||
|
|
||||||
function updateUsage(
|
function updateUsage(
|
||||||
actionReference: string,
|
actionReference: string,
|
||||||
actionYamlPath: string = 'action.yml',
|
actionYamlPath = 'action.yml',
|
||||||
readmePath: string = 'README.md',
|
readmePath = 'README.md',
|
||||||
startToken: string = '<!-- start usage -->',
|
startToken = '<!-- start usage -->',
|
||||||
endToken: string = '<!-- end usage -->'
|
endToken = '<!-- end usage -->'
|
||||||
): void {
|
): void {
|
||||||
if (!actionReference) {
|
if (!actionReference) {
|
||||||
throw new Error('Parameter actionReference must not be empty')
|
throw new Error('Parameter actionReference must not be empty')
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
src/misc/licensed-download.sh
|
||||||
|
|
||||||
|
echo 'Running: licensed cached'
|
||||||
|
_temp/licensed-3.3.1/licensed status
|
|
@ -0,0 +1,24 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
if [ ! -f _temp/licensed-3.3.1.done ]; then
|
||||||
|
echo 'Clearing temp'
|
||||||
|
rm -rf _temp/licensed-3.3.1 || true
|
||||||
|
|
||||||
|
echo 'Downloading licensed'
|
||||||
|
mkdir -p _temp/licensed-3.3.1
|
||||||
|
pushd _temp/licensed-3.3.1
|
||||||
|
if [[ "$OSTYPE" == "darwin"* ]]; then
|
||||||
|
curl -Lfs -o licensed.tar.gz https://github.com/github/licensed/releases/download/3.3.1/licensed-3.3.1-darwin-x64.tar.gz
|
||||||
|
else
|
||||||
|
curl -Lfs -o licensed.tar.gz https://github.com/github/licensed/releases/download/3.3.1/licensed-3.3.1-linux-x64.tar.gz
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo 'Extracting licenesed'
|
||||||
|
tar -xzf licensed.tar.gz
|
||||||
|
popd
|
||||||
|
touch _temp/licensed-3.3.1.done
|
||||||
|
else
|
||||||
|
echo 'Licensed already downloaded'
|
||||||
|
fi
|
|
@ -0,0 +1,8 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
src/misc/licensed-download.sh
|
||||||
|
|
||||||
|
echo 'Running: licensed cached'
|
||||||
|
_temp/licensed-3.3.1/licensed cache
|
|
@ -253,7 +253,9 @@ export async function checkCommitInfo(
|
||||||
await octokit.repos.get({owner: repositoryOwner, repo: repositoryName})
|
await octokit.repos.get({owner: repositoryOwner, repo: repositoryName})
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
core.debug(`Error when validating commit info: ${err.stack}`)
|
core.debug(
|
||||||
|
`Error when validating commit info: ${(err as any)?.stack ?? err}`
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,7 @@ export class RetryHelper {
|
||||||
try {
|
try {
|
||||||
return await action()
|
return await action()
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
core.info(err.message)
|
core.info((err as any)?.message)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sleep
|
// Sleep
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
import * as core from '@actions/core'
|
||||||
|
import * as fs from 'fs'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the organization ID of the running workflow or undefined if the value cannot be loaded from the GITHUB_EVENT_PATH
|
||||||
|
*/
|
||||||
|
export async function getOrganizationId(): Promise<number | undefined> {
|
||||||
|
try {
|
||||||
|
const eventPath = process.env.GITHUB_EVENT_PATH
|
||||||
|
if (!eventPath) {
|
||||||
|
core.debug(`GITHUB_EVENT_PATH is not defined`)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const content = await fs.promises.readFile(eventPath, {encoding: 'utf8'})
|
||||||
|
const event = JSON.parse(content)
|
||||||
|
const id = event?.repository?.owner?.id
|
||||||
|
if (typeof id !== 'number') {
|
||||||
|
core.debug('Repository owner ID not found within GITHUB event info')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
return id as number
|
||||||
|
} catch (err) {
|
||||||
|
core.debug(
|
||||||
|
`Unable to load organization ID from GITHUB_EVENT_PATH: ${(err as any)
|
||||||
|
.message || err}`
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
|
@ -10,7 +10,8 @@
|
||||||
"declaration": true,
|
"declaration": true,
|
||||||
"strict": true,
|
"strict": true,
|
||||||
"noImplicitAny": false,
|
"noImplicitAny": false,
|
||||||
"esModuleInterop": true
|
"esModuleInterop": true,
|
||||||
|
"skipLibCheck": true
|
||||||
},
|
},
|
||||||
"exclude": ["__test__", "lib", "node_modules"]
|
"exclude": ["__test__", "lib", "node_modules"]
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue