diff --git a/.github/workflows/lint_format.yml b/.github/workflows/lint_format.yml index e36bda7..82c63f7 100644 --- a/.github/workflows/lint_format.yml +++ b/.github/workflows/lint_format.yml @@ -24,5 +24,5 @@ jobs: - name: Prettier uses: creyD/prettier_action@v4.3 with: - prettier_options: "--check {**/*,*}.{js,jsx,json,html,css,yml,yaml}" + prettier_options: "--check {**/*,*}.{js,jsx,json,html,css}" prettier_version: "2.8.8" diff --git a/.github/workflows/old_prod_deploy.yml b/.github/workflows/old_prod_deploy.yml new file mode 100644 index 0000000..db011a9 --- /dev/null +++ b/.github/workflows/old_prod_deploy.yml @@ -0,0 +1,27 @@ +name: (DO NOT USE) Old Production Deployment + +on: + workflow_dispatch: + +jobs: + deploy: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup SSH + uses: webfactory/ssh-agent@v0.9.0 + with: + ssh-private-key: ${{ secrets.THE_KEY }} + + - name: Deploy to Server + run: | + ssh -o StrictHostKeyChecking=no thehub@traycer.7cav.us << 'EOF' + cd /etc/compose/apps/adr + git pull origin main + cd /etc/compose/apps/ + docker compose down + docker compose up -d + EOF diff --git a/.github/workflows/prod_deploy.yml b/.github/workflows/prod_deploy.yml index fa05703..8b3d73e 100644 --- a/.github/workflows/prod_deploy.yml +++ b/.github/workflows/prod_deploy.yml @@ -1,29 +1,45 @@ -name: Production Deployment +name: Production Deploy on: - push: - branches: - - main + release: + types: [published] jobs: - deploy: + build: runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v4 + with: + ref: ${{ github.event.inputs.branch }} + + - name: Log in to Docker Hub + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_PASSWORD }} + + - name: Build and Push Client Docker Image + uses: docker/build-push-action@v5 + with: + context: ./client + file: ./client/client.Dockerfile + push: true + tags: | + 7cav/apps_client:${{ github.ref_name }} + 7cav/apps_client:latest - - name: Setup SSH - uses: webfactory/ssh-agent@v0.9.0 + - name: Build and Push Server Docker Image + uses: docker/build-push-action@v5 with: - ssh-private-key: ${{ secrets.THE_KEY }} + context: ./server + file: ./server/server.Dockerfile + push: true + tags: | + 7cav/apps_server:${{ github.ref_name }} + 7cav/apps_server:latest - - name: Deploy to Server + - name: Force Watchtower Update run: | - ssh -o StrictHostKeyChecking=no thehub@traycer.7cav.us << 'EOF' - cd /etc/compose/apps/adr - git pull origin main - cd /etc/compose/apps/ - docker compose down - docker compose up -d - EOF + curl -H "Authorization: Bearer ${{ secrets.WATCHER_KEY }}" https://watcher.7cav.us/v1/update \ No newline at end of file diff --git a/client/app/adr/modules/ArrayMap.jsx b/client/app/adr/modules/ArrayMap.jsx index 262f801..adc5c61 100644 --- a/client/app/adr/modules/ArrayMap.jsx +++ b/client/app/adr/modules/ArrayMap.jsx @@ -7,7 +7,6 @@ milpac link, name and rank, and position title.*/ function ArrayMap(props) { let inputArray = props.inputArray; - console.log(inputArray); return ( diff --git a/client/app/adr/modules/MilpacParse.jsx b/client/app/adr/modules/MilpacParse.jsx index 0dc8960..3d84d24 100644 --- a/client/app/adr/modules/MilpacParse.jsx +++ b/client/app/adr/modules/MilpacParse.jsx @@ -10,8 +10,6 @@ function MilpacParse(props) { const rosterGroups = props.rosterGroups; let milpacArray = props.milpacArray; - console.log(rosterGroups); - const uniqueNamesSet = new Set(); let returnArray = []; @@ -121,8 +119,6 @@ function MilpacParse(props) { return aIndex - bIndex; }); - console.log(returnArray); - return (
diff --git a/client/app/reusableModules/BilletBank.jsx b/client/app/reusableModules/BilletBank.jsx index 6904946..9e75adb 100644 --- a/client/app/reusableModules/BilletBank.jsx +++ b/client/app/reusableModules/BilletBank.jsx @@ -183,13 +183,79 @@ const charlie1 = [ "344", ]; +const delta1 = [ + "1060", + "1061", + "1062", + "1063", + "1064", + "1065", + "1066", + "1067", + "1068", + "1069", + "1070", + "1071", + "1072", + "1073", + "1074", + "1075", + "1076", + "1077", + "1078", + "1079", + "1080", + "1081", + "1082", + "1083", + "1084", + "1085", + "1086", + "1087", + "1088", + "1089", + "1090", + "1091", + "1092", + "1093", + "1094", + "1095", + "1096", + "1097", + "1098", + "1099", + "1100", + "1101", + "1102", + "1103", + "1104", + "1105", + "1106", + "1107", + "1108", + "1109", + "1110", + "1111", + "1112", + "1113", + "1114", + "1115", + "1116", + "1117", + "1118", + "1119", + "1120", + "1121", +]; + const oneSeven = { - positionIds: [oneSevenCommand, alpha1, bravo1, charlie1], + positionIds: [oneSevenCommand, alpha1, bravo1, charlie1, delta1], positionTitles: [ "1-7 Headquarters", "Alpha Company", "Bravo Troop", "Charlie Company", + "Delta Company", ], collapsibleTitle: "First Battalion", }; @@ -1087,6 +1153,7 @@ const billetBank = { alpha1, bravo1, charlie1, + delta1, twoSevenCommand, alpha2, bravo2, diff --git a/client/app/rosterstatistics/modules/statistics.jsx b/client/app/rosterstatistics/modules/statistics.jsx index 857c85a..3519ba8 100644 --- a/client/app/rosterstatistics/modules/statistics.jsx +++ b/client/app/rosterstatistics/modules/statistics.jsx @@ -108,6 +108,7 @@ class Statistics extends Component { "#b61217", "#b61217", "#b61217", + "#b61217", "#2a487c", "#2a487c", "#2a487c", diff --git a/client/app/rosterstatistics/page.jsx b/client/app/rosterstatistics/page.jsx index 2ca7338..20ea6fb 100644 --- a/client/app/rosterstatistics/page.jsx +++ b/client/app/rosterstatistics/page.jsx @@ -51,6 +51,7 @@ export default async function RosterStatistics() { lists.alpha1, lists.bravo1, lists.charlie1, + lists.delta1, lists.twoSevenCommand, lists.alpha2, lists.bravo2, @@ -75,6 +76,7 @@ export default async function RosterStatistics() { "Alpha Company 1-7", "Bravo Troop 1-7", "Charlie Company 1-7", + "Delta Company 1-7", "2-7 Headquarters", "Alpha Company 2-7", "Bravo Company 2-7", @@ -105,6 +107,7 @@ export default async function RosterStatistics() { lists.alpha1, lists.bravo1, lists.charlie1, + lists.delta1, ]} centerLabel="Total 1-7 Strength" labelArray={[ @@ -112,6 +115,7 @@ export default async function RosterStatistics() { "Alpha Company", "Bravo Troop", "Charlie Company", + "Delta Company", ]} milpacArray={milpacArray} /> diff --git a/client/app/uniformbuilder/modules/AwardClasses.jsx b/client/app/uniformbuilder/modules/AwardClasses.jsx index 236da99..2311aec 100644 --- a/client/app/uniformbuilder/modules/AwardClasses.jsx +++ b/client/app/uniformbuilder/modules/AwardClasses.jsx @@ -73,6 +73,7 @@ export class MedalWithValor extends Medal { export class RibbonDonationLogic extends Ribbon { constructor(data, AwardRegistry) { super(data, AwardRegistry); + this.ribbonTrueAttachmentCount = 1; } incrementAwardCount() { diff --git a/client/app/uniformbuilder/modules/canvas.jsx b/client/app/uniformbuilder/modules/canvas.jsx index 8941dba..bbdab68 100644 --- a/client/app/uniformbuilder/modules/canvas.jsx +++ b/client/app/uniformbuilder/modules/canvas.jsx @@ -351,7 +351,7 @@ function Canvas(props) { let fontSize = 18; const dy = 313; - if (userData.nameTag.length < 8) { + if (userData.nameTag.length < 9) { tagWidth = 101; tagHeight = 40; selector = "short"; diff --git a/client/client.Dockerfile b/client/client.Dockerfile new file mode 100644 index 0000000..69101d3 --- /dev/null +++ b/client/client.Dockerfile @@ -0,0 +1,21 @@ +# Build + +FROM node:lts-alpine + +RUN apk add --no-cache curl wget + +WORKDIR /client + +# Acquire dependencies + +COPY package*.json ./ + +RUN npm install + +# Copy source code + +COPY . . + +# Expose, Deployment is handled by compose to allow server to start first + +EXPOSE 3000 \ No newline at end of file diff --git a/compose.yml b/compose.yml index 851994a..92c3eb7 100644 --- a/compose.yml +++ b/compose.yml @@ -1,37 +1,50 @@ services: server: restart: always - container_name: adr-server - image: node:lts-alpine - env_file: - - ./client/.env - volumes: - - ./server:/app + build: + dockerfile: "./server.Dockerfile" + context: "./server" + image: 7cav/cavapps-server:latest + container_name: cavapps-server ports: - "4000:4000" - working_dir: /app - command: /bin/sh -c "apk add curl && npm install && node server.js" + environment: + API_TOKEN: + CLIENT_TOKEN: + working_dir: /server healthcheck: - test: ["CMD", "curl", "-f", "http://server:4000"] + test: ["CMD", "curl", "-f", "http://localhost:4000"] interval: 10s timeout: 10s retries: 5 start_period: 30s + networks: + - cavapps-network client: restart: always - container_name: adr-client - image: node:lts-alpine - volumes: - - ./client:/app + build: + context: ./client + dockerfile: ./client.Dockerfile + image: 7cav/cavapps-client:latest + container_name: cavapps-client ports: - "80:3000" - env_file: - - ./client/.env - entrypoint: /bin/sh -c "until wget -q --spider http://server:4000; do echo 'Waiting for server...'; sleep 5; done; npm install && npm run build && npm run start" - working_dir: /app + environment: + NEXT_PUBLIC_CLIENT_TOKEN: + COMBAT_API_URL: http://server:4000/roster/combat + RESERVE_API_URL: http://server:4000/roster/reserves + NEXT_PUBLIC_INDIVIDUAL_API_URL: http://server:4000/roster/individual + CACHE_TIMESTAMP_URL: http://server:4000/cache-timestamp + GROUP_API_URL: http://server:4000/roster/groups + working_dir: /client + depends_on: + server: + condition: service_healthy + entrypoint: /bin/sh -c "until wget -q --spider http://server:4000; do echo 'Waiting for server...'; sleep 5; done; npm run build && npm run start" + networks: + - cavapps-network networks: - mynetwork: + cavapps-network: driver: bridge - external: true diff --git a/server/controllers/cacheManager.js b/server/controllers/cacheManager.js index 78c73de..59f6572 100644 --- a/server/controllers/cacheManager.js +++ b/server/controllers/cacheManager.js @@ -1,6 +1,6 @@ const axios = require("axios"); const axiosRetry = require("axios-retry").default || require("axios-retry"); -const { API_TOKEN } = require("../credentials/token"); +const API_TOKEN = process.env.API_TOKEN; let cacheStatus = { combat: false, diff --git a/server/credentials/example_token.js b/server/credentials/example_token.js deleted file mode 100644 index 6ae11a2..0000000 --- a/server/credentials/example_token.js +++ /dev/null @@ -1,6 +0,0 @@ -const API_TOKEN = "XXXXXXXXXXX"; -const CLIENT_TOKEN = "XXXXXXXX"; -module.exports = { API_TOKEN, CLIENT_TOKEN }; - -//rename this file as "token.js" when in use. -// should be in `../server/credentials/token.js` path. diff --git a/server/server.Dockerfile b/server/server.Dockerfile new file mode 100644 index 0000000..82c5fb2 --- /dev/null +++ b/server/server.Dockerfile @@ -0,0 +1,23 @@ +# Build + +FROM node:lts-alpine + +RUN apk add --no-cache curl + +WORKDIR /server + +# Acquire dependencies + +COPY package*.json ./ + +RUN npm install + +# Copy server source code + +COPY . . + +# Deploy + +EXPOSE 4000 + +CMD ["node", "server.js"] \ No newline at end of file diff --git a/server/server.js b/server/server.js index 398628e..14edae5 100644 --- a/server/server.js +++ b/server/server.js @@ -4,7 +4,7 @@ const compression = require("compression"); const app = express(); const cors = require("cors"); const port = 4000; -const { CLIENT_TOKEN } = require("./credentials/token"); +const CLIENT_TOKEN = process.env.CLIENT_TOKEN; const { cacheTime, initializeCache } = require("./controllers/cacheManager"); const corsOptions = {