mirror of
https://github.com/johndoe6345789/docker-swarm-termina.git
synced 2026-04-24 21:55:13 +00:00
Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 8794ff945b | |||
|
|
0733058349 | ||
| 3507e5ac34 | |||
|
|
77b8d0fa7a |
69
.github/workflows/docker-publish.yml
vendored
69
.github/workflows/docker-publish.yml
vendored
@@ -9,6 +9,12 @@ on:
|
||||
pull_request:
|
||||
branches:
|
||||
- main
|
||||
workflow_run:
|
||||
workflows: ["Run Tests"]
|
||||
types:
|
||||
- completed
|
||||
branches:
|
||||
- main
|
||||
|
||||
env:
|
||||
REGISTRY: ghcr.io
|
||||
@@ -23,6 +29,12 @@ jobs:
|
||||
packages: write
|
||||
|
||||
steps:
|
||||
- name: Check test workflow status
|
||||
if: github.event_name == 'workflow_run' && github.event.workflow_run.conclusion != 'success'
|
||||
run: |
|
||||
echo "❌ Test workflow failed. Cancelling build and push."
|
||||
exit 1
|
||||
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
@@ -46,7 +58,16 @@ jobs:
|
||||
type=semver,pattern={{major}}
|
||||
type=sha
|
||||
|
||||
- name: Log backend build information
|
||||
run: |
|
||||
echo "=== Building Backend Docker Image ==="
|
||||
echo "Context: ./backend"
|
||||
echo "Tags to apply:"
|
||||
echo "${{ steps.meta-backend.outputs.tags }}" | tr ',' '\n'
|
||||
echo ""
|
||||
|
||||
- name: Build and push backend image
|
||||
id: build-backend
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
context: ./backend
|
||||
@@ -54,6 +75,7 @@ jobs:
|
||||
push: true
|
||||
tags: ${{ steps.meta-backend.outputs.tags }}
|
||||
labels: ${{ steps.meta-backend.outputs.labels }}
|
||||
outputs: type=registry,push=true
|
||||
|
||||
- name: Extract metadata for frontend
|
||||
id: meta-frontend
|
||||
@@ -68,7 +90,17 @@ jobs:
|
||||
type=semver,pattern={{major}}
|
||||
type=sha
|
||||
|
||||
- name: Log frontend build information
|
||||
run: |
|
||||
echo "=== Building Frontend Docker Image ==="
|
||||
echo "Context: ./frontend"
|
||||
echo "Tags to apply:"
|
||||
echo "${{ steps.meta-frontend.outputs.tags }}" | tr ',' '\n'
|
||||
echo "Build args: NEXT_PUBLIC_API_URL=http://backend:5000"
|
||||
echo ""
|
||||
|
||||
- name: Build and push frontend image
|
||||
id: build-frontend
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
context: ./frontend
|
||||
@@ -76,5 +108,42 @@ jobs:
|
||||
push: true
|
||||
tags: ${{ steps.meta-frontend.outputs.tags }}
|
||||
labels: ${{ steps.meta-frontend.outputs.labels }}
|
||||
outputs: type=registry,push=true
|
||||
build-args: |
|
||||
NEXT_PUBLIC_API_URL=http://backend:5000
|
||||
|
||||
- name: Build summary
|
||||
run: |
|
||||
echo "=================================="
|
||||
echo " Docker Build & Push Complete"
|
||||
echo "=================================="
|
||||
echo ""
|
||||
echo "✅ Backend Image:"
|
||||
echo " Digest: ${{ steps.build-backend.outputs.digest }}"
|
||||
echo " Tags:"
|
||||
echo "${{ steps.meta-backend.outputs.tags }}" | tr ',' '\n' | sed 's/^/ - /'
|
||||
echo ""
|
||||
echo "✅ Frontend Image:"
|
||||
echo " Digest: ${{ steps.build-frontend.outputs.digest }}"
|
||||
echo " Tags:"
|
||||
echo "${{ steps.meta-frontend.outputs.tags }}" | tr ',' '\n' | sed 's/^/ - /'
|
||||
echo ""
|
||||
echo "📦 Images pushed to: ${{ env.REGISTRY }}"
|
||||
echo "=================================="
|
||||
|
||||
- name: Add job summary
|
||||
run: |
|
||||
echo "## 🐳 Docker Build & Push Summary" >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
echo "### Backend Image" >> $GITHUB_STEP_SUMMARY
|
||||
echo "- **Digest:** \`${{ steps.build-backend.outputs.digest }}\`" >> $GITHUB_STEP_SUMMARY
|
||||
echo "- **Tags:**" >> $GITHUB_STEP_SUMMARY
|
||||
echo "${{ steps.meta-backend.outputs.tags }}" | tr ',' '\n' | sed 's/^/ - `/' | sed 's/$/`/' >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
echo "### Frontend Image" >> $GITHUB_STEP_SUMMARY
|
||||
echo "- **Digest:** \`${{ steps.build-frontend.outputs.digest }}\`" >> $GITHUB_STEP_SUMMARY
|
||||
echo "- **Tags:**" >> $GITHUB_STEP_SUMMARY
|
||||
echo "${{ steps.meta-frontend.outputs.tags }}" | tr ',' '\n' | sed 's/^/ - `/' | sed 's/$/`/' >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
echo "### Registry" >> $GITHUB_STEP_SUMMARY
|
||||
echo "📦 Images pushed to: \`${{ env.REGISTRY }}\`" >> $GITHUB_STEP_SUMMARY
|
||||
|
||||
@@ -46,18 +46,29 @@ const mockUseDashboard = useDashboard as jest.MockedFunction<typeof useDashboard
|
||||
|
||||
describe('Dashboard Page', () => {
|
||||
const defaultDashboardState = {
|
||||
// Authentication
|
||||
isAuthenticated: true,
|
||||
authLoading: false,
|
||||
handleLogout: jest.fn(),
|
||||
|
||||
// Container list
|
||||
containers: [],
|
||||
isRefreshing: false,
|
||||
error: null,
|
||||
isLoading: false,
|
||||
error: '',
|
||||
refreshContainers: jest.fn(),
|
||||
|
||||
// Terminal modal
|
||||
selectedContainer: null,
|
||||
isTerminalOpen: false,
|
||||
openTerminal: jest.fn(),
|
||||
closeTerminal: jest.fn(),
|
||||
|
||||
// UI state
|
||||
isMobile: false,
|
||||
isInitialLoading: false,
|
||||
hasContainers: false,
|
||||
showEmptyState: false,
|
||||
handleLogout: jest.fn(),
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
|
||||
1
frontend/jest.d.ts
vendored
Normal file
1
frontend/jest.d.ts
vendored
Normal file
@@ -0,0 +1 @@
|
||||
/// <reference types="@testing-library/jest-dom" />
|
||||
@@ -1,6 +1,14 @@
|
||||
import { renderHook, act } from '@testing-library/react';
|
||||
import { useInteractiveTerminal } from '../useInteractiveTerminal';
|
||||
|
||||
type UseInteractiveTerminalProps = {
|
||||
open: boolean;
|
||||
containerId: string;
|
||||
containerName: string;
|
||||
isMobile: boolean;
|
||||
onFallback: (reason: string) => void;
|
||||
};
|
||||
|
||||
// Suppress console output during tests (terminal initialization logs)
|
||||
const originalConsoleLog = console.log;
|
||||
const originalConsoleWarn = console.warn;
|
||||
@@ -113,7 +121,7 @@ describe('useInteractiveTerminal', () => {
|
||||
const mockDiv = document.createElement('div');
|
||||
|
||||
const { rerender } = renderHook(
|
||||
(props) => {
|
||||
(props: UseInteractiveTerminalProps) => {
|
||||
const hook = useInteractiveTerminal(props);
|
||||
// Simulate ref being available
|
||||
if (hook.terminalRef.current === null) {
|
||||
|
||||
@@ -11,14 +11,17 @@ import * as apiClient from '@/lib/api';
|
||||
jest.mock('@/lib/api');
|
||||
|
||||
describe('authSlice', () => {
|
||||
let store: ReturnType<typeof configureStore>;
|
||||
type TestStore = ReturnType<typeof createTestStore>;
|
||||
let store: TestStore;
|
||||
|
||||
const createTestStore = () => configureStore({
|
||||
reducer: {
|
||||
auth: authReducer,
|
||||
},
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
store = configureStore({
|
||||
reducer: {
|
||||
auth: authReducer,
|
||||
},
|
||||
});
|
||||
store = createTestStore();
|
||||
jest.clearAllMocks();
|
||||
localStorage.clear();
|
||||
});
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
},
|
||||
"include": [
|
||||
"next-env.d.ts",
|
||||
"jest.d.ts",
|
||||
"**/*.ts",
|
||||
"**/*.tsx",
|
||||
".next/types/**/*.ts",
|
||||
|
||||
Reference in New Issue
Block a user