Compare commits

...

17 Commits

Author SHA1 Message Date
Andras Bacsai
1388bee62c Merge pull request #459 from pucilpet/pucilpet-patch-1
Removed space from the version number
2022-06-10 08:51:36 +02:00
Petteri Pucilowski
8ebc778d40 Removed space from the version number 2022-06-10 01:30:46 +03:00
Andras Bacsai
3a59091b41 fix: nocodb persistency 2022-06-09 19:44:41 +02:00
Andras Bacsai
e764c4651c Merge pull request #454 from coollabsio/next
v2.9.8
2022-06-09 15:50:30 +02:00
Andras Bacsai
10f04d2177 fix: persistent nocodb 2022-06-09 15:49:21 +02:00
Andras Bacsai
119f994b50 chore: version++ 2022-06-09 15:49:07 +02:00
Andras Bacsai
e39541c318 fix: Traefik middleware 2022-06-09 15:18:21 +02:00
Andras Bacsai
cf88885c94 Merge pull request #452 from coollabsio/next
Fixes for v2.9.7
2022-06-09 14:01:20 +02:00
Andras Bacsai
1192346ce3 fix: remove comments 2022-06-09 14:00:41 +02:00
Andras Bacsai
0e3bd85847 fix: remove console log 2022-06-09 14:00:08 +02:00
Andras Bacsai
edeb6c6965 fix: Plausible script and middlewares 2022-06-09 13:59:09 +02:00
Andras Bacsai
138fd5cb6d Merge pull request #451 from coollabsio/next
v2.9.7
2022-06-09 13:34:02 +02:00
Andras Bacsai
155410bd44 Merge branch 'next' of github.com:coollabsio/coolify into next 2022-06-09 13:31:10 +02:00
Andras Bacsai
20bd829c2e Merge pull request #448 from titouanmathis/feat/gitlab-filter-projects-branches
feat: Add support for search for GitLab applications
2022-06-09 13:31:06 +02:00
Andras Bacsai
7b7e222946 chore: version++ 2022-06-09 13:30:29 +02:00
Andras Bacsai
98d901d06c fix: Plausible custom script 2022-06-08 13:45:42 +02:00
Titouan Mathis
4e862cda6f Add support for accessing all projects and branches for GitLab applications
Fix #236
2022-06-03 12:21:42 +02:00
5 changed files with 166 additions and 87 deletions

View File

@@ -1,7 +1,7 @@
{
"name": "coolify",
"description": "An open-source & self-hostable Heroku / Netlify alternative.",
"version": "2.9.6",
"version": "2.9.8",
"license": "AGPL-3.0",
"scripts": {
"dev": "docker-compose -f docker-compose-dev.yaml up -d && cross-env NODE_ENV=development & svelte-kit dev --host 0.0.0.0",

View File

@@ -62,7 +62,7 @@ export const supportedDatabaseTypesAndVersions = [
name: 'postgresql',
fancyName: 'PostgreSQL',
baseImage: 'bitnami/postgresql',
versions: ['14.2.0', '13.6.0', '12.10.0 ', '11.15.0', '10.20.0']
versions: ['14.2.0', '13.6.0', '12.10.0', '11.15.0', '10.20.0']
},
{
name: 'redis',

View File

@@ -1,6 +1,7 @@
<script lang="ts">
export let application;
export let appId;
import Select from 'svelte-select';
import { page, session } from '$app/stores';
import { onMount } from 'svelte';
import { errorNotification } from '$lib/form';
@@ -33,6 +34,10 @@
let showSave = false;
let autodeploy = application.settings.autodeploy || true;
let search = {
project: '',
branch: ''
};
let selected = {
group: undefined,
project: undefined,
@@ -84,16 +89,49 @@
}, 100);
}
function selectGroup(event) {
selected.group = event.detail;
selected.project = null;
selected.branch = null;
showSave = false;
loadProjects();
}
async function searchProjects(searchText) {
if (!selected.group) {
return;
}
search.project = searchText;
await loadProjects();
return projects;
}
function selectProject(event) {
selected.project = event.detail;
selected.branch = null;
showSave = false;
loadBranches();
}
async function loadProjects() {
const params = new URLSearchParams({
page: 1,
per_page: 25,
archived: false
});
if (search.project) {
params.append('search', search.project);
}
loading.projects = true;
if (username === selected.group.name) {
try {
projects = await get(
`${apiUrl}/v4/users/${selected.group.name}/projects?min_access_level=40&page=1&per_page=25&archived=false`,
{
Authorization: `Bearer ${$gitTokens.gitlabToken}`
}
);
params.append('min_access_level', 40);
projects = await get(`${apiUrl}/v4/users/${selected.group.name}/projects?${params}`, {
Authorization: `Bearer ${$gitTokens.gitlabToken}`
});
} catch (error) {
errorNotification(error);
throw new Error(error);
@@ -102,12 +140,9 @@
}
} else {
try {
projects = await get(
`${apiUrl}/v4/groups/${selected.group.id}/projects?page=1&per_page=25&archived=false`,
{
Authorization: `Bearer ${$gitTokens.gitlabToken}`
}
);
projects = await get(`${apiUrl}/v4/groups/${selected.group.id}/projects?${params}`, {
Authorization: `Bearer ${$gitTokens.gitlabToken}`
});
} catch (error) {
errorNotification(error);
throw new Error(error);
@@ -117,11 +152,35 @@
}
}
async function searchBranches(searchText) {
if (!selected.project) {
return;
}
search.branch = searchText;
await loadBranches();
return branches;
}
function selectBranch(event) {
selected.branch = event.detail;
isBranchAlreadyUsed();
}
async function loadBranches() {
const params = new URLSearchParams({
page: 1,
per_page: 100
});
if (search.branch) {
params.append('search', search.branch);
}
loading.branches = true;
try {
branches = await get(
`${apiUrl}/v4/projects/${selected.project.id}/repository/branches?per_page=100&page=1`,
`${apiUrl}/v4/projects/${selected.project.id}/repository/branches?${params}`,
{
Authorization: `Bearer ${$gitTokens.gitlabToken}`
}
@@ -267,70 +326,79 @@
<form on:submit={handleSubmit}>
<div class="flex flex-col space-y-2 px-4 xl:flex-row xl:space-y-0 xl:space-x-2 ">
{#if loading.base}
<select name="group" disabled class="w-96">
<option selected value="">{$t('application.configuration.loading_groups')}</option>
</select>
{:else}
<select name="group" class="w-96" bind:value={selected.group} on:change={loadProjects}>
<option value="" disabled selected>{$t('application.configuration.select_a_group')}</option>
{#each groups as group}
<option value={group}>{group.full_name}</option>
{/each}
</select>
{/if}
{#if loading.projects}
<select name="project" disabled class="w-96">
<option selected value="">{$t('application.configuration.loading_projects')}</option>
</select>
{:else if !loading.projects && projects.length > 0}
<select
name="project"
class="w-96"
bind:value={selected.project}
on:change={loadBranches}
disabled={!selected.group}
>
<option value="" disabled selected
>{$t('application.configuration.select_a_project')}</option
>
{#each projects as project}
<option value={project}>{project.name}</option>
{/each}
</select>
{:else}
<select name="project" disabled class="w-96">
<option disabled selected value=""
>{$t('application.configuration.no_projects_found')}</option
>
</select>
{/if}
{#if loading.branches}
<select name="branch" disabled class="w-96">
<option selected value="">{$t('application.configuration.loading_branches')}</option>
</select>
{:else if !loading.branches && branches.length > 0}
<select
name="branch"
class="w-96"
bind:value={selected.branch}
on:change={isBranchAlreadyUsed}
disabled={!selected.project}
>
<option value="" disabled selected>{$t('application.configuration.select_a_branch')}</option
>
{#each branches as branch}
<option value={branch}>{branch.name}</option>
{/each}
</select>
{:else}
<select name="project" disabled class="w-96">
<option disabled selected value=""
>{$t('application.configuration.no_branches_found')}</option
>
</select>
{/if}
<div class="custom-select-wrapper">
<Select
placeholder={loading.base
? $t('application.configuration.loading_groups')
: $t('application.configuration.select_a_group')}
id="group"
showIndicator={!loading.base}
isWaiting={loading.base}
on:select={selectGroup}
on:clear={() => {
showSave = false;
projects = [];
branches = [];
selected.group = null;
selected.project = null;
selected.branch = null;
}}
value={selected.group}
isDisabled={loading.base}
isClearable={false}
items={groups}
labelIdentifier="full_name"
optionIdentifier="id"
/>
</div>
<div class="custom-select-wrapper">
<Select
placeholder={loading.projects
? $t('application.configuration.loading_projects')
: $t('application.configuration.select_a_project')}
noOptionsMessage={$t('application.configuration.no_projects_found')}
id="project"
showIndicator={!loading.projects}
isWaiting={loading.projects}
isDisabled={loading.projects || !selected.group}
on:select={selectProject}
on:clear={() => {
showSave = false;
branches = [];
selected.project = null;
selected.branch = null;
}}
value={selected.project}
isClearable={false}
items={projects}
loadOptions={searchProjects}
labelIdentifier="name"
optionIdentifier="id"
/>
</div>
<div class="custom-select-wrapper">
<Select
placeholder={loading.branches
? $t('application.configuration.loading_branches')
: $t('application.configuration.select_a_branch')}
noOptionsMessage={$t('application.configuration.no_branches_found')}
id="branch"
showIndicator={!loading.branches}
isWaiting={loading.branches}
isDisabled={loading.branches || !selected.project}
on:select={selectBranch}
on:clear={() => {
showSave = false;
selected.branch = null;
}}
value={selected.branch}
isClearable={false}
items={branches}
loadOptions={searchBranches}
labelIdentifier="name"
optionIdentifier="web_url"
/>
</div>
</div>
<div class="flex flex-col items-center justify-center space-y-4 pt-5">
<button

View File

@@ -27,6 +27,7 @@ export const post: RequestHandler = async (event) => {
const config = {
image: `${image}:${version}`,
volume: `${id}-nc:/usr/app/data`,
environmentVariables: {}
};
if (serviceSecret.length > 0) {
@@ -41,6 +42,7 @@ export const post: RequestHandler = async (event) => {
container_name: id,
image: config.image,
networks: [network],
volumes: [config.volume],
environment: config.environmentVariables,
restart: 'always',
...(exposePort ? { ports: [`${exposePort}:${port}`] } : {}),
@@ -59,6 +61,11 @@ export const post: RequestHandler = async (event) => {
[network]: {
external: true
}
},
volumes: {
[config.volume.split(':')[0]]: {
name: config.volume.split(':')[0]
}
}
};
const composeFileDestination = `${workdir}/docker-compose.yaml`;

View File

@@ -7,7 +7,7 @@ import { checkContainer } from '$lib/haproxy';
import type { RequestHandler } from '@sveltejs/kit';
function configureMiddleware(
{ id, container, port, domain, nakedDomain, isHttps, isWWW, isDualCerts },
{ id, container, port, domain, nakedDomain, isHttps, isWWW, isDualCerts, scriptName, type },
traefik
) {
if (isHttps) {
@@ -125,6 +125,15 @@ function configureMiddleware(
}
}
}
if (type === 'plausibleanalytics' && scriptName && scriptName !== 'plausible.js') {
if (!traefik.http.routers[`${id}`].middlewares.includes(`${id}-redir`)) {
traefik.http.routers[`${id}`].middlewares.push(`${id}-redir`);
}
if (!traefik.http.routers[`${id}-secure`].middlewares.includes(`${id}-redir`)) {
traefik.http.routers[`${id}-secure`].middlewares.push(`${id}-redir`);
}
}
}
export const get: RequestHandler = async (event) => {
const traefik = {
@@ -176,7 +185,7 @@ export const get: RequestHandler = async (event) => {
} = application;
if (destinationDockerId) {
const { engine, network } = destinationDocker;
const isRunning = await checkContainer(engine, id);
const isRunning = true;
if (fqdn) {
const domain = getDomain(fqdn);
const nakedDomain = domain.replace(/^www\./, '');
@@ -244,7 +253,7 @@ export const get: RequestHandler = async (event) => {
if (found) {
const port = found.ports.main;
const publicPort = service[type]?.publicPort;
const isRunning = await checkContainer(engine, id);
const isRunning = true;
if (fqdn) {
const domain = getDomain(fqdn);
const nakedDomain = domain.replace(/^www\./, '');
@@ -335,11 +344,6 @@ export const get: RequestHandler = async (event) => {
replacement: '/js/plausible.js'
}
};
if (traefik.http.routers[id].middlewares.length > 0) {
traefik.http.routers[id].middlewares.push(`${id}-redir`);
} else {
traefik.http.routers[id].middlewares = [`${id}-redir`];
}
}
}
for (const coolify of data.coolify) {