feat: update article files upload and setup ci/cd
This commit is contained in:
parent
07064f13ce
commit
c5563655a9
|
|
@ -0,0 +1,22 @@
|
|||
stages:
|
||||
- build
|
||||
- deploy
|
||||
|
||||
build:
|
||||
stage: build
|
||||
image: golang:alpine
|
||||
script:
|
||||
- go build -o main .
|
||||
artifacts:
|
||||
paths:
|
||||
- main
|
||||
|
||||
deploy:
|
||||
stage: deploy
|
||||
image: docker:stable
|
||||
services:
|
||||
- docker:dind
|
||||
script:
|
||||
- docker login -u $DEPLOY_USERNAME -p $DEPLOY_TOKEN registry.gitlab.com
|
||||
- docker build -t registry.gitlab.com/hanifsalafi/web-humas-be:dev .
|
||||
- docker push registry.gitlab.com/hanifsalafi/web-humas-be:dev
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
# Menggunakan Go image resmi dari Docker Hub sebagai base image
|
||||
FROM golang:alpine AS builder
|
||||
|
||||
# Menentukan direktori kerja
|
||||
WORKDIR /app
|
||||
|
||||
# Menyalin file Go mod dan Go sum untuk mendownload dependensi
|
||||
COPY go.mod ./
|
||||
COPY go.sum ./
|
||||
|
||||
# Mendownload dependensi menggunakan Go module
|
||||
RUN go mod download
|
||||
|
||||
# Menyalin seluruh file ke dalam image
|
||||
COPY build .
|
||||
|
||||
# Mengcompile aplikasi Go
|
||||
RUN go build -o main .
|
||||
|
||||
# Memindahkan binary hasil compile ke direktori yang lebih kecil
|
||||
FROM alpine:latest
|
||||
WORKDIR /root/
|
||||
COPY --from=builder /app/main .
|
||||
CMD ["./main"]
|
||||
|
|
@ -181,17 +181,19 @@ func (_i *articleFilesController) Delete(c *fiber.Ctx) error {
|
|||
})
|
||||
}
|
||||
|
||||
// Upload create ArticleFiles
|
||||
// @Summary Create ArticleFiles
|
||||
// Uploader upload ArticleFiles
|
||||
// @Summary Upload ArticleFiles
|
||||
// @Description API for create ArticleFiles
|
||||
// @Tags Task
|
||||
// @Security Bearer
|
||||
// @Produce json
|
||||
// @Param files formData file true "Upload file"
|
||||
// @Success 200 {object} response.Response
|
||||
// @Failure 401 {object} response.Response
|
||||
// @Failure 404 {object} response.Response
|
||||
// @Failure 422 {object} response.Response
|
||||
// @Failure 500 {object} response.Response
|
||||
// @Router /article-files [post]
|
||||
// @Router /article-files/uploader [post]
|
||||
func (_i *articleFilesController) Uploader(c *fiber.Ctx) error {
|
||||
|
||||
err := _i.articleFilesService.Uploader(c, 1)
|
||||
|
|
@ -209,12 +211,13 @@ func (_i *articleFilesController) Uploader(c *fiber.Ctx) error {
|
|||
// @Description API for create ArticleFiles
|
||||
// @Tags Task
|
||||
// @Security Bearer
|
||||
// @Param id path string true "Filename"
|
||||
// @Success 200 {object} response.Response
|
||||
// @Failure 401 {object} response.Response
|
||||
// @Failure 404 {object} response.Response
|
||||
// @Failure 422 {object} response.Response
|
||||
// @Failure 500 {object} response.Response
|
||||
// @Router /article-files/viewer [get]
|
||||
// @Router /article-files/viewer/{id} [get]
|
||||
func (_i *articleFilesController) Viewer(c *fiber.Ctx) error {
|
||||
|
||||
return _i.articleFilesService.Viewer(c, c.Params("id"))
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import (
|
|||
"go-humas-be/app/module/article_files/repository"
|
||||
"go-humas-be/app/module/article_files/request"
|
||||
"go-humas-be/app/module/article_files/response"
|
||||
minioUpload "go-humas-be/utils/minio"
|
||||
minioStorage "go-humas-be/config/config"
|
||||
"go-humas-be/utils/paginator"
|
||||
"io"
|
||||
"log"
|
||||
|
|
@ -22,6 +22,7 @@ import (
|
|||
type articleFilesService struct {
|
||||
Repo repository.ArticleFilesRepository
|
||||
Log zerolog.Logger
|
||||
MinioStorage *minioStorage.MinioStorage
|
||||
}
|
||||
|
||||
// ArticleFilesService define interface of IArticleFilesService
|
||||
|
|
@ -36,11 +37,12 @@ type ArticleFilesService interface {
|
|||
}
|
||||
|
||||
// NewArticleFilesService init ArticleFilesService
|
||||
func NewArticleFilesService(repo repository.ArticleFilesRepository, log zerolog.Logger) ArticleFilesService {
|
||||
func NewArticleFilesService(repo repository.ArticleFilesRepository, log zerolog.Logger, minioStorage *minioStorage.MinioStorage) ArticleFilesService {
|
||||
|
||||
return &articleFilesService{
|
||||
Repo: repo,
|
||||
Log: log,
|
||||
MinioStorage: minioStorage,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -83,7 +85,7 @@ func (_i *articleFilesService) Delete(id uint) error {
|
|||
}
|
||||
|
||||
func (_i *articleFilesService) Uploader(c *fiber.Ctx, id uint) (err error) {
|
||||
bucketName := "humas"
|
||||
bucketName := _i.MinioStorage.Cfg.ObjectStorage.MinioStorage.BucketName
|
||||
|
||||
form, err := c.MultipartForm()
|
||||
if err != nil {
|
||||
|
|
@ -92,7 +94,7 @@ func (_i *articleFilesService) Uploader(c *fiber.Ctx, id uint) (err error) {
|
|||
files := form.File["files"]
|
||||
|
||||
// Create minio connection.
|
||||
minioClient, err := minioUpload.MinioConnection()
|
||||
minioClient, err := _i.MinioStorage.ConnectMinio()
|
||||
if err != nil {
|
||||
// Return status 500 and minio connection error.
|
||||
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
|
||||
|
|
@ -130,15 +132,15 @@ func (_i *articleFilesService) Uploader(c *fiber.Ctx, id uint) (err error) {
|
|||
|
||||
func (_i *articleFilesService) Viewer(c *fiber.Ctx, id string) (err error) {
|
||||
ctx := context.Background()
|
||||
bucketName := _i.MinioStorage.Cfg.ObjectStorage.MinioStorage.BucketName
|
||||
objectName := id
|
||||
bucketName := "humas"
|
||||
|
||||
_i.Log.Info().Str("timestamp", time.Now().
|
||||
Format(time.RFC3339)).Str("Service:Resource", "Article:Uploads").
|
||||
Interface("data", objectName).Msg("")
|
||||
|
||||
// Create minio connection.
|
||||
minioClient, err := minioUpload.MinioConnection()
|
||||
minioClient, err := _i.MinioStorage.ConnectMinio()
|
||||
if err != nil {
|
||||
// Return status 500 and minio connection error.
|
||||
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
|
||||
|
|
|
|||
|
|
@ -65,11 +65,24 @@ type middleware = struct {
|
|||
}
|
||||
}
|
||||
|
||||
// minio struct config
|
||||
type objectStorage = struct {
|
||||
MinioStorage struct {
|
||||
Endpoint string `toml:"endpoint"`
|
||||
AccessKeyID string `toml:"access-key-id"`
|
||||
SecretAccessKey string `toml:"secret-access-key"`
|
||||
UseSSL bool `toml:"use-ssl"`
|
||||
BucketName string `toml:"bucket-name"`
|
||||
Location string `toml:"location"`
|
||||
}
|
||||
}
|
||||
|
||||
type Config struct {
|
||||
App app
|
||||
DB db
|
||||
Logger logger
|
||||
Middleware middleware
|
||||
ObjectStorage objectStorage
|
||||
}
|
||||
|
||||
// NewConfig : initialize config
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package minio
|
||||
package config
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
|
@ -7,13 +7,29 @@ import (
|
|||
"log"
|
||||
)
|
||||
|
||||
// MinioConnection membuka koneksi ke Minio.
|
||||
func MinioConnection() (*minio.Client, error) {
|
||||
// MinioSetup struct
|
||||
type MinioStorage struct {
|
||||
Cfg *Config
|
||||
}
|
||||
|
||||
func NewMinio(cfg *Config) *MinioStorage {
|
||||
minioSetup := &MinioStorage{
|
||||
Cfg: cfg,
|
||||
}
|
||||
|
||||
return minioSetup
|
||||
}
|
||||
|
||||
func (_minio *MinioStorage) ConnectMinio() (*minio.Client, error) {
|
||||
ctx := context.Background()
|
||||
endpoint := "localhost:9004"
|
||||
accessKeyID := "sc6ZiC6dpWMZWmfwukSF"
|
||||
secretAccessKey := "Q6MsoOhYFmRctWJLMrPXdV0vwKns8d9tgUJyu1ec"
|
||||
useSSL := false
|
||||
endpoint := _minio.Cfg.ObjectStorage.MinioStorage.Endpoint
|
||||
accessKeyID := _minio.Cfg.ObjectStorage.MinioStorage.AccessKeyID
|
||||
secretAccessKey := _minio.Cfg.ObjectStorage.MinioStorage.SecretAccessKey
|
||||
useSSL := _minio.Cfg.ObjectStorage.MinioStorage.UseSSL
|
||||
|
||||
bucketName := _minio.Cfg.ObjectStorage.MinioStorage.BucketName
|
||||
location := _minio.Cfg.ObjectStorage.MinioStorage.Location
|
||||
|
||||
// Initialize minio client object.
|
||||
minioClient, errInit := minio.New(endpoint, &minio.Options{
|
||||
Creds: credentials.NewStaticV4(accessKeyID, secretAccessKey, ""),
|
||||
|
|
@ -23,10 +39,6 @@ func MinioConnection() (*minio.Client, error) {
|
|||
log.Fatalln(errInit)
|
||||
}
|
||||
|
||||
// Make a new bucket called dev-minio.
|
||||
bucketName := "humas"
|
||||
location := "us-east-1"
|
||||
|
||||
err := minioClient.MakeBucket(ctx, bucketName, minio.MakeBucketOptions{Region: location})
|
||||
if err != nil {
|
||||
// Check to see if we already own this bucket (which happens if you run this twice)
|
||||
|
|
@ -18,6 +18,14 @@ time-format = "" # https://pkg.go.dev/time#pkg-constants, https://github.com/rs/
|
|||
level = 0 # panic -> 5, fatal -> 4, error -> 3, warn -> 2, info -> 1, debug -> 0, trace -> -1
|
||||
prettier = true
|
||||
|
||||
[objectstorage.miniostorage]
|
||||
endpoint = "103.37.125.216:9009"
|
||||
access-key-id = "mnwWy87WrNiY4V7n63Nt"
|
||||
secret-access-key = "OXG4Pzy5QaTJCbQmmA2aXt2jakxQVNfHA34kWzp5"
|
||||
use-ssl = false
|
||||
bucket-name = "humas"
|
||||
location = "us-east-1"
|
||||
|
||||
[middleware.compress]
|
||||
enable = true
|
||||
level = 1
|
||||
|
|
|
|||
|
|
@ -627,7 +627,65 @@ const docTemplate = `{
|
|||
}
|
||||
}
|
||||
},
|
||||
"/article-files/viewer": {
|
||||
"/article-files/uploader": {
|
||||
"post": {
|
||||
"security": [
|
||||
{
|
||||
"Bearer": []
|
||||
}
|
||||
],
|
||||
"description": "API for create ArticleFiles",
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"Task"
|
||||
],
|
||||
"summary": "Upload ArticleFiles",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "file",
|
||||
"description": "Upload file",
|
||||
"name": "files",
|
||||
"in": "formData",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/response.Response"
|
||||
}
|
||||
},
|
||||
"401": {
|
||||
"description": "Unauthorized",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/response.Response"
|
||||
}
|
||||
},
|
||||
"404": {
|
||||
"description": "Not Found",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/response.Response"
|
||||
}
|
||||
},
|
||||
"422": {
|
||||
"description": "Unprocessable Entity",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/response.Response"
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "Internal Server Error",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/response.Response"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/article-files/viewer/{id}": {
|
||||
"get": {
|
||||
"security": [
|
||||
{
|
||||
|
|
@ -639,6 +697,15 @@ const docTemplate = `{
|
|||
"Task"
|
||||
],
|
||||
"summary": "Create ArticleFiles",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "Filename",
|
||||
"name": "id",
|
||||
"in": "path",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
|
|
|
|||
|
|
@ -616,7 +616,65 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"/article-files/viewer": {
|
||||
"/article-files/uploader": {
|
||||
"post": {
|
||||
"security": [
|
||||
{
|
||||
"Bearer": []
|
||||
}
|
||||
],
|
||||
"description": "API for create ArticleFiles",
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"Task"
|
||||
],
|
||||
"summary": "Upload ArticleFiles",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "file",
|
||||
"description": "Upload file",
|
||||
"name": "files",
|
||||
"in": "formData",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/response.Response"
|
||||
}
|
||||
},
|
||||
"401": {
|
||||
"description": "Unauthorized",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/response.Response"
|
||||
}
|
||||
},
|
||||
"404": {
|
||||
"description": "Not Found",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/response.Response"
|
||||
}
|
||||
},
|
||||
"422": {
|
||||
"description": "Unprocessable Entity",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/response.Response"
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "Internal Server Error",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/response.Response"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/article-files/viewer/{id}": {
|
||||
"get": {
|
||||
"security": [
|
||||
{
|
||||
|
|
@ -628,6 +686,15 @@
|
|||
"Task"
|
||||
],
|
||||
"summary": "Create ArticleFiles",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "Filename",
|
||||
"name": "id",
|
||||
"in": "path",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
|
|
|
|||
|
|
@ -567,9 +567,52 @@ paths:
|
|||
summary: update ArticleFiles
|
||||
tags:
|
||||
- Task
|
||||
/article-files/viewer:
|
||||
/article-files/uploader:
|
||||
post:
|
||||
description: API for create ArticleFiles
|
||||
parameters:
|
||||
- description: Upload file
|
||||
in: formData
|
||||
name: files
|
||||
required: true
|
||||
type: file
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/response.Response'
|
||||
"401":
|
||||
description: Unauthorized
|
||||
schema:
|
||||
$ref: '#/definitions/response.Response'
|
||||
"404":
|
||||
description: Not Found
|
||||
schema:
|
||||
$ref: '#/definitions/response.Response'
|
||||
"422":
|
||||
description: Unprocessable Entity
|
||||
schema:
|
||||
$ref: '#/definitions/response.Response'
|
||||
"500":
|
||||
description: Internal Server Error
|
||||
schema:
|
||||
$ref: '#/definitions/response.Response'
|
||||
security:
|
||||
- Bearer: []
|
||||
summary: Upload ArticleFiles
|
||||
tags:
|
||||
- Task
|
||||
/article-files/viewer/{id}:
|
||||
get:
|
||||
description: API for create ArticleFiles
|
||||
parameters:
|
||||
- description: Filename
|
||||
in: path
|
||||
name: id
|
||||
required: true
|
||||
type: string
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
|
|
|
|||
Loading…
Reference in New Issue