Add jenkinsfile and versioning
Gitea/ncDocConverter/pipeline/head This commit looks good
Details
Gitea/ncDocConverter/pipeline/head This commit looks good
Details
parent
58121dabdc
commit
65cfa0ec64
|
@ -29,4 +29,10 @@ go.work
|
||||||
/.vite
|
/.vite
|
||||||
|
|
||||||
# Log files
|
# Log files
|
||||||
*.log
|
*.log
|
||||||
|
|
||||||
|
# Build binaries
|
||||||
|
/ncDocConverth-*
|
||||||
|
|
||||||
|
# Note folder
|
||||||
|
/notes
|
|
@ -0,0 +1,60 @@
|
||||||
|
pipeline {
|
||||||
|
agent any
|
||||||
|
|
||||||
|
tools {
|
||||||
|
go '1.18'
|
||||||
|
}
|
||||||
|
|
||||||
|
stages {
|
||||||
|
stage('Build') {
|
||||||
|
steps {
|
||||||
|
sh 'go get ./...'
|
||||||
|
|
||||||
|
// Script needed to define variables
|
||||||
|
script {
|
||||||
|
// Get version of program
|
||||||
|
VERSION = sh (
|
||||||
|
script: 'cat VERSION',
|
||||||
|
returnStdout: true
|
||||||
|
).trim()
|
||||||
|
|
||||||
|
// Cross compile
|
||||||
|
sh "GOOS=linux GOARCH=amd64 go build -o ncDocConverth-${VERSION}-amd64 ./cmd/ncDocConverth"
|
||||||
|
sh "GOOS=linux GOARCH=arm64 go build -o ncDocConverth-${VERSION}-arm64 ./cmd/ncDocConverth"
|
||||||
|
sh "GOOS=windows GOARCH=arm64 go build -o ncDocConverth-${VERSION}-amd64.exe ./cmd/ncDocConverth"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stage('Deploy') {
|
||||||
|
when {
|
||||||
|
buildingTag()
|
||||||
|
}
|
||||||
|
|
||||||
|
steps {
|
||||||
|
script {
|
||||||
|
if (env.BRANCH_NAME == "main") {
|
||||||
|
sh 'sudo ./scripts/deploy.sh'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
post {
|
||||||
|
success {
|
||||||
|
archiveArtifacts artifacts: 'ncDocConverth-*', fingerprint: true
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clean after build
|
||||||
|
cleanup {
|
||||||
|
cleanWs()
|
||||||
|
}
|
||||||
|
|
||||||
|
failure {
|
||||||
|
emailext body: "${currentBuild.currentResult}: Job ${env.JOB_NAME} build ${env.BUILD_NUMBER}\n More info at: ${env.BUILD_URL}",
|
||||||
|
recipientProviders: [[$class: 'DevelopersRecipientProvider'], [$class: 'RequesterRecipientProvider']],
|
||||||
|
subject: "Jenkins Build ${currentBuild.currentResult}: Job ${env.JOB_NAME}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -10,6 +10,8 @@ import (
|
||||||
"rpjosh.de/ncDocConverter/pkg/logger"
|
"rpjosh.de/ncDocConverter/pkg/logger"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var version string
|
||||||
|
|
||||||
type WebApplication struct {
|
type WebApplication struct {
|
||||||
logger *logger.Logger
|
logger *logger.Logger
|
||||||
config *models.WebConfig
|
config *models.WebConfig
|
||||||
|
@ -18,7 +20,7 @@ type WebApplication struct {
|
||||||
func main() {
|
func main() {
|
||||||
defer logger.CloseFile()
|
defer logger.CloseFile()
|
||||||
|
|
||||||
config, err := models.SetConfig()
|
config, err := models.SetConfig(version)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Error(err.Error())
|
logger.Error(err.Error())
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
|
// NOTE: This is not a valid JSON file.
|
||||||
|
// Remove all comments and rename the file from '.hjson' to '.json'
|
||||||
{
|
{
|
||||||
"nextcloudUsers": [
|
"nextcloudUsers": [
|
||||||
{
|
{
|
||||||
// Nextcloud user and instance to save the converted files
|
// Nextcloud user and instance to save the converted files
|
||||||
"nextcloudUrl": "https://cloud.rpjosh.de",
|
"nextcloudUrl": "https://cloud.myDomain.de",
|
||||||
"username": "exchange",
|
"username": "myUser",
|
||||||
"password": "Zj9cQ-eF3n6-R6DSt-8sJXf-kYseJ",
|
"password": "A41cP-eR3n6-OIP13-8sQ1f-kYqp3",
|
||||||
|
|
||||||
// OnlyOffice (docx, xlsx, ...) convertion to pdf
|
// OnlyOffice (docx, xlsx, ...) convertion to pdf
|
||||||
"jobs": [
|
"jobs": [
|
||||||
|
@ -27,9 +29,9 @@
|
||||||
|
|
||||||
// Conversion from bookStack to pdf/html
|
// Conversion from bookStack to pdf/html
|
||||||
"bookStack": {
|
"bookStack": {
|
||||||
"url": "https://wiki.rpjosh.de",
|
"url": "https://wiki.myDomain.de",
|
||||||
"username": "test@rpjosh.de",
|
"username": "test@rpjosh.de",
|
||||||
"apiToken": "typCf2LoSQDHicpeeAZQCDZwAq7BvVdl:PcKMZVDrIwEJeKIKyaD7w0cf20JCjpZz",
|
"apiToken": "typfe29famd983amdk12a93:ave550l3fqu72cays51o84da71fvlqvtia6x19wZz",
|
||||||
|
|
||||||
"jobs": [
|
"jobs": [
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,21 +1,46 @@
|
||||||
{
|
{
|
||||||
"users": [
|
"nextcloudUsers": [
|
||||||
{
|
{
|
||||||
"authUser": "Unique Username (from ",
|
"nextcloudUrl": "https://cloud.myDomain.de",
|
||||||
"nextcloudUrl": "https://cloud.myDomain.de",
|
"username": "myUser",
|
||||||
"username": "MyUsername",
|
"password": "A41cP-eR3n6-OIP13-8sQ1f-kYqp3",
|
||||||
"password": "App Password",
|
|
||||||
|
|
||||||
"jobs": [
|
"jobs": [
|
||||||
{
|
{
|
||||||
"jobName": "",
|
"jobName": "Convert my books",
|
||||||
"sourceDir": "Arbeit/",
|
"sourceDir": "api/",
|
||||||
"destinationDir": "Ebooks/",
|
"destinationDir": "ebooks/",
|
||||||
|
|
||||||
"keepFolders": true,
|
"keepFolders": true,
|
||||||
"recursive": true,
|
"recursive": true,
|
||||||
"execution": [ "01:00", "15:00" ]
|
"execution": "45 23 * * 6"
|
||||||
}
|
}
|
||||||
]
|
],
|
||||||
|
|
||||||
|
"bookStack": {
|
||||||
|
"url": "https://wiki.myDomain.de",
|
||||||
|
"username": "test@myDomain.de",
|
||||||
|
"apiToken": "typfe29famd983amdk12a93:ave550l3fqu72cays51o84da71fvlqvtia6x19wZz",
|
||||||
|
|
||||||
|
"jobs": [
|
||||||
|
{
|
||||||
|
"jobName": "Convert my favorite books",
|
||||||
|
|
||||||
|
"shelves": [ "Work", "Linux" ],
|
||||||
|
"shelveRegex": "",
|
||||||
|
|
||||||
|
"books": [],
|
||||||
|
"booksRegex": "",
|
||||||
|
|
||||||
|
"includeBooksWithoutShelve": false,
|
||||||
|
"destinationDir": "ebooks/wiki/",
|
||||||
|
"format": "html",
|
||||||
|
"keepStructure": true,
|
||||||
|
"execution": "45 23 * * 6",
|
||||||
|
"cache": 3
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
9
go.mod
9
go.mod
|
@ -3,13 +3,12 @@ module rpjosh.de/ncDocConverter
|
||||||
go 1.18
|
go 1.18
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/go-chi/chi/v5 v5.0.8 // indirect
|
github.com/go-chi/chi/v5 v5.0.8
|
||||||
github.com/go-co-op/gocron v1.18.0 // indirect
|
github.com/go-co-op/gocron v1.18.0
|
||||||
github.com/go-yaml/yaml v2.1.0+incompatible // indirect
|
github.com/justinas/nosurf v1.1.1
|
||||||
github.com/justinas/nosurf v1.1.1 // indirect
|
gopkg.in/yaml.v3 v3.0.1
|
||||||
github.com/robfig/cron/v3 v3.0.1 // indirect
|
github.com/robfig/cron/v3 v3.0.1 // indirect
|
||||||
golang.org/x/sync v0.1.0 // indirect
|
golang.org/x/sync v0.1.0 // indirect
|
||||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// https://zhwt.github.io/yaml-to-go/
|
// https://zhwt.github.io/yaml-to-go/
|
||||||
|
|
|
@ -2,6 +2,7 @@ package models
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"flag"
|
"flag"
|
||||||
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
yaml "gopkg.in/yaml.v3"
|
yaml "gopkg.in/yaml.v3"
|
||||||
|
@ -17,6 +18,7 @@ type Server struct {
|
||||||
Address string `yaml:"address"`
|
Address string `yaml:"address"`
|
||||||
Certificate string `yaml:"certificate"`
|
Certificate string `yaml:"certificate"`
|
||||||
OneShot bool `yaml:"oneShot"`
|
OneShot bool `yaml:"oneShot"`
|
||||||
|
Version string
|
||||||
}
|
}
|
||||||
|
|
||||||
type Logging struct {
|
type Logging struct {
|
||||||
|
@ -56,7 +58,7 @@ func getDefaultConfig() *WebConfig {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Applies the cli and the configuration options from the config files
|
// Applies the cli and the configuration options from the config files
|
||||||
func SetConfig() (*WebConfig, error) {
|
func SetConfig(version string) (*WebConfig, error) {
|
||||||
configPath := "./config.yaml"
|
configPath := "./config.yaml"
|
||||||
// the path of the configuration file is needed first to determine the "default" values
|
// the path of the configuration file is needed first to determine the "default" values
|
||||||
for i, arg := range os.Args {
|
for i, arg := range os.Args {
|
||||||
|
@ -66,6 +68,8 @@ func SetConfig() (*WebConfig, error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
webConfig := getDefaultConfig()
|
webConfig := getDefaultConfig()
|
||||||
|
webConfig.Server.Version = version
|
||||||
|
|
||||||
webConfig, err := ParseWebConfig(webConfig, configPath)
|
webConfig, err := ParseWebConfig(webConfig, configPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Error("Unable to parse the configuration file '%s': %s", configPath, err)
|
logger.Error("Unable to parse the configuration file '%s': %s", configPath, err)
|
||||||
|
@ -77,12 +81,18 @@ func SetConfig() (*WebConfig, error) {
|
||||||
address := flag.String("address", webConfig.Server.Address, "Address and port on which the api and the web server should listen to")
|
address := flag.String("address", webConfig.Server.Address, "Address and port on which the api and the web server should listen to")
|
||||||
printLogLevel := flag.String("printLogLevel", webConfig.Logging.PrintLogLevel, "Minimum log level to log (debug, info, warning, error, fatal)")
|
printLogLevel := flag.String("printLogLevel", webConfig.Logging.PrintLogLevel, "Minimum log level to log (debug, info, warning, error, fatal)")
|
||||||
oneShot := flag.Bool("oneShot", webConfig.Server.OneShot, "All jobs are executed immediately and the program exists afterwards")
|
oneShot := flag.Bool("oneShot", webConfig.Server.OneShot, "All jobs are executed immediately and the program exists afterwards")
|
||||||
|
printVersion := flag.Bool("version", false, "Prints the version of the program")
|
||||||
|
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
webConfig.Server.Address = *address
|
webConfig.Server.Address = *address
|
||||||
webConfig.Logging.PrintLogLevel = *printLogLevel
|
webConfig.Logging.PrintLogLevel = *printLogLevel
|
||||||
webConfig.Server.OneShot = *oneShot
|
webConfig.Server.OneShot = *oneShot
|
||||||
|
|
||||||
|
if *printVersion {
|
||||||
|
fmt.Println(webConfig.Server.Version)
|
||||||
|
os.Exit(0)
|
||||||
|
}
|
||||||
|
|
||||||
defaultLogger := logger.Logger{
|
defaultLogger := logger.Logger{
|
||||||
PrintLevel: logger.GetLevelByName(webConfig.Logging.PrintLogLevel),
|
PrintLevel: logger.GetLevelByName(webConfig.Logging.PrintLogLevel),
|
||||||
LogLevel: logger.GetLevelByName(webConfig.Logging.WriteLogLevel),
|
LogLevel: logger.GetLevelByName(webConfig.Logging.WriteLogLevel),
|
||||||
|
|
|
@ -96,7 +96,7 @@ func (job *convertJob) ExecuteJob() {
|
||||||
wg.Add(len(destinationMap))
|
wg.Add(len(destinationMap))
|
||||||
for _, dest := range destinationMap {
|
for _, dest := range destinationMap {
|
||||||
go func(file *nextcloud.NcFile) {
|
go func(file *nextcloud.NcFile) {
|
||||||
err := nextcloud.DeleteFile(job.ncUser, dest.Path)
|
err := nextcloud.DeleteFile(job.ncUser, file.Path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Error(utils.FirstCharToUppercase(err.Error()))
|
logger.Error(utils.FirstCharToUppercase(err.Error()))
|
||||||
}
|
}
|
||||||
|
@ -118,7 +118,6 @@ func (job *convertJob) ExecuteJob() {
|
||||||
// Convert the files
|
// Convert the files
|
||||||
wg.Add(len(filesToConvert))
|
wg.Add(len(filesToConvert))
|
||||||
for _, file := range filesToConvert {
|
for _, file := range filesToConvert {
|
||||||
logger.Info("Path: %s", file.source.Path)
|
|
||||||
go func(cvt convertQueu) {
|
go func(cvt convertQueu) {
|
||||||
job.convertFile(cvt.source.Path, cvt.source.Fileid, cvt.destination)
|
job.convertFile(cvt.source.Path, cvt.source.Fileid, cvt.destination)
|
||||||
wg.Done()
|
wg.Done()
|
||||||
|
|
|
@ -0,0 +1,64 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
## This script deploys the build files to the given directory.
|
||||||
|
##
|
||||||
|
## You can define all below variables also via environment variables
|
||||||
|
## with the prefix NC_DOC_CONVERTER_
|
||||||
|
## Example: NC_DOC_CONVERTER_ROOT_DIRECTORY="/home/ncDocConverter/"
|
||||||
|
## You can set theses for example in jenkins.
|
||||||
|
|
||||||
|
# Directory in which the executable file should be installed
|
||||||
|
ROOT_DIRECTORY="/usr/share/RPJosh/ncDocConverter/"
|
||||||
|
|
||||||
|
# Configuration directory containing the configuration file
|
||||||
|
CONFIGURATION_DIRECTORY="/etc/ncDocConverter/"
|
||||||
|
|
||||||
|
# User to execute the program
|
||||||
|
USER=ncDocConverter
|
||||||
|
|
||||||
|
# The service name for systemctl
|
||||||
|
SERVICE_NAME=ncDocConverter
|
||||||
|
|
||||||
|
# Arch and operating system
|
||||||
|
ARCH="amd64"
|
||||||
|
|
||||||
|
version="$(cat VERSION)"
|
||||||
|
|
||||||
|
overwriteVars() {
|
||||||
|
vars=( ROOT_DIRECTORY CONFIGURATION_DIRECTORY USER SERVICE_NAME )
|
||||||
|
for var in "${vars[@]}"; do
|
||||||
|
envVar="NC_DOC_CONVERTER_"$var""
|
||||||
|
#envVar="$(eval "echo \$$envVar")"
|
||||||
|
envVar="${!envVar}"
|
||||||
|
if [ -n "$envVar" ]; then
|
||||||
|
declare -g $var="$envVar"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
# Overwrite environment variables
|
||||||
|
overwriteVars
|
||||||
|
set -e
|
||||||
|
|
||||||
|
## Stop service
|
||||||
|
systemctl is-active --quiet "$SERVICE_NAME" && systemctl stop "$SERVICE_NAME"
|
||||||
|
|
||||||
|
## Copy binary
|
||||||
|
mkdir -p "$ROOT_DIRECTORY"
|
||||||
|
cp "ncDocConverth-"$version"-"$ARCH"" ""$ROOT_DIRECTORY"ncDocConverth"
|
||||||
|
chown -R ""$USER":"$USER"" "$ROOT_DIRECTORY"
|
||||||
|
|
||||||
|
## Copy configuration
|
||||||
|
mkdir -p "$CONFIGURATION_DIRECTORY"
|
||||||
|
if ! [ -e ""$CONFIGURATION_DIRECTORY"config.yaml" ]; then
|
||||||
|
cp ./configs/config.yaml ""$CONFIGURATION_DIRECTORY"config.yaml.example"
|
||||||
|
cp ./configs/ncConverter.hjson ""$CONFIGURATION_DIRECTORY"config.hjson.example"
|
||||||
|
fi
|
||||||
|
chown -R ""$USER":"$USER"" "$CONFIGURATION_DIRECTORY"
|
||||||
|
chmod -R 0600 "$CONFIGURATION_DIRECTORY"
|
||||||
|
chmod 0700 "$CONFIGURATION_DIRECTORY"
|
||||||
|
|
||||||
|
## Start service
|
||||||
|
systemctl start "$SERVICE_NAME"
|
||||||
|
|
||||||
|
exit 0
|
Loading…
Reference in New Issue