Compare commits
No commits in common. "42ccd7c0499d00bca79811f22453d35e79b0a6ca" and "51e2c8782897f2b837730ae783c6997b942a29cc" have entirely different histories.
42ccd7c049
...
51e2c87828
|
@ -1 +0,0 @@
|
||||||
.DS_Store
|
|
18
.drone.yml
18
.drone.yml
|
@ -1,18 +0,0 @@
|
||||||
kind: pipeline
|
|
||||||
type: docker
|
|
||||||
name: Build and Push to Local Registry
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: Build and Push Docker Image
|
|
||||||
image: plugins/docker
|
|
||||||
settings:
|
|
||||||
# Custom registry address
|
|
||||||
registry: localhost:32000
|
|
||||||
# Repository name (include registry address in repo path)
|
|
||||||
repo: localhost:32000/log101-dot-dev
|
|
||||||
# Tags for the image
|
|
||||||
tags:
|
|
||||||
- latest
|
|
||||||
- ${DRONE_COMMIT_SHA:0:7}
|
|
||||||
# Allow insecure connections (for HTTP registries)
|
|
||||||
insecure: true
|
|
|
@ -1,45 +1,18 @@
|
||||||
name: Build and Push Docker Image
|
run-name: ${{ gitea.actor }}, deploy to docker registry
|
||||||
run-name: Build triggered by ${{ gitea.actor }}
|
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- main
|
- "main"
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
runs-on: ubuntu-22.04 # Using specific Ubuntu version instead of latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repository
|
- name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Set up Docker Buildx
|
|
||||||
uses: docker/setup-buildx-action@v3
|
|
||||||
|
|
||||||
- name: Log in to private registry
|
|
||||||
uses: docker/login-action@v3
|
|
||||||
with:
|
|
||||||
registry: registry.acayip.dev
|
|
||||||
username: ${{ secrets.REGISTRY_USERNAME }}
|
|
||||||
password: ${{ secrets.REGISTRY_PASSWORD }}
|
|
||||||
|
|
||||||
- name: Generate image tag
|
|
||||||
id: meta
|
|
||||||
run: |
|
|
||||||
VERSION=$(date +%Y%m%d)-$(git rev-parse --short HEAD)
|
|
||||||
echo "TAG=registry.acayip.dev/log101-dot-dev:${VERSION}" >> $GITHUB_OUTPUT
|
|
||||||
|
|
||||||
- name: Build and push Docker image
|
- name: Build and push Docker image
|
||||||
uses: docker/build-push-action@v6
|
uses: docker/build-push-action@v6
|
||||||
with:
|
with:
|
||||||
context: .
|
push: ${{ github.event_name != 'pull_request' }}
|
||||||
push: ${{ gitea.event_name != 'pull_request' }}
|
tags: registry.container-registry:5000/log101-blog:latest
|
||||||
tags: ${{ steps.meta.outputs.TAG }}
|
|
||||||
# Add build caching for faster builds
|
|
||||||
cache-from: type=gha
|
|
||||||
cache-to: type=gha,mode=max
|
|
||||||
# Add labels for better tracking
|
|
||||||
labels: |
|
|
||||||
org.opencontainers.image.source=${{ gitea.repository }}
|
|
||||||
org.opencontainers.image.revision=${{ gitea.sha }}
|
|
||||||
org.opencontainers.image.created=${{ gitea.event.created_at }}
|
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
FROM oven/bun AS build
|
FROM node:lts AS build
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
COPY package*.json ./
|
COPY package*.json ./
|
||||||
RUN bun install
|
RUN npm install
|
||||||
COPY . .
|
COPY . .
|
||||||
ENV PUBLIC_BACKEND_HOST=https://api.acayip.dev
|
RUN npm run build
|
||||||
RUN bun run build
|
|
||||||
|
|
||||||
FROM nginx:alpine AS runtime
|
FROM nginx:alpine AS runtime
|
||||||
COPY ./nginx/nginx.conf /etc/nginx/nginx.conf
|
COPY ./nginx/nginx.conf /etc/nginx/nginx.conf
|
||||||
|
|
50
Jenkinsfile
vendored
50
Jenkinsfile
vendored
|
@ -1,50 +0,0 @@
|
||||||
pipeline {
|
|
||||||
agent {
|
|
||||||
docker {
|
|
||||||
image 'ubuntu-latest'
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
stages {
|
|
||||||
stage('Checkout') {
|
|
||||||
steps {
|
|
||||||
git(branch: 'main', url: 'https://git.acayip.dev/log101/log101-dot-dev.git')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
stage('Build Docker Image') {
|
|
||||||
steps {
|
|
||||||
script {
|
|
||||||
docker.build("${REGISTRY}/${DOCKER_IMAGE}:${DOCKER_TAG}")
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
stage('Push to microk8s Registry') {
|
|
||||||
steps {
|
|
||||||
script {
|
|
||||||
docker.withRegistry("http://${REGISTRY}") {
|
|
||||||
docker.image("${REGISTRY}/${DOCKER_IMAGE}:${DOCKER_TAG}").push()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
stage('Cleanup') {
|
|
||||||
steps {
|
|
||||||
script {
|
|
||||||
sh "docker rmi ${REGISTRY}/${DOCKER_IMAGE}:${DOCKER_TAG} || true"
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
environment {
|
|
||||||
DOCKER_IMAGE = 'log101-dot-dev'
|
|
||||||
DOCKER_TAG = 'latest'
|
|
||||||
REGISTRY = '192.168.88.252:5000'
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,6 +1,3 @@
|
||||||
> Geçmesi imkansız geçmiş, gelmesi imkansız gelecek...
|
> Geçmesi imkansız geçmiş, gelmesi imkansız gelecek...
|
||||||
|
|
||||||
log101.dev blog
|
log101.dev blog
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@ import remarkToc from "remark-toc";
|
||||||
|
|
||||||
// https://astro.build/config
|
// https://astro.build/config
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
site: "https://blog.acayip.dev",
|
site: "https://blog.log101.dev",
|
||||||
markdown: {
|
markdown: {
|
||||||
remarkPlugins: [[remarkToc, { heading: "İçindekiler" }]],
|
remarkPlugins: [[remarkToc, { heading: "İçindekiler" }]],
|
||||||
shikiConfig: {
|
shikiConfig: {
|
||||||
|
|
|
@ -1,23 +0,0 @@
|
||||||
# Patterns to ignore when building packages.
|
|
||||||
# This supports shell glob matching, relative path matching, and
|
|
||||||
# negation (prefixed with !). Only one pattern per line.
|
|
||||||
.DS_Store
|
|
||||||
# Common VCS dirs
|
|
||||||
.git/
|
|
||||||
.gitignore
|
|
||||||
.bzr/
|
|
||||||
.bzrignore
|
|
||||||
.hg/
|
|
||||||
.hgignore
|
|
||||||
.svn/
|
|
||||||
# Common backup files
|
|
||||||
*.swp
|
|
||||||
*.bak
|
|
||||||
*.tmp
|
|
||||||
*.orig
|
|
||||||
*~
|
|
||||||
# Various IDEs
|
|
||||||
.project
|
|
||||||
.idea/
|
|
||||||
*.tmproj
|
|
||||||
.vscode/
|
|
|
@ -1,24 +0,0 @@
|
||||||
apiVersion: argoproj.io/v1alpha1
|
|
||||||
name: blog
|
|
||||||
description: blog.log101.dev helm chart
|
|
||||||
|
|
||||||
# A chart can be either an 'application' or a 'library' chart.
|
|
||||||
#
|
|
||||||
# Application charts are a collection of templates that can be packaged into versioned archives
|
|
||||||
# to be deployed.
|
|
||||||
#
|
|
||||||
# Library charts provide useful utilities or functions for the chart developer. They're included as
|
|
||||||
# a dependency of application charts to inject those utilities and functions into the rendering
|
|
||||||
# pipeline. Library charts do not define any templates and therefore cannot be deployed.
|
|
||||||
type: application
|
|
||||||
|
|
||||||
# This is the chart version. This version number should be incremented each time you make changes
|
|
||||||
# to the chart and its templates, including the app version.
|
|
||||||
# Versions are expected to follow Semantic Versioning (https://semver.org/)
|
|
||||||
version: 0.1.0
|
|
||||||
|
|
||||||
# This is the version number of the application being deployed. This version number should be
|
|
||||||
# incremented each time you make changes to the application. Versions are not expected to
|
|
||||||
# follow Semantic Versioning. They should reflect the version the application is using.
|
|
||||||
# It is recommended to use it with quotes.
|
|
||||||
appVersion: "1.0.0"
|
|
|
@ -1,22 +0,0 @@
|
||||||
1. Get the application URL by running these commands:
|
|
||||||
{{- if .Values.ingress.enabled }}
|
|
||||||
{{- range $host := .Values.ingress.hosts }}
|
|
||||||
{{- range .paths }}
|
|
||||||
http{{ if $.Values.ingress.tls }}s{{ end }}://{{ $host.host }}{{ .path }}
|
|
||||||
{{- end }}
|
|
||||||
{{- end }}
|
|
||||||
{{- else if contains "NodePort" .Values.service.type }}
|
|
||||||
export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "chart.fullname" . }})
|
|
||||||
export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}")
|
|
||||||
echo http://$NODE_IP:$NODE_PORT
|
|
||||||
{{- else if contains "LoadBalancer" .Values.service.type }}
|
|
||||||
NOTE: It may take a few minutes for the LoadBalancer IP to be available.
|
|
||||||
You can watch its status by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "chart.fullname" . }}'
|
|
||||||
export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "chart.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}")
|
|
||||||
echo http://$SERVICE_IP:{{ .Values.service.port }}
|
|
||||||
{{- else if contains "ClusterIP" .Values.service.type }}
|
|
||||||
export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "chart.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
|
|
||||||
export CONTAINER_PORT=$(kubectl get pod --namespace {{ .Release.Namespace }} $POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}")
|
|
||||||
echo "Visit http://127.0.0.1:8080 to use your application"
|
|
||||||
kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8080:$CONTAINER_PORT
|
|
||||||
{{- end }}
|
|
|
@ -1,62 +0,0 @@
|
||||||
{{/*
|
|
||||||
Expand the name of the chart.
|
|
||||||
*/}}
|
|
||||||
{{- define "chart.name" -}}
|
|
||||||
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
|
|
||||||
{{- end }}
|
|
||||||
|
|
||||||
{{/*
|
|
||||||
Create a default fully qualified app name.
|
|
||||||
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
|
|
||||||
If release name contains chart name it will be used as a full name.
|
|
||||||
*/}}
|
|
||||||
{{- define "chart.fullname" -}}
|
|
||||||
{{- if .Values.fullnameOverride }}
|
|
||||||
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
|
|
||||||
{{- else }}
|
|
||||||
{{- $name := default .Chart.Name .Values.nameOverride }}
|
|
||||||
{{- if contains $name .Release.Name }}
|
|
||||||
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
|
|
||||||
{{- else }}
|
|
||||||
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
|
|
||||||
{{- end }}
|
|
||||||
{{- end }}
|
|
||||||
{{- end }}
|
|
||||||
|
|
||||||
{{/*
|
|
||||||
Create chart name and version as used by the chart label.
|
|
||||||
*/}}
|
|
||||||
{{- define "chart.chart" -}}
|
|
||||||
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
|
|
||||||
{{- end }}
|
|
||||||
|
|
||||||
{{/*
|
|
||||||
Common labels
|
|
||||||
*/}}
|
|
||||||
{{- define "chart.labels" -}}
|
|
||||||
helm.sh/chart: {{ include "chart.chart" . }}
|
|
||||||
{{ include "chart.selectorLabels" . }}
|
|
||||||
{{- if .Chart.AppVersion }}
|
|
||||||
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
|
|
||||||
{{- end }}
|
|
||||||
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
|
||||||
{{- end }}
|
|
||||||
|
|
||||||
{{/*
|
|
||||||
Selector labels
|
|
||||||
*/}}
|
|
||||||
{{- define "chart.selectorLabels" -}}
|
|
||||||
app.kubernetes.io/name: {{ include "chart.name" . }}
|
|
||||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
|
||||||
{{- end }}
|
|
||||||
|
|
||||||
{{/*
|
|
||||||
Create the name of the service account to use
|
|
||||||
*/}}
|
|
||||||
{{- define "chart.serviceAccountName" -}}
|
|
||||||
{{- if .Values.serviceAccount.create }}
|
|
||||||
{{- default (include "chart.fullname" .) .Values.serviceAccount.name }}
|
|
||||||
{{- else }}
|
|
||||||
{{- default "default" .Values.serviceAccount.name }}
|
|
||||||
{{- end }}
|
|
||||||
{{- end }}
|
|
|
@ -1,86 +0,0 @@
|
||||||
apiVersion: apps/v1
|
|
||||||
kind: Deployment
|
|
||||||
metadata:
|
|
||||||
name: {{ include "chart.fullname" . }}
|
|
||||||
labels:
|
|
||||||
{{- include "chart.labels" . | nindent 4 }}
|
|
||||||
spec:
|
|
||||||
{{- if not .Values.autoscaling.enabled }}
|
|
||||||
replicas: {{ .Values.replicaCount }}
|
|
||||||
{{- end }}
|
|
||||||
revisionHistoryLimit: {{ .Values.revisionHistoryLimit }}
|
|
||||||
selector:
|
|
||||||
matchLabels:
|
|
||||||
{{- include "chart.selectorLabels" . | nindent 6 }}
|
|
||||||
template:
|
|
||||||
metadata:
|
|
||||||
{{- with .Values.podAnnotations }}
|
|
||||||
annotations:
|
|
||||||
{{- toYaml . | nindent 8 }}
|
|
||||||
{{- end }}
|
|
||||||
labels:
|
|
||||||
{{- include "chart.labels" . | nindent 8 }}
|
|
||||||
{{- with .Values.podLabels }}
|
|
||||||
{{- toYaml . | nindent 8 }}
|
|
||||||
{{- end }}
|
|
||||||
spec:
|
|
||||||
{{- with .Values.imagePullSecrets }}
|
|
||||||
imagePullSecrets:
|
|
||||||
{{- toYaml . | nindent 8 }}
|
|
||||||
{{- end }}
|
|
||||||
serviceAccountName: {{ include "chart.serviceAccountName" . }}
|
|
||||||
{{- with .Values.podSecurityContext }}
|
|
||||||
securityContext:
|
|
||||||
{{- toYaml . | nindent 8 }}
|
|
||||||
{{- end }}
|
|
||||||
containers:
|
|
||||||
- name: {{ .Chart.Name }}
|
|
||||||
{{- with .Values.securityContext }}
|
|
||||||
securityContext:
|
|
||||||
{{- toYaml . | nindent 12 }}
|
|
||||||
{{- end }}
|
|
||||||
image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
|
|
||||||
imagePullPolicy: {{ .Values.image.pullPolicy }}
|
|
||||||
ports:
|
|
||||||
- name: http
|
|
||||||
containerPort: {{ .Values.containerPort | default 8080 }} # ← Now points to 8080
|
|
||||||
protocol: TCP
|
|
||||||
{{- if .Values.env }}
|
|
||||||
env:
|
|
||||||
{{- range $key, $value := .Values.env }}
|
|
||||||
- name: {{ $key }}
|
|
||||||
value: {{ $value | quote }}
|
|
||||||
{{- end }}
|
|
||||||
{{- end }}
|
|
||||||
{{- with .Values.livenessProbe }}
|
|
||||||
livenessProbe:
|
|
||||||
{{- toYaml . | nindent 12 }}
|
|
||||||
{{- end }}
|
|
||||||
{{- with .Values.readinessProbe }}
|
|
||||||
readinessProbe:
|
|
||||||
{{- toYaml . | nindent 12 }}
|
|
||||||
{{- end }}
|
|
||||||
{{- with .Values.resources }}
|
|
||||||
resources:
|
|
||||||
{{- toYaml . | nindent 12 }}
|
|
||||||
{{- end }}
|
|
||||||
{{- with .Values.volumeMounts }}
|
|
||||||
volumeMounts:
|
|
||||||
{{- toYaml . | nindent 12 }}
|
|
||||||
{{- end }}
|
|
||||||
{{- with .Values.volumes }}
|
|
||||||
volumes:
|
|
||||||
{{- toYaml . | nindent 8 }}
|
|
||||||
{{- end }}
|
|
||||||
{{- with .Values.nodeSelector }}
|
|
||||||
nodeSelector:
|
|
||||||
{{- toYaml . | nindent 8 }}
|
|
||||||
{{- end }}
|
|
||||||
{{- with .Values.affinity }}
|
|
||||||
affinity:
|
|
||||||
{{- toYaml . | nindent 8 }}
|
|
||||||
{{- end }}
|
|
||||||
{{- with .Values.tolerations }}
|
|
||||||
tolerations:
|
|
||||||
{{- toYaml . | nindent 8 }}
|
|
||||||
{{- end }}
|
|
|
@ -1,32 +0,0 @@
|
||||||
{{- if .Values.autoscaling.enabled }}
|
|
||||||
apiVersion: autoscaling/v2
|
|
||||||
kind: HorizontalPodAutoscaler
|
|
||||||
metadata:
|
|
||||||
name: {{ include "chart.fullname" . }}
|
|
||||||
labels:
|
|
||||||
{{- include "chart.labels" . | nindent 4 }}
|
|
||||||
spec:
|
|
||||||
scaleTargetRef:
|
|
||||||
apiVersion: apps/v1
|
|
||||||
kind: Deployment
|
|
||||||
name: {{ include "chart.fullname" . }}
|
|
||||||
minReplicas: {{ .Values.autoscaling.minReplicas }}
|
|
||||||
maxReplicas: {{ .Values.autoscaling.maxReplicas }}
|
|
||||||
metrics:
|
|
||||||
{{- if .Values.autoscaling.targetCPUUtilizationPercentage }}
|
|
||||||
- type: Resource
|
|
||||||
resource:
|
|
||||||
name: cpu
|
|
||||||
target:
|
|
||||||
type: Utilization
|
|
||||||
averageUtilization: {{ .Values.autoscaling.targetCPUUtilizationPercentage }}
|
|
||||||
{{- end }}
|
|
||||||
{{- if .Values.autoscaling.targetMemoryUtilizationPercentage }}
|
|
||||||
- type: Resource
|
|
||||||
resource:
|
|
||||||
name: memory
|
|
||||||
target:
|
|
||||||
type: Utilization
|
|
||||||
averageUtilization: {{ .Values.autoscaling.targetMemoryUtilizationPercentage }}
|
|
||||||
{{- end }}
|
|
||||||
{{- end }}
|
|
|
@ -1,43 +0,0 @@
|
||||||
{{- if .Values.ingress.enabled -}}
|
|
||||||
apiVersion: networking.k8s.io/v1
|
|
||||||
kind: Ingress
|
|
||||||
metadata:
|
|
||||||
name: {{ include "chart.fullname" . }}
|
|
||||||
labels:
|
|
||||||
{{- include "chart.labels" . | nindent 4 }}
|
|
||||||
{{- with .Values.ingress.annotations }}
|
|
||||||
annotations:
|
|
||||||
{{- toYaml . | nindent 4 }}
|
|
||||||
{{- end }}
|
|
||||||
spec:
|
|
||||||
{{- with .Values.ingress.className }}
|
|
||||||
ingressClassName: {{ . }}
|
|
||||||
{{- end }}
|
|
||||||
{{- if .Values.ingress.tls }}
|
|
||||||
tls:
|
|
||||||
{{- range .Values.ingress.tls }}
|
|
||||||
- hosts:
|
|
||||||
{{- range .hosts }}
|
|
||||||
- {{ . | quote }}
|
|
||||||
{{- end }}
|
|
||||||
secretName: {{ .secretName }}
|
|
||||||
{{- end }}
|
|
||||||
{{- end }}
|
|
||||||
rules:
|
|
||||||
{{- range .Values.ingress.hosts }}
|
|
||||||
- host: {{ .host | quote }}
|
|
||||||
http:
|
|
||||||
paths:
|
|
||||||
{{- range .paths }}
|
|
||||||
- path: {{ .path }}
|
|
||||||
{{- with .pathType }}
|
|
||||||
pathType: {{ . }}
|
|
||||||
{{- end }}
|
|
||||||
backend:
|
|
||||||
service:
|
|
||||||
name: {{ include "chart.fullname" $ }}
|
|
||||||
port:
|
|
||||||
number: {{ $.Values.service.port }}
|
|
||||||
{{- end }}
|
|
||||||
{{- end }}
|
|
||||||
{{- end }}
|
|
|
@ -1,13 +0,0 @@
|
||||||
apiVersion: v1
|
|
||||||
kind: Service
|
|
||||||
metadata:
|
|
||||||
name: {{ include "chart.fullname" . }}
|
|
||||||
labels: {{- include "chart.labels" . | nindent 4 }}
|
|
||||||
spec:
|
|
||||||
type: {{ .Values.service.type }}
|
|
||||||
ports:
|
|
||||||
- port: {{ .Values.service.port }}
|
|
||||||
targetPort: http
|
|
||||||
protocol: TCP
|
|
||||||
name: http
|
|
||||||
selector: {{- include "chart.selectorLabels" . | nindent 4 }}
|
|
|
@ -1,13 +0,0 @@
|
||||||
{{- if .Values.serviceAccount.create -}}
|
|
||||||
apiVersion: v1
|
|
||||||
kind: ServiceAccount
|
|
||||||
metadata:
|
|
||||||
name: {{ include "chart.serviceAccountName" . }}
|
|
||||||
labels:
|
|
||||||
{{- include "chart.labels" . | nindent 4 }}
|
|
||||||
{{- with .Values.serviceAccount.annotations }}
|
|
||||||
annotations:
|
|
||||||
{{- toYaml . | nindent 4 }}
|
|
||||||
{{- end }}
|
|
||||||
automountServiceAccountToken: {{ .Values.serviceAccount.automount }}
|
|
||||||
{{- end }}
|
|
|
@ -1,15 +0,0 @@
|
||||||
apiVersion: v1
|
|
||||||
kind: Pod
|
|
||||||
metadata:
|
|
||||||
name: "{{ include "chart.fullname" . }}-test-connection"
|
|
||||||
labels:
|
|
||||||
{{- include "chart.labels" . | nindent 4 }}
|
|
||||||
annotations:
|
|
||||||
"helm.sh/hook": test
|
|
||||||
spec:
|
|
||||||
containers:
|
|
||||||
- name: wget
|
|
||||||
image: busybox
|
|
||||||
command: ['wget']
|
|
||||||
args: ['{{ include "chart.fullname" . }}:{{ .Values.service.port }}']
|
|
||||||
restartPolicy: Never
|
|
|
@ -1,136 +0,0 @@
|
||||||
# Default values for chart.
|
|
||||||
# This is a YAML-formatted file.
|
|
||||||
# Declare variables to be passed into your templates.
|
|
||||||
|
|
||||||
# This will set the replicaset count more information can be found here: https://kubernetes.io/docs/concepts/workloads/controllers/replicaset/
|
|
||||||
replicaCount: 1
|
|
||||||
revisionHistoryLimit: 3
|
|
||||||
|
|
||||||
# This sets the container image more information can be found here: https://kubernetes.io/docs/concepts/containers/images/
|
|
||||||
image:
|
|
||||||
repository: registry.acayip.dev/log101-dot-dev
|
|
||||||
# This sets the pull policy for images.
|
|
||||||
pullPolicy: IfNotPresent
|
|
||||||
# Overrides the image tag whose default is the chart appVersion.
|
|
||||||
tag: ""
|
|
||||||
|
|
||||||
# This is for the secrets for pulling an image from a private repository more information can be found here: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/
|
|
||||||
imagePullSecrets:
|
|
||||||
- name: acayip-registry-secret
|
|
||||||
# This is to override the chart name.
|
|
||||||
nameOverride: ""
|
|
||||||
fullnameOverride: ""
|
|
||||||
|
|
||||||
# This section builds out the service account more information can be found here: https://kubernetes.io/docs/concepts/security/service-accounts/
|
|
||||||
serviceAccount:
|
|
||||||
# Specifies whether a service account should be created
|
|
||||||
create: true
|
|
||||||
# Automatically mount a ServiceAccount's API credentials?
|
|
||||||
automount: true
|
|
||||||
# Annotations to add to the service account
|
|
||||||
annotations: {}
|
|
||||||
# The name of the service account to use.
|
|
||||||
# If not set and create is true, a name is generated using the fullname template
|
|
||||||
name: ""
|
|
||||||
|
|
||||||
# This is for setting Kubernetes Annotations to a Pod.
|
|
||||||
# For more information checkout: https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/
|
|
||||||
podAnnotations: {}
|
|
||||||
# This is for setting Kubernetes Labels to a Pod.
|
|
||||||
# For more information checkout: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/
|
|
||||||
podLabels: {}
|
|
||||||
|
|
||||||
podSecurityContext:
|
|
||||||
{}
|
|
||||||
# fsGroup: 2000
|
|
||||||
|
|
||||||
securityContext:
|
|
||||||
{}
|
|
||||||
# capabilities:
|
|
||||||
# drop:
|
|
||||||
# - ALL
|
|
||||||
# readOnlyRootFilesystem: true
|
|
||||||
# runAsNonRoot: true
|
|
||||||
# runAsUser: 1000
|
|
||||||
|
|
||||||
# This is for setting up a service more information can be found here: https://kubernetes.io/docs/concepts/services-networking/service/
|
|
||||||
service:
|
|
||||||
# This sets the service type more information can be found here: https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types
|
|
||||||
type: ClusterIP
|
|
||||||
# This sets the ports more information can be found here: https://kubernetes.io/docs/concepts/services-networking/service/#field-spec-ports
|
|
||||||
port: 8080
|
|
||||||
|
|
||||||
containerPort: 8080
|
|
||||||
|
|
||||||
# Environment variables to be passed to the container
|
|
||||||
env:
|
|
||||||
PUBLIC_BACKEND_HOST: "https://api.acayip.dev"
|
|
||||||
|
|
||||||
# This block is for setting up the ingress for more information can be found here: https://kubernetes.io/docs/concepts/services-networking/ingress/
|
|
||||||
ingress:
|
|
||||||
enabled: true
|
|
||||||
className: ""
|
|
||||||
annotations:
|
|
||||||
cert-manager.io/cluster-issuer: lets-encrypt
|
|
||||||
# kubernetes.io/ingress.class: nginx
|
|
||||||
# kubernetes.io/tls-acme: "true"
|
|
||||||
hosts:
|
|
||||||
- host: blog.acayip.dev
|
|
||||||
paths:
|
|
||||||
- path: /
|
|
||||||
pathType: Prefix
|
|
||||||
|
|
||||||
tls:
|
|
||||||
- secretName: blog-tls
|
|
||||||
hosts:
|
|
||||||
- blog.acayip.dev
|
|
||||||
|
|
||||||
resources:
|
|
||||||
{}
|
|
||||||
# We usually recommend not to specify default resources and to leave this as a conscious
|
|
||||||
# choice for the user. This also increases chances charts run on environments with little
|
|
||||||
# resources, such as Minikube. If you do want to specify resources, uncomment the following
|
|
||||||
# lines, adjust them as necessary, and remove the curly braces after 'resources:'.
|
|
||||||
# limits:
|
|
||||||
# cpu: 100m
|
|
||||||
# memory: 128Mi
|
|
||||||
# requests:
|
|
||||||
# cpu: 100m
|
|
||||||
# memory: 128Mi
|
|
||||||
|
|
||||||
# This is to setup the liveness and readiness probes more information can be found here: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/
|
|
||||||
livenessProbe:
|
|
||||||
httpGet:
|
|
||||||
path: /
|
|
||||||
port: http
|
|
||||||
readinessProbe:
|
|
||||||
httpGet:
|
|
||||||
path: /
|
|
||||||
port: http
|
|
||||||
|
|
||||||
# This section is for setting up autoscaling more information can be found here: https://kubernetes.io/docs/concepts/workloads/autoscaling/
|
|
||||||
autoscaling:
|
|
||||||
enabled: false
|
|
||||||
minReplicas: 1
|
|
||||||
maxReplicas: 100
|
|
||||||
targetCPUUtilizationPercentage: 80
|
|
||||||
# targetMemoryUtilizationPercentage: 80
|
|
||||||
|
|
||||||
# Additional volumes on the output Deployment definition.
|
|
||||||
volumes: []
|
|
||||||
# - name: foo
|
|
||||||
# secret:
|
|
||||||
# secretName: mysecret
|
|
||||||
# optional: false
|
|
||||||
|
|
||||||
# Additional volumeMounts on the output Deployment definition.
|
|
||||||
volumeMounts: []
|
|
||||||
# - name: foo
|
|
||||||
# mountPath: "/etc/foo"
|
|
||||||
# readOnly: true
|
|
||||||
|
|
||||||
nodeSelector: {}
|
|
||||||
|
|
||||||
tolerations: []
|
|
||||||
|
|
||||||
affinity: {}
|
|
|
@ -1,20 +0,0 @@
|
||||||
apiVersion: apps/v1
|
|
||||||
kind: Deployment
|
|
||||||
metadata:
|
|
||||||
name: blog-deployment
|
|
||||||
labels:
|
|
||||||
app: blog
|
|
||||||
spec:
|
|
||||||
selector:
|
|
||||||
matchLabels:
|
|
||||||
app: blog
|
|
||||||
template:
|
|
||||||
metadata:
|
|
||||||
labels:
|
|
||||||
app: blog
|
|
||||||
spec:
|
|
||||||
containers:
|
|
||||||
- name: blog
|
|
||||||
image: localhost:32000/log101-dot-dev:v3
|
|
||||||
ports:
|
|
||||||
- containerPort: 8080
|
|
7
cypress.config.js
Normal file
7
cypress.config.js
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
import { defineConfig } from "cypress";
|
||||||
|
|
||||||
|
export default defineConfig({
|
||||||
|
e2e: {
|
||||||
|
supportFile: false,
|
||||||
|
},
|
||||||
|
});
|
7
cypress/e2e/index.cy.js
Normal file
7
cypress/e2e/index.cy.js
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
describe("Home", () =>
|
||||||
|
it("titles are correct", () => {
|
||||||
|
const page = cy.visit("http://localhost:4321");
|
||||||
|
|
||||||
|
page.get("title").should("have.text", "log101");
|
||||||
|
page.get("h1").should("have.text", "Log101");
|
||||||
|
}));
|
|
@ -8,7 +8,6 @@ http {
|
||||||
server {
|
server {
|
||||||
listen 8080;
|
listen 8080;
|
||||||
server_name _;
|
server_name _;
|
||||||
client_max_body_size 50M;
|
|
||||||
|
|
||||||
root /usr/share/nginx/html;
|
root /usr/share/nginx/html;
|
||||||
index index.html index.htm;
|
index index.html index.htm;
|
||||||
|
|
6535
package-lock.json
generated
6535
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
|
@ -7,19 +7,20 @@
|
||||||
"start": "astro dev",
|
"start": "astro dev",
|
||||||
"build": "astro check && astro build",
|
"build": "astro check && astro build",
|
||||||
"preview": "astro preview",
|
"preview": "astro preview",
|
||||||
"astro": "astro"
|
"astro": "astro",
|
||||||
|
"test": "cypress run --browser chrome && cypress run --browser firefox"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@astrojs/check": "0.9.4",
|
"@astrojs/check": "0.9.4",
|
||||||
"@astrojs/tailwind": "^6.0.2",
|
"@astrojs/tailwind": "6.0.0",
|
||||||
"astro": "^5.13.7",
|
"astro": "5.3.0",
|
||||||
"dewp": "^0.0.6",
|
|
||||||
"htmx.org": "^1.9.12",
|
"htmx.org": "^1.9.12",
|
||||||
"remark-toc": "^9.0.0",
|
"remark-toc": "^9.0.0",
|
||||||
"tailwindcss": "^3.4.3",
|
"tailwindcss": "^3.4.3",
|
||||||
"typescript": "^5.4.5"
|
"typescript": "^5.4.5"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"cypress": "^13.11.0",
|
||||||
"prettier": "^3.2.5",
|
"prettier": "^3.2.5",
|
||||||
"prettier-plugin-astro": "^0.14.0"
|
"prettier-plugin-astro": "^0.14.0"
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,25 +0,0 @@
|
||||||
backend:
|
|
||||||
name: gitea
|
|
||||||
repo: log101/log101-dot-dev # Path to your Gitea repository
|
|
||||||
app_id: 2cb1c31c-4c74-4272-ac74-5d60a4b5c9ab # The Client ID provided by Gitea
|
|
||||||
api_root: https://git.acayip.dev/api/v1 # API URL of your Gitea instance
|
|
||||||
base_url: https://git.acayip.dev # Root URL of your Gitea instance
|
|
||||||
auth_endpoint: https://git.acayip.dev/login/oauth/authorize
|
|
||||||
branch: draft
|
|
||||||
collections:
|
|
||||||
- name: "blog" # Used in routes, e.g., /admin/collections/blog
|
|
||||||
label: "Blog" # Used in the UI
|
|
||||||
folder: "src/content/blog" # The path to the folder where the documents are stored
|
|
||||||
create: true # Allow users to create new documents in this collection
|
|
||||||
slug: "{{year}}-{{month}}-{{day}}-{{slug}}" # Filename template, e.g., YYYY-MM-DD-title.md
|
|
||||||
format: frontmatter
|
|
||||||
fields: # The fields for each document, usually in front matter
|
|
||||||
- { label: "Taslak", name: "draft", widget: "boolean", default: true }
|
|
||||||
- { label: "Başlık", name: "title", widget: "string" }
|
|
||||||
- { label: "Tarih", name: "date", widget: "datetime" }
|
|
||||||
- { label: "Özet", name: "summary", widget: "string" }
|
|
||||||
- { label: "Kategori", name: "category", widget: "select", options: ["fikir", "teknik", "edebiyat", "ansiklopedi"] }
|
|
||||||
- { label: "Alt Kategori", name: "subcategory", widget: "string" }
|
|
||||||
- { label: "Body", name: "body", widget: "markdown" }
|
|
||||||
media_folder: "public/images"
|
|
||||||
public_folder: "/images"
|
|
Binary file not shown.
Before Width: | Height: | Size: 47 KiB |
|
@ -1,19 +1,13 @@
|
||||||
---
|
---
|
||||||
import { render, getCollection, type CollectionEntry } from "astro:content";
|
import type { CollectionEntry } from "astro:content";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
post: CollectionEntry<"posts">;
|
post: CollectionEntry<"blog">;
|
||||||
componentType: "short" | "long" | "full";
|
componentType: "short" | "long" | "full";
|
||||||
}
|
}
|
||||||
|
|
||||||
const { post, componentType } = Astro.props;
|
const { post, componentType } = Astro.props;
|
||||||
|
|
||||||
const categoryTitles = await Promise.all(
|
|
||||||
post.data.categories.map(async (c) => await getEntry("categories", c.id))
|
|
||||||
);
|
|
||||||
|
|
||||||
const parentCategory = categoryTitles.find((c) => !Boolean(c?.data.parent?.id));
|
|
||||||
|
|
||||||
// default options for the post component
|
// default options for the post component
|
||||||
const deafultOptions = {
|
const deafultOptions = {
|
||||||
showTags: false,
|
showTags: false,
|
||||||
|
@ -53,15 +47,16 @@ const postDateFormatted = post.data.date.toLocaleDateString("tr-TR", {
|
||||||
});
|
});
|
||||||
|
|
||||||
// Create post link
|
// Create post link
|
||||||
const postLink = `/${parentCategory?.data.slug}/${post.data.slug}`;
|
const postLink = `/${post.data.category}/${post.slug}`;
|
||||||
|
|
||||||
// Create post content as an astro component
|
// Create post content as an astro component
|
||||||
const { Content } = await render(post);
|
const { Content } = await post.render();
|
||||||
|
|
||||||
|
const copyPost = post;
|
||||||
|
|
||||||
import { Image } from "astro:assets";
|
import { Image } from "astro:assets";
|
||||||
import questionMark from "@/images/questionMark.svg";
|
import questionMark from "@/images/questionMark.svg";
|
||||||
import calendar from "@/images/calendar.svg";
|
import calendar from "@/images/calendar.svg";
|
||||||
import { getEntry } from "astro:content";
|
|
||||||
---
|
---
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
@ -75,13 +70,26 @@ import { getEntry } from "astro:content";
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<div class="flex flex-col gap-1">
|
<div class="flex flex-col gap-3">
|
||||||
<div class="flex flex-col gap-2">
|
<div class="flex flex-col gap-2">
|
||||||
<p class="tracking-wide text-slate-700">{categoryTitles[0]?.data.name}</p>
|
<p class="tracking-wide text-slate-700">{post.data.subcategory}</p>
|
||||||
<a class="no-underline text-inherit" href={postLink}>
|
<a class="no-underline text-inherit" href={postLink}>
|
||||||
<h4 class="text-2xl font-normal">{post.data.title.rendered}</h4>
|
<h4 class="text-3xl font-normal">{post.data.title}</h4>
|
||||||
</a>
|
</a>
|
||||||
<div class="flex flex-row gap-2">
|
<div class="flex flex-row gap-2">
|
||||||
|
{
|
||||||
|
options.showTags && post.data.tags?.length && (
|
||||||
|
<div class="flex items-center gap-1">
|
||||||
|
<Image alt="question mark" src={questionMark} />
|
||||||
|
<ul class="list-none flex pl-0 meta-list">
|
||||||
|
{post.data.tags.map((tag) => (
|
||||||
|
<li class="text-sm text-gray-500">{tag}</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
<div class="flex items-center gap-1">
|
<div class="flex items-center gap-1">
|
||||||
<Image alt="calendar" src={calendar} />
|
<Image alt="calendar" src={calendar} />
|
||||||
<ul class="list-none flex pl-0 meta-list">
|
<ul class="list-none flex pl-0 meta-list">
|
||||||
|
@ -92,7 +100,7 @@ import { getEntry } from "astro:content";
|
||||||
</div>
|
</div>
|
||||||
{
|
{
|
||||||
(options.shortSummary || options.longSummary) && (
|
(options.shortSummary || options.longSummary) && (
|
||||||
<p class="post-summary" set:html={post.data.excerpt.rendered} />
|
<p class="post-summary">{post.data.summary}</p>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -135,7 +135,7 @@ Peki tüm bu saydığım servisler ne kadar kaynak tüketiyor? Özellikle RAM ka
|
||||||
|
|
||||||
### Gelecek
|
### Gelecek
|
||||||
|
|
||||||
Sistemimde çalışan servisleri kısaca tanıttım. Bunlar şimdilik işimi görüyor fakat yakın gelecekte daha fazlasına ihtiyaç duyacağımı tahmin ediyorum. Özellikle güvenlik açısından sunucumun çok eksiği var. DDoS saldırılarına açık ve bildiğim bilmediğim birçok zafiyete sahip. Yine de kendi CI/CD sistemimi kullanmak ve kodum ile alakalı bütün süreçleri yönetmek projelerime esneklik katıyor.
|
Sistemimde çalışan servisleri kısaca tanıtmış oldum. Bunlar şimdilik işimi görüyor fakat yakın gelecekte daha fazlasına ihtiyaç duyacağımı tahmin ediyorum. Özellikle güvenlik açısından sunucumun çok eksiği var. DDoS saldırılarına açık ve bildiğim bilmediğim birçok zafiyete sahip. Yine de kendi CI/CD sistemimi kullanmak ve kodum ile alakalı bütün süreçleri yönetmek projelerime esneklik katıyor.
|
||||||
|
|
||||||
Kendi sunucunuzu kurmanın, sizin için de keyifli ve kıymetli bir tecrübe olacağına inanıyorum.
|
Kendi sunucunuzu kurmanın, sizin için de keyifli ve kıymetli bir tecrübe olacağına inanıyorum.
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
import { z, defineCollection } from "astro:content";
|
import { z, defineCollection } from "astro:content";
|
||||||
import { wpCollections } from "dewp/loaders";
|
|
||||||
|
|
||||||
export const CATEGORIES = ["fikir", "teknik", "edebiyat", "ansiklopedi"];
|
export const CATEGORIES = ["fikir", "teknik", "edebiyat", "ansiklopedi"];
|
||||||
|
|
||||||
|
@ -36,5 +35,4 @@ const bookReviewCollection = defineCollection({
|
||||||
export const collections = {
|
export const collections = {
|
||||||
blog: blogCollection,
|
blog: blogCollection,
|
||||||
bookReview: bookReviewCollection,
|
bookReview: bookReviewCollection,
|
||||||
...wpCollections({ endpoint: "https://wp.log101.dev/wp-json/" }),
|
|
||||||
};
|
};
|
||||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 1.1 MiB |
|
@ -1,6 +1,7 @@
|
||||||
---
|
---
|
||||||
import type { Page } from "astro";
|
import type { Page } from "astro";
|
||||||
import { getCollection } from "astro:content";
|
import { getCollection } from "astro:content";
|
||||||
|
import { CATEGORIES } from "@/content/config";
|
||||||
|
|
||||||
import Header from "@/components/Header.astro";
|
import Header from "@/components/Header.astro";
|
||||||
import Footer from "@/components/Footer.astro";
|
import Footer from "@/components/Footer.astro";
|
||||||
|
@ -8,16 +9,19 @@ import Layout from "@/layouts/Layout.astro";
|
||||||
import Post from "@/components/Post.astro";
|
import Post from "@/components/Post.astro";
|
||||||
|
|
||||||
export async function getStaticPaths({ paginate }: { paginate: any }) {
|
export async function getStaticPaths({ paginate }: { paginate: any }) {
|
||||||
const posts = await getCollection("posts");
|
const blogEntries = await getCollection("blog");
|
||||||
const categories = await getCollection("categories");
|
const allReviews = await getCollection("bookReview");
|
||||||
|
|
||||||
return categories.flatMap((category) => {
|
const allPosts = [...allReviews, ...blogEntries].filter(
|
||||||
const filteredPosts = posts.filter((post) =>
|
(post) => !post.data.draft
|
||||||
post.data.categories.find((c) => c.id === category.id)
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
return CATEGORIES.flatMap((category) => {
|
||||||
|
const filteredPosts = allPosts.filter(
|
||||||
|
(post) => post.data.category == category
|
||||||
|
);
|
||||||
return paginate(filteredPosts, {
|
return paginate(filteredPosts, {
|
||||||
params: { category: category.data.slug },
|
params: { category },
|
||||||
pageSize: 3,
|
pageSize: 3,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
---
|
---
|
||||||
import { getCollection, getEntry } from "astro:content";
|
import { getCollection } from "astro:content";
|
||||||
|
|
||||||
import Footer from "@/components/Footer.astro";
|
import Footer from "@/components/Footer.astro";
|
||||||
import Header from "@/components/Header.astro";
|
import Header from "@/components/Header.astro";
|
||||||
|
@ -8,6 +8,7 @@ import Post from "@/components/Post.astro";
|
||||||
import EmojiReactionForm from "@/components/EmojiReactionForm.astro";
|
import EmojiReactionForm from "@/components/EmojiReactionForm.astro";
|
||||||
import CommentForm from "@/components/CommentForm.astro";
|
import CommentForm from "@/components/CommentForm.astro";
|
||||||
import HorizontalLine from "@/components/HorizontalLine.astro";
|
import HorizontalLine from "@/components/HorizontalLine.astro";
|
||||||
|
import BookReview from "@/components/BookReview.astro";
|
||||||
|
|
||||||
const { entry } = Astro.props;
|
const { entry } = Astro.props;
|
||||||
|
|
||||||
|
@ -16,37 +17,33 @@ const URL = Astro.url;
|
||||||
const backendHost = import.meta.env.PUBLIC_BACKEND_HOST;
|
const backendHost = import.meta.env.PUBLIC_BACKEND_HOST;
|
||||||
|
|
||||||
export async function getStaticPaths() {
|
export async function getStaticPaths() {
|
||||||
const posts = await getCollection("posts");
|
const blogEntries = await getCollection("blog");
|
||||||
|
const allReviews = await getCollection("bookReview");
|
||||||
|
|
||||||
return await Promise.all(
|
const allPosts = [...allReviews, ...blogEntries].filter(
|
||||||
posts.map(async (entry) => {
|
(post) => !post.data.draft
|
||||||
const categoryTitles = await Promise.all(
|
|
||||||
entry.data.categories.map(
|
|
||||||
async (c) => await getEntry("categories", c.id)
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
|
|
||||||
const parentCategory = categoryTitles.find(
|
return allPosts.map((entry) => ({
|
||||||
(c) => !Boolean(c?.data.parent?.id)
|
params: { category: entry.data.category, slug: entry.slug },
|
||||||
);
|
|
||||||
|
|
||||||
return {
|
|
||||||
params: { category: parentCategory?.data.slug, slug: entry.data.slug },
|
|
||||||
props: { entry },
|
props: { entry },
|
||||||
};
|
}));
|
||||||
})
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
---
|
---
|
||||||
|
|
||||||
<Layout
|
<Layout
|
||||||
title="log101"
|
title="log101"
|
||||||
ogTitle={entry.data.title.rendered}
|
ogTitle={entry.data.title}
|
||||||
ogDescription={entry.data.excerpt.rendered}
|
ogDescription={entry.data.summary}
|
||||||
ogURL={URL.toString()}>
|
ogURL={URL.toString()}>
|
||||||
<Header />
|
<Header />
|
||||||
|
{
|
||||||
|
entry.collection === "blog" ? (
|
||||||
<Post post={entry} componentType="full" />
|
<Post post={entry} componentType="full" />
|
||||||
|
) : (
|
||||||
|
<BookReview post={entry} componentType="full" />
|
||||||
|
)
|
||||||
|
}
|
||||||
<EmojiReactionForm entryId={entry.id} />
|
<EmojiReactionForm entryId={entry.id} />
|
||||||
|
|
||||||
<section class="comments">
|
<section class="comments">
|
||||||
|
|
|
@ -5,17 +5,30 @@ import Layout from "@/layouts/Layout.astro";
|
||||||
|
|
||||||
import { getCollection } from "astro:content";
|
import { getCollection } from "astro:content";
|
||||||
import Post from "@/components/Post.astro";
|
import Post from "@/components/Post.astro";
|
||||||
|
import BookReview from "@/components/BookReview.astro";
|
||||||
|
|
||||||
const posts = await getCollection("posts");
|
const allTeknikPosts = await getCollection("blog");
|
||||||
|
const allReviews = await getCollection("bookReview");
|
||||||
|
|
||||||
|
const allPosts = [...allReviews, ...allTeknikPosts].filter(
|
||||||
|
(post) => !post.data.draft
|
||||||
|
);
|
||||||
---
|
---
|
||||||
|
|
||||||
<Layout title="log101">
|
<Layout title="log101">
|
||||||
<Header />
|
<Header />
|
||||||
<div class="posts">
|
<div class="posts">
|
||||||
{
|
{
|
||||||
posts
|
allPosts
|
||||||
.sort((p1, p2) => p2.data.date.getTime() - p1.data.date.getTime())
|
.sort((p1, p2) => p2.data.date.getTime() - p1.data.date.getTime())
|
||||||
.map((p) => <Post post={p} componentType="short" />)
|
.map((p) => {
|
||||||
|
if (p.collection == "blog") {
|
||||||
|
return <Post post={p} componentType="short" />;
|
||||||
|
} else {
|
||||||
|
p.collection == "bookReview";
|
||||||
|
return <BookReview post={p} componentType="short" />;
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
<a class="text-inherit" href="/posts/1">Tüm Yayınlar</a>
|
<a class="text-inherit" href="/posts/1">Tüm Yayınlar</a>
|
||||||
|
|
|
@ -8,10 +8,15 @@ import Layout from "@/layouts/Layout.astro";
|
||||||
import Post from "@/components/Post.astro";
|
import Post from "@/components/Post.astro";
|
||||||
|
|
||||||
export async function getStaticPaths({ paginate }: { paginate: any }) {
|
export async function getStaticPaths({ paginate }: { paginate: any }) {
|
||||||
const posts = await getCollection("posts");
|
const blogEntries = await getCollection("blog");
|
||||||
|
const allReviews = await getCollection("bookReview");
|
||||||
|
|
||||||
return paginate(posts, {
|
const allPosts = [...allReviews, ...blogEntries].filter(
|
||||||
pageSize: 10,
|
(post) => !post.data.draft
|
||||||
|
);
|
||||||
|
|
||||||
|
return paginate(allPosts, {
|
||||||
|
pageSize: 3,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -43,51 +43,3 @@ video {
|
||||||
font-family: "Source Code Pro", monospace;
|
font-family: "Source Code Pro", monospace;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.shiki {
|
|
||||||
font-size: 16px;
|
|
||||||
line-height: 1rem;
|
|
||||||
padding: 18px;
|
|
||||||
border-radius: 8px;
|
|
||||||
margin-bottom: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
h3,
|
|
||||||
hr {
|
|
||||||
margin: 0.7em 0 0.5em 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#full-text p {
|
|
||||||
margin: 0.5em 0 1.2em 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
figcaption {
|
|
||||||
color: gray;
|
|
||||||
text-align: center;
|
|
||||||
font-size: 0.9em;
|
|
||||||
}
|
|
||||||
|
|
||||||
#toc > ul {
|
|
||||||
line-height: 2em;
|
|
||||||
}
|
|
||||||
|
|
||||||
li a {
|
|
||||||
color: black;
|
|
||||||
}
|
|
||||||
|
|
||||||
table {
|
|
||||||
border: 1px solid slategrey;
|
|
||||||
padding: 4px;
|
|
||||||
background-color: #f8f9fa;
|
|
||||||
margin: 0.5em 0 1.2em 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
th {
|
|
||||||
text-align: left;
|
|
||||||
white-space: nowrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
td {
|
|
||||||
text-align: left;
|
|
||||||
white-space: nowrap;
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,5 +1,9 @@
|
||||||
{
|
{
|
||||||
"extends": "astro/tsconfigs/strict",
|
"extends": "astro/tsconfigs/strict",
|
||||||
"exclude": ["./src/components/*.astro"],
|
"compilerOptions": {
|
||||||
"compilerOptions": { "baseUrl": ".", "paths": { "@/*": ["./src/*"] } }
|
"baseUrl": ".",
|
||||||
|
"paths": {
|
||||||
|
"@/*": ["./src/*"]
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user