Skip to content
This repository has been archived by the owner on Sep 29, 2023. It is now read-only.

Merge latest from upstream #1

Open
wants to merge 51 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
a51ed9e
Add branding to action.yml
axelniklasson May 23, 2023
34ebbba
Update action.yml
axelniklasson May 23, 2023
276e912
Update release script to also update major version tag
axelniklasson May 23, 2023
d22f985
Version 1.3.2
axelniklasson May 23, 2023
ec93f16
Fix release script
axelniklasson May 23, 2023
dfbb66d
Version 1.3.2
axelniklasson May 23, 2023
006235e
Update release notes
axelniklasson May 23, 2023
27e266a
Update README.md
axelniklasson May 23, 2023
38406de
Update action.yml to set name as not required (#13)
b099l3 May 24, 2023
8b368a3
Version 1.3.3
axelniklasson May 24, 2023
4614570
Add support for iOS version config (#15)
axelniklasson Jun 12, 2023
30d670d
Update README.md
axelniklasson Jun 12, 2023
0bc8258
Update README (#16)
axelniklasson Jun 13, 2023
8cf8aef
Version 1.4.0
axelniklasson Jun 13, 2023
2421273
Changing IOS versions specified in README
Jun 13, 2023
24cdd07
Revert "Changing IOS versions specified in README"
Jun 13, 2023
dca94e8
Fix bug causing rejected uploads when ios-version is not set (#17)
axelniklasson Jun 19, 2023
2458fd5
Version 1.4.1
axelniklasson Jun 19, 2023
54742c3
Output console URL (#20)
axelniklasson Aug 31, 2023
2bc194f
Show errors and better cancellation messages in StatusPoller (#19)
axelniklasson Aug 31, 2023
b56b3d9
Store upload status and flow results in output (#21)
axelniklasson Aug 31, 2023
3c896c7
Update README
axelniklasson Aug 31, 2023
d701602
Update README
axelniklasson Aug 31, 2023
baa70d5
Version 1.5.0
axelniklasson Aug 31, 2023
1e1571a
feat: add app binary id to input and output (#23)
igorsmotto Oct 6, 2023
80f9291
Release: Version 1.6.0 (#24)
igorsmotto Oct 6, 2023
06ef0c4
feat: add support for device locale (#26)
artem888 Oct 20, 2023
ec9d3f5
Release: Version 1.7.0 (#27)
artem888 Nov 10, 2023
4499213
feat: add timeout parameter (#30)
igorsmotto Nov 15, 2023
796e192
Release: Version 1.8.0 (#31)
igorsmotto Nov 15, 2023
fa6929d
Fix broken link in README (#32)
bartekpacia Nov 27, 2023
94fbd11
Update README with output variable types (#33)
meatnordrink Jan 18, 2024
36c06a3
chore: bump to node 20 (#36)
axelniklasson Feb 16, 2024
c974d6d
Version 1.8.1
axelniklasson Feb 16, 2024
398c367
Update README.md - fix double colon (#38)
dominicletz Jun 7, 2024
ae2da37
Added robin actions (#42)
proksh Aug 30, 2024
2c449e8
fix: add project-id to action.yml (#43)
axelniklasson Sep 2, 2024
f4573b6
Version 1.9.1
axelniklasson Sep 2, 2024
e011061
[fix] Support setting upload name in Robin
Leland-Takamine Oct 9, 2024
5da5c6a
Version 1.9.1
Leland-Takamine Oct 9, 2024
f96a607
Version 1.9.2
Leland-Takamine Oct 9, 2024
0c230a9
fix: add stopped status (#44)
amanjeetsingh150 Oct 16, 2024
9efcddc
Version 1.9.3
axelniklasson Nov 6, 2024
6346442
chore: update to new robin domain (#45)
axelniklasson Nov 6, 2024
6696ae0
Version 1.9.4
axelniklasson Nov 6, 2024
d7e2fb7
Add Robin to README (#46)
Fishbowler Nov 8, 2024
2a5ce0a
Use existing API URL (#47)
Fishbowler Nov 8, 2024
aa773c5
Version 1.9.6
Fishbowler Nov 8, 2024
b53ea3a
feat:added new run status PREPARING & INSTALLING (#49)
proksh Nov 19, 2024
c220d1d
Separated out status for upload and flows (#50)
proksh Nov 21, 2024
ab98a98
Feat/added new run status (#51)
proksh Nov 21, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"singleQuote": true,
"semi": false,
"useTabs": false,
"trailingComma": "none",
"tabWidth": 2,
"importOrderSeparation": true,
"importOrderSortSpecifiers": true,
"printWidth": 80
}
217 changes: 157 additions & 60 deletions ApiClient.ts
Original file line number Diff line number Diff line change
@@ -1,119 +1,216 @@
import fetch, { FetchError, fileFromSync, FormData } from 'node-fetch';
import fetch, { fileFromSync, FormData } from 'node-fetch'

export enum BenchmarkStatus {
export enum RunStatus {
PENDING = 'PENDING',
PREPARING = 'PREPARING',
INSTALLING = 'INSTALLING',
RUNNING = 'RUNNING',
SUCCESS = 'SUCCESS',
ERROR = 'ERROR',
CANCELED = 'CANCELED',
WARNING = 'WARNING',
STOPPED = 'STOPPED'
}

export type UploadRequest = {
export enum UploadStatus {
PENDING = 'PENDING',
RUNNING = 'RUNNING',
SUCCESS = 'SUCCESS',
ERROR = 'ERROR',
CANCELED = 'CANCELED',
WARNING = 'WARNING',
STOPPED = 'STOPPED'
}

export type CloudUploadRequest = {
benchmarkName?: string
repoOwner?: string
repoName?: string
pullRequestId?: string
branch?: string
commitSha?: string
env?: { [key: string]: string }
agent: string
androidApiLevel?: number
iOSVersion?: number
includeTags: string[]
excludeTags: string[]
appBinaryId?: string
deviceLocale?: string
}

export type RobinUploadRequest = {
benchmarkName?: string
projectId: string
repoOwner?: string
repoName?: string
pullRequestId?: string
branch?: string,
commitSha?: string,
env?: { [key: string]: string },
agent: string,
androidApiLevel?: number,
includeTags: string[],
excludeTags: string[],
branch?: string
commitSha?: string
env?: { [key: string]: string }
agent: string
androidApiLevel?: number
iOSVersion?: number
includeTags: string[]
excludeTags: string[]
appBinaryId?: string
deviceLocale?: string
}

// irrelevant data has been factored out from this model
export type UploadResponse = {
uploadId: string,
teamId: string,
uploadId: string
teamId: string
targetId: string
appBinaryId: string
}

export type RobinUploadResponse = {
uploadId: string
orgId: string
appId: string
appBinaryId: string
}

export class UploadStatusError {
constructor(public status: number, public text: string) { }
constructor(public status: number, public text: string) {}
}

export enum CancellationReason {
BENCHMARK_DEPENDENCY_FAILED = 'BENCHMARK_DEPENDENCY_FAILED',
INFRA_ERROR = 'INFRA_ERROR',
OVERLAPPING_BENCHMARK = 'OVERLAPPING_BENCHMARK',
TIMEOUT = 'TIMEOUT'
}

export type Flow = {
name: string,
status: BenchmarkStatus
name: string
status: RunStatus
errors?: string[]
cancellationReason?: CancellationReason
}

export type UploadStatusResponse = {
uploadId: string,
status: BenchmarkStatus,
completed: boolean,
uploadId: string
status: UploadStatus
completed: boolean
flows: Flow[]
}

export default class ApiClient {

constructor(
private apiKey: string,
private apiUrl: string
) { }
private apiUrl: string,
private projectId?: string
) {}

async uploadRequest(
request: UploadRequest,
appFile: string,
async cloudUploadRequest(
request: CloudUploadRequest,
appFile: string | null,
workspaceZip: string | null,
mappingFile: string | null,
mappingFile: string | null
): Promise<UploadResponse> {
const formData = new FormData()

formData.set('request', JSON.stringify(request))
formData.set(
'app_binary',
fileFromSync(appFile)
)

if (appFile) {
formData.set('app_binary', fileFromSync(appFile))
}
if (workspaceZip) {
formData.set(
'workspace',
fileFromSync(workspaceZip)
);
formData.set('workspace', fileFromSync(workspaceZip))
}

if (mappingFile) {
formData.set(
'mapping',
fileFromSync(mappingFile)
)
formData.set('mapping', fileFromSync(mappingFile))
}

formData.set('request', JSON.stringify(request))
const res = await fetch(`${this.apiUrl}/v2/upload`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${this.apiKey}`,
Authorization: `Bearer ${this.apiKey}`
},
body: formData
});
})
if (!res.ok) {
const body = await res.text();
throw new Error(`Request to ${res.url} failed (${res.status}): ${body}`);
const body = await res.text()
throw new Error(`Request to ${res.url} failed (${res.status}): ${body}`)
}
return await res.json() as UploadResponse;
return (await res.json()) as UploadResponse
}

async getUploadStatus(
uploadId: string,
): Promise<UploadStatusResponse> {
const res = await fetch(`${this.apiUrl}/v2/upload/${uploadId}/status`, {
method: 'GET',
async robinUploadRequest(
request: RobinUploadRequest,
appFile: string | null,
workspaceZip: string | null,
mappingFile: string | null
): Promise<RobinUploadResponse> {
const formData = new FormData()

if (appFile) {
formData.set('app_binary', fileFromSync(appFile))
}
if (workspaceZip) {
formData.set('workspace', fileFromSync(workspaceZip))
}
if (mappingFile) {
formData.set('mapping', fileFromSync(mappingFile))
}
formData.set('request', JSON.stringify(request))

const res = await fetch(`${this.apiUrl}/runMaestroTest`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${this.apiKey}`,
Authorization: `Bearer ${this.apiKey}`
},
});
body: formData
})
if (!res.ok) {
const body = await res.text();
throw new Error(`Request to ${res.url} failed (${res.status}): ${body}`);
const body = await res.text()
throw new Error(`Request to ${res.url} failed (${res.status}): ${body}`)
}
return (await res.json()) as RobinUploadResponse
}

if (res.status >= 400) {
const text = await res.text();
Promise.reject(new UploadStatusError(res.status, text));
async getUploadStatus(uploadId: string): Promise<UploadStatusResponse> {
// If Project Id exist - Hit robin
if (!!this.projectId) {
const res = await fetch(`${this.apiUrl}/upload/${uploadId}`, {
method: 'GET',
headers: {
Authorization: `Bearer ${this.apiKey}`
}
})
if (!res.ok) {
const body = await res.text()
throw new Error(`Request to ${res.url} failed (${res.status}): ${body}`)
}

if (res.status >= 400) {
const text = await res.text()
Promise.reject(new UploadStatusError(res.status, text))
}

return (await res.json()) as UploadStatusResponse
}
// Else if no project id - Hit Cloud
else {
const res = await fetch(
`${this.apiUrl}/v2/upload/${uploadId}/status?includeErrors=true`,
{
method: 'GET',
headers: {
Authorization: `Bearer ${this.apiKey}`
}
}
)
if (!res.ok) {
const body = await res.text()
throw new Error(`Request to ${res.url} failed (${res.status}): ${body}`)
}

return await res.json() as UploadStatusResponse;
if (res.status >= 400) {
const text = await res.text()
Promise.reject(new UploadStatusError(res.status, text))
}

return (await res.json()) as UploadStatusResponse
}
}
}
Loading