Compare commits

...
4 Commits
Author SHA1 Message Date
Lauri Ojansivu 9bc889e274 v8.71 2026-04-06 03:40:47 +03:00
Lauri Ojansivu 5df924f416 Fix: Added missing null check to notification.
Thanks to xet7 !
2026-04-06 03:35:28 +03:00
Lauri Ojansivu 5ef94b7079 v8.70 2026-04-06 02:43:39 +03:00
Lauri Ojansivu dfcaaf0ae7 Convert upsert calls to async in authentication.js .
Thanks to snowsky and xet7 !

Fixes https://github.com/wekan/wekan/pull/6243,
fixes https://github.com/wekan/wekan/pull/6245
2026-04-06 02:36:45 +03:00
14 changed files with 54 additions and 36 deletions

No files matched your search

+18
View File
@@ -30,6 +30,24 @@ WeKan 8.43 and newer uses Meteor 3.x, Node.js 22.x and MongoDB 7.x, huge thanks
- https://harryadel.com/dev-diary-25/
- https://harryadel.com/dev-diary-26/
# v8.71 2026-04-06 WeKan ® release
This release fixes the following bugs:
- [Fix: Added missing null check to notification](https://github.com/wekan/wekan/commit/5df924f416083a50795443687e1c28f402dc8132).
Thanks to xet7.
Thanks to above GitHub users for their contributions and translators for their translations.
# v8.70 2026-04-06 WeKan ® release
This release fixes the following bugs:
- [Convert upsert calls to async in authentication.js](https://github.com/wekan/wekan/commit/dfcaaf0ae719e8d8b918ac632100293a6e401371).
Thanks to snowsky and xet7.
Thanks to above GitHub users for their contributions and translators for their translations.
# v8.69 2026-04-06 WeKan ® release
This release fixes the following bugs:
+1 -1
View File
@@ -7,7 +7,7 @@ LABEL org.opencontainers.image.source="https://github.com/wekan/wekan"
# TARGETARCH and TARGETVARIANT are automatically provided by Docker Buildx
ARG TARGETARCH
ARG TARGETVARIANT
ARG VERSION=8.69
ARG VERSION=8.71
ARG DEBIAN_FRONTEND=noninteractive
ENV BUILD_DEPS="apt-utils gnupg wget bzip2 g++ curl libarchive-tools build-essential git ca-certificates python3 unzip"
+1 -1
View File
@@ -1,5 +1,5 @@
appId: wekan-public/apps/77b94f60-dec9-0136-304e-16ff53095928
appVersion: "v8.69.0"
appVersion: "v8.71.0"
files:
userUploads:
- README.md
+2 -2
View File
@@ -10,7 +10,7 @@ This is without container (without Docker or Snap).
Right click and download files 1-4:
1. [wekan-8.69-amd64-windows.zip](https://github.com/wekan/wekan/releases/download/v8.69/wekan-8.69-amd64-windows.zip)
1. [wekan-8.71-amd64-windows.zip](https://github.com/wekan/wekan/releases/download/v8.71/wekan-8.71-amd64-windows.zip)
2. [node.exe](https://nodejs.org/dist/latest-v22.x/win-x64/node.exe)
@@ -22,7 +22,7 @@ Right click and download files 1-4:
6. Double click `mongodb-windows-x86_64-7.0.31-signed.msi` . In installer, uncheck downloading MongoDB compass.
7. Unzip `wekan-8.69-amd64-windows.zip` , inside it is directory `bundle`, to it copy other files:
7. Unzip `wekan-8.71-amd64-windows.zip` , inside it is directory `bundle`, to it copy other files:
```
bundle (directory)
+2 -2
View File
@@ -1,12 +1,12 @@
{
"name": "wekan",
"version": "v8.69.0",
"version": "v8.71.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "wekan",
"version": "v8.69.0",
"version": "v8.71.0",
"license": "MIT",
"dependencies": {
"@aws-sdk/client-s3": "^3.1019.0",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "wekan",
"version": "v8.69.0",
"version": "v8.71.0",
"description": "Open-Source kanban",
"private": true,
"repository": {
+3 -3
View File
@@ -3,7 +3,7 @@
<head>
<meta charset="utf8" />
<title>WeKan REST API v8.69</title>
<title>WeKan REST API v8.71</title>
<!-- needed for adaptive design -->
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
@@ -390,7 +390,7 @@ data-styled.g138[id="sc-iJQrDi"]{content:"gtHWGb,"}/*!sc*/
55.627 l 55.6165,55.627 -231.245496,231.24803 c -127.185,127.1864
-231.5279,231.248 -231.873,231.248 -0.3451,0 -104.688,
-104.0616 -231.873,-231.248 z
" fill="currentColor"></path></g></svg></div></div><div class="sc-juTflS gfWNtA api-content"><div class="sc-eDDNvO eTiIZG"><div class="sc-iAEyYj cmAaWK"><div class="sc-hLseeT hoYmkG api-info"><h1 class="sc-fsQipe sc-crPCXn ePkAIL bSStQp">Wekan REST API<!-- --> <span>(<!-- -->v8.69<!-- -->)</span></h1><p>Download OpenAPI specification<!-- -->:</p><div class="sc-iKGpAq sc-cCYyou dXXcln dHaogz"></div><div data-role="redoc-summary" html="" class="sc-iKGpAq sc-cCYyou dXXcln dHaogz"></div><div data-role="redoc-description" html="&lt;p&gt;The REST API allows you to control and extend Wekan with ease.&lt;/p&gt;
" fill="currentColor"></path></g></svg></div></div><div class="sc-juTflS gfWNtA api-content"><div class="sc-eDDNvO eTiIZG"><div class="sc-iAEyYj cmAaWK"><div class="sc-hLseeT hoYmkG api-info"><h1 class="sc-fsQipe sc-crPCXn ePkAIL bSStQp">Wekan REST API<!-- --> <span>(<!-- -->v8.71<!-- -->)</span></h1><p>Download OpenAPI specification<!-- -->:</p><div class="sc-iKGpAq sc-cCYyou dXXcln dHaogz"></div><div data-role="redoc-summary" html="" class="sc-iKGpAq sc-cCYyou dXXcln dHaogz"></div><div data-role="redoc-description" html="&lt;p&gt;The REST API allows you to control and extend Wekan with ease.&lt;/p&gt;
&lt;p&gt;If you are an end-user and not a dev or a tester, &lt;a href=&quot;https://github.com/wekan/wekan/issues/new&quot;&gt;create an issue&lt;/a&gt; to request new APIs.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;All API calls in the documentation are made using &lt;code&gt;curl&lt;/code&gt;. However, you are free to use Java / Python / PHP / Golang / Ruby / Swift / Objective-C / Rust / Scala / C# or any other programming languages.&lt;/p&gt;
@@ -446,7 +446,7 @@ data-styled.g138[id="sc-iJQrDi"]{content:"gtHWGb,"}/*!sc*/
" class="sc-iKGpAq sc-cCYyou sc-cjERFZ dXXcln fTBBlJ dkmSdy"><p>Error in registration</p>
</div></button></div></div></div><div class="sc-jTrPJt sc-gLDzao dVngAA fYLqku"><div class="sc-fYzRkH dHdMVa"><button class="sc-jYvNnh iWrBta"><span type="post" class="sc-eGFuAY ejslkd http-verb post">post</span><span class="sc-GJyyy dkiPkt">/users/register</span><svg class="sc-fbJfz ivEQut" style="margin-right:-25px" version="1.1" viewBox="0 0 24 24" x="0" xmlns="http://www.w3.org/2000/svg" y="0" aria-hidden="true"><polygon points="17.3 8.3 12 13.6 6.7 8.3 5.3 9.7 12 16.4 18.7 9.7 "></polygon></svg></button><div aria-hidden="true" class="sc-fnxdBX dplsyJ"><div class="sc-llcuoK cNCbuV"><div html="" class="sc-iKGpAq sc-cCYyou dXXcln cFvDiF"></div><div tabindex="0" role="button"><div class="sc-jnsZEx eobUac"><span></span>/users/register</div></div></div></div></div></div></div></div></div><div class="sc-emEvRt jYOHCb"></div></div></div>
<script>
const __redoc_state = {"menu":{"activeItemIdx":-1},"spec":{"data":{"openapi":"3.0.0","info":{"title":"Wekan REST API","version":"v8.69","description":"The REST API allows you to control and extend Wekan with ease.\n\nIf you are an end-user and not a dev or a tester, [create an issue](https://github.com/wekan/wekan/issues/new) to request new APIs.\n\n> All API calls in the documentation are made using `curl`. However, you are free to use Java / Python / PHP / Golang / Ruby / Swift / Objective-C / Rust / Scala / C# or any other programming languages.\n\n# Production Security Concerns\nWhen calling a production Wekan server, ensure it is running via HTTPS and has a valid SSL Certificate. The login method requires you to post your username and password in plaintext, which is why we highly suggest only calling the REST login api over HTTPS. Also, few things to note:\n\n* Only call via HTTPS\n* Implement a timed authorization token expiration strategy\n* Ensure the calling user only has permissions for what they are calling and no more\n"},"paths":{"/users/login":{"post":{"operationId":"login","summary":"Login with REST API","tags":["Login"],"requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["username","password"],"properties":{"username":{"description":"Your username\n","type":"string"},"password":{"description":"Your password\n","type":"string","format":"password"}}}},"application/x-www-form-urlencoded":{"schema":{"type":"object","required":["username","password"],"properties":{"username":{"description":"Your username\n","type":"string"},"password":{"description":"Your password\n","type":"string","format":"password"}}}}},"description":"Login credentials","required":true},"responses":{"200":{"description":"Successful authentication","content":{"*/*":{"schema":{"type":"object","required":["id","token","tokenExpires"],"properties":{"id":{"type":"string","description":"User ID"},"token":{"type":"string","description":"Authentication token\n"},"tokenExpires":{"type":"string","format":"date-time","description":"Token expiration date\n"}}}}}},"400":{"description":"Error in authentication\n","content":{"*/*":{"schema":{"type":"object","properties":{"error":{"type":"string"},"reason":{"type":"string"}}}}}},"default":{"description":"Error in authentication\n"}}}},"/users/register":{"post":{"operationId":"register","summary":"Register with REST API","description":"Notes:\n - You will need to provide the token for any of the authenticated methods.\n","tags":["Login"],"requestBody":{"content":{"application/x-www-form-urlencoded":{"schema":{"type":"object","properties":{"username":{"description":"Your username\n","type":"string"},"password":{"description":"Your password\n","type":"string","format":"password"},"email":{"description":"Your email\n","type":"string"}},"required":["username","password","email"]}}},"required":true},"responses":{"200":{"description":"Successful registration","content":{"*/*":{"schema":{"items":{"properties":{"id":{"type":"string"},"token":{"type":"string"},"tokenExpires":{"type":"string"}}}}}}},"400":{"description":"Error in registration\n","content":{"*/*":{"schema":{"items":{"properties":{"error":{"type":"number"},"reason":{"type":"string"}}}}}}},"default":{"description":"Error in registration\n"}}}}},"components":{"securitySchemes":{"UserSecurity":{"type":"apiKey","in":"header","name":"Authorization"}}}}},"searchIndex":{"store":["section/Production-Security-Concerns","tag/Login","tag/Login/operation/login","tag/Login/operation/register"],"index":{"version":"2.3.9","fields":["title","description"],"fieldVectors":[["title/0",[0,0.641,1,1.113,2,1.113]],["description/0",[0,0.353,3,1.592,4,0.613,5,0.613,6,0.995,7,0.613,8,0.995,9,1.257,10,0.613,11,0.613,12,0.613,13,0.295,14,0.353,15,0.613,16,0.613,17,0.613,18,0.613,19,0.613,20,0.613,21,0.613,22,0.182,23,0.182,24,0.613,25,0.613,26,0.613,27,0.353,28,0.724,29,0.613,30,0.613,31,0.613,32,0.353,33,0.613,34,0.613,35,0.613,36,0.613,37,0.613]],["title/1",[13,0.473]],["description/1",[]],["title/2",[13,0.33,22,0.33,23,0.33]],["description/2",[38,1.941]],["title/3",[22,0.33,23,0.33,39,1.113]],["description/3",[14,0.841,27,0.841,28,0.841,32,0.841,40,1.46,41,1.46,42,1.46,43,1.46]]],"invertedIndex":[["",{"_index":28,"title":{},"description":{"0":{},"3":{}}}],["api",{"_index":23,"title":{"2":{},"3":{}},"description":{"0":{}}}],["authent",{"_index":42,"title":{},"description":{"3":{}}}],["author",{"_index":31,"title":{},"description":{"0":{}}}],["call",{"_index":3,"title":{},"description":{"0":{}}}],["certif",{"_index":12,"title":{},"description":{"0":{}}}],["concern",{"_index":2,"title":{"0":{}},"description":{}}],["ensur",{"_index":6,"title":{},"description":{"0":{}}}],["expir",{"_index":33,"title":{},"description":{"0":{}}}],["few",{"_index":25,"title":{},"description":{"0":{}}}],["highli",{"_index":20,"title":{},"description":{"0":{}}}],["http",{"_index":9,"title":{},"description":{"0":{}}}],["implement",{"_index":29,"titLine truncated
const __redoc_state = {"menu":{"activeItemIdx":-1},"spec":{"data":{"openapi":"3.0.0","info":{"title":"Wekan REST API","version":"v8.71","description":"The REST API allows you to control and extend Wekan with ease.\n\nIf you are an end-user and not a dev or a tester, [create an issue](https://github.com/wekan/wekan/issues/new) to request new APIs.\n\n> All API calls in the documentation are made using `curl`. However, you are free to use Java / Python / PHP / Golang / Ruby / Swift / Objective-C / Rust / Scala / C# or any other programming languages.\n\n# Production Security Concerns\nWhen calling a production Wekan server, ensure it is running via HTTPS and has a valid SSL Certificate. The login method requires you to post your username and password in plaintext, which is why we highly suggest only calling the REST login api over HTTPS. Also, few things to note:\n\n* Only call via HTTPS\n* Implement a timed authorization token expiration strategy\n* Ensure the calling user only has permissions for what they are calling and no more\n"},"paths":{"/users/login":{"post":{"operationId":"login","summary":"Login with REST API","tags":["Login"],"requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["username","password"],"properties":{"username":{"description":"Your username\n","type":"string"},"password":{"description":"Your password\n","type":"string","format":"password"}}}},"application/x-www-form-urlencoded":{"schema":{"type":"object","required":["username","password"],"properties":{"username":{"description":"Your username\n","type":"string"},"password":{"description":"Your password\n","type":"string","format":"password"}}}}},"description":"Login credentials","required":true},"responses":{"200":{"description":"Successful authentication","content":{"*/*":{"schema":{"type":"object","required":["id","token","tokenExpires"],"properties":{"id":{"type":"string","description":"User ID"},"token":{"type":"string","description":"Authentication token\n"},"tokenExpires":{"type":"string","format":"date-time","description":"Token expiration date\n"}}}}}},"400":{"description":"Error in authentication\n","content":{"*/*":{"schema":{"type":"object","properties":{"error":{"type":"string"},"reason":{"type":"string"}}}}}},"default":{"description":"Error in authentication\n"}}}},"/users/register":{"post":{"operationId":"register","summary":"Register with REST API","description":"Notes:\n - You will need to provide the token for any of the authenticated methods.\n","tags":["Login"],"requestBody":{"content":{"application/x-www-form-urlencoded":{"schema":{"type":"object","properties":{"username":{"description":"Your username\n","type":"string"},"password":{"description":"Your password\n","type":"string","format":"password"},"email":{"description":"Your email\n","type":"string"}},"required":["username","password","email"]}}},"required":true},"responses":{"200":{"description":"Successful registration","content":{"*/*":{"schema":{"items":{"properties":{"id":{"type":"string"},"token":{"type":"string"},"tokenExpires":{"type":"string"}}}}}}},"400":{"description":"Error in registration\n","content":{"*/*":{"schema":{"items":{"properties":{"error":{"type":"number"},"reason":{"type":"string"}}}}}}},"default":{"description":"Error in registration\n"}}}}},"components":{"securitySchemes":{"UserSecurity":{"type":"apiKey","in":"header","name":"Authorization"}}}}},"searchIndex":{"store":["section/Production-Security-Concerns","tag/Login","tag/Login/operation/login","tag/Login/operation/register"],"index":{"version":"2.3.9","fields":["title","description"],"fieldVectors":[["title/0",[0,0.641,1,1.113,2,1.113]],["description/0",[0,0.353,3,1.592,4,0.613,5,0.613,6,0.995,7,0.613,8,0.995,9,1.257,10,0.613,11,0.613,12,0.613,13,0.295,14,0.353,15,0.613,16,0.613,17,0.613,18,0.613,19,0.613,20,0.613,21,0.613,22,0.182,23,0.182,24,0.613,25,0.613,26,0.613,27,0.353,28,0.724,29,0.613,30,0.613,31,0.613,32,0.353,33,0.613,34,0.613,35,0.613,36,0.613,37,0.613]],["title/1",[13,0.473]],["description/1",[]],["title/2",[13,0.33,22,0.33,23,0.33]],["description/2",[38,1.941]],["title/3",[22,0.33,23,0.33,39,1.113]],["description/3",[14,0.841,27,0.841,28,0.841,32,0.841,40,1.46,41,1.46,42,1.46,43,1.46]]],"invertedIndex":[["",{"_index":28,"title":{},"description":{"0":{},"3":{}}}],["api",{"_index":23,"title":{"2":{},"3":{}},"description":{"0":{}}}],["authent",{"_index":42,"title":{},"description":{"3":{}}}],["author",{"_index":31,"title":{},"description":{"0":{}}}],["call",{"_index":3,"title":{},"description":{"0":{}}}],["certif",{"_index":12,"title":{},"description":{"0":{}}}],["concern",{"_index":2,"title":{"0":{}},"description":{}}],["ensur",{"_index":6,"title":{},"description":{"0":{}}}],["expir",{"_index":33,"title":{},"description":{"0":{}}}],["few",{"_index":25,"title":{},"description":{"0":{}}}],["highli",{"_index":20,"title":{},"description":{"0":{}}}],["http",{"_index":9,"title":{},"description":{"0":{}}}],["implement",{"_index":29,"titLine truncated
var container = document.getElementById('redoc');
Redoc.hydrate(__redoc_state, container);
+1 -1
View File
@@ -1,7 +1,7 @@
swagger: '2.0'
info:
title: Wekan REST API
version: v8.69
version: v8.71
description: |
The REST API allows you to control and extend Wekan with ease.
+2 -2
View File
@@ -22,10 +22,10 @@ const pkgdef :Spk.PackageDefinition = (
appTitle = (defaultText = "Wekan"),
# The name of the app as it is displayed to the user.
appVersion = 869,
appVersion = 871,
# Increment this for every release.
appMarketingVersion = (defaultText = "8.69.0~2026-03-23"),
appMarketingVersion = (defaultText = "8.71.0~2026-03-23"),
# Human-readable presentation of the app version.
minUpgradableAppVersion = 0,
+5 -5
View File
@@ -28,11 +28,11 @@ class AttachmentMigrationService {
* @param {string} boardId - The board ID
* @returns {boolean} - True if board has been migrated
*/
isBoardMigrated(boardId) {
async isBoardMigrated(boardId) {
const isMigrated = migratedBoards.has(boardId);
// Update status collection for pub/sub
AttachmentMigrationStatus.upsert(
await AttachmentMigrationStatus.upsertAsync(
{ boardId },
{
$set: {
@@ -53,7 +53,7 @@ class AttachmentMigrationService {
async migrateBoardAttachments(boardId) {
try {
// Check if board has already been migrated
if (this.isBoardMigrated(boardId)) {
if (await this.isBoardMigrated(boardId)) {
console.log(`Board ${boardId} has already been migrated, skipping`);
return { success: true, message: 'Board already migrated' };
}
@@ -102,7 +102,7 @@ class AttachmentMigrationService {
console.log(`Marked board ${boardId} as migrated`);
// Update status collection
AttachmentMigrationStatus.upsert(
await AttachmentMigrationStatus.upsertAsync(
{ boardId },
{
$set: {
@@ -224,7 +224,7 @@ class AttachmentMigrationService {
const migratedCount = total - unconverted.length;
// Update status collection for pub/sub
AttachmentMigrationStatus.upsert(
await AttachmentMigrationStatus.upsertAsync(
{ boardId },
{
$set: {
+4 -4
View File
@@ -75,7 +75,7 @@ Meteor.startup(() => {
process.env.ORACLE_OIM_ENABLED === 'true' ||
process.env.ORACLE_OIM_ENABLED === true
) {
ServiceConfiguration.configurations.upsert(
ServiceConfiguration.configurations.upsertAsync(
// eslint-disable-line no-undef
{ service: 'oidc' },
{
@@ -97,7 +97,7 @@ Meteor.startup(() => {
process.env.OAUTH2_ENABLED === 'true' ||
process.env.OAUTH2_ENABLED === true
) {
ServiceConfiguration.configurations.upsert(
ServiceConfiguration.configurations.upsertAsync(
// eslint-disable-line no-undef
{ service: 'oidc' },
{
@@ -121,7 +121,7 @@ Meteor.startup(() => {
process.env.CAS_ENABLED === 'true' ||
process.env.CAS_ENABLED === true
) {
ServiceConfiguration.configurations.upsert(
ServiceConfiguration.configurations.upsertAsync(
// eslint-disable-line no-undef
{ service: 'cas' },
{
@@ -145,7 +145,7 @@ Meteor.startup(() => {
process.env.SAML_ENABLED === 'true' ||
process.env.SAML_ENABLED === true
) {
ServiceConfiguration.configurations.upsert(
ServiceConfiguration.configurations.upsertAsync(
// eslint-disable-line no-undef
{ service: 'saml' },
{
+9 -9
View File
@@ -1713,7 +1713,7 @@ class CronMigrationManager {
this.startTime = Date.now();
// Update CronJobStatus for immediate pub/sub notification
CronJobStatus.upsert(
await CronJobStatus.upsertAsync(
{ jobId: 'migration' },
{
$set: {
@@ -1784,7 +1784,7 @@ class CronMigrationManager {
this.isRunning = false;
// Update CronJobStatus
CronJobStatus.upsert(
await CronJobStatus.upsertAsync(
{ jobId: 'migration' },
{
$set: {
@@ -1800,7 +1800,7 @@ class CronMigrationManager {
}
// Update to running state
CronJobStatus.upsert(
await CronJobStatus.upsertAsync(
{ jobId: 'migration' },
{
$set: {
@@ -2555,7 +2555,7 @@ class CronMigrationManager {
cronMigrationStatus.set('Migrations paused');
// Update CronJobStatus for immediate pub/sub notification
CronJobStatus.upsert(
await CronJobStatus.upsertAsync(
{ jobId: 'migration' },
{
$set: {
@@ -2577,7 +2577,7 @@ class CronMigrationManager {
}
// Update to final paused state
CronJobStatus.upsert(
await CronJobStatus.upsertAsync(
{ jobId: 'migration' },
{
$set: {
@@ -2597,7 +2597,7 @@ class CronMigrationManager {
*/
async stopAllMigrations() {
// Update CronJobStatus for immediate pub/sub notification
CronJobStatus.upsert(
await CronJobStatus.upsertAsync(
{ jobId: 'migration' },
{
$set: {
@@ -2635,7 +2635,7 @@ class CronMigrationManager {
cronMigrationStatus.set('All migrations stopped');
// Update to final stopped state
CronJobStatus.upsert(
await CronJobStatus.upsertAsync(
{ jobId: 'migration' },
{
$set: {
@@ -2649,9 +2649,9 @@ class CronMigrationManager {
);
// Clear status message after delay
Meteor.setTimeout(() => {
Meteor.setTimeout(async () => {
cronMigrationStatus.set('');
CronJobStatus.upsert(
await CronJobStatus.upsertAsync(
{ jobId: 'migration' },
{
$set: {
+1 -1
View File
@@ -858,7 +858,7 @@ const runNotificationCleanup = async function runNotificationCleanup() {
for (const user of await ReactiveCache.getUsers()) {
if (!user.profile || !user.profile.notifications) continue;
for (const notification of user.profile.notifications) {
if (notification.read) {
if (notification && notification.read) {
const removeDate = new Date(notification.read);
removeDate.setDate(removeDate.getDate() + removeAge);
if (removeDate <= new Date()) {
+4 -4
View File
@@ -1,5 +1,5 @@
name: wekan
version: '8.69'
version: '8.71'
base: core24
summary: Open Source kanban
description: |
@@ -135,9 +135,9 @@ parts:
rm -rf .build
mkdir .build
cd .build
wget https://github.com/wekan/wekan/releases/download/v8.69/wekan-8.69-amd64.zip
unzip wekan-8.69-amd64.zip
rm wekan-8.69-amd64.zip
wget https://github.com/wekan/wekan/releases/download/v8.71/wekan-8.71-amd64.zip
unzip wekan-8.71-amd64.zip
rm wekan-8.71-amd64.zip
cd ..
# Copy to Snap
wget https://nodejs.org/dist/latest-v22.x/node-v22.22.2-linux-x64.tar.xz