diff --git a/.github/workflows/prod-deploy.yml b/.github/workflows/prod-deploy.yml index f282b89b..d652c65d 100644 --- a/.github/workflows/prod-deploy.yml +++ b/.github/workflows/prod-deploy.yml @@ -6,18 +6,8 @@ on: jobs: deploy: name: Deploy to Prod - runs-on: ubuntu-latest - concurrency: deploy-group # optional: ensure only one action runs at a time + runs-on: self-hosted + #concurrency: deploy-group # optional: ensure only one action runs at a time steps: - - name: Execute remote SSH commands using password - uses: appleboy/ssh-action@v1 - with: - host: ${{ secrets.HOST }} - username: ${{ secrets.USERNAME }} - password: ${{ secrets.PASSWORD }} - script: | - cd /home/deploy/source-be - git checkout main - git pull - ./build.sh - sudo /bin/systemctl restart source-be + - name: Execute deploy script + run: cd ~/Developer/source-be-deploy && ./deploy.sh diff --git a/.gitignore b/.gitignore index 11809f10..18254b01 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,5 @@ resources/admins_encrypted.json .db admins.json +admins_encrypted.json +prod.env diff --git a/deploy.sh b/deploy.sh new file mode 100755 index 00000000..a87589db --- /dev/null +++ b/deploy.sh @@ -0,0 +1,33 @@ +#!/bin/bash + +cd ~/Developer/source-be-deploy + +echo "Pulling changes..." +git pull + +echo "Starting compilation..." +clojure -T:build uber + +echo "Creating archive..." +mkdir source-be-deploy +cp start.sh migrate.sh source-be.service deps.edn target/source-be-standalone.jar source-be-deploy +cp -r resources src source-be-deploy +cp prod.env source-be-deploy/.env +tar -czvf source-be-deploy.tar.gz ./source-be-deploy + +echo "Copying archive..." +sshpass -e scp -r ~/Developer/source-be-deploy/source-be-deploy.tar.gz deploy@api.wearesource.earth:/home/deploy +echo "Done!" + +echo "Setting up prod server..." +sshpass -e ssh deploy@api.wearesource.earth " + echo "Extracting archive..." + tar -xvzf source-be-deploy.tar.gz + + echo "Restarting service..." + sudo systemctl restart source-fe.service +" + +echo "Cleaning up..." +rm -rf source-be-deploy +rm source-be-deploy.tar.gz diff --git a/install.sh b/install.sh new file mode 100755 index 00000000..cfbc20ec --- /dev/null +++ b/install.sh @@ -0,0 +1,19 @@ +#!/bin/bash + +echo "Installing service..." +chmod +x deploy.sh +chmod +x install_runner.sh +chmod +x migrate.sh + +./deploy.sh + +sshpass -e ssh deploy@api.wearesource.earth " + cd /home/deploy/source-be-deploy + chmod +x start.sh + chmod +x migrate.sh + + sudo mv source-be.service /etc/systemd/system + sudo systemctl daemon-reload + sudo systemctl enable source-be.service + sudo systemctl start source-be.service +" diff --git a/install_runner.sh b/install_runner.sh new file mode 100755 index 00000000..d86f7b01 --- /dev/null +++ b/install_runner.sh @@ -0,0 +1,10 @@ +#!/bin/bash + +mkdir -p ~/.config/source-be/actions-runner +cd ~/.config/source-be/actions-runner + +curl -o actions-runner-linux-x64-2.334.0.tar.gz -L https://github.com/actions/runner/releases/download/v2.334.0/actions-runner-linux-x64-2.334.0.tar.gz + +tar xzf ./actions-runner-linux-x64-2.334.0.tar.gz + +./config.sh --url https://github.com/modulr-software/source-be --token AMFR4ML2O5TLDW2O5JR6KCTJ7H7U2 diff --git a/migrate.sh b/migrate.sh index 24715f2b..6138385a 100755 --- a/migrate.sh +++ b/migrate.sh @@ -2,4 +2,5 @@ export $(grep '.*' .env | xargs) +echo "Running migrations..." clojure -M:migrate "$@" diff --git a/resources/admins_encrypted.json b/resources/admins_encrypted.json deleted file mode 100644 index 1418c113..00000000 --- a/resources/admins_encrypted.json +++ /dev/null @@ -1 +0,0 @@ -1f849fdbcaaa4d5cf82b56107541fa49174399ba9cc32f67fd7eceb7f0847b8050f85973837676f7d7f8d92fa4d6cacf9e175a8fd6fff154212d1187c2888ec39e5d813d2a247e571991dc61e3ab567e796a92e0fbb7a4ee4ff62567a2c405d3008ce6fa89e6b85f7515aff0420cf59ed7e6112e232dec6952b2165f46a167d875b46ec1d1fa4f2a035112fe739607040da8f90bc8abd8f40b798020b6046535a4415e373bc1be463b447cb3218d88419b05d47d99cd053e16f985610cbe9565db3192db3c2810958176f2ebcbd8808a55e2c7e970f2f12b201ce39babdfd1ffe1cf22910395aeb8ff16a5af98896765046a0514c23b1f4fee34bc1a7ad293406151deba329de10c71b919038c165f0c848b60de52a4737ed0f27793c4bc85e7a3c1373e8982280fd53edddad4fca12eeaf212633a55c63ef457185887477ab6068957502a76932f9a267afb03f18ccacf53e52faea2fc56527fedc89570261403b9ade0a6e43e2244223a998338ca623e291ed714b133913e870f1fc07dff801e4450a0a67ac328b6b22f18ffd3ac4704a8e8d6e63dd1940a1c02b6f9c4183358585dc600857fdc0b8a72309e4edb41d1cd2fa2f450b4c6ff4dca70a2a09b9fcafac195493dc43d4d25062bee0b7b29e4fb89c592c7d0eee06724b8fd60c501a5ed49cde6a25679f86c207527c6cbc52c6c7f4215a2d1c857a4de92d14d016b \ No newline at end of file diff --git a/resources/staging_config.edn b/resources/config.edn similarity index 76% rename from resources/staging_config.edn rename to resources/config.edn index 3df88ecb..e28d267d 100644 --- a/resources/staging_config.edn +++ b/resources/config.edn @@ -1,10 +1,10 @@ {:supersecretkey #env SUPER_SECRET_KEY :admins-path "resources/admins.json" :admins-encrypted-path "resources/admins_encrypted.json" - :cors-origin #or [#env CORS_ORIGIN "https://mervstation.tail4f070.ts.net"] - :base-url #or [#env BASE_URL "https://mervstation.tail4f070.ts.net/sourcebe"] - :port #or [#env PORT 3998] - :env #or [#env ENV "staging"] + :cors-origin #or [#env CORS_ORIGIN "https://localhost:4000"] + :base-url #or [#env BASE_URL "http://localhost:3000"] + :port #or [#env PORT 3000] + :env #or [#env ENV "prod"] :database {:url #or [#env DATABASE_URL "postgres://localhost"] :type "postgresql"} :email {:address #or [#env SUPPORT_ADDRESS "lee@wearesource.earth"] @@ -12,7 +12,7 @@ :password #env EMAIL_PASSWORD} :oauth2 {:google {:authorization-uri "https://accounts.google.com/o/oauth2/auth" :access-token-uri "https://oauth2.googleapis.com/token" - :redirect-uri #or [#env GOOGLE_REDIRECT_URI "https://mervstation.tail4f070.ts.net/sourcebe/oauth2/google/callback"] + :redirect-uri #or [#env GOOGLE_REDIRECT_URI "https://api.wearesource.earth/oauth2/google/callback"] :client-id #env GOOGLE_CLIENT_ID :client-secret #env GOOGLE_CLIENT_SECRET :access-query-param :access_token diff --git a/resources/dev_config.edn b/resources/dev_config.edn deleted file mode 100644 index 5f2aed99..00000000 --- a/resources/dev_config.edn +++ /dev/null @@ -1,22 +0,0 @@ -{:supersecretkey #env SUPER_SECRET_KEY - :admins-path "resources/admins.json" - :admins-encrypted-path "resources/admins_encrypted.json" - :cors-origin #or [#env CORS_ORIGIN "http://localhost:3001"] - :base-url #or [#env BASE_URL "https://localhost:3000"] - :port #or [#env PORT 3000] - :env #or [#env ENV "dev"] - :database {:url #or [#env DATABASE_URL "postgres://localhost"] - :type "postgresql" - :staging #or [#env STAGING_DATABASE_URL "postgres://username:password@localhost:16380"] - :prod #or [#env PROD_DATABASE_URL "postgres://username:password@localhost:16380"]} - :email {:address #or [#env SUPPORT_ADDRESS "lee@wearesource.earth"] - :username #env EMAIL_USERNAME - :password #env EMAIL_PASSWORD} - :oauth2 {:google {:authorization-uri "https://accounts.google.com/o/oauth2/auth" - :access-token-uri "https://oauth2.googleapis.com/token" - :redirect-uri #or [#env GOOGLE_REDIRECT_URI "http://localhost:3000/oauth2/google/callback"] - :client-id #env GOOGLE_CLIENT_ID - :client-secret #env GOOGLE_CLIENT_SECRET - :access-query-param :access_token - :scope ["https://www.googleapis.com/auth/userinfo.email"] - :grant-type "authorization_code"}}} diff --git a/runner_config.txt b/runner_config.txt new file mode 100644 index 00000000..a3b7b785 --- /dev/null +++ b/runner_config.txt @@ -0,0 +1,4 @@ + + + +Y diff --git a/source-be.service b/source-be.service new file mode 100644 index 00000000..18abab1d --- /dev/null +++ b/source-be.service @@ -0,0 +1,12 @@ +[Unit] +Description=Source Back End Server Startup Service +After=postgresql.service + +[Service] +Type=simple +ExecStart=/home/deploy/source-be-deploy/start.sh +Restart=on-failure +RestartSec=5s + +[Install] +WantedBy=multi-user.target diff --git a/src/source/config.clj b/src/source/config.clj index 63c33154..fbba9f4f 100644 --- a/src/source/config.clj +++ b/src/source/config.clj @@ -31,9 +31,7 @@ [:oauth2 [:map-of keyword? oauth2-provider-schema]]]) (defn- load-config [] - (let [environment (get (System/getenv) "ENV") - environment (if (nil? environment) "dev" environment) - config (aero/read-config (io/resource (str environment "_config.edn"))) + (let [config (aero/read-config (io/resource "config.edn")) decoded (m/decode schema config mt/string-transformer)] (when-not (m/validate schema decoded) (println (->> decoded diff --git a/start.sh b/start.sh index 91693940..b3c46af7 100755 --- a/start.sh +++ b/start.sh @@ -1,8 +1,9 @@ #!/bin/bash + +cd /home/deploy/source-be-deploy export $(grep '.*' .env | xargs) -echo "Running migrations before startup..." -clojure -M:migrate +./migrate.sh up -echo "Starting server..." -$JAVA_CMD -jar target/source-be-standalone.jar +echo "Starting backend server..." +/home/deploy/.jenv/shims/java -jar source-be-standalone.jar diff --git a/test/source_be/cache_test.clj b/test/source_be/cache_test.clj deleted file mode 100644 index 80b9f8a8..00000000 --- a/test/source_be/cache_test.clj +++ /dev/null @@ -1,43 +0,0 @@ -(ns source-be.cache-test - (:require [clojure.test :refer :all] - [source.cache :as cache])) - -(deftest use-cache - (testing "adding, retrieving and removing values in cache by uuid" - (let [google-test-cache (cache/create-cache) - emails-test-cache (cache/create-cache) - google-result (do - (cache/add-item google-test-cache {:uri "http://yeet.com/test"} "testuuid") - (cache/get-item google-test-cache "testuuid")) - emails-result (do - (cache/add-item emails-test-cache "test@toast.com" "testuuid") - (cache/get-item emails-test-cache "testuuid"))] - - (is (= (count (cache/get-all-items google-test-cache)) 1)) - (is (= (count (cache/get-all-items emails-test-cache)) 1)) - (is (= google-result {:uri "http://yeet.com/test"})) - (is (= emails-result "test@toast.com")) - - (cache/add-item google-test-cache {:uri "http://delete.com/"} "todelete") - (cache/add-item google-test-cache {:uri "http://dontdelete.com/"}) - (is (= (count (cache/get-all-items google-test-cache)) 3)) - - (cache/add-item emails-test-cache "delete@delete.com" "todelete") - (cache/add-item emails-test-cache "dontdelete@dontdelete.com") - (is (= (count (cache/get-all-items emails-test-cache)) 3)) - - (let [google-removed (do - (cache/remove-item google-test-cache "testuuid") - (cache/get-item google-test-cache "testuuid")) - email-removed (do - (cache/remove-item emails-test-cache "testuuid") - (cache/get-item emails-test-cache "testuuid"))] - - (is (= (count (cache/get-all-items google-test-cache)) 2)) - (is (= (count (cache/get-all-items emails-test-cache)) 2)) - - (is (not (some? google-removed))) - (is (not (some? email-removed))))))) - - -(run-tests) diff --git a/test/source_be/google_test.clj b/test/source_be/google_test.clj deleted file mode 100644 index 12321377..00000000 --- a/test/source_be/google_test.clj +++ /dev/null @@ -1,59 +0,0 @@ -(ns source-be.google-test - (:require [clojure.test :refer :all] - [source.cache :as cache] - [source.oauth2.google.core :as google] - [clj-oauth2.client :as oauth2])) - -(defn oauth2-get [uri headers] - (let [auth-header (get-in - headers - [:headers "Authorization"])] - (if (and (some? uri) (= "Bearer access-token" auth-header)) - {:body "{\"email\":\"toast@toast.com\"}"} - {:body nil}))) - -(defn oauth2-get-access-token - [endpoint - & [params {expected-state :state expected-scope :scope}]] - (when (some? (:code params)) - {:access-token "access-token"})) - -(defn google-auth-flow-test-case - [mock-code - expected-email - get-access-token-override - get-override] - - (with-redefs [oauth2/get-access-token get-access-token-override - oauth2/get get-override] - - (let [auth-reqs-service (cache/create-cache) - auth-req (google/-auth-uri auth-reqs-service)] - - (is (some? (:uri auth-req))) - (is (some? (:uuid auth-req))) - (is (= (count (cache/get-all-items auth-reqs-service)) 1)) - - (let [email (google/-google-session-user - auth-reqs-service - (:uuid auth-req) - mock-code)] - - (is (= expected-email email)))))) - -(deftest google-auth-flow-test - (testing "testing the google oauth2 flow" - - (testing "successful auth flow" - (google-auth-flow-test-case - {:code "a1b2c3"} - "toast@toast.com" - oauth2-get-access-token - oauth2-get)) - - (testing "missing code verifier" - (google-auth-flow-test-case - {} - nil - oauth2-get-access-token - oauth2-get))))