Skip to content
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] Test deploy #671

Merged
merged 16 commits into from
Dec 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 11 additions & 8 deletions .github/workflows/prod_deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,34 +20,37 @@ jobs:

# Build a Docker image of the application and tag the image with the $GITHUB_SHA.
- name: Build backend image
run: docker build -t registry.digitalocean.com/programming-languages/backend:$(echo $GITHUB_SHA | head -c7) ./backend
run: docker build -t registry.digitalocean.com/programming-languages-2/backend:$(echo $GITHUB_SHA | head -c7) ./backend

- name: Build web image
run: docker build -t registry.digitalocean.com/programming-languages/web:$(echo $GITHUB_SHA | head -c7) ./frontend
run: docker build -t registry.digitalocean.com/programming-languages-2/web:$(echo $GITHUB_SHA | head -c7) ./frontend

- name: Log in to DigitalOcean Container Registry with short-lived credentials
run: doctl registry login --expiry-seconds 1200

# Push the Docker image to registry

- name: Push backend image
run: docker push registry.digitalocean.com/programming-languages/backend:$(echo $GITHUB_SHA | head -c7)
run: docker push registry.digitalocean.com/programming-languages-2/backend:$(echo $GITHUB_SHA | head -c7)

- name: Push web image
run: docker push registry.digitalocean.com/programming-languages/web:$(echo $GITHUB_SHA | head -c7)
run: docker push registry.digitalocean.com/programming-languages-2/web:$(echo $GITHUB_SHA | head -c7)

# tag as latest

- name: Tag backend image
run: docker tag registry.digitalocean.com/programming-languages/backend:$(echo $GITHUB_SHA | head -c7) registry.digitalocean.com/programming-languages/backend:latest
run: docker tag registry.digitalocean.com/programming-languages-2/backend:$(echo $GITHUB_SHA | head -c7) registry.digitalocean.com/programming-languages-2/backend:latest

- name: Tag web image
run: docker tag registry.digitalocean.com/programming-languages/web:$(echo $GITHUB_SHA | head -c7) registry.digitalocean.com/programming-languages/web:latest
run: docker tag registry.digitalocean.com/programming-languages-2/web:$(echo $GITHUB_SHA | head -c7) registry.digitalocean.com/programming-languages-2/web:latest

# Push the Docker image to registry

- name: Push backend image
run: docker push registry.digitalocean.com/programming-languages/backend:latest
run: docker push registry.digitalocean.com/programming-languages-2/backend:latest

- name: Push web image
run: docker push registry.digitalocean.com/programming-languages/web:latest
run: docker push registry.digitalocean.com/programming-languages-2/web:latest

- name: Create deployment again to ensure both images are up to date
run: doctl apps create-deployment 58cc1048-2af2-42f8-a71f-5d1085113742
16 changes: 8 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -114,24 +114,24 @@ docker compose build

```bash
# for prod
docker tag bounswe2024group1-451-web:latest registry.digitalocean.com/programming-languages/web:latest
docker tag bounswe2024group1-451-backend:latest registry.digitalocean.com/programming-languages/backend:latest
docker tag bounswe2024group1-451-web:latest registry.digitalocean.com/programming-languages-2/web:latest
docker tag bounswe2024group1-451-backend:latest registry.digitalocean.com/programming-languages-2/backend:latest

# for staging
docker tag bounswe2024group1-451-web:latest registry.digitalocean.com/programming-languages/web:staging
docker tag bounswe2024group1-451-backend:latest registry.digitalocean.com/programming-languages/backend:staging
docker tag bounswe2024group1-451-web:latest registry.digitalocean.com/programming-languages-2/web:staging
docker tag bounswe2024group1-451-backend:latest registry.digitalocean.com/programming-languages-2/backend:staging
```

3. Push images to the registry.

```bash
# for prod
docker push registry.digitalocean.com/programming-languages/web:latest
docker push registry.digitalocean.com/programming-languages/backend:latest
docker push registry.digitalocean.com/programming-languages-2/web:latest
docker push registry.digitalocean.com/programming-languages-2/backend:latest

# for staging
docker push registry.digitalocean.com/programming-languages/web:staging
docker push registry.digitalocean.com/programming-languages/backend:staging
docker push registry.digitalocean.com/programming-languages-2/web:staging
docker push registry.digitalocean.com/programming-languages-2/backend:staging
```

This will trigger a deployment on the DigitalOcean backend.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import com.group1.programminglanguagesforum.Exceptions.UnauthorizedAccessException;
import com.group1.programminglanguagesforum.Services.TagService;
import com.group1.programminglanguagesforum.Services.UserContextService;
import com.group1.programminglanguagesforum.Services.UserService;
import com.group1.programminglanguagesforum.Util.ApiResponseBuilder;

import jakarta.persistence.EntityExistsException;
Expand All @@ -26,6 +27,7 @@

import java.util.Arrays;
import java.util.NoSuchElementException;
import java.util.Optional;


@RestController
Expand All @@ -35,6 +37,7 @@ public class TagController extends BaseController {

private final TagService tagService;
private final UserContextService userContextService;
private final UserService userService;

@GetMapping(value = EndpointConstants.TagEndpoints.SEARCH)
public ResponseEntity<GenericApiResponse<TagSearchResponseDto>> tagSearch(
Expand Down Expand Up @@ -94,6 +97,13 @@ public ResponseEntity<GenericApiResponse<GetTagDetailsResponseDto>> getTagDetail
@PostMapping(value = EndpointConstants.TagEndpoints.BASE_PATH)
public ResponseEntity<GenericApiResponse<GetTagDetailsResponseDto>> createTag(@RequestBody CreateTagRequestDto dto){
try{
User user = userContextService.getCurrentUser();
if(userService.calculateReputation(user) < 50){
return ExceptionResponseHandler.IllegalArgumentException(
new IllegalArgumentException("User does not have enough reputation to create a tag which should be at least 50")
);
}

GetTagDetailsResponseDto tagDetails = tagService.createTag(dto);
GenericApiResponse<GetTagDetailsResponseDto> response = GenericApiResponse.<GetTagDetailsResponseDto>builder()
.status(201)
Expand All @@ -115,6 +125,8 @@ public ResponseEntity<GenericApiResponse<GetTagDetailsResponseDto>> createTag(@R
.build();
ApiResponseBuilder.buildErrorResponse(GetTagDetailsResponseDto.class, "Invalid tag type", 400, errorResponse);
return buildResponse(response, HttpStatus.BAD_REQUEST);
} catch (UnauthorizedAccessException e) {
return ExceptionResponseHandler.UnauthorizedAccessException(e);
}

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@
@Repository
public interface TagRepository extends JpaRepository<Tag,Long> {
List<Tag> findAllByIdIn(List<Long> ids);
@Query("SELECT t FROM Tag t " +
"JOIN Question q ON t MEMBER OF q.tags " +
"GROUP BY t.id " +
"ORDER BY COUNT(q.id) DESC")

Page<Tag> findTagsByTagNameContainingIgnoreCase(String tagName, Pageable pageable);
@Query("SELECT t FROM Tag t JOIN t.followers u WHERE u.id = :userId")
Expand Down
4 changes: 2 additions & 2 deletions frontend/src/components/AnswerCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export const AnswerCard: React.FC<AnswerCardProps> = ({
author,
}) => {
return (
<Card className="border-none bg-neutral-150 px-6 py-8 shadow-sm">
<Card className="border-none #e5e5e5 px-6 py-8 shadow-sm">
<div className="flex flex-col gap-6">
<h3 className="line-clamp-2 text-xl font-semibold text-gray-800">
{title}
Expand All @@ -49,7 +49,7 @@ export const AnswerCard: React.FC<AnswerCardProps> = ({
<Link to={`/users/${author.id}`} className="h-10 w-10">
<img
src={author.profilePicture}
alt={author.name}
alt={"Profile picture"}
className="rounded-full object-cover"
/>
</Link>
Expand Down
4 changes: 2 additions & 2 deletions frontend/src/components/AnswerItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export const AnswerItem: React.FC<AnswerItemProps> = ({
const { token } = useAuthStore();

return (
<Card className="border-none bg-neutral-150 px-6 py-8 shadow-sm">
<Card className="border-none #e5e5e5 px-6 py-8 shadow-sm">
<div className="flex flex-col gap-4">
<ContentWithSnippets content={answer.content} />
<div className="flex items-center justify-between">
Expand Down Expand Up @@ -64,7 +64,7 @@ export const AnswerItem: React.FC<AnswerItemProps> = ({
answer.author?.profilePicture ||
"https://placehold.co/100x100"
}
alt={answer.author?.name}
alt={"Profile picture"}
className="h-8 w-8 rounded-full object-cover"
/>
<span className="text-sm font-medium">{answer.author?.name}</span>
Expand Down
8 changes: 4 additions & 4 deletions frontend/src/components/CodeSnippet.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { useExecuteCode } from "@/services/api/programmingForumComponents";
import { CodeExecution } from "@/services/api/programmingForumSchemas";
import React from "react";
import { Light as SyntaxHighlighter } from "react-syntax-highlighter";
import { docco } from "react-syntax-highlighter/dist/esm/styles/hljs";
import { a11yLight } from "react-syntax-highlighter/dist/esm/styles/hljs";

interface CodeSnippetProps {
code: string;
Expand Down Expand Up @@ -37,15 +37,15 @@ export const CodeSnippet: React.FC<CodeSnippetProps> = ({ code, language }) => {

return (
<div className="not-prose relative flex flex-col gap-2 overflow-hidden rounded-xl border border-gray-400 bg-gray-100 p-4">
<h4 className="text-sm font-bold">
<h1 className="text-sm font-bold">
{languageUserFriendlyName[
language.replace("-exec", "") as keyof typeof languageUserFriendlyName
] ?? "Unknown"}{" "}
Code Snippet
</h4>
</h1>
<SyntaxHighlighter
language={language.replace("-exec", "")}
style={docco}
style={a11yLight}
PreTag={({ children, ...rest }) => {
return (
<div {...rest}>
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/components/DifficultyBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ export const DifficultyBar: React.FC<DifficultyBarProps> = ({
{/* Difficulty Bar */}
<div>
<h2 className="mb-2 text-lg font-semibold">
The community finds this question <strong>{getHighestVotedDifficulty()}</strong> difficulty.
The community finds this question: <strong>{getHighestVotedDifficulty()}</strong> difficulty.
</h2>
<div className="text-sm text-gray-600 mb-2">
<span>Easy: {localCounts.easy} votes</span>,{" "}
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/components/DifficultyFilter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export function DifficultyFilter({ value, onChange }: DifficultyFilterProps) {
onChange(val === "all" ? undefined : (val as DifficultyLevel))
}
>
<SelectTrigger className="w-[180px]">
<SelectTrigger className="w-[180px]" aria-label="Filter questions by difficulty">
<SelectValue placeholder="Filter by difficulty" />
</SelectTrigger>
<SelectContent>
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/components/ExerciseCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export const ExerciseCard: React.FC<ExerciseCardProps> = ({
link,
}) => {
return (
<Card className="flex flex-1 border-none bg-neutral-150 px-6 py-8 shadow-sm">
<Card className="flex flex-1 border-none #e5e5e5 px-6 py-8 shadow-sm">
<div className="flex flex-col gap-6">
<h3 className="line-clamp-2 text-xl font-semibold text-gray-800">
{title}
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/components/HighlightedQuestionCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ export const HighlightedQuestionCard: React.FC<Partial<QuestionSummary>> = ({
)}
<Link
to={`/question/${id}`}
className="flex items-center text-sm font-medium text-gray-800 hover:underline"
className="flex items-center text-sm font-medium text-gray-800 hover:underline p-2"
>
Go to question
<ArrowRight className="ml-1 h-4 w-4" />
Expand Down
4 changes: 2 additions & 2 deletions frontend/src/components/QuestionCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export const QuestionCard = React.forwardRef<HTMLDivElement, QuestionCardProps>(
({ id, title, content, votes, answerCount, author, difficulty }, ref) => {
return (
<Card
className="flex flex-1 border-none bg-neutral-150 px-6 py-8 shadow-sm"
className="flex flex-1 border-none #e5e5e5 px-6 py-8 shadow-sm"
ref={ref}
>
<div className="flex flex-col gap-6">
Expand Down Expand Up @@ -65,7 +65,7 @@ export const QuestionCard = React.forwardRef<HTMLDivElement, QuestionCardProps>(
)}
<Link
to={`/question/${id}`}
className="flex items-center text-sm font-medium text-gray-800 hover:underline"
className="flex items-center text-sm font-medium text-gray-800 hover:underline p-2"
>
Go to question
<ArrowRight className="ml-1 h-4 w-4" />
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/components/Tag.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ export const Tag = ({
)}
<Link
to={`/tag/${tagId}`}
className="text-sm font-medium text-blue-500 hover:underline"
className="text-sm font-medium text-blue-700 hover:underline"
>
See all questions →
</Link>
Expand Down
6 changes: 3 additions & 3 deletions frontend/src/components/TagCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,13 @@ export const TagCard = React.forwardRef<HTMLDivElement, TagCardProps>(
({ tag }, ref) => {
return (
<Card
className="flex-1 border-none bg-neutral-150 px-6 py-8 shadow-sm"
className="flex-1 border-none #e5e5e5 px-6 py-8 shadow-sm"
ref={ref}
>
<div className="flex flex-col gap-6">
<h3 className="line-clamp-2 text-xl font-semibold text-gray-800">
<h1 className="line-clamp-2 text-xl font-semibold text-gray-800">
{tag.name}
</h3>
</h1>
<div className="flex items-start gap-2">
<p className="line-clamp-3 text-sm font-light text-gray-800">
{tag.description}
Expand Down
6 changes: 5 additions & 1 deletion frontend/src/routes/create-question.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -282,15 +282,19 @@ export default function QuestionCreationPage() {
name="difficulty"
render={({ field }) => (
<FormItem>
<label htmlFor="difficulty-select" className="font-semibold mb-2 block">
Difficulty Level
</label>
<FormControl>
<select
id="difficulty-select"
className="rounded border border-gray-300 px-4 py-2"
value={field.value}
onChange={(e) => field.onChange(e.target.value)}
>
<option value="EASY">Easy</option>
<option value="MEDIUM">Medium</option>
<option value="HARD">Hard</option>
<option value="HARD">Hard</option>
</select>
</FormControl>
<FormMessage />
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/routes/feed.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ export const Feed = () => {
<section className="mb-12">
<div className="flex items-center justify-between">
<h2 className="text-2xl font-bold">Tags</h2>
<a href="/tags" className="text-red-500 hover:underline">
<a href="/tags" className="text-red-700 hover:underline">
See all →
</a>
</div>
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/routes/profile.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@ export default function Profile() {
size="icon"
className="rounded-full bg-red-500 text-white"
>
<Link to="/questions/new">
<Link to="/questions/new" aria-label="Create New Question">
<Plus />
</Link>
</Button>
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/routes/question.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ export default function QuestionPage() {
src={
question.author.profilePicture || "https://placehold.co/640x640"
}
alt={question.author.name + " profile picture"}
alt={"Profile picture"}
className="h-8 w-8 rounded-full object-cover"
/>
<span className="font-semibold">{question.author.name}</span>
Expand Down
10 changes: 6 additions & 4 deletions frontend/src/routes/tag.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ export default function TagPage() {
{tag.logoImage && (
<img
src={tag?.logoImage || "https://placehold.co/400x300"}
alt={`The logo image of ${tag.name}`}
alt={`${tag.name} logo`}
title={`alt:The logo image of ${tag.name}`}
className="h-48 w-full rounded-3xl object-contain lg:h-96"
/>
Expand Down Expand Up @@ -161,6 +161,7 @@ export default function TagPage() {
to={tag.stackExchangeTag}
className="flex items-center gap-2 text-sm font-semibold text-gray-500"
target="_blank"
aria-label={`Visit Stack Exchange for ${tag.name}`}
>
Stack Exchange
</Link>
Expand All @@ -177,15 +178,16 @@ export default function TagPage() {
<div className="mt-4 flex flex-col gap-4 px-4 py-2">
<div className="flex items-center justify-between">
<div className="flex items-center gap-4">
<h3>Questions</h3>
<h1>Questions</h1>
{!!token && (
<Button
asChild
size="icon"
className="rounded-full bg-red-500 text-white"
className="rounded-full bg-red-700 text-white"
aria-label="Create a new question"
>
<Link to={`/questions/new?tagIds=${tag.tagId}`}>
<Plus />
<Plus aria-hidden="true" />
</Link>
</Button>
)}
Expand Down
5 changes: 4 additions & 1 deletion mobile/app/(tabs)/index.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { ScrollView, Text } from "react-native";

import { Button, ButtonText, VStack } from "@/components/ui";
import { Button, ButtonText, Divider, VStack } from "@/components/ui";
import useAuthStore from "@/services/auth";
import { Ionicons } from "@expo/vector-icons";
import { router } from "expo-router";
import { Feed } from "@/components/Feed";

export default function HomeScreen() {
const auth = useAuthStore();
Expand Down Expand Up @@ -45,6 +46,8 @@ export default function HomeScreen() {
<ButtonText>Logout</ButtonText>
</Button>
)}
<Divider className="my-8" />
<Feed />
</VStack>
</ScrollView>
);
Expand Down
Loading
Loading