Skip to content

Commit fd15578

Browse files
Merge pull request #80 from codefresh-io/CR-13197
CR-13197
2 parents 4dd3a67 + d63bcf3 commit fd15578

File tree

11 files changed

+1072
-1372
lines changed

11 files changed

+1072
-1372
lines changed

README.md

Lines changed: 35 additions & 112 deletions
Original file line numberDiff line numberDiff line change
@@ -26,119 +26,42 @@ Commit that resulted in the image being built
2626

2727
## Example - github-actions
2828
```
29-
- name: report image by action
30-
with:
31-
CF_HOST: "https://my-runtime-url"
32-
CF_API_KEY: ${{ secrets.CF_TOKEN }}
33-
34-
#Codefresh Integrations to USE
35-
CF_CONTAINER_REGISTRY_INTEGRATION: "dockerhub"
36-
CF_JIRA_INTEGRATION: "jira"
37-
38-
CF_IMAGE: ${{ secrets.DOCKERHUB_USERNAME }}/my-image-name:tag
39-
40-
CF_GITHUB_TOKEN: ${{ secrets.GIT_TOKEN }}
41-
42-
#Jira issues that match
43-
CF_JIRA_MESSAGE: "CR-12293"
44-
CF_JIRA_PROJECT_PREFIX: "CR"
45-
uses: codefresh-io/codefresh-report-image@latest
29+
30+
- name: report image
31+
with:
32+
# Name of runtime to implement the enrichment
33+
CF_RUNTIME_NAME: 'codefresh-hosted'
34+
35+
# Codefresh API key !! Committing a plain text token is a security risk. We highly recommend using an encrypted secrets. !!
36+
# Documentation - https://docs.github.com/en/actions/security-guides/encrypted-secrets
37+
CF_API_KEY: ${{ secrets.CF_TOKEN }}
38+
39+
# Image path to enrich
40+
CF_IMAGE: ${{ secrets.DOCKERHUB_USERNAME }}/my-image-name:tag
41+
42+
# Name of Container registry integration
43+
CF_CONTAINER_REGISTRY_INTEGRATION: 'testghjmjhg'
44+
45+
# The git branch which is related for the commit
46+
CF_GIT_BRANCH: '${{ github.ref_name }}'
47+
48+
# GitHub Access token !! Committing a plain text token is a security risk. We highly recommend using an encrypted secrets. !!
49+
# Documentation - https://docs.github.com/en/actions/security-guides/encrypted-secrets
50+
CF_GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
51+
52+
# Name of Jira integration
53+
CF_JIRA_INTEGRATION: 'eti-jira'
54+
55+
# Jira project filter
56+
CF_JIRA_PROJECT_PREFIX: 'CR'
57+
58+
# String starting with the issue ID to associate with image
59+
CF_JIRA_MESSAGE: 'CR-12293'
60+
61+
62+
uses: codefresh-io/codefresh-report-image@latest
4663
```
4764

4865

4966
# Complete List of Arguments
50-
### service
51-
- #### CF_HOST
52-
- **description**: Name of runtime to implement the enrichment
53-
- required
54-
- ["example",["https://codefresh.yourdoamin.com:80"]]
55-
- **default**: [runtime_host_url]
56-
- #### CF_API_KEY
57-
- **description**: Codefresh API key
58-
- required
59-
- secret
60-
### general
61-
- #### CF_IMAGE
62-
- **description**: Image path to enrich
63-
- required
64-
- ["examples",["mydockerhub/pushedimage:fix"]]
65-
- **default**: [full image path here, including tag]
66-
- #### CF_CONTAINER_REGISTRY_INTEGRATION
67-
- **description**: Name of Container registry integration
68-
- #### CF_WORKFLOW_URL
69-
- **description**: The reported URL of the workflow that builds the image.
70-
- ["examples",["https://github.com/saffi-codefresh/csdp-report-image-github-action/actions/runs/2389116616"]]
71-
- **default**: [URL of the workflow that builds the image]
72-
- #### CF_WORKFLOW_NAME
73-
- **description**: The name assigned to the workflow that builds the image. When defined, the name is displayed in the Codefresh platform.
74-
- ["examples",["Staging build step"]]
75-
- #### CF_CI_TYPE
76-
- **description**: Name of integration type, used for filtering results by the reporting tool type
77-
- ["examples",["git-action","classic","jenkins",""]]
78-
### git
79-
- #### CF_GIT_BRANCH
80-
- **description**: The git branch which is related for the commit
81-
- #### CF_GIT_REPO
82-
- **description**: The the git repository used for building the image
83-
- required
84-
### explicit-git-setup
85-
- #### CF_GIT_PROVIDER
86-
- **description**: The git integration type use (i.e. github)
87-
- required
88-
### github
89-
- #### CF_GITHUB_TOKEN
90-
- **description**: GitHub Access token
91-
- required
92-
- ["examples",["ghp_vVvA6oh5iCO...."]]
93-
- secret
94-
- **default**: [github-personal-access-token]
95-
- #### CF_GITHUB_API_URL
96-
- **description**: Specify github host api url
97-
- ["examples",["https://api.github.com"]]
98-
### gitlab
99-
- #### CF_GITLAB_TOKEN
100-
- **description**: When explicit authentication used: For gitlab use, authenticate with a gitlab-token
101-
- required
102-
- ["examples",["glpat-CzJ...."]]
103-
- secret
104-
- #### CF_GITLAB_HOST_URL
105-
- **description**: Specify gitlab host url
106-
- ["examples",["https://gitlab.com"]]
107-
### bitbucket
108-
- #### CF_BITBUCKET_USERNAME
109-
- **description**: Bitbucket username
110-
- required
111-
- #### CF_BITBUCKET_PASSWORD
112-
- **description**: Bitbucket password
113-
- required
114-
- secret
115-
### bitbucketServer
116-
- #### CF_BITBUCKET_USERNAME
117-
- **description**: Bitbucket server username
118-
- required
119-
- #### CF_BITBUCKET_PASSWORD
120-
- **description**: Bitbucket server password
121-
- required
122-
- secret
123-
- #### CF_BITBUCKET_HOST_URL
124-
- **description**: Bitbucket server host url
125-
- required
126-
- ["examples",["https://bitbucket-server:7990"]]
127-
### jira
128-
- #### CF_JIRA_INTEGRATION
129-
- **description**: Name of Jira integration
130-
- **default**: [jira-registry-integration-name]
131-
- #### CF_JIRA_PROJECT_PREFIX
132-
- **description**: Jira project filter
133-
- required
134-
- ["examples",["CR"]]
135-
- **default**: [jira-project-prefix]
136-
- #### CF_JIRA_MESSAGE
137-
- **description**: String starting with the issue ID to associate with image
138-
- required
139-
- ["examples",["fix CR-11312 "]]
140-
- **default**: [issue id]
141-
- #### CF_JIRA_FAIL_ON_NOT_FOUND
142-
- **description**: When enabled, Fail the image report when the specified Jira issue is not found.
143-
- ["examples",["true"]]
144-
67+
https://codefresh.io/csdp-docs/docs/integrations/github-actions/#codefresh-github-action-integration-arguments

action.yaml

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ inputs:
1010
required: true
1111
CF_HOST:
1212
description: "Codefresh runtime exposed in cluster address: https://your.clusters.ci-cd.com/app-proxy"
13+
required: false
14+
CF_RUNTIME_NAME:
15+
description: "Codefresh runtime name"
1316
required: true
1417
CF_VERBOSE:
1518
description: "verbose output"
@@ -41,6 +44,9 @@ inputs:
4144
CF_WORKFLOW_URL:
4245
required: false
4346
description: "external url for the workflow"
47+
CF_WORKFLOW_NAME:
48+
required: false
49+
description: "The name assigned to the workflow that builds the image. When defined, the name is displayed in the Codefresh platform."
4450
CF_LOGS_URL:
4551
required: false
4652
description: "external url for the logs"
@@ -107,6 +113,7 @@ runs:
107113
env:
108114
VERSION: "${{ inputs.VERSION }}"
109115
CF_HOST: "${{ inputs.CF_HOST }}"
116+
CF_RUNTIME_NAME: "${{ inputs.CF_RUNTIME_NAME }}"
110117
CF_API_KEY: "${{ inputs.CF_API_KEY }}"
111118

112119
CF_IMAGE: "${{ inputs.CF_IMAGE }}"
@@ -119,6 +126,7 @@ runs:
119126
CF_REGISTRY_DOMAIN: "${{ inputs.CF_REGISTRY_DOMAIN }}"
120127
CF_INSECURE: "${{ inputs.CF_INSECURE }}"
121128
CF_WORKFLOW_URL: "${{ inputs.CF_WORKFLOW_URL }}"
129+
CF_WORKFLOW_NAME: "${{ inputs.CF_WORKFLOW_NAME }}"
122130
CF_LOGS_URL: "${{ inputs.CF_LOGS_URL }}"
123131

124132
CF_ENRICHERS: "${{ inputs.CF_ENRICHERS }}"
@@ -149,16 +157,17 @@ runs:
149157
# github
150158
GITHUB_REF_NAME: "${{ github.ref_name }}"
151159
GITHUB_REPOSITORY: "${{ github.repository }}"
152-
GITHUB_COMMIT_MESSAGE: "${{ github.event.head_commit.message }}"
153-
GITHUB_PAYLOAD_MESSAGE: "${{ github.event.client_payload.message }}"
160+
GITHUB_WORKFLOW_NAME: "${{ github.repository }}/${{ github.run_id }}"
161+
GITHUB_WORKFLOW_URL: "${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"
154162

155163

156164
run: |
157165
# add defaults
158166
export CF_GIT_BRANCH="${CF_GIT_BRANCH:-$GITHUB_REF_NAME}"
159167
export CF_GIT_REPO="${CF_GIT_REPO:-$GITHUB_REPOSITORY}"
160168
# built vars
161-
export CF_WORKFLOW_URL="${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID}"
169+
export CF_WORKFLOW_URL="${CF_WORKFLOW_URL:-$GITHUB_WORKFLOW_URL}"
170+
export CF_WORKFLOW_NAME="${CF_WORKFLOW_NAME:-$GITHUB_WORKFLOW_NAME}"
162171
export CF_GIT_PROVIDER="${CF_GIT_PROVIDER:-github}"
163172
export CF_CI_TYPE=github-actions
164173

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@
2626
"dependencies": {
2727
"chalk": "4.1.2",
2828
"eventsource": "^2.0.1",
29+
"graphql": "^16.5.0",
30+
"graphql-request": "^4.3.0",
2931
"winston": "^3.7.2"
3032
},
3133
"devDependencies": {

service.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
name: codefresh-report-image
2-
version: 0.0.153
2+
version: 0.0.154

src/__tests__/request-builder.spec.ts

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
1-
import { buildUrlHeaders } from '../utils'
2-
1+
import { Utils } from '../utils'
32

43
describe('request builder test', () => {
5-
it('not clean CF_', async () => {
6-
const
7-
{ url, headers } = buildUrlHeaders({
4+
it('support CF_HOST', async () => {
5+
const { url, headers } = await Utils.buildUrlHeaders({
86
'CF_API_KEY': 'the-token',
97
'CF_HOST': 'https://g.codefresh.io',
108
'CF_IMAGE': 'testImage'
@@ -13,4 +11,16 @@ describe('request builder test', () => {
1311
expect(headers).toEqual({ 'authorization': 'the-token' })
1412
})
1513

14+
it('support CF_RUNTIME_NAME', async () => {
15+
const ingressHost = 'https://my.codefresh.ingress'
16+
jest.spyOn(Utils, 'getRuntimeIngressHost').mockResolvedValue(ingressHost)
17+
const { url, headers } = await Utils.buildUrlHeaders({
18+
'CF_API_KEY': 'the-token',
19+
'CF_RUNTIME_NAME': 'runtime',
20+
'CF_IMAGE': 'testImage'
21+
})
22+
expect(url).toEqual(`${ingressHost}/app-proxy/api/image-report?CF_IMAGE=testImage`)
23+
expect(headers).toEqual({ 'authorization': 'the-token' })
24+
})
25+
1626
})

src/__tests__/validate.spec.ts

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,23 @@ describe('client report-image validation', () => {
66
try {
77
validate({ ENV1: '1', someVal: 'ignored' })
88
} catch (error) {
9-
expect(error.message).toBe(`Validation Error: ["CF_API_KEY must be provided as environment variable.",` +
10-
`"CF_IMAGE must be provided as environment variable.",`+
11-
`"CF_HOST must be provided as app-proxy http/s address"]`)
9+
const expectedErrorMsg = '["CF_API_KEY must be provided as environment variable.","CF_IMAGE must be provided as environment variable.","CF_RUNTIME_NAME must be provided as environment variable."]'
10+
expect(error.message).toBe(expectedErrorMsg)
1211
return
1312
}
1413
fail(`should have thrown Validation Error`)
1514
})
16-
it('All OK', async () => {
15+
it('not support both CF_HOST and CF_RUNTIME_NAME', async () => {
16+
try {
17+
validate({ CF_API_KEY: '1', alsoIgnored: 'ignored', IGNORED: 'ignored too', CF_IMAGE: 'testImage', CF_HOST: `host.io`, CF_RUNTIME_NAME: 'runtime' })
18+
} catch (error) {
19+
const expectedErrorMsg = '["You can only specify CF_RUNTIME_NAME or CF_HOST. please delete one of them."]'
20+
expect(error.message).toBe(expectedErrorMsg)
21+
return
22+
}
23+
fail(`should have thrown Validation Error`)
24+
})
25+
it('support CF_HOST', async () => {
1726
let res
1827
try {
1928
res = validate({ CF_API_KEY: '1', alsoIgnored: 'ignored', IGNORED: 'ignored too', CF_IMAGE: 'testImage', CF_HOST: `host.io` })
@@ -26,4 +35,17 @@ describe('client report-image validation', () => {
2635
'CF_IMAGE': 'testImage'
2736
})
2837
})
38+
it('support CF_RUNTIME_NAME', async () => {
39+
let res
40+
try {
41+
res = validate({ CF_API_KEY: '1', alsoIgnored: 'ignored', IGNORED: 'ignored too', CF_IMAGE: 'testImage', CF_RUNTIME_NAME: `runtime` })
42+
} catch (error) {
43+
fail(`should have not thrown an error ${JSON.stringify(error)}`)
44+
}
45+
expect(res).toEqual({
46+
'CF_API_KEY': '1',
47+
'CF_RUNTIME_NAME': 'runtime',
48+
'CF_IMAGE': 'testImage'
49+
})
50+
})
2951
})

src/errors.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
export const errors = {
2+
EventSourceError: class extends Error {
3+
constructor(message?: string, name?: string) {
4+
super(message)
5+
this.name = name || 'EventSourceError'
6+
}
7+
},
8+
ValidationError: class extends Error {
9+
constructor(message?: string, name?: string) {
10+
super(message)
11+
this.name = name || 'ValidationError'
12+
}
13+
}
14+
}

src/main.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
import EventSource from 'eventsource'
22

33
import { validate } from './validate'
4-
import { tryParseJson, errors, buildUrlHeaders } from './utils'
4+
import { Utils } from './utils'
5+
import { errors } from './errors'
56
import { logger, workflowLogger } from './logger'
67

78
const { EventSourceError } = errors
89

10+
911
/**
1012
* Take (CF_ prefixed) Env variables and perform http/s request (SSE) to app-proxy for image-report with CF_ENRICHERS
1113
*/
@@ -15,7 +17,7 @@ async function main(argv, env): Promise<void> {
1517
logger.debug('running with verbose log')
1618
}
1719
const payload = validate(env)
18-
const { url, headers } = buildUrlHeaders(payload)
20+
const { url, headers } = await Utils.buildUrlHeaders(payload)
1921
if (verbose) {
2022
logger.debug(`payload: ${JSON.stringify(payload, null, 2)}`)
2123
logger.debug(`sending request: ${url}, headers: ${JSON.stringify(headers)}`)
@@ -37,7 +39,7 @@ async function main(argv, env): Promise<void> {
3739
logger.warn(event.data)
3840
})
3941
eventSource.addEventListener('workflow-log', function (event) {
40-
const log = tryParseJson(event.data)
42+
const log = Utils.tryParseJson(event.data)
4143
if (typeof log === 'object' && log.content && log.podName) {
4244
workflowLogger.info({ pod: log.podName, message: log.content })
4345
} else {
@@ -47,7 +49,7 @@ async function main(argv, env): Promise<void> {
4749
eventSource.addEventListener('error', (errorEvent) => {
4850
eventSource.close()
4951

50-
const error = tryParseJson(errorEvent.data)
52+
const error = Utils.tryParseJson(errorEvent.data)
5153
let name
5254
let message
5355
if (typeof error === 'string') {

0 commit comments

Comments
 (0)