diff --git a/.github/workflows/check-be-pull-request.yml b/.github/workflows/check-be-pull-request.yml new file mode 100644 index 000000000..f17d8c5c8 --- /dev/null +++ b/.github/workflows/check-be-pull-request.yml @@ -0,0 +1,41 @@ +name: Check Backend Pull Request + +on: + pull_request: + types: [ opened, synchronize ] + paths: + - 'backend/**' + - '!backend/README.md' + - '!backend/.*' + - 'backend/.eslintrc.js' + + +jobs: + + check-be-pr: + name: Check + runs-on: ubuntu-latest + + steps: + - + name: โ˜๏ธ Checkout source + uses: actions/checkout@v3 + - + name: ๐Ÿ”ง Setup Node 16 + uses: actions/setup-node@v3 + with: + node-version: '16' + cache: 'npm' + cache-dependency-path: backend/package-lock.json + - + name: ๐Ÿ“ฆ Install dependencies + run: npm ci --only-production --ignore-scripts + working-directory: backend + # - + # name: ๐Ÿงช Run tests + # run: npm run test:ci + # working-directory: backend + - + name: ๐Ÿ—๏ธ Run build + run: npm run build + working-directory: backend diff --git a/.github/workflows/check-fe-pull-request.yml b/.github/workflows/check-fe-pull-request.yml new file mode 100644 index 000000000..b91e6f060 --- /dev/null +++ b/.github/workflows/check-fe-pull-request.yml @@ -0,0 +1,41 @@ +name: Check Frontend Pull Request + +on: + pull_request: + types: [ opened, synchronize ] + paths: + - 'frontend/**' + - '!frontend/README.md' + - '!frontend/.*' + - 'frontend/.eslintrc.js' + + +jobs: + + check-fe-pr: + name: Check + runs-on: ubuntu-latest + + steps: + - + name: โ˜๏ธ Checkout source + uses: actions/checkout@v3 + - + name: ๐Ÿ”ง Setup Node 16 + uses: actions/setup-node@v3 + with: + node-version: '16' + cache: 'npm' + cache-dependency-path: frontend/package-lock.json + - + name: ๐Ÿ“ฆ Install dependencies + run: npm ci --only-production --ignore-scripts + working-directory: frontend + # - + # name: ๐Ÿงช Run tests + # run: npm run test:ci + # working-directory: frontend + - + name: ๐Ÿ—๏ธ Run build + run: npm run build + working-directory: frontend diff --git a/.github/workflows/docker-image.yml b/.github/workflows/docker-image.yml index 769a5f7a3..e85ddcfd5 100644 --- a/.github/workflows/docker-image.yml +++ b/.github/workflows/docker-image.yml @@ -11,7 +11,7 @@ jobs: steps: - name: โ˜๏ธ Checkout source - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: ๐Ÿ”ง Set up QEMU uses: docker/setup-qemu-action@v2 @@ -36,7 +36,7 @@ jobs: # run: | # docker run --rm infisical/backend:test - - name: ๐Ÿ“ฆ Build backend and push + name: ๐Ÿ—๏ธ Build backend and push uses: docker/build-push-action@v3 with: push: true @@ -52,7 +52,7 @@ jobs: steps: - name: โ˜๏ธ Checkout source - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: ๐Ÿ”ง Set up QEMU uses: docker/setup-qemu-action@v2 @@ -79,10 +79,12 @@ jobs: # run: | # docker run --rm infisical/frontend:test - - name: ๐Ÿ“ฆ Build frontend and push + name: ๐Ÿ—๏ธ Build frontend and push uses: docker/build-push-action@v3 with: push: true context: frontend tags: infisical/frontend:latest platforms: linux/amd64,linux/arm64 + build-args: | + POSTHOG_API_KEY=${{ secrets.PUBLIC_POSTHOG_API_KEY }} diff --git a/README.md b/README.md index eadd4723f..4e0b7a053 100644 --- a/README.md +++ b/README.md @@ -52,6 +52,12 @@ And more. To quickly get started, visit our [get started guide](https://infisical.com/docs/getting-started/introduction). +

+ + + +

+ ## ๐Ÿ”ฅ What's cool about this? Infisical makes secret management simple and end-to-end encrypted by default. We're on a mission to make it more accessible to all developers, not just security teams. @@ -279,4 +285,4 @@ Looking to report a security vulnerability? Please don't post about it in GitHub - + diff --git a/frontend/components/context/Notifications/Notification.tsx b/frontend/components/context/Notifications/Notification.tsx index 974843cf6..e473ddb52 100644 --- a/frontend/components/context/Notifications/Notification.tsx +++ b/frontend/components/context/Notifications/Notification.tsx @@ -1,3 +1,4 @@ +import { useEffect, useRef } from "react"; import { faXmarkCircle } from "@fortawesome/free-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import classnames from "classnames"; @@ -5,14 +6,35 @@ import classnames from "classnames"; import { Notification as NotificationType } from "./NotificationProvider"; interface NotificationProps { - notification: NotificationType; - clearNotification: (text?: string) => void; + notification: Required; + clearNotification: (text: string) => void; } const Notification = ({ notification, clearNotification, }: NotificationProps) => { + const timeout = useRef(); + + const handleClearNotification = () => clearNotification(notification.text); + + const setNotifTimeout = () => { + timeout.current = window.setTimeout( + handleClearNotification, + notification.timeoutMs + ); + }; + + const cancelNotifTimeout = () => { + clearTimeout(timeout.current); + }; + + useEffect(() => { + setNotifTimeout(); + + return cancelNotifTimeout; + }, []); + return (
void; + createNotification: (newNotification: Notification) => void; }; const NotificationContext = createContext({ @@ -24,26 +25,30 @@ interface NotificationProviderProps { } const NotificationProvider = ({ children }: NotificationProviderProps) => { - const [notifications, setNotifications] = useState([]); + const [notifications, setNotifications] = useState[]>( + [] + ); - const clearNotification = (text?: string) => { - if (text) { - return setNotifications((state) => - state.filter((notif) => notif.text !== text) - ); - } - - return setNotifications([]); + const clearNotification = (text: string) => { + return setNotifications((state) => + state.filter((notif) => notif.text !== text) + ); }; - const createNotification = ({ text, type = "success" }: Notification) => { + const createNotification = ({ + text, + type = "success", + timeoutMs = 2000, + }: Notification) => { const doesNotifExist = notifications.some((notif) => notif.text === text); if (doesNotifExist) { return; } - return setNotifications((state) => [...state, { text, type }]); + const newNotification: Required = { text, type, timeoutMs }; + + return setNotifications((state) => [...state, newNotification]); }; return ( diff --git a/frontend/components/context/Notifications/Notifications.tsx b/frontend/components/context/Notifications/Notifications.tsx index 856331e24..6940c3345 100644 --- a/frontend/components/context/Notifications/Notifications.tsx +++ b/frontend/components/context/Notifications/Notifications.tsx @@ -2,25 +2,27 @@ import Notification from "./Notification"; import { Notification as NotificationType } from "./NotificationProvider"; interface NoticationsProps { - notifications: NotificationType[]; - clearNotification: (text?: string) => void; + notifications: Required[]; + clearNotification: (text: string) => void; } const Notifications = ({ notifications, clearNotification, }: NoticationsProps) => { + if (!notifications.length) { + return null; + } + return ( -
-
- {notifications.map((notif) => ( - - ))} -
+
+ {notifications.map((notif) => ( + + ))}
); };