-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
deploy the app #511
Merged
Merged
deploy the app #511
Changes from 74 commits
Commits
Show all changes
108 commits
Select commit
Hold shift + click to select a range
b7b9a63
chore(client): bootstrap client application (#506)
umitcan07 d61e1c3
feat(client): implement login page and routing (#508)
hks1444 55ab5a1
feat(be): implement token obtain pair (login) and register endopints …
MucahitErdoganUnlu b06ae04
chore(mobile): bootstrap mobile app (#522)
Meminseeker b14955c
fix(be): remove cache from git
MucahitErdoganUnlu 1cb4157
fix(be): add pycache from migrations folder to gitignore
MucahitErdoganUnlu cfc8990
feat(be): add username, full_name, and email fields to token view res…
MucahitErdoganUnlu 1b744d7
feat(mobile): add auth context (#523)
Meminseeker 33e2fda
feat(client): implement register page and routing (#512)
umitcan07 a048a8d
w3c(client): add relevant aria attributes to toast modal (#530)
umitcan07 4d2ad88
fix(be): change paths of login and register endpoints to /auth/
MucahitErdoganUnlu 7a7a96d
docs(be): add /swagger.yaml/ path to generate yaml file for swagger d…
MucahitErdoganUnlu 4f20d0e
docs(be): add swagger.yaml file that contains /auth/ and /token/ paths
MucahitErdoganUnlu 26c74d1
feat(client): implement logger utility (#531)
hks1444 fd7f9b6
chore(mobile): remove unnecessary .idea files
Meminseeker eecc9de
chore(mobile): update .gitignore
Meminseeker 5d8c6d0
feat(client): implement quizzes route & msw (#540)
umitcan07 241da4f
chore(mobile): implement mock server for forum pages (#542)
Meminseeker c9dda0b
feat(devops): add Dockerfile and update settings.py
ozankrkya 61af956
feat(devops): add wait-for-it.sh script and docker-compose.yml
ozankrkya 175a137
[wip]feat(devops): Add Dockerfile for client containerization
ozankrkya 561c201
feat(devops): update Dockerfile and dependencies
Meminseeker 52600f7
feat(devops): Update Dockerfile and docker-compose.yml for client ser…
ozankrkya 9b0ca00
feat(devops): Add nginx container and configuration
ozankrkya 7ff3cd3
chore(devops): build client app
Meminseeker fafee2a
feat(devops): dockerize application (#555)
ozankrkya 9f19159
feat(devops): add nginx Dockerfile
Meminseeker 9ca7dd6
feat(devops): add docker-compose.dev.yml for development environment …
Meminseeker dbebe7d
feat(devops): add AWS Dev deployment workflow for GitHub Actions
Meminseeker 3281dfc
refactor(devops): refactor GitHub Actions secrets
Meminseeker d25717d
feat(client): add quizzes route and page & more configuration through…
umitcan07 b5219fa
feat(client): implement quiz id route (#548)
hks1444 a63875b
chore(client): configure project and meta tags (#557)
umitcan07 ff89730
refactor(devops): update client build command in docker-compose.dev.yml
Meminseeker b22071f
feat(client): generate mock data for quizzes (#560)
hks1444 40ddf73
des(client): improve design, add necessary components (#558)
umitcan07 2202872
chore(gitignore): update gitignore file
Meminseeker 6c72b9c
fix(devops): fix docker-compose.dev.yml for development environment
Meminseeker 89f213e
fix(devops): update aws.dev.yml build command
Meminseeker dc5cfd6
feat(be): implement forum-question endpoint and tagging endpoint (#546)
MucahitErdoganUnlu 6f62acb
chore(devops): update .gitignore file
Meminseeker 4e5ad73
chore(devops): update ALLOWED_HOSTS in settings.py to be set by .env …
Meminseeker 5e1c694
feat(devops): Add Makefile for development environment setup with Doc…
Meminseeker cff8f91
feat(devops): Add dev-deploy target to Makefile
Meminseeker a7c7a07
Merge branch 'development' into devops
Meminseeker 43f48b1
feat(mobile): implement forumQuestionDetail screen and enhance forum …
Meminseeker 35ea2cb
chore(mobile): add prettier as a dev dependency for mobile applicatio…
Meminseeker e4da6ba
feat(mobile): implement CreateQuestion on forum screen (#576)
yunuskaydin ebe40d4
des(client): refine quiz card, quiz page, page heads, router (#572)
umitcan07 65ca0f6
feat(client): add quiz start screen, timer, progress bar and overall …
umitcan07 3ac57e7
feat(client): add a simple leaderboard table (#579)
umitcan07 bcf51c6
chore(mobile): update .gitignore to temporarily ignore some newly cre…
Meminseeker 8116941
Merge branch 'development' into devops
Meminseeker c2bc647
Merge pull request #570 from bounswe/devops
ozankrkya d6f696c
feat(mobile): build mobile app (#580)
Meminseeker caff62a
fix(client): prevent id duplication (#581)
umitcan07 e80b560
feat(client): refine leaderboard (#582)
umitcan07 9156f7d
fix(be): extend the expiration of jwt token
MucahitErdoganUnlu ecb6ccb
update(be): update forum-question fields to mock question metadata su…
MucahitErdoganUnlu e65d8ec
docs(be): update swagger.yaml to include forum question mock meta data
MucahitErdoganUnlu 0844c8a
feat(be): add random avatar generation for users
MucahitErdoganUnlu a81d383
feat(client): add content to home and refine leaderboard data & desig…
umitcan07 b95c20b
feat(mobile): update navigation and add Register screen (#585)
yunuskaydin fe39cb3
feat(mobile): add bottom Tab (#584)
yunuskaydin d95f902
chore(client): add more mock data to home and changed names on the l…
hks1444 36ccf31
feat(mobile): connect mobile to backend and implement tagging for for…
Meminseeker 84aa9e3
feat(devops): add prod-mobile target in Makefile for releasing Androi…
Meminseeker 591dc82
chore(mobile): add expo-build-properties plugin for Android app confi…
Meminseeker 3bc41e6
fix(mobile): fix app.json for Android configs
Meminseeker 84d9622
fix(be): add if block to check if the returned box from babelnet pars…
MucahitErdoganUnlu 0f610a7
fix(be): move all backend endpoints to /api/v1/
MucahitErdoganUnlu ff3d24c
feat(be): add seeder json file for models in backend
MucahitErdoganUnlu 334ec2a
Merge branch 'main' into development
umitcan07 8c5a3e1
Merge branch 'main' into development
umitcan07 8751f20
chore: delete redundant files on root
umitcan07 981bd92
feature(client): implemented forum post feed (#591)
hks1444 7e21eee
feat(be): implement quiz and rate-quiz CRUD endpoints (#624)
MucahitErdoganUnlu 92c3c58
fix(be): change user field to author in quizSerializer
MucahitErdoganUnlu d924246
feat(be): implement bookmark functionality for forum questions and tests
ceydanursen 5e2f654
feat(be): add new model QuizQuestionChoice to efficiently handle choi…
MucahitErdoganUnlu 2aeb323
Merge branch 'development' into backend/forum-bookmark
ceydanursen 7d6eeba
resolve(be): resolve conflict on migrations
MucahitErdoganUnlu 8a507b8
feat(be): implement TakeQuiz ModelViewset endpoints. implement unit t…
MucahitErdoganUnlu 88def9b
feat(be): implement forum upvote and downvote endpoints and tests (#641)
meminciftci 6bb9794
feat(be): Implement Forum Answers (#642)
ozankrkya 2ed45c2
feat(be): connect upvote, downvote, bookmark to forum question fields…
044f827
fix: fix a Docker-compose build error
Meminseeker a540279
fix(devops): update docker-compose.dev.yml to remove restart on failu…
Meminseeker ac8c70a
lab(client): lab6 work (#613)
hks1444 dffb29f
feat(be) prepare at least 1 fixture for each model (#645)
MucahitErdoganUnlu 43a50ab
chore(be): update swagger.yaml
MucahitErdoganUnlu a0b3774
fix(devops): fix errors preventing Docker builds
Meminseeker 4c3785e
lab: work done for lab7 & forum integration (#646)
umitcan07 bcac431
Merge branch 'main' into development
umitcan07 6c186f7
feat(be): implement forum-answer-upvote and downvote (#662)
MucahitErdoganUnlu 3ae6d96
feat(mobile): add Leaderboard Screen (#654)
yunuskaydin dc10e12
chore(backend): fix forum upvote downvote answer serializers
umitcan07 a261471
fix(backend): use correct serializer fields
umitcan07 51695d1
feat(client): implement forum answer posting
umitcan07 03801b3
feat(client): update swagger to include forum-answer-upvote and downvote
MucahitErdoganUnlu 3b3710f
feat(client): implement forum answer upvote downvote mechanism and in…
umitcan07 96f4b29
chore(client): dispose mock server
umitcan07 96ffe25
implement more control for forum pagination and refine questions
umitcan07 2f054b9
feat(client): implement create a forum question with dummy tags
umitcan07 a43186f
feat(backend): add is my forum question field to the serializer
umitcan07 f4b7c6e
fix(client): redirect to forum page upon deleting a forum question
umitcan07 67feee8
refactor(client, backend): add pagination controls to quiz, refactor …
umitcan07 01e7cd2
chore(backend): add is my quiz field to the serializer
umitcan07 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
PEM_FILE=<YOUR_PEM_FILE_FOR_SSH&SCP> | ||
SSH_USER=<YOUR_SSH_USER> | ||
SSH_HOST=<YOUR_SSH_HOST> | ||
FILES_TO_COPY="FILE1 FILE2 ... FILEN" | ||
TARGET_DIR=<PROJECT_ROOT_DIR_IN_DEPLOYMENT_SERVER> | ||
ANDROID_DIR=<YOUR_MOBILE_APP_ANDROID_BUILD_DIR> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
name: Deploy to AWS Dev (Docker Hub + EC2) | ||
|
||
on: | ||
push: | ||
branches: ["development"] | ||
|
||
env: | ||
AWS_REGION: ${{ secrets.AWS_REGION }} | ||
CONTAINER_REPOSITORY: ${{ secrets.CONTAINER_REPOSITORY }} | ||
IMAGE_TAG: ${{ github.sha }} #! ?? | ||
BACKEND_IMAGE_TAG: ${{ secrets.BACKEND_IMAGE }} | ||
CLIENT_IMAGE_TAG: ${{ secrets.CLIENT_IMAGE }} | ||
NGINX_IMAGE_TAG: ${{ secrets.NGINX_IMAGE }} | ||
SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }} | ||
SSH_HOST: ${{ secrets.SSH_HOST }} | ||
SSH_USER: ${{ secrets.SSH_USER }} | ||
PROJECT_DIR: ${{ secrets.PROJECT_DIR }} | ||
MYSQL_ROOT_PASSWORD: ${{ secrets.MYSQL_ROOT_PASSWORD }} | ||
MYSQL_USER: ${{ secrets.MYSQL_USER }} | ||
MYSQL_PASSWORD: ${{ secrets.MYSQL_PASSWORD }} | ||
DB_NAME: ${{ secrets.DB_NAME }} | ||
DB_HOST: ${{ secrets.DB_HOST }} | ||
DB_PORT: ${{ secrets.DB_PORT }} | ||
CORS_ALLOWED_ORIGINS: ${{ secrets.CORS_ALLOWED_ORIGINS }} | ||
VITE_BACKEND_URL: ${{ secrets.VITE_BACKEND_URL }} | ||
VITE_ENABLE_MOCKS: ${{ secrets.VITE_ENABLE_MOCKS }} | ||
VITE_LOGGING: ${{ secrets.VITE_LOGGING }} | ||
|
||
permissions: | ||
contents: read | ||
|
||
jobs: | ||
deploy: | ||
name: Deploy to AWS Dev | ||
runs-on: ubuntu-latest | ||
environment: development | ||
|
||
steps: | ||
- name: Checkout | ||
uses: actions/checkout@v4 | ||
|
||
- name: Configure AWS credentials | ||
uses: aws-actions/configure-aws-credentials@v1 | ||
with: | ||
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} | ||
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} | ||
aws-region: ${{ env.AWS_REGION }} | ||
|
||
- name: Login to Docker Hub | ||
id: login-docker-hub | ||
run: | | ||
echo "${{ secrets.DOCKER_HUB_PASSWORD }}" | docker login -u "${{ secrets.DOCKER_HUB_USERNAME }}" --password-stdin | ||
|
||
- name: Build, tag, and push images to Docker Hub | ||
id: build-image | ||
run: | | ||
docker-compose -f docker-compose.dev.yml build | ||
docker push $CONTAINER_REPOSITORY:$BACKEND_IMAGE_TAG | ||
docker push $CONTAINER_REPOSITORY:$CLIENT_IMAGE_TAG | ||
docker push $CONTAINER_REPOSITORY:$NGINX_IMAGE_TAG | ||
echo "image=$CONTAINER_REPOSITORY:$BACKEND_IMAGE_TAG" >> $GITHUB_OUTPUT | ||
echo "image=$CONTAINER_REPOSITORY:$CLIENT_IMAGE_TAG" >> $GITHUB_OUTPUT | ||
echo "image=$CONTAINER_REPOSITORY:$NGINX_IMAGE_TAG" >> $GITHUB_OUTPUT | ||
|
||
- name: Configure .env.dev file | ||
run: | | ||
cat >> .env.dev <<END | ||
MYSQL_ROOT_PASSWORD=$MYSQL_ROOT_PASSWORD | ||
MYSQL_USER=$MYSQL_USER | ||
MYSQL_PASSWORD=$MYSQL_PASSWORD | ||
DB_NAME=$DB_NAME | ||
DB_HOST=$DB_HOST | ||
DB_PORT=$DB_PORT | ||
CORS_ALLOWED_ORIGINS=$CORS_ALLOWED_ORIGINS | ||
VITE_BACKEND_URL=$VITE_BACKEND_URL | ||
VITE_ENABLE_MOCKS=$VITE_ENABLE_MOCKS | ||
VITE_LOGGING=$VITE_LOGGING | ||
END | ||
|
||
- name: Configure SSH | ||
run: | | ||
mkdir -p ~/.ssh | ||
echo "$SSH_PRIVATE_KEY" > ~/.ssh/aws_dev.pem | ||
chmod 400 ~/.ssh/aws_dev.pem | ||
|
||
- name: SSH to AWS EC2 and down the containers | ||
run: | | ||
ssh -i ~/.ssh/aws_dev.pem $SSH_USER@$SSH_HOST << 'ENDSSH' | ||
cd $PROJECT_DIR | ||
docker-compose -f docker-compose.dev.yml down | ||
ENDSSH | ||
|
||
- name: SCP .env.dev and docker-compose.dev.yml to AWS EC2 | ||
run: | | ||
scp -i ~/.ssh/aws_dev.pem \ | ||
-r $(pwd)/{.env.dev,docker-compose.dev.yml} \ | ||
$SSH_USER@$SSH_HOST:$PROJECT_DIR | ||
|
||
- name: SSH to AWS EC2 and deploy | ||
run: | | ||
ssh -i ~/.ssh/aws_dev.pem $SSH_USER@$SSH_HOST << 'ENDSSH' | ||
cd $PROJECT_DIR | ||
docker pull $CONTAINER_REPOSITORY:$BACKEND_IMAGE_TAG | ||
docker pull $CONTAINER_REPOSITORY:$CLIENT_IMAGE_TAG | ||
docker pull $CONTAINER_REPOSITORY/$NGINX_IMAGE_TAG | ||
docker-compose -f docker-compose.staging.yml up -d | ||
docker-compose -f docker-compose.staging.yml exec backend python manage.py migrate --noinput | ||
ENDSSH |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,13 @@ | ||
.DS_Store | ||
|
||
# Legacy web project | ||
web/ | ||
web/ | ||
|
||
.idea/ | ||
|
||
# Env files | ||
.env | ||
.env.dev | ||
.env.stage | ||
.env.prod | ||
.env.makefile |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
{ | ||
"editor.defaultFormatter": "esbenp.prettier-vscode", | ||
"editor.codeActionsOnSave": { | ||
"source.fixAll.eslint": "explicit", | ||
"source.fixAll.tslint": "explicit", | ||
"source.organizeImports": "explicit", | ||
"source.fixAll.ts": "explicit", | ||
"source.sortImports": "explicit" | ||
}, | ||
"[typescriptreact]": { | ||
"editor.defaultFormatter": "esbenp.prettier-vscode" | ||
}, | ||
"[typescript]": { | ||
"editor.defaultFormatter": "esbenp.prettier-vscode" | ||
}, | ||
"[javascript]": { | ||
"editor.defaultFormatter": "esbenp.prettier-vscode" | ||
}, | ||
"editor.formatOnSave": true, | ||
"tailwindCSS.experimental.classRegex": [ | ||
["clsx\\(([^)]*)\\)", "(?:'|\"|`)([^']*)(?:'|\"|`)", "cva\\(([^)]*)\\)"] | ||
], | ||
"[ignore]": { | ||
"editor.defaultFormatter": "foxundermoon.shell-format" | ||
}, | ||
"[dotenv]": { | ||
"editor.defaultFormatter": "foxundermoon.shell-format" | ||
} | ||
} |
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This makefile is currently in use (Milestone 1) since workflows are not ready to execute. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
# Load secrets from a .env file (optional) | ||
ifneq (,$(wildcard .env.makefile)) | ||
include .env.makefile | ||
export | ||
endif | ||
|
||
# variables | ||
COMPOSE_FILE=docker-compose.dev.yml | ||
CONTAINER_REPOSITORY=meminseeker/turquiz | ||
SERVICES=backend client nginx | ||
|
||
# Variables from the env file | ||
PEM_FILE ?= $(PEM_FILE) | ||
SSH_USER ?= $(SSH_USER) | ||
SSH_HOST ?= $(SSH_HOST) | ||
FILES_TO_COPY ?= $(FILES_TO_COPY) | ||
TARGET_DIR ?= $(TARGET_DIR) | ||
ANDROID_DIR ?= $(ANDROID_DIR) | ||
|
||
# command for building images from dev | ||
dev-build: | ||
docker-compose -f $(COMPOSE_FILE) build | ||
|
||
# command for pushing dev images to Docker Hub | ||
dev-push: | ||
@for service in $(SERVICES); do \ | ||
docker push $(CONTAINER_REPOSITORY):$$service; \ | ||
done | ||
|
||
# command for down containers | ||
dev-down: | ||
@if [ -z "$(PEM_FILE)" ] || [ -z "$(SSH_USER)" ] || [ -z "$(SSH_HOST)" ] || [ -z "$(TARGET_DIR)" ] || [ -z "$(COMPOSE_FILE)" ]; then \ | ||
echo "Error: Please set PEM_FILE, SSH_USER, SSH_HOST, TARGET_DIR, and COMPOSE_FILE environment variables"; \ | ||
exit 1; \ | ||
fi | ||
ssh -i $(PEM_FILE) $(SSH_USER)@$(SSH_HOST) \ | ||
'cd $(TARGET_DIR) || { echo "Failed to change directory to $(TARGET_DIR)"; exit 1; }; \ | ||
echo "Successfully changed directory to $(TARGET_DIR)"; \ | ||
~/.docker/cli-plugins/docker-compose -f $(COMPOSE_FILE) down; \ | ||
exit' | ||
|
||
# command for SCP files to a remote server | ||
dev-scp: | ||
@if [ -z "$(PEM_FILE)" ] || [ -z "$(SSH_USER)" ] || [ -z "$(SSH_HOST)" ] || [ -z "$(FILES_TO_COPY)" ] || [ -z "$(TARGET_DIR)" ]; then \ | ||
echo "Error: Please set PEM_FILE, SSH_USER, SSH_HOST, FILES_TO_COPY, and TARGET_DIR environment variables"; \ | ||
exit 1; \ | ||
fi | ||
@for file in $(FILES_TO_COPY); do \ | ||
if [ ! -f $$file ]; then \ | ||
echo "Error: File $$file does not exist"; \ | ||
exit 1; \ | ||
fi; \ | ||
scp -i $(PEM_FILE) $$file $(SSH_USER)@$(SSH_HOST):$(TARGET_DIR); \ | ||
done | ||
|
||
# command for deployment to a remote server | ||
dev-up: | ||
@if [ -z "$(PEM_FILE)" ] || [ -z "$(SSH_USER)" ] || [ -z "$(SSH_HOST)" ] || [ -z "$(TARGET_DIR)" ] || [ -z "$(COMPOSE_FILE)" ] || [ -z "$(CONTAINER_REPOSITORY)" ] || [ -z "$(SERVICES)" ]; then \ | ||
echo "Error: Please set PEM_FILE, SSH_USER, SSH_HOST, TARGET_DIR, COMPOSE_FILE, CONTAINER_REPOSITORY, and SERVICES environment variables"; \ | ||
exit 1; \ | ||
fi | ||
ssh -i $(PEM_FILE) $(SSH_USER)@$(SSH_HOST) \ | ||
'cd $(TARGET_DIR) || { echo "Failed to change directory to $(TARGET_DIR)"; exit 1; }; \ | ||
echo "Successfully changed directory to $(TARGET_DIR)"; \ | ||
docker pull $(CONTAINER_REPOSITORY):backend; \ | ||
docker pull $(CONTAINER_REPOSITORY):client; \ | ||
docker pull $(CONTAINER_REPOSITORY):nginx; \ | ||
~/.docker/cli-plugins/docker-compose -f $(COMPOSE_FILE) up -d; \ | ||
~/.docker/cli-plugins/docker-compose -f docker-compose.dev.yml exec backend python manage.py migrate --noinput; \ | ||
exit' | ||
|
||
# Composition of the commands | ||
dev-bp: dev-build dev-push | ||
dev-dsu: dev-down dev-scp dev-up | ||
dev-deploy: dev-bp dev-dsu | ||
|
||
dev-mobile: | ||
@if [ -z "$(ANDROID_DIR)" ]; then \ | ||
echo "Error: Please set ANDROID_BUILDER_PATH environment variable"; \ | ||
exit 1; \ | ||
fi | ||
cd $(ANDROID_DIR) && \ | ||
./gradlew assembleDebug | ||
|
||
prod-mobile: | ||
@if [ -z "$(ANDROID_DIR)" ]; then \ | ||
echo "Error: Please set ANDROID_BUILDER_PATH environment variable"; \ | ||
exit 1; \ | ||
fi | ||
cd $(ANDROID_DIR) && \ | ||
./gradlew assembleRelease | ||
|
||
.PHONY: dev-build dev-push dev-down dev-scp dev-up dev-bp dev-dsu dev-deploy dev-mobile prod-mobile |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.