Skip to content

Commit 82ad165

Browse files
Merge pull request #16 from gitautoai/wes
Get and display integrated repositories on a Jira ticket
2 parents acece32 + 1a24277 commit 82ad165

File tree

4 files changed

+97
-11
lines changed

4 files changed

+97
-11
lines changed

.github/workflows/deploy.yml

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,10 @@ jobs:
5757
forge deploy -e staging
5858
fi
5959
60-
# Install Forge app dependencies
60+
# Install or upgrade Forge app
6161
# https://developer.atlassian.com/platform/forge/cli-reference/install/
62-
- name: Install Forge dependencies
62+
- name: Install/Upgrade Forge app
6363
if: github.event_name == 'pull_request'
64-
run: forge install -e staging -s gitauto.atlassian.net -p Jira --upgrade --confirm-scopes --non-interactive --verbose
64+
run: |
65+
forge install -e staging -s gitauto.atlassian.net -p Jira --confirm-scopes --non-interactive --verbose || \
66+
forge install -e staging -s gitauto.atlassian.net -p Jira --upgrade --confirm-scopes --non-interactive --verbose

manifest.yml

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,14 @@
11
modules:
2+
# The trigger module invokes a function or calls a remote backend when a product event, app lifecycle event, or data security policy event is fired.
3+
# https://developer.atlassian.com/platform/forge/manifest-reference/modules/trigger/
4+
# trigger:
5+
# - key: app-lifecycle-trigger
6+
# function: lifecycleHandler
7+
# events:
8+
# - installed # https://developer.atlassian.com/platform/forge/events-reference/life-cycle/
9+
# - uninstalled
10+
11+
# The jira module provides functionality for Jira products.
212
jira:issuePanel:
313
- key: gitauto-jira-hello-world-issue-panel
414
resource: main
@@ -7,16 +17,33 @@ modules:
717
render: native
818
title: GitAuto
919
icon: https://developer.atlassian.com/platform/forge/images/icons/issue-panel-icon.svg
20+
21+
# https://developer.atlassian.com/platform/forge/runtime-reference/forge-resolver/
1022
function:
1123
- key: resolver
1224
handler: index.handler
25+
1326
resources:
1427
- key: main
1528
path: src/frontend/index.jsx
1629
app:
1730
runtime:
1831
name: nodejs20.x # Has to be 'sandbox', 'nodejs18.x', 'nodejs20.x'
1932
id: ari:cloud:ecosystem::app/f434bcc5-834f-45e5-ba1d-62e2ee8952cd
33+
34+
# Environment variables are not supported in the manifest.yml file.
35+
# https://developer.atlassian.com/platform/forge/manifest-reference/permissions/
2036
permissions:
2137
scopes:
2238
- read:jira-work
39+
external:
40+
fetch:
41+
backend:
42+
- https://dkrxtcbaqzrodvsagwwn.supabase.co
43+
- https://awegqusxzsmlgxaxyyrq.supabase.co
44+
45+
# https://developer.atlassian.com/platform/forge/manifest-reference/variables/
46+
environment:
47+
variables:
48+
- SUPABASE_URL
49+
- SUPABASE_API_KEY

src/frontend/index.jsx

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
import React, { useEffect, useState } from "react";
22
import ForgeReconciler, { Select, Text, useProductContext } from "@forge/react";
3-
import { requestJira } from "@forge/bridge";
3+
import { invoke } from "@forge/bridge";
44

55
const App = () => {
66
// Get Jira cloud ID (== workspace ID)
77
const context = useProductContext();
8+
9+
// Get Jira cloud ID
810
const [cloudId, setCloudId] = useState(null);
911
useEffect(() => {
1012
if (context) {
@@ -14,17 +16,47 @@ const App = () => {
1416
}
1517
}, [context]);
1618

19+
// Get Jira project ID
20+
const [projectId, setProjectId] = useState(null);
21+
useEffect(() => {
22+
if (context) setProjectId(context.extension.project.id);
23+
}, [context]);
24+
25+
// Get corresponding GitHub repositories from Supabase
26+
const [githubRepos, setGithubRepos] = useState([]);
27+
useEffect(() => {
28+
const fetchRepositories = async () => {
29+
if (cloudId && projectId) {
30+
try {
31+
const response = await invoke("getGithubRepos", {
32+
cloudId,
33+
projectId,
34+
});
35+
36+
// response will be an array of repositories from Supabase
37+
setGithubRepos(
38+
response.map((repo) => `${repo.github_owner_name}/${repo.github_repo_name}`)
39+
);
40+
} catch (error) {
41+
console.error("Error fetching repositories:", error);
42+
setGithubRepos([]);
43+
}
44+
}
45+
};
46+
47+
fetchRepositories();
48+
}, [cloudId, projectId]);
49+
1750
// Get repository list where GitAuto is installed
18-
const repositories = ["gitautoai/gitauto", "gitautoai/gitauto-jira"];
19-
const [selectedRepo, setSelectedRepo] = useState(repositories[0]);
51+
const [selectedRepo, setSelectedRepo] = useState(githubRepos[0]);
2052

2153
return (
2254
<>
2355
<Text>Target GitHub Repository:</Text>
2456
<Select
2557
value={selectedRepo}
2658
onChange={setSelectedRepo}
27-
options={repositories.map((repo) => ({ label: repo, value: repo }))}
59+
options={githubRepos.map((repo) => ({ label: repo, value: repo }))}
2860
/>
2961
</>
3062
);

src/resolvers/index.js

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,35 @@
1-
import Resolver from '@forge/resolver';
1+
import Resolver from "@forge/resolver";
2+
import forge from "@forge/api";
23

34
const resolver = new Resolver();
45

5-
resolver.define('getText', (req) => {
6-
console.log(req);
7-
return 'Hello, world!';
6+
// https://developer.atlassian.com/platform/forge/runtime-reference/forge-resolver/
7+
resolver.define("getGithubRepos", async ({ payload }) => {
8+
const { cloudId, projectId } = payload;
9+
10+
// https://supabase.com/docs/guides/api/sql-to-rest
11+
const queryParams = new URLSearchParams({
12+
select: "*",
13+
jira_site_id: `eq.${cloudId}`,
14+
jira_project_id: `eq.${projectId}`,
15+
}).toString();
16+
const url = `${process.env.SUPABASE_URL}/rest/v1/jira_github_links?${queryParams}`;
17+
console.log(url);
18+
19+
const response = await forge.fetch(url, {
20+
method: "GET",
21+
headers: {
22+
apikey: process.env.SUPABASE_API_KEY,
23+
Authorization: `Bearer ${process.env.SUPABASE_API_KEY}`,
24+
"Content-Type": "application/json",
25+
},
26+
});
27+
28+
if (!response.ok) throw new Error(`Failed to fetch repositories: ${response.status}`);
29+
30+
const data = await response.json();
31+
console.log(data);
32+
return data;
833
});
934

1035
export const handler = resolver.getDefinitions();

0 commit comments

Comments
 (0)