Browse Source

fix(image-updater): refactored linkbot monitors to increase code reuse

+ aligned linkbot information with other js projects

Ticket: None
Changelog: None
Signed-off-by: Manuel Zedel <manuel.zedel@northern.tech>
pr_475
Manuel Zedel 2 years ago
parent
commit
25bc66d626
No known key found for this signature in database GPG Key ID: 26B023069A7BE03C
  1. 29
      .github/workflows/automatically-update-test-links.yml
  2. 70
      scripts/linkbot/common.js
  3. 31
      scripts/linkbot/index.js
  4. 66
      scripts/linkbot/monitor-bb-sd.js
  5. 70
      scripts/linkbot/monitor-bb.js
  6. 133
      scripts/linkbot/monitor-raspbian-os.js
  7. 93
      scripts/linkbot/monitor-rpi.js
  8. 98
      scripts/linkbot/monitor-ub-server.js
  9. 4
      scripts/linkbot/package-lock.json
  10. 21
      scripts/linkbot/package.json

29
.github/workflows/automatically-update-test-links.yml

@ -1,7 +1,7 @@
name: automatically-update-test-links
on:
schedule:
- cron: "0 03 * * 1"
- cron: '0 03 * * 1'
workflow_dispatch:
jobs:
@ -12,29 +12,24 @@ jobs:
- uses: actions/setup-node@v2
- name: Make changes to pull request
run: |
npm ci
node monitor-bb.js
node monitor-bb-sd.js
node monitor-rpi.js
node monitor-ub-server.js
node monitor-raspbian-os.js
npm ci
npm run start
working-directory: scripts/linkbot
- name: Create Pull Request
id: cpr
uses: peter-evans/create-pull-request@v3
with:
title: "Image-Bot: New images available"
body: |
New images are available for update
commit-message: |
chore: Image-Bot image updates
Base image updates for our provided images.
committer: mender-test-bot <mender@northern.tech>
author: mender-test-bot <mender@northern.tech>
signoff: true
title: 'Image-Bot: New images available'
body: |
New images are available for update
commit-message: |
chore: Image-Bot image updates
Base image updates for our provided images.
committer: mender-test-bot <mender@northern.tech>
author: mender-test-bot <mender@northern.tech>
signoff: true
- name: Check outputs
run: |

70
scripts/linkbot/common.js

@ -1,18 +1,58 @@
const fs = require('fs');
const updateURLLink = (newLine, target) => {
try {
const data = fs.readFileSync('../test/run-tests.sh', 'utf8')
.replace(RegExp(`## Auto-update\n${target}=.*`), `## Auto-update\n${newLine}`);
fs.writeFile('../test/run-tests.sh', data, (err, data) => {
if (err) {
console.error(err);
}
});
} catch (err) {
import { JSDOM } from 'jsdom';
import fs from 'fs';
export const fileTypes = {
testRunner: {
key: 'testRunner',
path: '../test/run-tests.sh',
matcher: (target) => (line) => line.match(`${target}=.*`),
replacer: ({ newLine, target }) => [RegExp(`## Auto-update\n${target}=.*`), `## Auto-update\n${newLine}`]
},
ciFile: {
key: 'ciFile',
path: '../../.gitlab-ci.yml',
matcher: (target) => (line) => line.match(`${target}: .*`),
replacer: ({ targetName, targetUrl, newName, newUrl }) => [
RegExp(` *## Auto-update\n *${targetUrl}:.*\n *${targetName}: .*`),
` ## Auto-update\n ${targetUrl}: "${newUrl}"\n ${targetName}: ${newName}`
]
}
};
export const updateURLLink = (updatedValues, fileType = fileTypes.testRunner.key) => {
try {
const data = fs.readFileSync(fileTypes[fileType].path, 'utf8').replace(...fileTypes[fileType].replacer(updatedValues));
fs.writeFile(fileTypes[fileType].path, data, (err) => {
if (err) {
console.error(err);
process.exit(1);
}
}
});
} catch (err) {
console.error(err);
process.exit(1);
}
};
module.exports = {
updateURLLink
export const getCurrentTestData = (target, matcher, fileType = fileTypes.testRunner.key) => {
let line;
try {
line = fs.readFileSync(fileTypes[fileType].path, 'utf8').split('\n').find(fileTypes[fileType].matcher(target));
} catch (err) {
console.error(err);
process.exit(1);
}
const match = line.match(matcher);
return match.groups;
};
export const getLinksByMatch = (url, matcher) =>
JSDOM.fromURL(url, {}).then((dom) => {
const refs = dom.window.document.getElementsByTagName('a');
return Array.from(refs).reduce((accu, element) => {
const match = element.textContent.match(matcher);
if (match) {
accu.push({ element, link: element.href, match });
}
return accu;
}, []);
});

31
scripts/linkbot/index.js

@ -0,0 +1,31 @@
import { updateURLLink } from './common.js';
import * as bbMonitor from './monitor-bb.js';
import * as bbSdMonitor from './monitor-bb-sd.js';
import * as rpiMonitor from './monitor-rpi.js';
import * as ubuntuServerMonitor from './monitor-ub-server.js';
import * as raspbianOsMonitor from './monitor-raspbian-os.js';
const monitors = {
bbMonitor,
bbSdMonitor,
rpiMonitor,
ubuntuServerMonitor,
raspbianOsMonitor
};
Object.entries(monitors).map(async ([monitorName, { checkForUpdates, determineCurrentState, target, updateReference }]) => {
console.log(`${monitorName}: starting`);
// Read the input file, and parse the variable input
const state = await determineCurrentState();
const result = await checkForUpdates(state);
if (!result) {
console.log(`${monitorName}: no updates found`);
return;
}
console.log(`${monitorName}: We've got a new release! \\o/`);
if (updateReference) {
await updateReference(result);
return;
}
await updateURLLink({ ...result, target });
});

66
scripts/linkbot/monitor-bb-sd.js

@ -1,49 +1,23 @@
const jsdom = require("jsdom");
const { JSDOM } = jsdom;
const fs = require('fs')
const { updateURLLink } = require('./common');
import { getCurrentTestData, getLinksByMatch } from './common.js';
const target = "BBB_DEBIAN_SDCARD_IMAGE_URL"
const reg = 'bone-debian-(?<version>[0-9]+.[0-9]+)-iot-armhf-(?<date>[0-9]{4}-[0-9]{2}-[0-9]{1,2})-4gb.img.xz$';
export const target = 'BBB_DEBIAN_SDCARD_IMAGE_URL';
var reg = "bone-debian-(?<version>[0-9]+\.[0-9]+)-iot-armhf-(?<date>[0-9]{4}-[0-9]{2}-[0-9]{1,2})-4gb.img.xz$"
// Read the input file, and parse the variable input
try {
const data = fs.readFileSync('../test/run-tests.sh', 'utf8')
.split('\n')
.filter(line => line.match(`${target}=.*`))
var line = data[0]
var m = line.match(".*=\"(?<url>[a-zA-Z-://\._]*)(?<imageName>bone-debian-(?<version>[0-9]+\.[0-9]+)-iot-armhf-(?<date>[0-9]{4}-[0-9]{2}-[0-9]{1,2})-4gb.img.xz)")
var url = m.groups.url
var currentImageName = m.groups.imageName
} catch (err) {
console.error(err)
process.exit(1)
}
JSDOM.fromURL(url, {}).then(dom => {
var document = dom.window.document;
var table = document.getElementById("list");
var rows = table.rows;
var matches = Array.from(rows)
.filter(row => row.firstChild.textContent.match(reg))
.reduce((acc, element) => {
var regMatch = element.firstChild.textContent.match(reg)
acc.push({
text: element.firstChild.textContent,
version: regMatch.groups.version,
date: regMatch.groups.date,
})
return acc
}, [])
.sort((a,b) => {
// The bone-debian setup has two parts which needs comparing:
// * The release-version: i.e., 10.3
// * The date: i.e., 2020-04-06
return parseFloat(b.version) - parseFloat(a.version) || Date.parse(b.date) - Date.parse(a.date)
})
if (matches[0].text !== currentImageName) {
console.error("We've got a new release! \\o/");
updateURLLink(`${target}=\"${url}/${matches[0].text}\"`)
export const checkForUpdates = ({ url, imageName }) =>
getLinksByMatch(url, reg).then(async (links) => {
// The bone-debian setup has two parts which needs comparing:
// * The release-version: i.e., 10.3
// * The date: i.e., 2020-04-06
const matches = links.sort((a, b) => parseFloat(b.match.groups.version) - parseFloat(a.match.groups.version) || Date.parse(b.date) - Date.parse(a.date));
const { element, link } = matches[0];
if (element.textContent === imageName) {
return;
}
});
return { newLine: `${target}="${link}"` };
});
export const determineCurrentState = () =>
getCurrentTestData(
target,
'.*="(?<url>[a-zA-Z-://._]*)(?<imageName>bone-debian-(?<version>[0-9]+.[0-9]+)-iot-armhf-(?<date>[0-9]{4}-[0-9]{2}-[0-9]{1,2})-4gb.img.xz)'
);

70
scripts/linkbot/monitor-bb.js

@ -1,58 +1,18 @@
const jsdom = require("jsdom");
const { JSDOM } = jsdom;
const fs = require('fs')
const { updateURLLink } = require('./common');
import { getCurrentTestData, getLinksByMatch } from './common.js';
const reg = "[0-9]{4}-[0-9]{2}-[0-9]{1,2}/"
const target = "BBB_DEBIAN_EMMC_IMAGE_URL"
const reg = '[0-9]{4}-[0-9]{2}-[0-9]{1,2}/';
export const target = 'BBB_DEBIAN_EMMC_IMAGE_URL';
// Read the input file, and parse the variable input
try {
const data = fs.readFileSync('../test/run-tests.sh', 'utf8')
.split('\n')
.filter(line => line.match(`${target}=.*`))
var line = data[0]
var m = line.match(".*=\"(?<url>[a-zA-Z-://\.]*)(?<latestDate>[0-9]{4}-[0-9]{2}-[0-9]{1,2}/).*")
var url = m.groups.url
var latestDate = m.groups.latestDate
} catch (err) {
console.error(err)
process.exit(1)
}
function getNewBoneDebian(url) {
return JSDOM.fromURL(url, {}).then(dom => {
var document = dom.window.document;
var refs = document.getElementsByTagName("a");
var test = Array.from(refs)
.filter(ref => ref.textContent.match(("bone-debian.*\.img\.xz$")))
.reduce((acc, element) => {
acc.push(element.textContent.match("bone-debian.*\.img\.xz$").input)
return acc
}, [])[0]
return `${target}=\"${url}/${test}\"`;
});
}
JSDOM.fromURL(url, {}).then(async dom => {
var document = dom.window.document;
var table = document.getElementsByTagName("table");
var rows = table[0].rows;
var matches = Array.from(rows)
.filter(row => row.children.length == 5)
.filter(row => row.children[1].textContent.match(reg))
.reduce((acc, row ) => {
acc.push(row.children[1].textContent)
return acc
}, [])
.sort((a,b) => {
return Date.parse(b) - Date.parse(a)
})
if (matches[0] !== latestDate) {
console.error("We've got a new release! \\o/");
var newVar = await getNewBoneDebian(`${url}${matches[0]}buster-console`)
if (newVar) {
updateURLLink(newVar, target)
}
export const checkForUpdates = ({ url, latestDate }) =>
getLinksByMatch(url, reg).then(async (links) => {
const matches = links.sort((a, b) => Date.parse(b.element.textContent) - Date.parse(a.element.textContent));
const date = matches[0].element.textContent;
if (date === latestDate) {
return;
}
});
const consoleLinks = await getLinksByMatch(matches[0].link, 'buster-console');
const result = await getLinksByMatch(consoleLinks[0].link, 'bone-debian.*.img.xz$').then((links) => `${target}=\"${links[0].link}\"`);
return { newLine: result };
});
export const determineCurrentState = () => getCurrentTestData(target, '.*="(?<url>[a-zA-Z-://.]*)(?<latestDate>[0-9]{4}-[0-9]{2}-[0-9]{1,2}/).*');

133
scripts/linkbot/monitor-raspbian-os.js

@ -1,115 +1,30 @@
const jsdom = require("jsdom");
const { JSDOM } = jsdom;
const fs = require("fs");
const { updateURLLink } = require("./common");
import { getCurrentTestData, getLinksByMatch, fileTypes, updateURLLink } from './common.js';
const target = "RASPBIAN_URL";
const reg = 'raspios_lite_armhf-(?<date>[0-9]{4}-[0-9]{2}-[0-9]{1,2})/.*';
export const target = 'RASPBIAN_URL';
// Read the input file, and parse the variable input
try {
const data = fs
.readFileSync("../../.gitlab-ci.yml", "utf8")
.split("\n")
.filter((line) => line.match(`${target}: .*`));
var line = data[0];
console.log(line);
var reg =
"raspios_lite_armhf-(?<date>[0-9]{4}-[0-9]{2}-[0-9]{1,2})/(?<updated>[0-9]{4}-[0-9]{2}-[0-9]{1,2}).*$";
var m = line.match(
".*: \"(?<url>[a-zA-Z-://._]*)(?<imageName>raspios_lite_armhf-[0-9]{4}-[0-9]{2}-[0-9]{1,2})/(?<updated>[0-9]{4}-[0-9]{2}-[0-9]{1,2}).*\"$"
);
console.log(m);
var url = m.groups.url;
var imageName = m.groups.imageName;
var updated = m.groups.updated;
} catch (err) {
console.error(err);
process.exit(1);
}
function getNewRaspbian(target, url, separator) {
console.log("getNewRaspbian");
console.log(`${url}`);
return JSDOM.fromURL(url, {}).then((dom) => {
var document = dom.window.document;
var refs = document.getElementsByTagName("a");
var test = Array.from(refs)
.filter((ref) => ref.textContent.match("raspios-.*-lite.*\.img\.(zip|xz)$"))
.reduce((acc, element) => {
acc.push(element.textContent.match("raspios-.*-lite.*\.img\.(zip|xz)$").input);
return acc;
}, [])[0];
console.log(`Test var: ${test}`);
const imageName = test.substring(0, test.lastIndexOf('.img'));
if (separator) {
return {
replacementLine: `${target}${separator} \"${url}/${test}\"`,
imageName: imageName,
};
}
return { replacementLine: `${target}=\"${url}/${test}\"`, imageName: imageName };
});
}
function updateGitlabCILink(newLine, newURL, newName) {
try {
const data = fs
.readFileSync("../../.gitlab-ci.yml", "utf8")
.replace(
RegExp(` *## Auto-update\n *${newURL}:.*\n *RASPBIAN_NAME: .*`),
` ## Auto-update\n ${newLine}\n RASPBIAN_NAME: ${newName}`
);
fs.writeFile("../../.gitlab-ci.yml", data, (err, data) => {
if (err) {
console.error(err);
}
});
} catch (err) {
console.error(err);
process.exit(1);
}
}
JSDOM.fromURL(url, {}).then((dom) => {
var document = dom.window.document;
var table = document.getElementsByTagName("table");
var rows = table[0].rows;
var matches = [];
for (var i = 0; i < rows.length; i++) {
var rowText = rows[i].textContent;
var regMatch = rowText.match(reg);
if (regMatch) {
matches.push(regMatch);
}
}
// Sort the accumulated matches
matches.sort(function (a, b) {
let al = Date.parse(a.groups.date);
let bl = Date.parse(b.groups.date);
if (al == bl) {
let ad = Date.parse(a.groups.updated);
let bd = Date.parse(b.groups.updated);
return bd - ad;
export const checkForUpdates = ({ url, imageName: currentImageName }) =>
getLinksByMatch(url, reg).then(async (links) => {
const { link, match } = links.sort((a, b) => Date.parse(b.match.groups.date) - Date.parse(a.match.groups.date))[0];
const matchOn = match.input.split('/')[0];
if (matchOn === currentImageName) {
return;
}
return bl - al;
});
var matchOn = matches[0].input.split("/")[0];
if (matchOn !== imageName) {
// We also need to extract the new image name from the index folder, as
// dated folders contain images with different dates in them o_O
console.error("We've got a new release! \\o/");
const newLinks = await getLinksByMatch(link, 'raspios-.*-lite.*.img.(zip|xz)$');
const { link: newUrl, match: imageMatch } = newLinks[0];
const imageName = imageMatch.input.substring(0, imageMatch.input.lastIndexOf('.img'));
console.log(`New release: ${newUrl}`);
return { newName: imageName, newUrl };
});
// Update the GitlabCI link unconditionally
console.log("Updating the GitlabCI Link");
var newVar = getNewRaspbian(
"RASPBIAN_URL",
`${url}${matches[0].input.split(" ")[0].split("/").slice(0, -1)}`,
(separator = ":")
).then(({ replacementLine, imageName }) => {
console.log(`New release: ${replacementLine}`);
updateGitlabCILink(replacementLine, "RASPBIAN_URL", imageName);
});
}
});
// Read the input file, and parse the variable input
export const determineCurrentState = () =>
getCurrentTestData(target, '.*: "(?<url>[a-zA-Z-://._]*)(?<imageName>raspios_lite_armhf-[0-9]{4}-[0-9]{2}-[0-9]{1,2})/.*"$', fileTypes.ciFile.key);
export const updateReference = ({ newName, newUrl }) => {
// Update the GitlabCI link
console.log('Updating the GitlabCI Link');
updateURLLink({ targetName: 'RASPBIAN_NAME', targetUrl: target, newName, newUrl }, fileTypes.ciFile.key);
};

93
scripts/linkbot/monitor-rpi.js

@ -1,77 +1,22 @@
const jsdom = require("jsdom");
const { JSDOM } = jsdom;
const fs = require('fs');
const { updateURLLink } = require('./common');
import { getCurrentTestData, getLinksByMatch } from './common.js';
const target = "RASPBIAN_IMAGE_URL";
const reg = 'raspbian_lite-(?<date>[0-9]{4}-[0-9]{2}-[0-9]{1,2})/';
export const target = 'RASPBIAN_IMAGE_URL';
// Read the input file, and parse the variable input
try {
const data = fs.readFileSync('../test/run-tests.sh', 'utf8')
.split('\n')
.filter(line => line.match(`${target}=.*`));
var line = data[0];
console.log(line);
var reg = "raspbian_lite-(?<date>[0-9]{4}-[0-9]{2}-[0-9]{1,2})/(?<updated>[0-9]{4}-[0-9]{2}-[0-9]{1,2}).*$";
var m = line.match(".*=\"(?<url>[a-zA-Z-://\._]*)(?<imageName>raspbian_lite-[0-9]{4}-[0-9]{2}-[0-9]{1,2})/(?<updated>[0-9]{4}-[0-9]{2}-[0-9]{1,2}).*$");
console.log(m);
var url = m.groups.url;
var imageName = m.groups.imageName;
var updated = m.groups.updated;
} catch (err) {
console.error(err);
process.exit(1);
}
function getNewRaspbian(url) {
console.log("getNewRaspbian");
console.log(`${url}`);
return JSDOM.fromURL(url, {}).then(dom => {
var document = dom.window.document;
var refs = document.getElementsByTagName("a");
var test = Array.from(refs)
.filter(ref => ref.textContent.match(("raspbian-.*-lite.*\.zip$")))
.reduce((acc, element) => {
acc.push(element.textContent.match("raspbian-.*-lite.*\.zip$").input);
return acc;
}, [])[0];
return `${target}=\"${url}/${test}\"`;
});
}
JSDOM.fromURL(url, {}).then(dom => {
var document = dom.window.document;
var table = document.getElementsByTagName("table");
var rows = table[0].rows;
var matches = [];
for (var i=0; i< rows.length; i++) {
var rowText = rows[i].textContent;
var regMatch = rowText.match(reg);
if (regMatch) {
matches.push(regMatch);
}
export const checkForUpdates = ({ url, imageName }) =>
getLinksByMatch(url, reg).then(async (links) => {
const matches = links.sort((a, b) => Date.parse(b.match.groups.date) - Date.parse(a.match.groups.date));
const { link, match } = matches[0];
const matchOn = match.input.split('/')[0];
if (matchOn === imageName) {
return;
}
// Sort the accumulated matches
matches.sort(function(a,b) {
let al = Date.parse(a.groups.date);
let bl = Date.parse(b.groups.date);
if (al == bl) {
let ad = Date.parse(a.groups.updated);
let bd = Date.parse(b.groups.updated);
return bd - ad;
}
return bl - al;
});
var matchOn = matches[0].input.split("/")[0];
if (matchOn !== imageName) {
// We also need to extract the new image name from the index folder, as
// dated folders contain images with different dates in them o_O
console.error("We've got a new release! \\o/");
var newVar = getNewRaspbian(`${url}${matches[0].input.split(" ")[0].split("/").slice(0, -1)}`)
.then(res => {
console.log(`New release: ${res}`);
updateURLLink(res, target);
});
}
});
// We also need to extract the new image name from the index folder, as
// dated folders contain images with different dates in them o_O
console.error("We've got a new release! \\o/");
const newLink = await getLinksByMatch(link, 'raspbian-.*-lite.*.zip$').then((links) => `${target}=\"${links[0].link}\"`);
console.log(`New release: ${newLink}`);
return { newLine: newLink };
});
export const determineCurrentState = () => getCurrentTestData(target, '.*="(?<url>[a-zA-Z-://._]*)(?<imageName>raspbian_lite-[0-9]{4}-[0-9]{2}-[0-9]{1,2})/');

98
scripts/linkbot/monitor-ub-server.js

@ -1,68 +1,38 @@
const jsdom = require("jsdom");
const { JSDOM } = jsdom;
const fs = require('fs');
const { updateURLLink } = require('./common');
import { getCurrentTestData, getLinksByMatch } from './common.js';
const target = "UBUNTU_SERVER_RPI_IMAGE_URL";
const url = "http://cdimage.ubuntu.com/ubuntu/releases/";
const reg = ".*(?<release>[0-9][02468])\.04\.?(?<minor>[0-9]{1})?.*";
const reg = '(?<url>[a-zA-Z-://._]*)(?<release>[0-9][02468]).04.?(?<minor>[0-9]{1})?.*';
export const target = 'UBUNTU_SERVER_RPI_IMAGE_URL';
// Read the input file, and parse the variable input
try {
const data = fs.readFileSync('../test/run-tests.sh', 'utf8')
.split('\n')
.filter(line => line.match(`${target}=.*`));
var line = data[0];
var m = line.match(`.*=\"${reg}\"`);
var imageName = m.groups.release;
var minor = m.groups.minor || 0;
} catch (err) {
console.error(err);
process.exit(1);
}
const getReleaseName = (release, minor) => `${release}.04${minor ? `.${minor}` : ''}`;
JSDOM.fromURL(url, {}).then(dom => {
var document = dom.window.document;
var refs = document.getElementsByTagName("a");
var matches = Array.from(refs)
.filter(ref => ref.textContent.match(reg))
.filter(ref => !ref.textContent.match(reg).groups.minor) // Ignore the minor number
.reduce((acc, ref) => {
acc.push(ref.textContent.match(reg));
return acc;
}, [])
.sort((a,b) => {
return parseInt(b.groups.release) - parseInt(a.groups.release);
});
var matchOn = matches[0].input;
return matchOn;
// Get the release image url from the releases (sub)-page
// const url = "http://cdimage.ubuntu.com/ubuntu/releases/"
}).then(releaseVersion => {
var releasedVersion = releaseVersion.replace(/\s/g, "").replace(/\//g, "");
JSDOM.fromURL(`${url}${releasedVersion}/release/`, {}).then(dom => {
var document = dom.window.document;
var refs = document.getElementsByTagName("a");
const match = Array.from(refs).find(ref => ref.href.match(`.*ubuntu-${releasedVersion}\.?[0-9]+-preinstalled-server-armhf.*\.img\.xz$`));
if (match) {
console.log(`Ubuntu server image has a new release: ${match}`);
updateURLLink(`${target}=\"${match}\"`, target);
}
})
.catch(err => {
console.log('Failed to get the update URL');
console.log(`${url}${releasedVersion}/release/`);
JSDOM.fromURL(`${url}${releasedVersion}/beta/`, {})
.then(dom => {
console.log('Only the beta is out still');
});
});
})
.catch(err => {
console.log('Failed to get the URL');
console.log(url);
console.log(err);
throw err;
// Get the release image url from the releases (sub)-page
export const checkForUpdates = async ({ url, release }) => {
const releasedVersion = await getLinksByMatch(url, reg).then((links) => {
const matches = links.sort((a, b) => {
if (b.match.groups.release === a.match.groups.release) {
return parseInt(b.match.groups.minor) - parseInt(a.match.groups.minor);
}
return parseInt(b.match.groups.release) - parseInt(a.match.groups.release);
});
const { match } = matches[0];
return getReleaseName(match.groups.release, match.groups.minor);
});
if (release === releasedVersion) {
return;
}
console.log(`Ubuntu server image has a new release: ${releasedVersion}`);
const links = await getLinksByMatch(`${url}${releasedVersion}/release/`, `.*ubuntu-${releasedVersion}-preinstalled-server-armhf.*\.img\.xz$`);
const { link, match } = links[0];
if (match) {
return { newLine: `${target}="${link}"` };
}
const betaLinks = await getLinksByMatch(`${url}${releasedVersion}/release/`, `.*ubuntu-${releasedVersion}-beta-preinstalled-server-armhf.*\.img\.xz$`);
if (betaLinks.length) {
console.log('Only the beta is out still');
}
};
export const determineCurrentState = () => {
const { minor, release, url } = getCurrentTestData(target, reg);
return { url, release: getReleaseName(release, minor) };
};

4
scripts/linkbot/package-lock.json

@ -1,9 +1,13 @@
{
"name": "linkbot",
"version": "1.0.0",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "linkbot",
"version": "1.0.0",
"license": "Apache-2.0",
"dependencies": {
"bent": "^7.3.12",
"jsdom": "^19.0.0"

21
scripts/linkbot/package.json

@ -1,6 +1,25 @@
{
"name": "linkbot",
"version": "1.0.0",
"description": "",
"main": "index.js",
"dependencies": {
"bent": "^7.3.12",
"jsdom": "^19.0.0"
}
},
"scripts": {
"start": "node index.js",
"test": "echo \"Error: no test specified\" && exit 1"
},
"type": "module",
"repository": {
"type": "git",
"url": "git+https://github.com/mendersoftware/mender-convert.git"
},
"author": "Northern.tech AS",
"license": "Apache-2.0",
"bugs": {
"url": "https://tracker.mender.io/projects/MEN"
},
"homepage": "https://github.com/mendersoftware/mender-convert#readme"
}

Loading…
Cancel
Save