Skip to content

Commit cf769f0

Browse files
committed
Merge branch 'edge' into chore_update-cypress
2 parents 09e00ed + 838e356 commit cf769f0

File tree

925 files changed

+53521
-16795
lines changed

Some content is hidden

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

925 files changed

+53521
-16795
lines changed

.github/workflows/app-test-build-deploy.yaml

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -112,8 +112,6 @@ jobs:
112112
- uses: actions/setup-python@v4
113113
with:
114114
python-version: '3.10'
115-
- name: 'downgrade npm version'
116-
run: npm install -g npm@6
117115
- name: check make version
118116
run: make --version
119117
- name: 'install libudev and libsystemd'
@@ -245,8 +243,6 @@ jobs:
245243
- uses: actions/setup-python@v4
246244
with:
247245
python-version: '3.10'
248-
- name: 'downgrade npm version'
249-
run: npm install -g npm@6
250246
- name: check make version
251247
run: make --version
252248
- name: 'install libudev and libsystemd'

.github/workflows/components-test-build-deploy.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,10 +174,13 @@ jobs:
174174
with:
175175
node-version: '18.19.0'
176176
registry-url: 'https://registry.npmjs.org'
177+
- name: 'install udev for usb-detection'
178+
run: sudo apt-get update && sudo apt-get install libudev-dev
177179
- name: 'setup-js'
178180
run: |
179181
npm config set cache ./.npm-cache
180182
yarn config set cache-folder ./.yarn-cache
183+
make setup-js
181184
- name: 'build typescript'
182185
run: make build-ts
183186
- name: 'build library'
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
# Run tests, build the app, and deploy it cross platform
2+
3+
name: 'OpentronsAI client test, build, and deploy'
4+
5+
# ToDo (kk:04/16/2024) Add build and deploy task
6+
7+
on:
8+
push:
9+
paths:
10+
- 'Makefile'
11+
- 'opentrons-ai-client/**/*'
12+
- 'components/**/*'
13+
- '*.js'
14+
- '*.json'
15+
- 'yarn.lock'
16+
- '.github/workflows/app-test-build-deploy.yaml'
17+
- '.github/workflows/utils.js'
18+
branches:
19+
- '**'
20+
tags:
21+
- 'v*'
22+
- 'ot3@*'
23+
pull_request:
24+
paths:
25+
- 'Makefile'
26+
- 'opentrons-ai-client/**/*'
27+
- 'components/**/*'
28+
- '*.js'
29+
- '*.json'
30+
- 'yarn.lock'
31+
workflow_dispatch:
32+
33+
concurrency:
34+
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}-${{ github.ref_name != 'edge' || github.run_id}}-${{ github.ref_type != 'tag' || github.run_id }}
35+
cancel-in-progress: true
36+
37+
env:
38+
CI: true
39+
40+
jobs:
41+
js-unit-test:
42+
runs-on: 'ubuntu-22.04'
43+
name: 'opentrons ai frontend unit tests'
44+
timeout-minutes: 60
45+
steps:
46+
- uses: 'actions/checkout@v3'
47+
- uses: 'actions/setup-node@v3'
48+
with:
49+
node-version: '18.19.0'
50+
- name: 'install udev'
51+
run: sudo apt-get update && sudo apt-get install libudev-dev
52+
- name: 'set complex environment variables'
53+
id: 'set-vars'
54+
uses: actions/github-script@v6
55+
with:
56+
script: |
57+
const { buildComplexEnvVars } = require(`${process.env.GITHUB_WORKSPACE}/.github/workflows/utils.js`)
58+
buildComplexEnvVars(core, context)
59+
- name: 'cache yarn cache'
60+
uses: actions/cache@v3
61+
with:
62+
path: |
63+
${{ github.workspace }}/.npm-cache/_prebuild
64+
${{ github.workspace }}/.yarn-cache
65+
key: js-${{ secrets.GH_CACHE_VERSION }}-${{ runner.os }}-yarn-${{ hashFiles('yarn.lock') }}
66+
- name: 'setup-js'
67+
run: |
68+
npm config set cache ${{ github.workspace }}/.npm-cache
69+
yarn config set cache-folder ${{ github.workspace }}/.yarn-cache
70+
make setup-js
71+
- name: 'test frontend packages'
72+
run: |
73+
make -C opentrons-ai-client test-cov
74+
- name: 'Upload coverage report'
75+
uses: codecov/codecov-action@v3
76+
with:
77+
files: ./coverage/lcov.info
78+
flags: opentrons-ai-client
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
# This workflow runs lint on pull requests that touch anything in the performance-metrics directory
2+
3+
name: 'performance-metrics test & lint'
4+
5+
on:
6+
pull_request:
7+
paths:
8+
- 'performance-metrics/**'
9+
- '.github/workflows/performance-metrics-test-lint.yaml'
10+
workflow_dispatch:
11+
12+
concurrency:
13+
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
14+
cancel-in-progress: true
15+
16+
defaults:
17+
run:
18+
shell: bash
19+
20+
jobs:
21+
lint:
22+
name: 'performance-metrics test & lint'
23+
timeout-minutes: 5
24+
runs-on: 'ubuntu-latest'
25+
steps:
26+
- name: Checkout opentrons repo
27+
uses: 'actions/checkout@v4'
28+
29+
- name: Setup Python
30+
uses: 'actions/setup-python@v5'
31+
with:
32+
python-version: '3.10'
33+
cache: 'pipenv'
34+
cache-dependency-path: performance-metrics/Pipfile.lock
35+
36+
- name: "Install Python deps"
37+
uses: './.github/actions/python/setup'
38+
with:
39+
project: 'performance-metrics'
40+
41+
- name: Setup
42+
id: install
43+
working-directory: ./performance-metrics
44+
run: make setup
45+
46+
- name: Test
47+
if: always() && steps.install.outcome == 'success' || steps.install.outcome == 'skipped'
48+
working-directory: ./performance-metrics
49+
run: make test
50+
51+
- name: Lint
52+
if: always() && steps.install.outcome == 'success' || steps.install.outcome == 'skipped'
53+
working-directory: ./performance-metrics
54+
run: make lint

.github/workflows/shared-data-test-lint-deploy.yaml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,8 @@ jobs:
237237
- name: 'js deps'
238238
run: |
239239
npm config set cache ./.npm-cache
240-
yarn config set cache-folder ./.yarn-cache
240+
yarn config set cache-folder ./.yarn-cache
241+
make setup-js
241242
- name: 'build typescript'
242243
run: make build-ts
243244
- name: 'build library'

.storybook/main.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ module.exports = {
22
stories: [
33
'../components/**/*.stories.@(js|jsx|ts|tsx)',
44
'../app/**/*.stories.@(js|jsx|ts|tsx)',
5+
'../opentrons-ai-client/**/*.stories.@(js|jsx|ts|tsx)',
56
],
67

78
addons: [

.storybook/preview.jsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ export const parameters = {
2020
options: {
2121
storySort: {
2222
method: 'alphabetical',
23-
order: ['Design Tokens', 'Library', 'App', 'ODD'],
23+
order: ['Design Tokens', 'Library', 'App', 'ODD', 'AI'],
2424
},
2525
},
2626
}

abr-testing/abr_testing/google_automation/google_drive_tool.py renamed to abr-testing/abr_testing/automation/google_drive_tool.py

Lines changed: 50 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
"""Google Drive Tool."""
22
import os
3-
from typing import Set, Any
3+
from typing import Set, Any, Optional
4+
import webbrowser
5+
import mimetypes
46
from oauth2client.service_account import ServiceAccountCredentials # type: ignore[import]
57
from googleapiclient.discovery import build
68
from googleapiclient.http import MediaFileUpload
@@ -14,15 +16,15 @@
1416
class google_drive:
1517
"""Google Drive Tool."""
1618

17-
def __init__(self, credentials: Any, folder_name: str, parent_folder: Any) -> None:
19+
def __init__(self, credentials: Any, folder_name: str, email: str) -> None:
1820
"""Connects to google drive via credentials file."""
1921
self.scope = ["https://www.googleapis.com/auth/drive"]
2022
self.credentials = ServiceAccountCredentials.from_json_keyfile_name(
2123
credentials, self.scope
2224
)
2325
self.drive_service = build("drive", "v3", credentials=self.credentials)
24-
self.folder_name = folder_name
25-
self.parent_folder = parent_folder
26+
self.parent_folder = folder_name
27+
self.email = email
2628

2729
def list_folder(self, delete: Any = False) -> Set[str]:
2830
"""List folders and files in Google Drive."""
@@ -72,26 +74,37 @@ def upload_file(self, file_path: str) -> str:
7274
"""Upload file to Google Drive."""
7375
file_metadata = {
7476
"name": os.path.basename(file_path),
75-
"mimeType": "application/vnd.google-apps.folder",
76-
"parents": [self.parent_folder] if self.parent_folder else "",
77+
"mimeType": str(mimetypes.guess_type(file_path)[0]),
78+
"parents": [self.parent_folder],
7779
}
78-
7980
media = MediaFileUpload(file_path, resumable=True)
8081

8182
uploaded_file = (
8283
self.drive_service.files()
8384
.create(body=file_metadata, media_body=media, fields="id") # type: ignore
8485
.execute()
8586
)
86-
8787
return uploaded_file["id"]
8888

89-
def upload_missing_files(self, storage_directory: str, missing_files: set) -> None:
89+
def upload_missing_files(self, storage_directory: str) -> None:
9090
"""Upload missing files to Google Drive."""
91+
# Read Google Drive .json files.
92+
google_drive_files = self.list_folder()
93+
google_drive_files_json = [
94+
file for file in google_drive_files if file.endswith(".json")
95+
]
96+
# Read local directory.
97+
local_files_json = set(
98+
file for file in os.listdir(storage_directory) if file.endswith(".json")
99+
)
100+
missing_files = local_files_json - set(google_drive_files_json)
101+
print(f"Missing files: {len(missing_files)}")
102+
# Upload missing files.
91103
uploaded_files = []
92104
for file in missing_files:
93105
file_path = os.path.join(storage_directory, file)
94106
uploaded_file_id = google_drive.upload_file(self, file_path)
107+
self.share_permissions(uploaded_file_id)
95108
uploaded_files.append(
96109
{"name": os.path.basename(file_path), "id": uploaded_file_id}
97110
)
@@ -108,3 +121,31 @@ def upload_missing_files(self, storage_directory: str, missing_files: set) -> No
108121
print(
109122
f"File '{this_name}' was not found in the list of files after uploading."
110123
)
124+
125+
def open_folder(self) -> Optional[str]:
126+
"""Open folder in web browser."""
127+
folder_metadata = (
128+
self.drive_service.files()
129+
.get(fileId=self.parent_folder, fields="webViewLink")
130+
.execute()
131+
)
132+
folder_link = folder_metadata.get("webViewLink")
133+
if folder_link:
134+
print(f"Folder link: {folder_link}")
135+
webbrowser.open(
136+
folder_link
137+
) # Open the folder link in the default web browser
138+
else:
139+
print("Folder link not found.")
140+
return folder_link
141+
142+
def share_permissions(self, file_id: str) -> None:
143+
"""Share permissions with self."""
144+
new_permission = {
145+
"type": "user",
146+
"role": "writer",
147+
"emailAddress": self.email,
148+
}
149+
self.drive_service.permissions().create(
150+
fileId=file_id, body=new_permission, transferOwnership=False # type: ignore
151+
).execute()

abr-testing/abr_testing/google_automation/google_sheets_tool.py renamed to abr-testing/abr_testing/automation/google_sheets_tool.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import gspread # type: ignore[import]
33
import socket
44
import httplib2
5+
from datetime import datetime
56
from oauth2client.service_account import ServiceAccountCredentials # type: ignore[import]
67
from typing import Dict, List, Any, Set, Tuple
78

@@ -57,6 +58,12 @@ def write_to_row(self, data: List) -> None:
5758
"""Write data into a row in a List[] format."""
5859
try:
5960
self.row_index += 1
61+
data = [
62+
item.strftime("%Y/%m/%d %H:%M:%S")
63+
if isinstance(item, datetime)
64+
else item
65+
for item in data
66+
]
6067
self.worksheet.insert_row(data, index=self.row_index)
6168
except socket.gaierror:
6269
pass

0 commit comments

Comments
 (0)