Skip to content

Commit

Permalink
Merge pull request #193 from napse-invest/dev
Browse files Browse the repository at this point in the history
Dev
  • Loading branch information
tomjeannesson authored Mar 12, 2024
2 parents e6a51ef + a4a62dc commit f6a3af3
Show file tree
Hide file tree
Showing 91 changed files with 12,961 additions and 853 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout main
uses: actions/checkout@v2
uses: actions/checkout@v4

- name: Deploy docs
uses: mhausenblas/mkdocs-deploy-gh-pages@master
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/nextron.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,13 @@ jobs:
node-version: 18.x

- name: Run install
uses: borales/actions-yarn@v4
uses: borales/actions-yarn@v5
with:
cmd: install # will run `yarn install` command
dir: desktop-app

- name: Build production bundle
uses: borales/actions-yarn@v4
uses: borales/actions-yarn@v5
with:
cmd: build # will run `yarn build` command
dir: desktop-app
3 changes: 2 additions & 1 deletion desktop-app/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ node_modules
/app
dist
next-env.d.ts
out/
out/
secrets.json
128 changes: 125 additions & 3 deletions desktop-app/main/background.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,17 @@
import { app } from 'electron'
import { EnvironmentStatus } from '@aws-sdk/client-elastic-beanstalk'
import { BrowserWindow, app, ipcMain } from 'electron'
import serve from 'electron-serve'
import { createWindow } from './helpers'

import {
EB_APP_NAME,
EB_ENV_NAME,
createWindow,
deployToAWS,
fullCleanupAWS,
getEnvironments,
getNapseVersion,
syncConfig,
updateAWSApp
} from './helpers'
const isProd: boolean = process.env.NODE_ENV === 'production'

process.env.ELECTRON_DISABLE_SECURITY_WARNINGS = 'true'
Expand All @@ -20,6 +30,118 @@ if (isProd) {
height: 600
})

ipcMain.handle('deployAWS', async (event, args) => {
if (args.secrets) {
return await deployToAWS(args.secrets, mainWindow)
}
})
ipcMain.handle('fullCleanupAWS', async (event, args) => {
if (args.secrets) {
return await fullCleanupAWS(args.secrets, mainWindow)
}
})
ipcMain.handle('updateAWS', async (event, args) => {
if (args.secrets) {
return await updateAWSApp(args.secrets, mainWindow)
}
})

ipcMain.handle('sync-config', async (event, args) => {
if (args.secrets) {
return await syncConfig(args.secrets, mainWindow)
}
})

ipcMain.handle('isDeployedAWS', async (event, args) => {
if (args.secrets) {
let allTerminated = true
const environments = await getEnvironments(
args.secrets,
mainWindow,
EB_APP_NAME,
EB_ENV_NAME
)
if (environments) {
for (const env of environments) {
if (env.Status != EnvironmentStatus.Terminated) {
allTerminated = false
break
}
}
}
return !allTerminated
}
throw new Error('Not implemented')
})

ipcMain.handle('isReadyToUpdateAWS', async (event, args) => {
if (args.secrets) {
let allReady = true
const environments = await getEnvironments(
args.secrets,
mainWindow,
EB_APP_NAME,
EB_ENV_NAME
)
if (environments) {
for (const env of environments) {
if (env.Status != EnvironmentStatus.Ready) {
allReady = false
break
}
}
} else {
allReady = false
}
return allReady
}
throw new Error('Not implemented')
})

ipcMain.handle('hasAvailableUpdate', async (event, args) => {
if (args.secrets) {
let label = ''
const environments = await getEnvironments(
args.secrets,
mainWindow,
EB_APP_NAME,
EB_ENV_NAME
)
if (environments) {
for (const env of environments) {
if (env.Status === EnvironmentStatus.Ready) {
if (!env.VersionLabel) {
throw new Error('No version label found')
}
label = env.VersionLabel
break
}
}
}
if (!label) {
return false
}
let napseLabel = ''
try {
napseLabel = await getNapseVersion()
} catch (e) {
return false
}
return label !== napseLabel
}
throw new Error('Not implemented')
})

ipcMain.on('open-new-window', async (event, url) => {
const newWindow = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
nodeIntegration: true
}
})
newWindow.loadURL(url)
})
if (isProd) {
await mainWindow.loadURL('app://./index.html')
} else {
Expand Down
33 changes: 33 additions & 0 deletions desktop-app/main/helpers/aws/EB/createEBApp.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import {
CreateApplicationCommand,
ElasticBeanstalkClient
} from '@aws-sdk/client-elastic-beanstalk'
import { BrowserWindow } from 'electron'

export default async function Main(
secrets: {
AWS__API_TOKEN: string
AWS__API_SECRET: string
AWS__REGION: string
},
mainWindow: BrowserWindow,
ApplicationName: string,
ApplicationDescription: string
) {
const client = new ElasticBeanstalkClient({
region: secrets.AWS__REGION,
credentials: {
accessKeyId: secrets.AWS__API_TOKEN,
secretAccessKey: secrets.AWS__API_SECRET
}
})

const params = {
ApplicationName: ApplicationName,
Description: ApplicationDescription
}

try {
const data = await client.send(new CreateApplicationCommand(params))
} catch (err) {}
}
36 changes: 36 additions & 0 deletions desktop-app/main/helpers/aws/EB/createEBAppVersion.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import {
CreateApplicationVersionCommand,
ElasticBeanstalkClient
} from '@aws-sdk/client-elastic-beanstalk'

export default async function Main(
secrets: {
AWS__API_TOKEN: string
AWS__API_SECRET: string
AWS__REGION: string
},
mainWindow: Electron.BrowserWindow,
applicationName: string,
s3BucketName: string,
newVersionLabel: string
) {
const ebClient = new ElasticBeanstalkClient({
region: secrets.AWS__REGION,
credentials: {
accessKeyId: secrets.AWS__API_TOKEN,
secretAccessKey: secrets.AWS__API_SECRET
}
})
try {
const data = await ebClient.send(
new CreateApplicationVersionCommand({
ApplicationName: applicationName,
VersionLabel: newVersionLabel,
SourceBundle: {
S3Bucket: s3BucketName,
S3Key: `deploy-${newVersionLabel}.zip`
}
})
)
} catch (err) {}
}
109 changes: 109 additions & 0 deletions desktop-app/main/helpers/aws/EB/createEBEnvironement.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
import {
CreateEnvironmentCommand,
ElasticBeanstalkClient
} from '@aws-sdk/client-elastic-beanstalk'
import {
EB_BUCKET_NAME,
getBucketURL,
getIAMRoleArn,
getInstanceProfileArn
} from 'main/helpers'

export default async function Main(
secrets: {
AWS__API_TOKEN: string
AWS__API_SECRET: string
AWS__REGION: string
},
mainWindow: Electron.BrowserWindow,
applicationName: string,
environmentName: string,
instanceProfileName: string,
serviceRoleName: string,
versionLabel: string
) {
const client = new ElasticBeanstalkClient({
region: secrets.AWS__REGION,
credentials: {
accessKeyId: secrets.AWS__API_TOKEN,
secretAccessKey: secrets.AWS__API_SECRET
}
})

const params = {
ApplicationName: applicationName,
EnvironmentName: environmentName,
SolutionStackName: '64bit Amazon Linux 2023 v4.1.2 running Docker',
OptionSettings: [
{
Namespace: 'aws:autoscaling:launchconfiguration',
OptionName: 'IamInstanceProfile',
Value: await getInstanceProfileArn(
secrets,
mainWindow,
instanceProfileName
)
},
{
Namespace: 'aws:autoscaling:launchconfiguration',
OptionName: 'InstanceType',
Value: 't2.small'
},
{
Namespace: 'aws:elasticbeanstalk:environment',
OptionName: 'EnvironmentType',
Value: 'SingleInstance'
},
{
Namespace: 'aws:ec2:instances',
OptionName: 'EnableSpot',
Value: 'true'
},
{
Namespace: 'aws:elasticbeanstalk:environment',
OptionName: 'ServiceRole',
Value: await getIAMRoleArn(secrets, mainWindow, serviceRoleName)
},
{
Namespace: 'aws:elasticbeanstalk:cloudwatch:logs',
OptionName: 'StreamLogs',
Value: 'true'
},
{
Namespace: 'aws:elasticbeanstalk:cloudwatch:logs',
OptionName: 'DeleteOnTerminate',
Value: 'true'
},
{
Namespace: 'aws:elasticbeanstalk:cloudwatch:logs',
OptionName: 'RetentionInDays',
Value: '7'
},
{
Namespace: 'aws:elasticbeanstalk:application:environment',
OptionName: 'DJANGO_SECRET_KEY',
Value: 'django-secret-key'
},
{
Namespace: 'aws:elasticbeanstalk:application:environment',
OptionName: 'AWS_ACCESS_KEY_ID',
Value: secrets.AWS__API_TOKEN
},
{
Namespace: 'aws:elasticbeanstalk:application:environment',
OptionName: 'AWS_SECRET_ACCESS_KEY',
Value: secrets.AWS__API_SECRET
},
{
Namespace: 'aws:elasticbeanstalk:application:environment',
OptionName: 'AWS_S3_BUCKET_URI',
Value: getBucketURL(EB_BUCKET_NAME, 'litestream')
}
],
VersionLabel: versionLabel
}

try {
const data = await client.send(new CreateEnvironmentCommand(params))
} catch (err) {}
}
31 changes: 31 additions & 0 deletions desktop-app/main/helpers/aws/EB/deleteEBApp.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import {
DeleteApplicationCommand,
ElasticBeanstalkClient
} from '@aws-sdk/client-elastic-beanstalk'
import { BrowserWindow } from 'electron'

export default async function Main(
secrets: {
AWS__API_TOKEN: string
AWS__API_SECRET: string
AWS__REGION: string
},
mainWindow: BrowserWindow,
ApplicationName: string
) {
const client = new ElasticBeanstalkClient({
region: secrets.AWS__REGION,
credentials: {
accessKeyId: secrets.AWS__API_TOKEN,
secretAccessKey: secrets.AWS__API_SECRET
}
})

const params = {
ApplicationName: ApplicationName
}

try {
const data = await client.send(new DeleteApplicationCommand(params))
} catch (err) {}
}
Loading

0 comments on commit f6a3af3

Please sign in to comment.