Skip to content

Commit d0317cd

Browse files
authored
Merge pull request #71 from Teamwork/migrate-boards-to-workflows
Migrate board columns to workflow stages
2 parents fd4c7d6 + d49b92c commit d0317cd

5 files changed

Lines changed: 79 additions & 51 deletions

File tree

.github/workflows/test.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,6 @@ jobs:
1717
TEAMWORK_URI: "localhost"
1818
TEAMWORK_API_TOKEN: "test_api_token"
1919
AUTOMATIC_TAGGING: true
20-
BOARD_COLUMN_OPENED: "PR Open"
21-
BOARD_COLUMN_MERGED: "Ready to Test"
22-
BOARD_COLUMN_CLOSED: "Rejected"
20+
WORKFLOW_STAGE_OPENED: "PR Open"
21+
WORKFLOW_STAGE_MERGED: "Ready to Test"
22+
WORKFLOW_STAGE_CLOSED: "Rejected"

README.md

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,9 @@ jobs:
4848
TEAMWORK_URI: ${{ secrets.TEAMWORK_URI }}
4949
TEAMWORK_API_TOKEN: ${{ secrets.TEAMWORK_API_TOKEN }}
5050
AUTOMATIC_TAGGING: false
51-
BOARD_COLUMN_OPENED: 'PR Open'
52-
BOARD_COLUMN_MERGED: 'Ready to Test'
53-
BOARD_COLUMN_CLOSED: 'Rejected'
51+
WORKFLOW_STAGE_OPENED: 'PR Open'
52+
WORKFLOW_STAGE_MERGED: 'Ready to Test'
53+
WORKFLOW_STAGE_CLOSED: 'Rejected'
5454
env:
5555
IGNORE_PROJECT_IDS: '1 2 3'
5656

@@ -71,12 +71,12 @@ Tags are added automatically on the task if you are have the option `AUTOMATIC_T
7171
- A PR is merged: tags `PR Open` and `PR Approved` removed, tag `PR merged` added
7272
- A PR is closed: tags `PR Open` and `PR Approved` removed
7373

74-
You may also specify columns you'd like the task to be moved to on every stage of the PR:
75-
- `BOARD_COLUMN_OPENED`: The case-sensitive column name of the column you'd like the task to be moved to once the PR has been opened
76-
- `BOARD_COLUMN_MERGED`: The case-sensitive column name of the column you'd like the task to be moved to once the PR has been merged
77-
- `BOARD_COLUMN_CLOSED`: The case-sensitive column name of the column you'd like the task to be moved to if the PR was closed without being merged
74+
You may also specify [workflow](https://support.teamwork.com/projects/workflows/workflows-introduction) stages you'd like the task to be moved to on every stage of the PR:
75+
- `WORKFLOW_STAGE_OPENED`: The case-sensitive name of the workflow stage you'd like the task to be moved to once the PR has been opened
76+
- `WORKFLOW_STAGE_MERGED`: The case-sensitive name of the workflow stage you'd like the task to be moved to once the PR has been merged
77+
- `WORKFLOW_STAGE_CLOSED`: The case-sensitive name of the workflow stage you'd like the task to be moved to if the PR was closed without being merged
7878

79-
The column names will be checked against all board columns in the task's project, this will be using a `contains()` method so you may specify part of the name instead of the full name, however this `contains()` check is case-sensitive. The first matching column will be used.
79+
The stage names will be checked against the stages of every workflow in the task's project, this will be using a `contains()` method so you may specify part of the name instead of the full name, however this `contains()` check is case-sensitive. The first matching stage will be used.
8080

8181
## Contributing
8282
* Open a PR: https://github.com/Teamwork/github-sync/pulls

action.yml

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,22 +16,34 @@ inputs:
1616
AUTOMATIC_TAGGING:
1717
description: 'Do you want to enable automatic tagging: true/false'
1818
required: false
19-
BOARD_COLUMN_OPENED:
20-
description: 'The case-sensitive column name of the column you would like the task to be moved to once the PR has been opened'
19+
WORKFLOW_STAGE_OPENED:
20+
description: 'The case-sensitive name of the workflow stage you would like the task to be moved to once the PR has been opened'
2121
required: false
2222
default: ''
23-
BOARD_COLUMN_MERGED:
24-
description: 'The case-sensitive column name of the column you would like the task to be moved to once the PR has been merged'
23+
WORKFLOW_STAGE_MERGED:
24+
description: 'The case-sensitive name of the workflow stage you would like the task to be moved to once the PR has been merged'
2525
required: false
2626
default: ''
27-
BOARD_COLUMN_CLOSED:
28-
description: 'The case-sensitive column name of the column you would like the task to be moved to if the PR was closed without being merged'
27+
WORKFLOW_STAGE_CLOSED:
28+
description: 'The case-sensitive name of the workflow stage you would like the task to be moved to if the PR was closed without being merged'
2929
required: false
3030
default: ''
3131
LIGHTWEIGHT_COMMENT:
3232
description: 'Generate tiny comments with minimal information'
3333
required: false
3434
default: 'false'
35+
BOARD_COLUMN_OPENED:
36+
description: 'Deprecated.'
37+
required: false
38+
default: ''
39+
BOARD_COLUMN_MERGED:
40+
description: 'Deprecated.'
41+
required: false
42+
default: ''
43+
BOARD_COLUMN_CLOSED:
44+
description: 'Deprecated.'
45+
required: false
46+
default: ''
3547
runs:
3648
using: 'docker'
3749
image: 'Dockerfile'
@@ -40,7 +52,10 @@ runs:
4052
- ${{ inputs.TEAMWORK_URI }}
4153
- ${{ inputs.TEAMWORK_API_TOKEN }}
4254
- ${{ inputs.AUTOMATIC_TAGGING }}
55+
- ${{ inputs.WORKFLOW_STAGE_OPENED }}
56+
- ${{ inputs.WORKFLOW_STAGE_MERGED }}
57+
- ${{ inputs.WORKFLOW_STAGE_CLOSED }}
58+
- ${{ inputs.LIGHTWEIGHT_COMMENT }}
4359
- ${{ inputs.BOARD_COLUMN_OPENED }}
4460
- ${{ inputs.BOARD_COLUMN_MERGED }}
45-
- ${{ inputs.BOARD_COLUMN_CLOSED }}
46-
- ${{ inputs.LIGHTWEIGHT_COMMENT }}
61+
- ${{ inputs.BOARD_COLUMN_CLOSED }}

src/main.sh

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,20 @@ main() {
1717
export TEAMWORK_URI="$2"
1818
export TEAMWORK_API_TOKEN="$3"
1919
export AUTOMATIC_TAGGING="$4"
20-
export BOARD_COLUMN_OPENED="$5"
21-
export BOARD_COLUMN_MERGED="$6"
22-
export BOARD_COLUMN_CLOSED="$7"
20+
export WORKFLOW_STAGE_OPENED="$5"
21+
export WORKFLOW_STAGE_MERGED="$6"
22+
export WORKFLOW_STAGE_CLOSED="$7"
2323
export LIGHTWEIGHT_COMMENT="$8"
24+
# BOARD_COLUMN_* are deprecated aliases kept for backwards compatibility.
25+
export BOARD_COLUMN_OPENED="${9:-}"
26+
export BOARD_COLUMN_MERGED="${10:-}"
27+
export BOARD_COLUMN_CLOSED="${11:-}"
28+
29+
# Fall back to the deprecated BOARD_COLUMN_* inputs when their WORKFLOW_STAGE_*
30+
# replacements are not set.
31+
: "${WORKFLOW_STAGE_OPENED:=$BOARD_COLUMN_OPENED}"
32+
: "${WORKFLOW_STAGE_MERGED:=$BOARD_COLUMN_MERGED}"
33+
: "${WORKFLOW_STAGE_CLOSED:=$BOARD_COLUMN_CLOSED}"
2434

2535
env::set_environment
2636

src/teamwork.sh

Lines changed: 32 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -31,54 +31,57 @@ teamwork::get_project_id_from_task() {
3131
echo "$response"
3232
}
3333

34-
teamwork::get_matching_board_column_id() {
35-
local -r column_name=$1
36-
37-
if [ -z "$column_name" ]; then
34+
# Resolves a workflow stage name to its "<workflowId> <stageId>" pair within the
35+
# task's project. Matching is a case-sensitive substring match against the stage
36+
# name (mirroring the legacy board-column behaviour), and the first match wins.
37+
# Echoes nothing when no stage name is provided or no stage matches.
38+
teamwork::get_workflow_stage() {
39+
local -r stage_name=$1
40+
41+
if [ -z "$stage_name" ]; then
3842
return
3943
fi
4044

4145
if [ "$ENV" == "test" ]; then
42-
echo "$TEAMWORK_PROJECT_ID"
46+
echo "$TEAMWORK_PROJECT_ID $TEAMWORK_PROJECT_ID"
4347
return
4448
fi
4549

46-
response=$(
47-
curl "$TEAMWORK_URI/projects/$TEAMWORK_PROJECT_ID/boards/columns.json" -u "$TEAMWORK_API_TOKEN"':' |\
48-
jq -r --arg column_name "$column_name" '[.columns[] | select(.name | contains($column_name))] | map(.id)[0]'
49-
)
50-
51-
if [ "$response" = "null" ]; then
52-
return
53-
fi
54-
55-
echo "$response"
50+
# A single call scoped to the project sideloads every stage across the
51+
# project's workflow(s); each stage carries its parent workflow id, which the
52+
# move endpoint also needs.
53+
curl -s "$TEAMWORK_URI/projects/api/v3/workflows.json?projectIds=$TEAMWORK_PROJECT_ID&include=stages" \
54+
-u "$TEAMWORK_API_TOKEN"':' |\
55+
jq -r --arg stage_name "$stage_name" \
56+
'[.included.stages[]? | select(.name | contains($stage_name)) | "\(.workflow.id) \(.id)"][0] // empty'
5657
}
5758

58-
teamwork::move_task_to_column() {
59-
local -r task_id=$TEAMWORK_TASK_ID
60-
local -r column_name=$1
59+
teamwork::move_task_to_stage() {
60+
local -r stage_name=$1
6161

62-
if [ -z "$column_name" ]; then
63-
log::message "No column name provided"
62+
if [ -z "$stage_name" ]; then
63+
log::message "No workflow stage name provided"
6464
return
6565
fi
6666

67-
local -r column_id=$(teamwork::get_matching_board_column_id "$column_name")
68-
if [ -z "$column_id" ]; then
69-
log::message "Failed to find a matching board column for '$column_name'"
67+
local -r stage=$(teamwork::get_workflow_stage "$stage_name")
68+
if [ -z "$stage" ]; then
69+
log::message "Failed to find a matching workflow stage for '$stage_name'"
7070
return
7171
fi
7272

73+
local workflow_id stage_id
74+
read -r workflow_id stage_id <<< "$stage"
75+
7376
if [ "$ENV" == "test" ]; then
74-
log::message "Test - Simulate request. Task ID: $TEAMWORK_TASK_ID - Project ID: $TEAMWORK_PROJECT_ID - Column ID: $column_id"
77+
log::message "Test - Simulate request. Task ID: $TEAMWORK_TASK_ID - Project ID: $TEAMWORK_PROJECT_ID - Workflow ID: $workflow_id - Stage ID: $stage_id"
7578
return
7679
fi
7780

78-
response=$(curl -X "PUT" "$TEAMWORK_URI/tasks/$TEAMWORK_TASK_ID.json" \
81+
response=$(curl -X "PATCH" "$TEAMWORK_URI/projects/api/v3/tasks/$TEAMWORK_TASK_ID/workflows/$workflow_id.json" \
7982
-u "$TEAMWORK_API_TOKEN"':' \
8083
-H 'Content-Type: application/json; charset=utf-8' \
81-
-d "{ \"todo-item\": { \"columnId\": $column_id } }" )
84+
-d "{ \"stageId\": $stage_id, \"positionAfterTask\": -1 }" )
8285

8386
log::message "$response"
8487
}
@@ -165,7 +168,7 @@ ${pr_body}
165168
fi
166169

167170
teamwork::add_tag "PR Open"
168-
teamwork::move_task_to_column "$BOARD_COLUMN_OPENED"
171+
teamwork::move_task_to_stage "$WORKFLOW_STAGE_OPENED"
169172
}
170173

171174
teamwork::pull_request_closed() {
@@ -186,7 +189,7 @@ teamwork::pull_request_closed() {
186189
teamwork::add_tag "PR Merged"
187190
teamwork::remove_tag "PR Open"
188191
teamwork::remove_tag "PR Approved"
189-
teamwork::move_task_to_column "$BOARD_COLUMN_MERGED"
192+
teamwork::move_task_to_stage "$WORKFLOW_STAGE_MERGED"
190193
else
191194
if [ "$LIGHTWEIGHT_COMMENT" == "true" ]; then
192195
teamwork::add_comment "PR [**\"$pr_title\"**]($pr_url) closed without merging by **$user**"
@@ -198,7 +201,7 @@ teamwork::pull_request_closed() {
198201
fi
199202
teamwork::remove_tag "PR Open"
200203
teamwork::remove_tag "PR Approved"
201-
teamwork::move_task_to_column "$BOARD_COLUMN_CLOSED"
204+
teamwork::move_task_to_stage "$WORKFLOW_STAGE_CLOSED"
202205
fi
203206
}
204207

0 commit comments

Comments
 (0)