Skip to content

Commit ab18fc8

Browse files
Merge branch 'main' into issue-1151
2 parents c9388bf + 7cdaf7e commit ab18fc8

147 files changed

Lines changed: 4606 additions & 1076 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/project.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
release:
2-
current-version: 7.13.6.Final
2+
current-version: 7.14.1.Final
33
next-version: 8.0.0-SNAPSHOT
Lines changed: 186 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,186 @@
1+
<!--
2+
Copyright 2021-Present The Serverless Workflow Specification Authors
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
-->
16+
17+
# Sync Issues to Target GitHub Project
18+
19+
Workflow file: `sync-issues-to-project.yml`
20+
21+
Automatically adds issues to a GitHub Project in another organization when they
22+
are opened, sets configurable initial field values, updates the Status when they
23+
are closed, and optionally imports pre-existing repo issues on demand.
24+
25+
---
26+
27+
## How it works
28+
29+
| Event | Action |
30+
|---|---|
31+
| Issue opened | Issue is added to the target project; initial field values are applied (skipped if `PSYNC_ENABLED=false` or `off`) |
32+
| Issue closed | Project item Status is updated to the configured close status (skipped if `PSYNC_ENABLED=false` or `off`) |
33+
| `workflow_dispatch` | If `PSYNC_IMPORT_EXISTING=true`, imports all open repo issues not yet in the project with initial field values applied |
34+
35+
The project item is natively linked to the source issue — no custom fields are
36+
needed. Clicking the item in the project board opens the original issue.
37+
38+
---
39+
40+
## Setup
41+
42+
### 1. Create a Personal Access Token (PAT)
43+
44+
The PAT must belong to a user with access to the target org's project.
45+
46+
Required scopes:
47+
- `project` — read/write access to GitHub Projects v2
48+
- `read:org` — required to resolve the org's project by number
49+
- `repo` (private repos) or `public_repo` (public repos) — required in either
50+
of these cases:
51+
- `PSYNC_INITIAL_VALUES` includes `Assignees=...` (REST API call to add
52+
assignees to the source repo issue)
53+
- `PSYNC_IMPORT_EXISTING=true` is used (REST API call to list all repo
54+
issues); for private repos this requires `repo`, for public repos
55+
`public_repo` is sufficient
56+
57+
> Classic PATs only. Fine-grained PATs do not yet support Projects v2 mutations.
58+
59+
### 2. Add the secret
60+
61+
Go to **Repo → Settings → Secrets and variables → Actions → Secrets**:
62+
63+
| Name | Value |
64+
|---|---|
65+
| `PSYNC_PAT` | The PAT created above |
66+
67+
### 3. Add the variables
68+
69+
Go to **Repo → Settings → Secrets and variables → Actions → Variables**:
70+
71+
| Name | Required | Default | Description | Example |
72+
|---|---|---|---|---|
73+
| `PSYNC_TARGET` | yes || Target project in `org:project_number` format | `my-org:1` |
74+
| `PSYNC_INITIAL_VALUES` | no || Comma-separated `field=value` pairs applied to new project items | `Status=Backlog, Area=Tooling, Assignees=user1` |
75+
| `PSYNC_CLOSE_STATUS` | no | `Done` | Status option name set on the project item when the issue is closed | `Done` |
76+
| `PSYNC_ENABLED` | no | `true` | Set to `false` or `off` to pause syncing without removing the workflow | `false` |
77+
| `PSYNC_IMPORT_EXISTING` | no | `false` | Set to `true` and trigger manually to bulk-import all open issues not yet in the project | `true` |
78+
| `PSYNC_AUTHORS_FILTER` | no || Comma-separated list of GitHub usernames; only issues opened by these users are synced. Empty means all authors are included | `user1, user2` |
79+
80+
The project number is visible in the project URL:
81+
`https://github.com/orgs/<org>/projects/<number>`
82+
83+
**`PSYNC_ENABLED`** — set to `false` or `off` to pause syncing without removing
84+
the workflow. `workflow_dispatch` runs (e.g. for importing) are not affected.
85+
86+
**`PSYNC_AUTHORS_FILTER`** — comma-separated list of GitHub usernames. When set, only
87+
issues created by one of the listed authors are synced to the target project. If
88+
unset or empty, all authors are included.
89+
90+
**`PSYNC_IMPORT_EXISTING`** — set to `true` and trigger the workflow manually
91+
via **Actions → Run workflow** to import all open repo issues not already in the
92+
project. The same `PSYNC_INITIAL_VALUES` rules apply. Issues already in the
93+
project are skipped. The run prints a summary: `Imported: N, Failed: N`.
94+
95+
#### `PSYNC_INITIAL_VALUES` format
96+
97+
Comma-separated `field=value` pairs. Field names must match the project field
98+
names exactly (case-sensitive). Example:
99+
100+
```
101+
Status=Backlog, Area=Tooling, Assignees=user1
102+
```
103+
104+
Supported field types:
105+
106+
| Field type | Behaviour |
107+
|---|---|
108+
| Single-select | Matches by option name |
109+
| Text | Sets the text value directly |
110+
| `Assignees` | Adds assignees to the source issue via the REST API; space-separate multiple users: `Assignees=user1 user2` |
111+
112+
> Number and date fields are not currently supported.
113+
114+
### 4. Ensure the target project has a Status field
115+
116+
The workflow looks for a **single-select field named exactly `Status`**. The
117+
option names used by `PSYNC_INITIAL_VALUES` and `PSYNC_CLOSE_STATUS` must
118+
exist in the project (case-sensitive).
119+
120+
Default options required unless overridden:
121+
122+
| Option | Used when |
123+
|---|---|
124+
| `Done` | Issue closed (default close Status) |
125+
126+
---
127+
128+
## Limitations
129+
130+
- **Sub-issues are not synced** — GitHub does not emit webhook events for
131+
sub-issues; only top-level issues trigger the `issues` event.
132+
- **Status field name is hardcoded** — the field must be named `Status`.
133+
- **Number and date fields** in `PSYNC_INITIAL_VALUES` are not supported;
134+
only single-select and text fields.
135+
136+
---
137+
138+
## Troubleshooting
139+
140+
### `gh: To use GitHub CLI in a GitHub Actions workflow, set the GH_TOKEN environment variable`
141+
142+
`PSYNC_PAT` is not set or is empty. Verify it exists under **Repo → Settings → Secrets and variables → Actions → Secrets**.
143+
144+
### `Error: Process completed with exit code 1` on the GraphQL steps
145+
146+
Run the query manually to inspect the response:
147+
148+
```bash
149+
gh api graphql -f query='
150+
query($org: String!, $number: Int!) {
151+
organization(login: $org) {
152+
projectV2(number: $number) {
153+
id
154+
}
155+
}
156+
}' \
157+
-f org="<target-org>" \
158+
-F number=<project-number>
159+
```
160+
161+
Common causes:
162+
- The PAT does not have access to the target org's project
163+
- The project number is wrong
164+
- The org name in `PSYNC_TARGET` has a typo
165+
166+
### Item not found on close (`item_id` is empty)
167+
168+
If the issue is not already in the project when it is closed (e.g., it was opened before the workflow was installed, or the `opened` sync failed), the workflow automatically adds it to the project and then sets the close Status.
169+
170+
If the close path still fails, likely causes are:
171+
- The PAT lacks `project` write access to the target org's project
172+
- The project ID lookup failed (check `PSYNC_TARGET` format and PAT scopes)
173+
174+
### Status not updated on close
175+
176+
Verify the target project has:
177+
- A single-select field named exactly `Status`
178+
- An option matching the value of `PSYNC_CLOSE_STATUS` (default: `Done`)
179+
180+
Field and option names are case-sensitive.
181+
182+
### Field not found warning in `Set initial field values`
183+
184+
The step prints `Warning: field '<name>' not found, skipping.` when a key in
185+
`PSYNC_INITIAL_VALUES` does not match any field in the project. Check for
186+
typos or extra spaces in the variable value.

0 commit comments

Comments
 (0)