Skip to content

Commit

Permalink
feat: added environments and launch functionality to projects (#87)
Browse files Browse the repository at this point in the history
* feat: add environments schema definition

Signed-off-by: Francisco Madeira <francisco.madeira@diconium.com>

* feat: remove query from getProjects action

* refactor: remove query from getProjects

* refactor: remove query from getProjectsById

* refactor: fix projects/{id} with fixed environtment

* refactor: project components list and add

* refactor: project components actions

* feat: add environment picker

* feat: add environment picker to projects page

Signed-off-by: Francisco Madeira <francisco.madeira@diconium.com>

* refactor: component actions with environments

* refactor: api routes for projects

* feat: add new environment based api routes

* feat: add copy url to environments

* feat: actions on project environments

* refactor: clean types on projects actions

* feat: add default environment to new projects

* feat: create launch page

Signed-off-by: Francisco Madeira <francisco.madeira@diconium.com>

* feat: added launch funcionality

* feat: improve comparison page result

Signed-off-by: Francisco Madeira <francisco.madeira@diconium.com>

* chore: add changeset

Signed-off-by: Francisco Madeira <francisco.madeira@diconium.com>

* fix: remove group to display all the components

Signed-off-by: Francisco Madeira <francisco.madeira@diconium.com>

* chore: update the release workflow

Signed-off-by: Francisco Madeira <francisco.madeira@diconium.com>

---------

Signed-off-by: Francisco Madeira <francisco.madeira@diconium.com>
  • Loading branch information
fgmadeira committed Sep 30, 2024
1 parent f3c585b commit 63b876e
Show file tree
Hide file tree
Showing 48 changed files with 2,509 additions and 766 deletions.
13 changes: 13 additions & 0 deletions .changeset/clever-fireants-walk.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
---
'@ethereal-nexus/dashboard': major
'@ethereal-nexus/site': major
'@ethereal-nexus/cli': major
'@ethereal-nexus/conector-aem-react': major
'@ethereal-nexus/core': major
'@ethereal-nexus/vite-plugin-ethereal-nexus': major
---

This is the first Major release of Ethereal Nexus!

Added environments features. This allows projects to have several configurations based on the respective environemnt and to publish them from one environment to the other using launches.
Because of this there were breaking changes to the schema of the component configs.
2 changes: 1 addition & 1 deletion .changeset/tiny-mayflies-yawn.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
'@ethereal-nexus/core': patch
---

fix type inference for select schema
Fix type inference for select schema
10 changes: 9 additions & 1 deletion .github/workflows/astro.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,44 +39,52 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Detect package manager
id: detect-package-manager
run: |
echo "manager=pnpm" >> $GITHUB_OUTPUT
echo "command=install" >> $GITHUB_OUTPUT
echo "runner=pnpm run" >> $GITHUB_OUTPUT
- name: Install Node.js
uses: actions/setup-node@v4
with:
node-version: 20

- uses: pnpm/action-setup@v4
name: Install pnpm
with:
version: 8
run_install: false

- name: Get pnpm store directory
shell: bash
run: |
echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV
- uses: actions/cache@v4
name: Setup pnpm cache
with:
path: ${{ env.STORE_PATH }}
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
restore-keys: |
${{ runner.os }}-pnpm-store-
- name: Setup Pages
id: pages
uses: actions/configure-pages@v4

- name: Install dependencies
run: ${{ steps.detect-package-manager.outputs.manager }} ${{ steps.detect-package-manager.outputs.command }}
working-directory: ${{ env.BUILD_PATH }}

- name: Build with Astro
run: |
${{ steps.detect-package-manager.outputs.runner }} astro build \
--site "${{ steps.pages.outputs.origin }}" \
--base "${{ steps.pages.outputs.base_path }}"
working-directory: ${{ env.BUILD_PATH }}

- name: Upload artifact
uses: actions/upload-pages-artifact@v3
with:
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/dashboard-preview.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ jobs:
echo "${{ secrets.AZURE_BLOB_STORAGE_ACCOUNT }}" >> ./web/dashboard/.env
echo "${{ secrets.AZURE_BLOB_STORAGE_SECRET }}" >> ./web/dashboard/.env
echo "${{ secrets.NEXT_AUTH_SECRET }}" >> ./web/dashboard/.env
echo "AZURE_CONTAINER_NAME=remote-components-aem-demo" >> ./web/dashboard/.env
echo "DRIZZLE_DATABASE_TYPE=neon" >> ./web/dashboard/.env
echo "DRIZZLE_DATABASE_URL=${{ steps.create-branch.outputs.db_url }}?sslmode=require" >> ./web/dashboard/.env
Expand Down
48 changes: 48 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
name: Release

on:
push:
branches:
- main

concurrency: ${{ github.workflow }}-${{ github.ref }}

jobs:
release:
name: Release
runs-on: ubuntu-latest
steps:
- name: Checkout Repo
uses: actions/checkout@v3

- name: Install Node.js
uses: actions/setup-node@v4
with:
node-version: 20

- uses: pnpm/action-setup@v4
name: Install pnpm
with:
run_install: false

- name: Install Dependencies
run: pnpm i --frozen-lockfile

- name: Build Packages
run: pnpm run build

- name: Fix npmrc
run: npm config set "//registry.npmjs.org/:_authToken" "$NPM_TOKEN"
env:
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}

- name: Publish to npm
id: changesets
uses: changesets/action@v1
with:
publish: pnpm release
commit: "chore: release version"
title: "[ci] Release version"
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ const dynamicSlots = {
dynamiczonetwo: dynamic({}),
};

const schema = component({ name: 'TestReactHelloWorld', version: '0.0.87' }, dialogSchema, dynamicSlots);
const schema = component({ name: 'TestReactHelloWorld', version: '0.0.86' }, dialogSchema, dynamicSlots);

type Props = Output<typeof schema>

Expand Down
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@
"name": "@ethereal-nexus/root",
"private": "true",
"scripts": {
"postinstall": "turbo run build --filter='./lib/*'"
"postinstall": "turbo run build --filter='./lib/*'",
"build": "turbo run build",
"release": "pnpm --filter \"...{lib/**}\" publish --access public"
},
"devDependencies": {
"@changesets/cli": "^2.27.8",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,51 +1,44 @@
import React from 'react';
import {Separator} from '@/components/ui/separator';
import {notFound} from 'next/navigation';
import {
getComponentById,
getComponentDependentsProjectsWithOwners,
getComponentVersions
} from "@/data/components/actions";
import ComponentVersionHeader from "@/components/components/component/version/header";
import ComponentVersionTabs from "@/components/components/component/version/tabs";
import {auth} from "@/auth";
import {getMembersByResourceId} from "@/data/member/actions";
import {getResourceEvents} from "@/data/events/actions";
import { Separator } from '@/components/ui/separator';
import { notFound } from 'next/navigation';
import { getComponentById, getComponentDependentsProjects, getComponentVersions } from '@/data/components/actions';
import ComponentVersionHeader from '@/components/components/component/version/header';
import ComponentVersionTabs from '@/components/components/component/version/tabs';
import { auth } from '@/auth';
import { getResourceEvents } from '@/data/events/actions';

export default async function EditComponentVersion({params: {id, versionId, tab}}: any) {
const session = await auth()

const component = await getComponentById(id);
const versions = await getComponentVersions(id);
const dependents = await getComponentDependentsProjectsWithOwners(id);
const dependents = await getComponentDependentsProjects(id, session?.user?.id);
const events = await getResourceEvents(id);
const projects = await getComponentDependentsProjectsWithOwners(id);

if (projects.success) {
projects.data = await Promise.all(
projects.data.map(async (project) => {
const membersData = await getMembersByResourceId(project.id, session?.user?.id);
const userHasAccess = (membersData.success && membersData.data.some(member => member.user_id == session?.user?.id));

return {
...project,
userHasAccess
};
})
);
}

if (!versions.success || !component.success || !dependents.success || !projects.success) {
if (!versions.success || !component.success || !dependents.success ) {
notFound();
}

const safeDependents = dependents.data.map(p => p.has_access ? p : null)
const selectedVersion = versions.data.filter((version: any) => version.id === versionId)[0];

return (
<div className="container space-y-6">
<ComponentVersionHeader versions={versions} component={component}
selectedVersion={selectedVersion} activeTab={tab}/>
<ComponentVersionHeader
versions={versions}
component={component}
selectedVersion={selectedVersion}
activeTab={tab}
/>
<Separator/>
<ComponentVersionTabs activeTab={tab} versions={versions} selectedVersion={selectedVersion}
component={component} dependents={projects.data} events={events}/>
<ComponentVersionTabs
activeTab={tab}
versions={versions}
selectedVersion={selectedVersion}
component={component}
dependents={safeDependents}
events={events}
/>
</div>
);
}
17 changes: 15 additions & 2 deletions web/dashboard/src/app/(session)/projects/[id]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,9 @@ import Link from 'next/link';
import ProjectsForm from '@/components/projects/project-form';
import { getResourceEvents } from '@/data/events/actions';
import { ProjectEvents } from '@/components/projects/project-events/project-events';
import { EnvironmentsList } from '@/components/projects/environments-table/environment-list';

export default async function EditProject({ params: { id }, searchParams: { tab } }: any) {
export default async function EditProject({ params: { id }, searchParams: { tab, env } }: any) {
const session = await auth();
const project = await getProjectById(id, session?.user?.id);
const events = await getResourceEvents(id);
Expand Down Expand Up @@ -39,6 +40,11 @@ export default async function EditProject({ params: { id }, searchParams: { tab
Users
</Link>
</TabsTrigger>
<TabsTrigger value="environments" asChild>
<Link href={`/projects/${id}?tab=environments`}>
Environments
</Link>
</TabsTrigger>
<TabsTrigger value="settings" asChild>
<Link href={`/projects/${id}?tab=settings`}>
Settings
Expand All @@ -52,21 +58,28 @@ export default async function EditProject({ params: { id }, searchParams: { tab
</TabsList>
<TabsContent value="components" className="space-y-4">
<ProjectComponentsList
key={env}
id={id}
environment={env}
/>
</TabsContent>
<TabsContent value="users" className="space-y-4">
<ProjectMemberList
id={id}
/>
</TabsContent>
<TabsContent value="environments" className="space-y-4">
<EnvironmentsList
id={id}
/>
</TabsContent>
<TabsContent value="settings">
<ProjectsForm
project={project.data}
/>
</TabsContent>
<TabsContent value="activity">
<ProjectEvents events={events} />
<ProjectEvents events={events} />
</TabsContent>
</Tabs>
</div>
Expand Down
87 changes: 87 additions & 0 deletions web/dashboard/src/app/(session)/projects/launch/new/[id]/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import React from 'react';
import { ComparisonResult, LaunchesList } from '@/components/launches/table/launches-list';
import { getEnvironmentsById, getEnvironmentsByProject } from '@/data/projects/actions';
import { auth } from '@/auth';
import { EnvironmentWithComponents } from '@/data/projects/dto';
import { notFound } from 'next/navigation';
import { EnvironmentPicker } from './picker';

function compareEnvironments(from: EnvironmentWithComponents, to: EnvironmentWithComponents): ComparisonResult[] {
const result: ComparisonResult[] = [];

from.components.forEach((compFrom) => {
const compTo = to.components.find((c) => c.id === compFrom.id);

if (compTo) {
result.push({
id: compFrom.id,
name: compFrom.name,
title: compFrom.title,
new: false,
is_active: {
from: compFrom.is_active,
to: compTo.is_active,
},
version: {
from: compFrom.version || 'latest',
to: compTo.version || 'latest',
},
});
} else {
result.push({
id: compFrom.id,
name: compFrom.name,
title: compFrom.title,
new: true,
is_active: {
from: compFrom.is_active,
to: null,
},
version: {
from: compFrom.version || 'latest',
to: null,
},
})
}
});

return result;
}

export default async function NewLaunch({ params: { id } }: any) {
const session = await auth()
const [fromId, toId] = id.split('...')

const from = await getEnvironmentsById(fromId, session?.user?.id)
const to = await getEnvironmentsById(toId, session?.user?.id)

if (!from.success || !to.success || from.data.project_id !== to.data.project_id) {
notFound();
}

const environments = await getEnvironmentsByProject(from.data.project_id, session?.user?.id)
const comparison = compareEnvironments(from.data, to.data);

return (
<div className="container h-full flex-1 flex-col space-y-8 p-8 md:flex">
<div className="w-full flex items-end">
<div className="mr-auto">
<div className="flex items-baseline">
<h2 className="text-2xl font-bold tracking-tight">Create Launch</h2>
</div>
<p className="text-muted-foreground">Compare the changes to launch</p>
</div>
</div>
<EnvironmentPicker
from={from.data}
to={to.data}
environments={environments.success ? environments.data : []}
/>
<LaunchesList
from={from.data}
to={to.data}
comparison={comparison}
/>
</div>
);
}
Loading

0 comments on commit 63b876e

Please sign in to comment.