diff --git a/.github/workflows/aws_dev_release.yml b/.github/workflows/aws_dev_release.yml index 46ddb74..602a41e 100644 --- a/.github/workflows/aws_dev_release.yml +++ b/.github/workflows/aws_dev_release.yml @@ -4,7 +4,7 @@ on: branches: - dev workflow_dispatch: - + env: REPOSITORY: 'sdk-example' ECS_Cluster: "topia-dev-sdk-apps" @@ -14,7 +14,7 @@ env: concurrency: group: ${{ github.event.pull_request.number || github.ref }} cancel-in-progress: true - + permissions: id-token: write # This is required for requesting the JWT contents: read # This is required for actions/checkout @@ -26,7 +26,7 @@ jobs: steps: - name: Checkout uses: actions/checkout@v4 - + - name: get servicename id: sername run: | @@ -42,27 +42,35 @@ jobs: echo "service=$service_value" >> "$GITHUB_OUTPUT" echo "Service value: $(echo $service_value | jq -c )" fi - + - uses: actions/setup-node@v4 with: node-version: 20.10 cache: 'npm' - run: npm i - run: CI=false npm run build - + - name: Set up QEMU uses: docker/setup-qemu-action@v3 - + with: + platforms: arm64,amd64 + - name: Configure AWS credentials uses: aws-actions/configure-aws-credentials@v4 with: role-to-assume: arn:aws:iam::368076259134:role/github-actions-role aws-region: us-east-1 - + - name: Login to Amazon ECR id: login-ecr uses: aws-actions/amazon-ecr-login@v2 + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + with: + buildkitd-flags: --debug + driver-opts: image=moby/buildkit:latest + - name: Image Metadata id: metadata uses: docker/metadata-action@v5 @@ -71,15 +79,23 @@ jobs: tags: | type=raw,value=${{ github.event.repository.name }} - - name: Build and tag - run: | - docker build --build-arg COMMIT_HASH=${{ github.sha }} --build-arg REF=${{ github.ref }} -t ${{ steps.metadata.outputs.tags }} . - - - name: push docker image to Amazon ECR - run: | - docker push ${{ steps.metadata.outputs.tags }} + - + - name: Build and push multi-platform images to ECR + uses: docker/build-push-action@v5 + with: + context: . + platforms: linux/amd64,linux/arm64 + push: true + tags: ${{ steps.metadata.outputs.tags }} + build-args: | + REF=${{ github.ref }} + COMMIT_HASH=${{ github.sha }} + cache-from: type=gha + cache-to: type=gha,mode=max + provenance: false + sbom: false + deploy_matrix: runs-on: ubuntu-latest needs: Build @@ -96,4 +112,4 @@ jobs: - name: deploy run: | aws ecs update-service --cluster ${{ env.ECS_Cluster }} --service topia-${{ env.ENV }}-${{ matrix.service }}0 --force-new-deployment - + diff --git a/.github/workflows/aws_prod_release.yml b/.github/workflows/aws_prod_release.yml index 3ca8116..dac19d0 100644 --- a/.github/workflows/aws_prod_release.yml +++ b/.github/workflows/aws_prod_release.yml @@ -12,7 +12,7 @@ env: concurrency: group: ${{ github.event.pull_request.number || github.ref }} cancel-in-progress: true - + permissions: id-token: write # This is required for requesting the JWT contents: read # This is required for actions/checkout @@ -27,7 +27,7 @@ jobs: uses: actions/checkout@v4 with: ref: ${{ github.event.release.tag_name }} - + - name: get servicename id: sername run: | @@ -53,16 +53,18 @@ jobs: - run: npm version ${{ github.event.release.tag_name }} - run: npm i - run: CI=false npm run build - + - name: Set up QEMU uses: docker/setup-qemu-action@v3.0.0 - + with: + platforms: arm64,amd64 + - name: Configure AWS credentials uses: aws-actions/configure-aws-credentials@v4 with: role-to-assume: arn:aws:iam::368076259134:role/github-actions-role aws-region: us-east-1 - + - name: Login to Amazon ECR id: login-ecr uses: aws-actions/amazon-ecr-login@v2 @@ -71,6 +73,7 @@ jobs: uses: docker/setup-buildx-action@v3 with: buildkitd-flags: --debug + driver-opts: image=moby/buildkit:latest - name: Image Metadata id: metadata @@ -79,26 +82,23 @@ jobs: images: ${{ steps.login-ecr.outputs.registry }}/${{ env.REPOSITORY }} tags: | type=raw,value=${{ github.event.repository.name }}-${{ github.event.release.tag_name }} - - - name: Image Metadata - id: metadata-latest - uses: docker/metadata-action@v5 - with: - images: ${{ steps.login-ecr.outputs.registry }}/${{ env.REPOSITORY }} - tags: | type=raw,value=${{ github.event.repository.name }}-latest - - name: Build and version tag - run: | - docker build --build-arg REF=${{ github.ref}} --build-arg COMMIT_HASH=$(git rev-parse --short ${{ github.sha }}) -t ${{ steps.metadata.outputs.tags }} . - docker tag ${{ steps.metadata.outputs.tags }} ${{ steps.metadata-latest.outputs.tags }} - - - name: push docker image to Amazon ECR - run: | - docker push ${{ steps.metadata.outputs.tags }} - docker push ${{ steps.metadata-latest.outputs.tags }} + - name: Build and push multi-platform images to ECR + uses: docker/build-push-action@v5 + with: + context: . + platforms: linux/amd64,linux/arm64 + push: true + tags: ${{ steps.metadata.outputs.tags }} + build-args: | + REF=${{ github.ref }} + COMMIT_HASH=${{ github.sha }} + cache-from: type=gha + cache-to: type=gha,mode=max + provenance: false + sbom: false - deploy_matrix: runs-on: ubuntu-latest needs: Build @@ -115,4 +115,4 @@ jobs: - name: deploy run: | aws ecs update-service --cluster ${{ env.ECS_Cluster }} --service topia-${{ env.ENV }}-${{ matrix.service }}0 --force-new-deployment - + diff --git a/README.md b/README.md index 24fd255..e781b71 100644 --- a/README.md +++ b/README.md @@ -23,6 +23,23 @@ Connect 4 is a completely on-canvas game where two players take turns dropping p - Reset Button: Clicking on the Reset Button as an admin will remove all assets and rebuild the board completely. This is especially helpful if an interactive asset has accidentally been deleted. +### Required Assets with Unique Names + +The app dynamically generates assets using the following unique names: + +| Unique Name | Description | +| -------------- | -------------------------------------------------- | +| `reset` | Key asset reset button | +| `board` | The board background image | +| `gameText` | Main game status message | +| `player1Text` | Player 1 name display | +| `player2Text` | Player 2 name display | +| `player1` | Player 1 selection button (red piece) | +| `player2` | Player 2 selection button (yellow piece) | +| `selector` | Column drop arrows (7 total, one per column) | +| `claimedSpace` | Player pieces placed on the board during gameplay | +| `crown` | Victory crown for the winner | + ### Data objects - Key Asset: the data object attached to the Reset Button key asset can stores all of the game play information including current players, player turn status, and game status. diff --git a/package-lock.json b/package-lock.json index c56c986..1e2851a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,7 +10,7 @@ "license": "ISC", "dependencies": { "@googleapis/sheets": "^7.0.0", - "@rtsdk/topia": "^0.15.9", + "@rtsdk/topia": "^0.19.9", "@types/cors": "^2.8.13", "axios": "^1.5.0", "body-parser": "^1.20.2", @@ -296,9 +296,9 @@ "dev": true }, "node_modules/@rtsdk/topia": { - "version": "0.15.9", - "resolved": "https://registry.npmjs.org/@rtsdk/topia/-/topia-0.15.9.tgz", - "integrity": "sha512-f8P6Teee0pca9+VIcQJcnZBCNaCjc3EzDosppeYQhI+y4HC0V/YPArp6vVjVRjVKrjd1gnz7H8QArpN7L5ICSg==" + "version": "0.19.9", + "resolved": "https://registry.npmjs.org/@rtsdk/topia/-/topia-0.19.9.tgz", + "integrity": "sha512-2ek1U2+FY3jFPeBiIbAp+RL1yDu+9GhXYdGZsIojGmRkbF3GfsuyPJbxzlqm215vh3X4nB5FCZoYyl1tOl8NWg==" }, "node_modules/@rushstack/eslint-patch": { "version": "1.10.4", diff --git a/package.json b/package.json index c90f27e..635d5c9 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ "main": "src/index.ts", "dependencies": { "@googleapis/sheets": "^7.0.0", - "@rtsdk/topia": "^0.15.9", + "@rtsdk/topia": "^0.19.9", "@types/cors": "^2.8.13", "axios": "^1.5.0", "body-parser": "^1.20.2", diff --git a/src/controllers/handleDropPiece.ts b/src/controllers/handleDropPiece.ts index c83c133..6a3df1d 100644 --- a/src/controllers/handleDropPiece.ts +++ b/src/controllers/handleDropPiece.ts @@ -19,10 +19,6 @@ export const handleDropPiece = async (req: Request, res: Response) => { const { displayName, identityId, sceneDropId, urlSlug, visitorId } = credentials; const { username } = req.body; - let text = "", - shouldUpdateGame = false, - analytics = []; - const column = parseInt(req.params.column); if (isNaN(column)) throw "Column id is required."; @@ -40,6 +36,10 @@ export const handleDropPiece = async (req: Request, res: Response) => { turnCount, } = keyAsset.dataObject as GameDataType; + let text = `It's ${lastPlayerTurn === player1.visitorId ? player1.username : player2.username}'s turn`, + shouldUpdateGame = false, + analytics = []; + if (isResetInProgress) throw "Reset in progress."; const columnStart = @@ -72,16 +72,16 @@ export const handleDropPiece = async (req: Request, res: Response) => { } if (isGameOver) { - text = "Game over! Press Reset to play again."; + text = "Game over! Press Reset to play again"; } else if (!player1.visitorId || !player2.visitorId) { - text = "Two players are needed to get started."; + text = "Two players are needed to get started"; } else if (player1.visitorId !== visitorId && player2.visitorId !== visitorId) { - text = "Game in progress."; + text = "Game in progress"; } else if (columns[column].length === 6) { - text = "Cannot place your move here."; + text = "Cannot place your move here"; } else if (lastPlayerTurn === visitorId) { const username = player2.visitorId === visitorId ? player1.username : player2.username; - text = `It's ${username}'s turn.`; + text = `It's ${username}'s turn`; } else { updatedData.lastPlayerTurn = visitorId; updatedData.columns[column]?.push(visitorId); diff --git a/src/utils/droppedAssets/dropTextAsset.ts b/src/utils/droppedAssets/dropTextAsset.ts index 1283373..439b396 100644 --- a/src/utils/droppedAssets/dropTextAsset.ts +++ b/src/utils/droppedAssets/dropTextAsset.ts @@ -29,6 +29,7 @@ export const dropTextAsset = async ({ position, sceneDropId, text, + textWidth: 500, uniqueName, urlSlug, yOrderAdjust: 500, diff --git a/src/utils/generateBoard.ts b/src/utils/generateBoard.ts index 676af28..b3496bd 100644 --- a/src/utils/generateBoard.ts +++ b/src/utils/generateBoard.ts @@ -45,7 +45,7 @@ export const generateBoard = async (credentials: Credentials) => { y: boardCenter.y - 130, }, style: { textSize: 20, textWidth: 150 }, - text: "", + text: "Player One", uniqueName: `player1Text`, }), dropTextAsset({ @@ -55,7 +55,7 @@ export const generateBoard = async (credentials: Credentials) => { y: boardCenter.y - 130, }, style: { textSize: 20, textWidth: 150 }, - text: "", + text: "Player Two", uniqueName: `player2Text`, }), ]);