mirror of
https://github.com/semaphoreui/semaphore.git
synced 2025-01-20 23:39:56 +01:00
Merge branch 'develop' into gometalinter
This commit is contained in:
commit
9931f15cd5
@ -1,94 +1,253 @@
|
||||
# This configuration was automatically generated from a CircleCI 1.0 config.
|
||||
# Workflow based configuration
|
||||
version: 2
|
||||
|
||||
aliases:
|
||||
|
||||
- &golang-image
|
||||
image: circleci/golang:1.10
|
||||
|
||||
- &working-dir
|
||||
/go/src/github.com/ansible-semaphore/semaphore
|
||||
|
||||
- &store-bin-artifacts
|
||||
store_artifacts:
|
||||
path: /go/src/github.com/ansible-semaphore/semaphore/bin
|
||||
|
||||
- &install-task-binary
|
||||
run:
|
||||
name: install task binary
|
||||
command: |
|
||||
cd /go/bin
|
||||
curl -L https://github.com/go-task/task/releases/download/v2.0.1/task_linux_amd64.tar.gz | tar xvz
|
||||
cd -
|
||||
|
||||
- &persist-bin
|
||||
persist_to_workspace:
|
||||
root: .
|
||||
paths:
|
||||
- bin/*
|
||||
|
||||
- &install-node
|
||||
run:
|
||||
name: Install node
|
||||
command: |
|
||||
set +e
|
||||
curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.5/install.sh | bash
|
||||
export NVM_DIR="$HOME/.nvm"
|
||||
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
|
||||
nvm install 8.2.0 && nvm alias default 8.2.0
|
||||
# Each step uses the same `$BASH_ENV`, so need to modify it
|
||||
echo 'export NVM_DIR="$HOME/.nvm"' >> $BASH_ENV
|
||||
echo "[ -s \"$NVM_DIR/nvm.sh\" ] && . \"$NVM_DIR/nvm.sh\"" >> $BASH_ENV
|
||||
|
||||
- &test-compile-changes
|
||||
run:
|
||||
name: test that compile did not create/modify untracked files
|
||||
command: git diff --exit-code --stat -- . ':(exclude)web/package-lock.json'
|
||||
|
||||
- &save-npm-cache
|
||||
save_cache:
|
||||
key: v1-npm-deps-{{ checksum "web/package.json" }}
|
||||
paths:
|
||||
- web/node_modules
|
||||
|
||||
- &save-go-cache
|
||||
save_cache:
|
||||
key: v1-go-deps-{{ checksum "Gopkg.lock" }}-{{ checksum "Gopkg.toml" }}
|
||||
paths:
|
||||
- vendor
|
||||
|
||||
- &load-npm-cache
|
||||
restore_cache:
|
||||
keys:
|
||||
- v1-npm-deps-{{ checksum "web/package.json" }}
|
||||
- v1-npm-deps-
|
||||
|
||||
- &load-go-cache
|
||||
restore_cache:
|
||||
keys:
|
||||
- v1-go-deps-{{ checksum "Gopkg.lock" }}-{{ checksum "Gopkg.toml" }}
|
||||
- v1-go-deps-{{ checksum "Gopkg.lock" }}
|
||||
- v1-go-deps-
|
||||
|
||||
jobs:
|
||||
build:
|
||||
machine: true
|
||||
# we hard code this because even in a fork our code references the canonical import urls
|
||||
working_directory: ~/.go_workspace/src/github.com/ansible-semaphore/semaphore
|
||||
build:local:
|
||||
docker:
|
||||
- *golang-image
|
||||
working_directory: *working-dir
|
||||
steps:
|
||||
# Remove go and restore the dependency cache
|
||||
- run: sudo rm -rf /usr/local/go
|
||||
- run: mkdir -p ${GOPATH}/bin
|
||||
- restore_cache:
|
||||
keys:
|
||||
# This branch if available
|
||||
- v4-dep-{{ .Branch }}-
|
||||
# Default branch if not
|
||||
- v4-dep-develop-
|
||||
# Any branch if there are none on the default branch - this should be unnecessary if you have your default branch configured correctly
|
||||
- v4-dep-
|
||||
- run: sudo apt-get update
|
||||
- run: sudo apt-get install rpm
|
||||
# Install node and go
|
||||
- run:
|
||||
name: Install node
|
||||
command: |
|
||||
set +e
|
||||
curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.5/install.sh | bash
|
||||
export NVM_DIR="/opt/circleci/.nvm"
|
||||
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
|
||||
nvm install 8.2.0 && nvm alias default 8.2.0
|
||||
# Each step uses the same `$BASH_ENV`, so need to modify it
|
||||
echo 'export NVM_DIR="/opt/circleci/.nvm"' >> $BASH_ENV
|
||||
echo "[ -s \"$NVM_DIR/nvm.sh\" ] && . \"$NVM_DIR/nvm.sh\"" >> $BASH_ENV
|
||||
- run: sudo curl -L https://storage.googleapis.com/golang/go1.10.linux-amd64.tar.gz > /tmp/go.tar.gz
|
||||
- run: sudo tar -C /usr/local -xzf /tmp/go.tar.gz
|
||||
# Needed for task orchestration
|
||||
- run: go get -u -v github.com/go-task/task/cmd/task
|
||||
# Needed only in ci to post coverage reports
|
||||
- run: go get github.com/schrej/godacov
|
||||
# Get app and install all its deps
|
||||
- checkout
|
||||
# Circle can provide a concatenated gopath and the second item is not actually in the path
|
||||
# which will cause builds to fail if deps are placed there
|
||||
- run: GOPATH=/home/circleci/.go_workspace task deps
|
||||
- run: task deps:docker
|
||||
# Save dependency cache
|
||||
- save_cache:
|
||||
key: v4-dep-{{ .Branch }}-{{ epoch }}
|
||||
paths:
|
||||
- ~/.go_workspace/src/github.com/ansible-semaphore/semaphore
|
||||
- ~/.go_workspace/bin
|
||||
- /opt/circleci/.nvm
|
||||
# Post cache compile
|
||||
- run: task compile
|
||||
- run: task lint:be
|
||||
# Test
|
||||
# This looks like utter filth in circleci v2 but we have no choice apart from this escaping madness
|
||||
- run: "cat > config.json <<EOF\n{\n\t\"mysql\": {\n\t\t\"host\": \"0.0.0.0:3306\"\
|
||||
,\n\t\t\"user\": \"root\",\n\t\t\"pass\": \"\",\n\t\t\"name\": \"circle_test\"\
|
||||
\n\t},\n\t\"email_alert\": false\n}\nEOF\n"
|
||||
- run: |
|
||||
docker run -d -p "3306:3306" --health-cmd='mysqladmin ping --silent' -e MYSQL_ALLOW_EMPTY_PASSWORD=true -e MYSQL_DATABASE=circle_test --name=mysql mysql:5.6
|
||||
function getContainerHealth {
|
||||
docker inspect --format "{{json .State.Health.Status }}" $1
|
||||
}
|
||||
- run: export
|
||||
- *install-node
|
||||
- *install-task-binary
|
||||
- checkout
|
||||
- *load-go-cache
|
||||
- *load-npm-cache
|
||||
- run: task deps
|
||||
- *save-go-cache
|
||||
- *save-npm-cache
|
||||
- run: task compile
|
||||
- *test-compile-changes
|
||||
- run: task build:local
|
||||
- *store-bin-artifacts
|
||||
- *persist-bin
|
||||
|
||||
function waitContainer {
|
||||
while STATUS=$(getContainerHealth $1); [ $STATUS != "\"healthy\"" ]; do
|
||||
if [ $STATUS == "\"unhealthy\"" ]; then
|
||||
exit -1
|
||||
fi
|
||||
printf .
|
||||
sleep 1
|
||||
done
|
||||
}
|
||||
build:
|
||||
docker:
|
||||
- *golang-image
|
||||
working_directory: *working-dir
|
||||
steps:
|
||||
- *install-node
|
||||
- *install-task-binary
|
||||
- run: sudo apt-get install rpm
|
||||
- checkout
|
||||
- *load-go-cache
|
||||
- *load-npm-cache
|
||||
- run: task deps
|
||||
- run: task compile
|
||||
- *test-compile-changes
|
||||
- run: task build
|
||||
- *store-bin-artifacts
|
||||
|
||||
# Run goverage and post results
|
||||
test:golang:
|
||||
docker:
|
||||
- *golang-image
|
||||
working_directory: *working-dir
|
||||
steps:
|
||||
- *install-task-binary
|
||||
# Needed only in ci to post coverage reports
|
||||
- run: go get github.com/schrej/godacov
|
||||
- checkout
|
||||
- *load-go-cache
|
||||
- run: task deps:tools
|
||||
- run: task deps:be
|
||||
- run: task compile:be
|
||||
- run: task lint:be
|
||||
- run: task test
|
||||
- run: godacov -t "${CODACY_TOKEN}" -r ./coverage.out -c "${CIRCLE_SHA1}" || true
|
||||
- store_test_results:
|
||||
path: /go/src/github.com/ansible-semaphore/semaphore/coverage.out
|
||||
- store_artifacts:
|
||||
path: /go/src/github.com/ansible-semaphore/semaphore/coverage.out
|
||||
|
||||
test:integration:
|
||||
docker:
|
||||
- *golang-image
|
||||
- image: circleci/mysql
|
||||
working_directory: *working-dir
|
||||
steps:
|
||||
- attach_workspace:
|
||||
at: *working-dir
|
||||
# This looks like utter filth in circleci v2 but we have no choice apart from this escaping madness
|
||||
- run: "cat > config.json <<EOF\n{\n\t\"mysql\": {\n\t\t\"host\": \"127.0.0.1:3306\"\
|
||||
,\n\t\t\"user\": \"root\",\n\t\t\"pass\": \"\",\n\t\t\"name\": \"circle_test\"\
|
||||
\n\t},\n\t\"email_alert\": false\n}\nEOF\n"
|
||||
- run:
|
||||
name: Wait for db
|
||||
command: dockerize -wait tcp://127.0.0.1:3306 -timeout 1m
|
||||
- run: bin/semaphore --migrate -config config.json
|
||||
# TODO - Here we could do some api/functional testing
|
||||
|
||||
test:docker:
|
||||
docker:
|
||||
- *golang-image
|
||||
steps:
|
||||
- *install-task-binary
|
||||
- checkout
|
||||
- setup_remote_docker
|
||||
- run: context=prod task docker:test
|
||||
|
||||
deploy:dev:
|
||||
docker:
|
||||
- *golang-image
|
||||
steps:
|
||||
- *install-task-binary
|
||||
- checkout
|
||||
- setup_remote_docker
|
||||
- run: docker login -u $DOCKER_USER -p $DOCKER_PASS
|
||||
- run: context=prod tag=develop task docker:build
|
||||
- run: tag=develop task docker:push
|
||||
|
||||
deploy:prod:
|
||||
docker:
|
||||
- *golang-image
|
||||
steps:
|
||||
- *install-task-binary
|
||||
- checkout
|
||||
- setup_remote_docker
|
||||
- run: docker login -u $DOCKER_USER -p $DOCKER_PASS
|
||||
- run: context=prod tag=latest task docker:build
|
||||
- run: tag=latest task docker:push
|
||||
- docker tag ansiblesemaphore/semaphore:latest ansiblesemaphore/semaphore:$CIRCLE_TAG
|
||||
- run: tag=$CIRCLE_TAG task docker:push
|
||||
|
||||
release:
|
||||
docker:
|
||||
- *golang-image
|
||||
working_directory: *working-dir
|
||||
steps:
|
||||
- *install-node
|
||||
- *install-task-binary
|
||||
- run: sudo apt-get install rpm
|
||||
- checkout
|
||||
- *load-go-cache
|
||||
- *load-npm-cache
|
||||
- run: task deps
|
||||
- run: task compile
|
||||
- *test-compile-changes
|
||||
- run: task release
|
||||
- *store-bin-artifacts
|
||||
|
||||
|
||||
workflows:
|
||||
version: 2
|
||||
build-deploy:
|
||||
jobs:
|
||||
- test:docker
|
||||
- test:golang
|
||||
- build:local
|
||||
- test:integration:
|
||||
requires:
|
||||
- build:local
|
||||
|
||||
# Don't build on master because build is just a gorelease without the release
|
||||
- build:
|
||||
requires:
|
||||
- test:golang
|
||||
- test:integration
|
||||
filters:
|
||||
branches:
|
||||
ignore: master
|
||||
|
||||
# Dev deploys require all tests to pass and app builds
|
||||
- deploy:dev:
|
||||
requires:
|
||||
- build
|
||||
- test:docker
|
||||
filters:
|
||||
branches:
|
||||
only: develop
|
||||
|
||||
# Production deploys only happen if everything passes
|
||||
# and we have a tag starting with v
|
||||
- release:
|
||||
requires:
|
||||
- test:golang
|
||||
- test:integration
|
||||
filters:
|
||||
branches:
|
||||
only: master
|
||||
tags:
|
||||
only: /^v.*/
|
||||
|
||||
# This deploy also happens on develop so we can publish beta/rc images
|
||||
- deploy:prod:
|
||||
requires:
|
||||
- test:docker
|
||||
- release
|
||||
filters:
|
||||
branches:
|
||||
ignore: /.*/
|
||||
tags:
|
||||
only: /^v.*/
|
||||
|
||||
waitContainer mysql
|
||||
- run: go run cli/main.go --migrate -config config.json
|
||||
- run: docker stop mysql && docker rm mysql
|
||||
- run: task test
|
||||
- run: context=prod task docker:test
|
||||
# Build artifacts for all architectures
|
||||
- run: task build
|
||||
# Post coverage
|
||||
- run: godacov -t "${CODACY_TOKEN}" -r ./coverage.out -c "${CIRCLE_SHA1}" || true
|
||||
# Teardown
|
||||
# Save test results
|
||||
- store_test_results:
|
||||
path: ~/.go_workspace/src/github.com/ansible-semaphore/semaphore/coverage.out
|
||||
# Save artifacts
|
||||
- store_artifacts:
|
||||
path: ~/.go_workspace/src/github.com/ansible-semaphore/semaphore/bin
|
||||
- store_artifacts:
|
||||
path: ~/.go_workspace/src/github.com/ansible-semaphore/semaphore/coverage.out
|
||||
|
3
.gitignore
vendored
3
.gitignore
vendored
@ -9,7 +9,8 @@ config.json
|
||||
node_modules/
|
||||
|
||||
.idea/
|
||||
bin/
|
||||
/bin/
|
||||
|
||||
*-packr.go
|
||||
util/version.go
|
||||
/vendor/
|
||||
|
@ -34,7 +34,6 @@ git clone --recursive git@github.com:ansible-semaphore/semaphore.git && cd semap
|
||||
3) Install dev dependencies
|
||||
|
||||
```
|
||||
go get ./...
|
||||
go get -u github.com/go-task/task/cmd/task
|
||||
task deps
|
||||
```
|
||||
|
@ -6,6 +6,7 @@
|
||||
[![semaphore on discord](https://img.shields.io/badge/discord-semaphore%20community-738bd7.svg)](https://discord.gg/ZW7Qu6a)
|
||||
|
||||
- [Releases](https://github.com/ansible-semaphore/semaphore/releases)
|
||||
- [Docker Hub](https://hub.docker.com/r/ansiblesemaphore/semaphore/)
|
||||
- [Install Instructions](https://github.com/ansible-semaphore/semaphore/wiki/Installation)
|
||||
- [Troubleshooting](https://github.com/ansible-semaphore/semaphore/wiki/Troubleshooting)
|
||||
- [Contribution Guide](https://github.com/ansible-semaphore/semaphore/blob/develop/CONTRIBUTING.md)
|
||||
|
34
Taskfile.yml
34
Taskfile.yml
@ -5,6 +5,10 @@
|
||||
# internally by other tasks and therefore are not listed when running `task` or `task -l`
|
||||
version: '2'
|
||||
|
||||
vars:
|
||||
docker_namespace: ansiblesemaphore
|
||||
docker_image: semaphore
|
||||
|
||||
tasks:
|
||||
all:
|
||||
desc: Install, Compile, Test and Build Semaphore for local architecture
|
||||
@ -30,7 +34,6 @@ tasks:
|
||||
desc: Installs npm requirements for front end from package.json
|
||||
dir: web
|
||||
cmds:
|
||||
- npm i -g less pug-cli
|
||||
- npm install
|
||||
|
||||
deps:tools:
|
||||
@ -39,13 +42,12 @@ tasks:
|
||||
vars:
|
||||
GORELEASER_VERSION: "0.62.5"
|
||||
cmds:
|
||||
- npm install -g nodemon
|
||||
- go get -u github.com/golang/dep/cmd/dep
|
||||
- go get github.com/cespare/reflex || true
|
||||
- go get -u github.com/gobuffalo/packr/...
|
||||
- go get -u github.com/haya14busa/goverage
|
||||
- '{{ if ne OS "windows" }} curl -L https://github.com/goreleaser/goreleaser/releases/download/v{{ .GORELEASER_VERSION }}/goreleaser_$(uname -s)_$(uname -m).tar.gz | tar -xz -C ${GOPATH}/bin{{ else }}ver>nul{{ end }}'
|
||||
- '{{ if ne OS "windows" }} chmod +x ${GOPATH}/bin/goreleaser{{ else }}ver>nul{{ end }}'
|
||||
- '{{ if ne OS "windows" }} curl -L https://github.com/goreleaser/goreleaser/releases/download/v{{ .GORELEASER_VERSION }}/goreleaser_$(uname -s)_$(uname -m).tar.gz | tar -xz -C ${GOPATH}/bin{{ else }} {{ end }}'
|
||||
- '{{ if ne OS "windows" }} chmod +x ${GOPATH}/bin/goreleaser{{ else }} {{ end }}'
|
||||
- '{{ if eq OS "windows" }} echo "NOTICE: You must download goreleaser manually to build this application https://github.com/goreleaser/goreleaser/releases "{{ else }}:{{ end }}'
|
||||
- go get -u github.com/alecthomas/gometalinter
|
||||
- gometalinter --install
|
||||
@ -69,8 +71,8 @@ tasks:
|
||||
- public/html/**/*.html
|
||||
- bundle.json
|
||||
cmds:
|
||||
- lessc resources/less/semaphore.less > public/css/semaphore.css
|
||||
- pug resources/pug --out public/html
|
||||
- ./node_modules/.bin/lessc resources/less/semaphore.less > public/css/semaphore.css
|
||||
- ./node_modules/.bin/pug resources/pug --out public/html
|
||||
- cp node_modules/font-awesome/fonts/* public/fonts
|
||||
- node bundler.js
|
||||
|
||||
@ -91,7 +93,8 @@ tasks:
|
||||
BRANCH:
|
||||
sh: git rev-parse --abbrev-ref HEAD
|
||||
DIRTY:
|
||||
sh: git status --porcelain
|
||||
# We must exclude the package-lock file as npm install can change it!
|
||||
sh: git diff --exit-code --stat -- . ':(exclude)web/package-lock.json'
|
||||
SHA:
|
||||
sh: git log --pretty=format:'%h' -n 1
|
||||
TIMESTAMP:
|
||||
@ -111,9 +114,9 @@ tasks:
|
||||
watch:fe:
|
||||
dir: web
|
||||
cmds:
|
||||
- nodemon -w js -i bundle.js -e js bundler.js &
|
||||
- nodemon -w css -e less --exec "lessc resources/less/semaphore.less > public/css/semaphore.css" &
|
||||
- pug -w -P --doctype html resources/pug --out public/html &
|
||||
- ./node_modules/.bin/nodemon -w js -i bundle.js -e js bundler.js &
|
||||
- ./node_modules/.bin/nodemon -w css -e less --exec "lessc resources/less/semaphore.less > public/css/semaphore.css" &
|
||||
- ./node_modules/.bin/pug -w -P --doctype html resources/pug --out public/html &
|
||||
|
||||
build:
|
||||
desc: Build a full set of release binaries and packages
|
||||
@ -228,7 +231,7 @@ tasks:
|
||||
context: "{{ .context }}"
|
||||
action: build
|
||||
tag: "{{ .tag }}"
|
||||
args: -t castawaylabs/semaphore:{{ .tag }} .
|
||||
args: -t "{{ .docker_namespace }}/{{ .docker_image }}:{{ .tag }}" .
|
||||
|
||||
deps:docker:
|
||||
desc: Install docker testing dependencies. These must be installed explicitly and are not included in the general deps task.
|
||||
@ -255,13 +258,13 @@ tasks:
|
||||
vars:
|
||||
tag: "{{ .context }}-test"
|
||||
- task: docker:goss
|
||||
- docker rmi "castawaylabs/semaphore:{{ .context }}-test"
|
||||
- docker rmi "{{ .docker_namespace }}/{{ .docker_image }}:{{ .context }}-test"
|
||||
|
||||
docker:goss:
|
||||
dir: "deployment/docker/{{ .context}}"
|
||||
deps: ['deps:docker']
|
||||
cmds:
|
||||
- GOSS_FILES_STRATEGY='cp' dgoss run -it "castawaylabs/semaphore:{{ .context }}-test"
|
||||
- GOSS_FILES_STRATEGY='cp' dgoss run -it "{{ .docker_namespace }}/{{ .docker_image }}:{{ .context }}-test"
|
||||
|
||||
docker:lint:
|
||||
desc: hadolint a dockerfile. Ignores version pinning warning
|
||||
@ -269,6 +272,11 @@ tasks:
|
||||
cmds:
|
||||
- hadolint Dockerfile --ignore DL3018
|
||||
|
||||
docker:push:
|
||||
desc: push a docker image to a repo. Defaults to the official docker hub
|
||||
cmds:
|
||||
- docker push {{ .docker_namespace }}/{{ .docker_image }}:{{ .tag }}
|
||||
|
||||
# templated command to reduce code duplication
|
||||
docker:
|
||||
vars:
|
||||
|
@ -1,6 +1,6 @@
|
||||
# Docker Deployments
|
||||
|
||||
Production images for each tag, latest and the development branch will be pushed to [docker hub](https://hub.docker.com/r/castawaylabs/semaphore).
|
||||
Production images for each tag, latest and the development branch will be pushed to [docker hub](https://hub.docker.com/r/ansiblesemaphore/semaphore).
|
||||
To build images locally see the contexts included here and use the `d` and `dc` tasks in the root Taskfile.yml to help with building and running.
|
||||
|
||||
## Contexts
|
||||
@ -11,7 +11,7 @@ To build a production image you should run
|
||||
|
||||
context=prod task docker:build
|
||||
|
||||
this will create an image called `castawaylabs/semaphore:latest` which will be compiled from the currently checked out code
|
||||
this will create an image called `ansiblesemaphore/semaphore:latest` which will be compiled from the currently checked out code
|
||||
|
||||
This image is run as non root user 1001 (for PaaS systems such as openshift) and is build on alpine with added glibc.
|
||||
With ansible etc... installed in the container it is ~283MiB in size.
|
||||
|
@ -10,7 +10,7 @@ services:
|
||||
MYSQL_PASSWORD: semaphore
|
||||
|
||||
semaphore_dev:
|
||||
image: castawaylabs/semaphore-dev:latest
|
||||
image: ansiblesemaphore/semaphore:dev-compose
|
||||
build:
|
||||
context: ./../../../
|
||||
dockerfile: ./deployment/docker/dev/Dockerfile
|
||||
|
@ -8,7 +8,6 @@ export PATH="${PATH}:${GOBIN}"
|
||||
|
||||
# Get prerequisites for building the app
|
||||
go get -u -v github.com/go-task/task/cmd/task
|
||||
go get ./...
|
||||
|
||||
# Compile and build
|
||||
task deps
|
||||
|
@ -13,7 +13,7 @@ services:
|
||||
MYSQL_PASSWORD: hx4hjxqthfwbfsy5535u4agfdscm
|
||||
|
||||
semaphore:
|
||||
image: castawaylabs/semaphore:prod
|
||||
image: ansiblesemaphore/semaphore:prod-compose
|
||||
build:
|
||||
context: ./../../../
|
||||
dockerfile: ./deployment/docker/prod/Dockerfile
|
||||
@ -31,7 +31,7 @@ services:
|
||||
depends_on:
|
||||
- mysql
|
||||
semaphore_proxy:
|
||||
image: castawaylabs/semaphore:proxy
|
||||
image: ansiblesemaphore/proxy:latest
|
||||
build:
|
||||
context: ./proxy
|
||||
ports:
|
||||
|
@ -19,7 +19,11 @@
|
||||
"requirejs": "^2.3.5",
|
||||
"sweetalert": "^2.1.0"
|
||||
},
|
||||
"devDependencies": {},
|
||||
"devDependencies": {
|
||||
"less": "^3.0.1",
|
||||
"pug-cli": "^1.0.0-alpha6",
|
||||
"nodemon": "^1.17.2"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
|
@ -5,7 +5,7 @@ define(function () {
|
||||
$scope.alert_chat = Project.alert_chat;
|
||||
|
||||
$scope.save = function (name, alert, alert_chat) {
|
||||
$http.put(Project.getURL(), { name: name, alert: alert, alert_chat: alert_chat}).then(function () {
|
||||
$http.put(Project.getURL(), {name: name, alert: alert, alert_chat: alert_chat}).then(function () {
|
||||
swal('Saved', 'Project settings saved.', 'success');
|
||||
}).catch(function () {
|
||||
swal('Error', 'Project settings were not saved', 'error');
|
||||
@ -16,15 +16,28 @@ define(function () {
|
||||
swal({
|
||||
title: 'Delete Project?',
|
||||
text: 'All data related to this project will be deleted.',
|
||||
type: 'warning',
|
||||
showCancelButton: true,
|
||||
confirmButtonColor: "#DD6B55",
|
||||
confirmButtonText: 'Yes, DELETE'
|
||||
}, function () {
|
||||
$http.delete(Project.getURL()).then(function () {
|
||||
$state.go('dashboard');
|
||||
}).catch(function () {
|
||||
swal('error', 'could not delete project!', 'error');
|
||||
icon: 'warning',
|
||||
buttons: {
|
||||
cancel: true,
|
||||
confirm: {
|
||||
text: 'Yes, DELETE',
|
||||
closeModal: false,
|
||||
className: 'bg-danger',
|
||||
},
|
||||
},
|
||||
}).then(function (value) {
|
||||
if (!value) {
|
||||
return;
|
||||
}
|
||||
|
||||
$http.delete(Project.getURL())
|
||||
.then(function () {
|
||||
swal.stopLoading();
|
||||
swal.close();
|
||||
|
||||
$state.go('dashboard');
|
||||
}).catch(function () {
|
||||
swal('Error', 'Could not delete project!', 'error');
|
||||
});
|
||||
});
|
||||
}
|
||||
|
@ -7,30 +7,46 @@ define(function () {
|
||||
}
|
||||
|
||||
$scope.remove = function (environment) {
|
||||
$http.delete(Project.getURL() + '/environment/' + environment.id).then(function () {
|
||||
$scope.reload();
|
||||
}).catch(function (response) {
|
||||
var d = response.data;
|
||||
if (!(d && d.inUse)) {
|
||||
swal('error', 'could not delete environment..', 'error');
|
||||
return;
|
||||
}
|
||||
|
||||
swal({
|
||||
title: 'Environment in use',
|
||||
text: d.error,
|
||||
type: 'error',
|
||||
showCancelButton: true,
|
||||
confirmButtonColor: "#DD6B55",
|
||||
confirmButtonText: 'Mark as removed'
|
||||
}, function () {
|
||||
$http.delete(Project.getURL() + '/environment/' + environment.id + '?setRemoved=1').then(function () {
|
||||
$scope.reload();
|
||||
}).catch(function () {
|
||||
$http.delete(Project.getURL() + '/environment/' + environment.id)
|
||||
.then(function () {
|
||||
$scope.reload();
|
||||
})
|
||||
.catch(function (response) {
|
||||
var d = response.data;
|
||||
if (!(d && d.inUse)) {
|
||||
swal('error', 'could not delete environment..', 'error');
|
||||
return;
|
||||
}
|
||||
|
||||
swal({
|
||||
title: 'Environment in use',
|
||||
text: d.error,
|
||||
icon: 'error',
|
||||
buttons: {
|
||||
cancel: true,
|
||||
confirm: {
|
||||
text: 'Mark as removed',
|
||||
closeModel: false,
|
||||
className: 'bg-danger',
|
||||
}
|
||||
}
|
||||
}).then(function (value) {
|
||||
if (!value) {
|
||||
return;
|
||||
}
|
||||
|
||||
$http.delete(Project.getURL() + '/environment/' + environment.id + '?setRemoved=1')
|
||||
.then(function () {
|
||||
swal.stopLoading();
|
||||
swal.close();
|
||||
|
||||
$scope.reload();
|
||||
})
|
||||
.catch(function () {
|
||||
swal('Error', 'Could not delete environment..', 'error');
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
$scope.add = function () {
|
||||
@ -44,12 +60,13 @@ define(function () {
|
||||
scope: scope
|
||||
}).result.then(function (env) {
|
||||
$http.post(Project.getURL() + '/environment', env.environment)
|
||||
.then(function () {
|
||||
$scope.reload();
|
||||
}).catch(function (response) {
|
||||
.then(function () {
|
||||
$scope.reload();
|
||||
}).catch(function (response) {
|
||||
swal('Error', 'Environment not added: ' + response.status, 'error');
|
||||
});
|
||||
}, function () {});
|
||||
}, function () {
|
||||
});
|
||||
}
|
||||
|
||||
$scope.editEnvironment = function (env) {
|
||||
@ -65,12 +82,13 @@ define(function () {
|
||||
}
|
||||
|
||||
$http.put(Project.getURL() + '/environment/' + env.id, opts.environment)
|
||||
.then(function () {
|
||||
$scope.reload();
|
||||
}).catch(function (response) {
|
||||
.then(function () {
|
||||
$scope.reload();
|
||||
}).catch(function (response) {
|
||||
swal('Error', 'Environment not updated: ' + response.status, 'error');
|
||||
});
|
||||
}, function () {});
|
||||
}, function () {
|
||||
});
|
||||
}
|
||||
|
||||
$scope.reload();
|
||||
|
@ -7,30 +7,47 @@ define(function () {
|
||||
}
|
||||
|
||||
$scope.remove = function (inventory) {
|
||||
$http.delete(Project.getURL() + '/inventory/' + inventory.id).then(function () {
|
||||
$scope.reload();
|
||||
}).catch(function (response) {
|
||||
var d = response.data;
|
||||
if (!(d && d.inUse)) {
|
||||
swal('error', 'could not delete inventory..', 'error');
|
||||
return;
|
||||
}
|
||||
|
||||
swal({
|
||||
title: 'Inventory in use',
|
||||
text: d.error,
|
||||
type: 'error',
|
||||
showCancelButton: true,
|
||||
confirmButtonColor: "#DD6B55",
|
||||
confirmButtonText: 'Mark as removed'
|
||||
}, function () {
|
||||
$http.delete(Project.getURL() + '/inventory/' + inventory.id + '?setRemoved=1').then(function () {
|
||||
$scope.reload();
|
||||
}).catch(function () {
|
||||
$http.delete(Project.getURL() + '/inventory/' + inventory.id)
|
||||
.then(function () {
|
||||
$scope.reload();
|
||||
})
|
||||
.catch(function (response) {
|
||||
var d = response.data;
|
||||
if (!(d && d.inUse)) {
|
||||
swal('error', 'could not delete inventory..', 'error');
|
||||
return;
|
||||
}
|
||||
|
||||
swal({
|
||||
title: 'Inventory in use',
|
||||
text: d.error,
|
||||
icon: 'error',
|
||||
buttons: {
|
||||
cancel: true,
|
||||
confirm: {
|
||||
text: 'Mark as removed',
|
||||
closeModel: false,
|
||||
className: 'bg-danger',
|
||||
}
|
||||
}
|
||||
}).then(function (value) {
|
||||
if (!value) {
|
||||
return;
|
||||
}
|
||||
|
||||
$http
|
||||
.delete(Project.getURL() + '/inventory/' + inventory.id + '?setRemoved=1')
|
||||
.then(function () {
|
||||
swal.stopLoading();
|
||||
swal.close();
|
||||
|
||||
$scope.reload();
|
||||
})
|
||||
.catch(function () {
|
||||
swal('Error', 'Could not delete inventory..', 'error');
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
$scope.add = function () {
|
||||
@ -43,12 +60,13 @@ define(function () {
|
||||
scope: scope
|
||||
}).result.then(function (inventory) {
|
||||
$http.post(Project.getURL() + '/inventory', inventory.inventory)
|
||||
.then(function () {
|
||||
$scope.reload();
|
||||
}).catch(function (response) {
|
||||
.then(function () {
|
||||
$scope.reload();
|
||||
}).catch(function (response) {
|
||||
swal('Error', 'Inventory not added: ' + response.status, 'error');
|
||||
});
|
||||
}, function () {});
|
||||
}, function () {
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@ -68,12 +86,13 @@ define(function () {
|
||||
}
|
||||
|
||||
$http.put(Project.getURL() + '/inventory/' + inventory.id, opts.inventory)
|
||||
.then(function () {
|
||||
$scope.reload();
|
||||
}).catch(function (response) {
|
||||
.then(function () {
|
||||
$scope.reload();
|
||||
}).catch(function (response) {
|
||||
swal('Error', 'Inventory not updated: ' + response.status, 'error');
|
||||
});
|
||||
}, function () {});
|
||||
}, function () {
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@ -87,16 +106,19 @@ define(function () {
|
||||
}).result.then(function (v) {
|
||||
inventory.inventory = v;
|
||||
$http.put(Project.getURL() + '/inventory/' + inventory.id, inventory)
|
||||
.then(function () {
|
||||
$scope.reload();
|
||||
}).catch(function (response) {
|
||||
.then(function () {
|
||||
$scope.reload();
|
||||
}).catch(function (response) {
|
||||
swal('Error', 'Inventory not updated: ' + response.status, 'error');
|
||||
});
|
||||
}, function () {});
|
||||
}, function () {
|
||||
});
|
||||
}
|
||||
|
||||
$scope.getKeys = function (cb) {
|
||||
if (typeof cb != 'function') cb = function () {}
|
||||
if (typeof cb != 'function') {
|
||||
cb = function () {};
|
||||
}
|
||||
|
||||
$http.get(Project.getURL() + '/keys?type=ssh').then(function (keys) {
|
||||
cb(keys.data);
|
||||
|
@ -7,31 +7,47 @@ define(function () {
|
||||
}
|
||||
|
||||
$scope.remove = function (key) {
|
||||
$http.delete(Project.getURL() + '/keys/' + key.id).then(function () {
|
||||
$scope.reload();
|
||||
}).catch(function (response) {
|
||||
var d = response.data;
|
||||
$http.delete(Project.getURL() + '/keys/' + key.id)
|
||||
.then(function () {
|
||||
$scope.reload();
|
||||
})
|
||||
.catch(function (response) {
|
||||
var d = response.data;
|
||||
|
||||
if (!(d && d.inUse)) {
|
||||
swal('error', 'could not delete key..', 'error');
|
||||
return;
|
||||
}
|
||||
if (!(d && d.inUse)) {
|
||||
swal('error', 'could not delete key..', 'error');
|
||||
return;
|
||||
}
|
||||
|
||||
swal({
|
||||
title: 'Key in use',
|
||||
text: d.error,
|
||||
type: 'error',
|
||||
showCancelButton: true,
|
||||
confirmButtonColor: "#DD6B55",
|
||||
confirmButtonText: 'Mark as removed'
|
||||
}, function () {
|
||||
$http.delete(Project.getURL() + '/keys/' + key.id + '?setRemoved=1').then(function () {
|
||||
$scope.reload();
|
||||
}).catch(function () {
|
||||
swal('error', 'could not remove key..', 'error');
|
||||
swal({
|
||||
title: 'Key in use',
|
||||
text: d.error,
|
||||
icon: 'error',
|
||||
buttons: {
|
||||
cancel: true,
|
||||
confirm: {
|
||||
text: 'Mark as removed',
|
||||
closeModel: false,
|
||||
className: 'bg-danger',
|
||||
}
|
||||
}
|
||||
}).then(function (value) {
|
||||
if (!value) {
|
||||
return;
|
||||
}
|
||||
|
||||
$http.delete(Project.getURL() + '/keys/' + key.id + '?setRemoved=1')
|
||||
.then(function () {
|
||||
swal.stopLoading();
|
||||
swal.close();
|
||||
|
||||
$scope.reload();
|
||||
})
|
||||
.catch(function () {
|
||||
swal('Error', 'Could not remove key..', 'error');
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
$scope.add = function () {
|
||||
@ -43,7 +59,8 @@ define(function () {
|
||||
}).catch(function (response) {
|
||||
swal('error', 'could not add key:' + response.status, 'error');
|
||||
});
|
||||
}, function () {});
|
||||
}, function () {
|
||||
});
|
||||
}
|
||||
|
||||
$scope.update = function (key) {
|
||||
@ -61,12 +78,13 @@ define(function () {
|
||||
}
|
||||
|
||||
$http.put(Project.getURL() + '/keys/' + key.id, opts.key)
|
||||
.then(function () {
|
||||
$scope.reload();
|
||||
}).catch(function (response) {
|
||||
.then(function () {
|
||||
$scope.reload();
|
||||
}).catch(function (response) {
|
||||
swal('Error', 'could not update key:' + response.status, 'error');
|
||||
});
|
||||
}, function () {});
|
||||
}, function () {
|
||||
});
|
||||
}
|
||||
|
||||
$scope.reload();
|
||||
|
@ -20,30 +20,46 @@ define(function () {
|
||||
}
|
||||
|
||||
$scope.remove = function (repo) {
|
||||
$http.delete(Project.getURL() + '/repositories/' + repo.id).then(function () {
|
||||
$scope.reload();
|
||||
}).then(function (response) {
|
||||
var d = response.data;
|
||||
if (!(d && d.templatesUse)) {
|
||||
swal('error', 'could not delete repository..', 'error');
|
||||
return;
|
||||
}
|
||||
|
||||
swal({
|
||||
title: 'Repository in use',
|
||||
text: d.error,
|
||||
type: 'error',
|
||||
showCancelButton: true,
|
||||
confirmButtonColor: "#DD6B55",
|
||||
confirmButtonText: 'Mark as removed'
|
||||
}, function () {
|
||||
$http.delete(Project.getURL() + '/repositories/' + repo.id + '?setRemoved=1').then(function () {
|
||||
$scope.reload();
|
||||
}).catch(function () {
|
||||
$http.delete(Project.getURL() + '/repositories/' + repo.id)
|
||||
.then(function () {
|
||||
$scope.reload();
|
||||
})
|
||||
.catch(function (response) {
|
||||
var d = response.data;
|
||||
if (!(d && d.templatesUse)) {
|
||||
swal('error', 'could not delete repository..', 'error');
|
||||
return;
|
||||
}
|
||||
|
||||
swal({
|
||||
title: 'Repository in use',
|
||||
text: d.error,
|
||||
icon: 'error',
|
||||
buttons: {
|
||||
cancel: true,
|
||||
confirm: {
|
||||
text: 'Mark as removed',
|
||||
closeModel: false,
|
||||
className: 'bg-danger',
|
||||
}
|
||||
}
|
||||
}).then(function (value) {
|
||||
if (!value) {
|
||||
return;
|
||||
}
|
||||
|
||||
$http.delete(Project.getURL() + '/repositories/' + repo.id + '?setRemoved=1')
|
||||
.then(function () {
|
||||
swal.stopLoading();
|
||||
swal.close();
|
||||
|
||||
$scope.reload();
|
||||
})
|
||||
.catch(function () {
|
||||
swal('Error', 'Could not delete repository..', 'error');
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
$scope.update = function (repo) {
|
||||
@ -64,7 +80,8 @@ define(function () {
|
||||
}).catch(function (response) {
|
||||
swal('Error', 'Repository not updated: ' + response.status, 'error');
|
||||
});
|
||||
}, function () {});
|
||||
}, function () {
|
||||
});
|
||||
}
|
||||
|
||||
$scope.add = function () {
|
||||
@ -76,12 +93,13 @@ define(function () {
|
||||
scope: scope
|
||||
}).result.then(function (repo) {
|
||||
$http.post(Project.getURL() + '/repositories', repo.repo)
|
||||
.then(function () {
|
||||
$scope.reload();
|
||||
}).catch(function (response) {
|
||||
.then(function () {
|
||||
$scope.reload();
|
||||
}).catch(function (response) {
|
||||
swal('Error', 'Repository not added: ' + response.status, 'error');
|
||||
});
|
||||
}, function () {});
|
||||
}, function () {
|
||||
});
|
||||
}
|
||||
|
||||
$scope.reload();
|
||||
|
Loading…
Reference in New Issue
Block a user