Skip to content

Commit

Permalink
Merge pull request #27 from nipe0324/feat-condition-script
Browse files Browse the repository at this point in the history
feat: add `skip-update-script`
  • Loading branch information
nipe0324 authored Feb 18, 2024
2 parents 57c5511 + 6772346 commit b35709b
Show file tree
Hide file tree
Showing 7 changed files with 91 additions and 21 deletions.
20 changes: 10 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ jobs:
run: echo "title=$(date --date='last monday' +'%Y-%m-%d')" >> $GITHUB_OUTPUT

- name: Set current iteration
uses: nipe0324/update-project-v2-item-field@v1.2.0
uses: nipe0324/update-project-v2-item-field@v1.3.0
with:
project-url: https://github.com/orgs|users/<ownerName>/projects/<projejctNumer>
github-token: ${{ secrets.UPDATE_PROJECT_V2_PAT }}
Expand All @@ -52,7 +52,7 @@ jobs:
timeout-minutes: 5
steps:
- name: Update status to "In Review"
uses: nipe0324/update-project-v2-item-field@v1.2.0
uses: nipe0324/update-project-v2-item-field@v1.3.0
with:
project-url: https://github.com/orgs|users/<ownerName>/projects/<projejctNumer>
github-token: ${{ secrets.UPDATE_PROJECT_V2_PAT }}
Expand Down Expand Up @@ -81,7 +81,7 @@ jobs:
- name: Set "Start Date" when issue opened
if: ${{ github.event.action == 'opened'}}
uses: nipe0324/update-project-v2-item-field@v1.2.0
uses: nipe0324/update-project-v2-item-field@v1.3.0
with:
project-url: https://github.com/orgs|users/<ownerName>/projects/<projejctNumer>
github-token: ${{ secrets.UPDATE_PROJECT_V2_PAT }}
Expand All @@ -90,7 +90,7 @@ jobs:

- name: Set "End Date" when issue closed
if: ${{ github.event.action == 'closed'}}
uses: nipe0324/update-project-v2-item-field@v1.2.0
uses: nipe0324/update-project-v2-item-field@v1.3.0
with:
project-url: https://github.com/orgs|users/<ownerName>/projects/<projejctNumer>
github-token: ${{ secrets.UPDATE_PROJECT_V2_PAT }}
Expand All @@ -99,7 +99,7 @@ jobs:

- name: Calculate "Time to Close Days"
if: ${{ github.event.action == 'closed'}}
uses: nipe0324/update-project-v2-item-field@v1.2.0
uses: nipe0324/update-project-v2-item-field@v1.3.0
with:
project-url: https://github.com/orgs|users/<ownerName>/projects/<projejctNumer>
github-token: ${{ secrets.UPDATE_PROJECT_V2_PAT }}
Expand Down Expand Up @@ -131,9 +131,9 @@ References
token](https://github.com/settings/tokens/new) with `repo` and `project` scopes. [more detail](#tokens)
- `field-name` **(required)** is a field name of the project v2 item to update.
- note: Supported field types are `text`, `number`, `date`, `single_select` and `iteration`.
- `field-value` **(conditionally required)** is a field value of the project v2 item to update.
- `field-value-script`: **(conditionally required)** is the that returns the value of the field to update.
- note: `field-value` or `field-value-script` is required.
- `field-value` **(conditionally required)** is a field value of the project v2 item to update. (`field-value` or `field-value-script` is required)
- `field-value-script`: **(conditionally required)** is the script that returns the value of the field to update. (`field-value` or `field-value-script` is required)
- `condition-script`: **(optional)** is the script that returns a boolean value to determine whether to update the field. If the script returns `true`, the field will not be updated.

## Outputs

Expand Down Expand Up @@ -183,8 +183,8 @@ the "dist/" directory.

```shell
npm run all
git tag v1.2.0
git push origin v1.2.0
git tag v1.3.0
git push origin v1.3.0
```

Now, a release can be created from the branch containing the built action.
Expand Down
35 changes: 35 additions & 0 deletions __tests__/update-project-v2-item-field.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { ExOctokit } from '../src/ex-octokit'

describe('updateProjectV2ItemField', () => {
let outputs: Record<string, string>
let info: jest.SpyInstance
let debug: jest.SpyInstance

beforeEach(() => {
Expand All @@ -28,6 +29,7 @@ describe('updateProjectV2ItemField', () => {
}
}

info = mockInfo()
debug = mockDebug()
outputs = mockSetOutput()
})
Expand Down Expand Up @@ -55,6 +57,7 @@ describe('updateProjectV2ItemField', () => {

await updateProjectV2ItemField()

expect(info).toHaveBeenCalledWith('update the project V2 item field')
expect(debug).toHaveBeenCalledWith('ProjectV2 ID: project-id')
expect(debug).toHaveBeenCalledWith('Item ID: item-id')
expect(debug).toHaveBeenCalledWith('Field ID: field-id')
Expand Down Expand Up @@ -85,6 +88,7 @@ describe('updateProjectV2ItemField', () => {

await updateProjectV2ItemField()

expect(info).toHaveBeenCalledWith('update the project V2 item field')
expect(debug).toHaveBeenCalledWith('ProjectV2 ID: project-id')
expect(debug).toHaveBeenCalledWith('Item ID: item-id')
expect(debug).toHaveBeenCalledWith('Field ID: field-id')
Expand Down Expand Up @@ -119,6 +123,7 @@ describe('updateProjectV2ItemField', () => {

await updateProjectV2ItemField()

expect(info).toHaveBeenCalledWith('update the project V2 item field')
expect(debug).toHaveBeenCalledWith('ProjectV2 ID: project-id')
expect(debug).toHaveBeenCalledWith('Item ID: item-id')
expect(debug).toHaveBeenCalledWith('Field ID: field-id')
Expand Down Expand Up @@ -161,13 +166,39 @@ describe('updateProjectV2ItemField', () => {

await updateProjectV2ItemField()

expect(info).toHaveBeenCalledWith('update the project V2 item field')
expect(debug).toHaveBeenCalledWith('ProjectV2 ID: project-id')
expect(debug).toHaveBeenCalledWith('Item ID: item-id')
expect(debug).toHaveBeenCalledWith('Field ID: field-id')
expect(debug).toHaveBeenCalledWith(`Field Value: {"date":"2024-02-02"}`)
expect(outputs.itemId).toEqual('item-id')
})

it('skip to update project v2 item field when condition-script is false', async () => {
mockGetInput({
'project-url': 'https://github.com/orgs/nipe0324/projects/1',
'github-token': 'gh_token',
'field-name': 'Text Input Field',
'field-value': 'Hello, World!',
'skip-update-script': 'return true'
})

mockFetchProjectV2Id().mockResolvedValue('project-id')
mockAddProjectV2ItemByContentId().mockResolvedValue({ id: 'item-id' })
mockFetchProjectV2FieldByName().mockResolvedValue({
id: 'field-id',
dataType: 'TEXT'
})
mockUpdateProjectV2ItemFieldValue().mockResolvedValue({ id: 'item-id' })

await updateProjectV2ItemField()

expect(info).toHaveBeenCalledWith(
'`skip-update-script` returns true. Skip updating the field'
)
expect(outputs.itemId).toEqual('item-id')
})

it(`throws an error when field-value and field-value-script are blank`, async () => {
mockGetInput({
'project-url': 'https://github.com/orgs/nipe0324/projects/1',
Expand Down Expand Up @@ -207,6 +238,10 @@ function mockSetOutput(): Record<string, string> {
return output
}

function mockInfo(): jest.SpyInstance {
return jest.spyOn(core, 'info').mockImplementation()
}

function mockDebug(): jest.SpyInstance {
return jest.spyOn(core, 'debug').mockImplementation()
}
Expand Down
4 changes: 4 additions & 0 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ inputs:
field-value-script:
required: false
description: The script that returns the value of the field to update. (`field-value` or `field-value-script` is required)
skip-update-script:
required: false
description: The script that returns a boolean value to determine whether to update the field. If the script returns `true`, the field will not be updated.


outputs:
projectId:
Expand Down
2 changes: 1 addition & 1 deletion badges/coverage.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
21 changes: 17 additions & 4 deletions dist/index.js

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

7 changes: 6 additions & 1 deletion src/inputs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export interface Inputs {
fieldName: string
fieldValue: string
fieldValueScript: string
skipUpdateScript: string | null
}

export function getInputs(): Inputs {
Expand All @@ -21,13 +22,17 @@ export function getInputs(): Inputs {
const fieldValueScript = core.getInput('field-value-script', {
required: false
})
const skipUpdateScript = core.getInput('skip-update-script', {
required: false
})

return {
projectUrl,
ghToken,
fieldName,
fieldValue,
fieldValueScript
fieldValueScript,
skipUpdateScript: skipUpdateScript !== '' ? skipUpdateScript : null
}
}

Expand Down
23 changes: 18 additions & 5 deletions src/update-project-v2-item-field.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import * as core from '@actions/core'
import { getInputs, Inputs, fetchProjectV2Id } from './inputs'
import { context } from '@actions/github'
import { callAsyncFunction } from './async-function'
import { ExOctokit, ProjectV2Item } from './ex-octokit'
import { ExOctokit } from './ex-octokit'
import { Item } from './item'

import type { ProjectV2Field, ProjectV2FieldValue } from './ex-octokit'
Expand Down Expand Up @@ -30,7 +30,7 @@ export async function updateProjectV2ItemField(): Promise<void> {
const issue = context.payload.issue ?? context.payload.pull_request
const contentId = issue?.node_id

const updatedItem = await updateItemField(
const itemId = await updateItemField(
exOctokit,
inputs,
projectV2Id,
Expand All @@ -39,7 +39,7 @@ export async function updateProjectV2ItemField(): Promise<void> {
)

// Set outputs for other workflow steps to use
core.setOutput('itemId', updatedItem.id)
core.setOutput('itemId', itemId)
}

async function updateItemField(
Expand All @@ -48,7 +48,7 @@ async function updateItemField(
projectV2Id: string,
contentId: string,
field: ProjectV2Field
): Promise<ProjectV2Item> {
): Promise<string> {
// Add the issue/PR to the project and get item
const itemData = await exOctokit.addProjectV2ItemByContentId(
projectV2Id,
Expand All @@ -60,6 +60,18 @@ async function updateItemField(

const item = Item.fromGraphQL(itemData)

// Check the skipUpdateScript
if (inputs.skipUpdateScript) {
const isSkip = await callAsyncFunction(
{ context, item },
inputs.skipUpdateScript
)
if (isSkip) {
core.info('`skip-update-script` returns true. Skip updating the field')
return item.id
}
}

// Build the value by field data type
const value =
inputs.fieldValue !== ''
Expand All @@ -78,12 +90,13 @@ async function updateItemField(
throw new Error(`Failed to update item field value`)
}

core.info('update the project V2 item field')
core.debug(`ProjectV2 ID: ${projectV2Id}`)
core.debug(`Item ID: ${item.id}`)
core.debug(`Field ID: ${field.id}`)
core.debug(`Field Value: ${JSON.stringify(projectV2FieldValue)}`)

return updatedItem
return updatedItem.id
}

function buildProjectV2FieldValue(
Expand Down

0 comments on commit b35709b

Please sign in to comment.