mirror of
https://github.com/laurent22/joplin.git
synced 2025-01-23 18:53:36 +02:00
Merge branch 'release-2.12' into dev
This commit is contained in:
commit
60b89e7c52
@ -393,6 +393,7 @@ packages/app-desktop/services/sortOrder/notesSortOrderUtils.test.js
|
|||||||
packages/app-desktop/services/sortOrder/notesSortOrderUtils.js
|
packages/app-desktop/services/sortOrder/notesSortOrderUtils.js
|
||||||
packages/app-desktop/services/spellChecker/SpellCheckerServiceDriverNative.js
|
packages/app-desktop/services/spellChecker/SpellCheckerServiceDriverNative.js
|
||||||
packages/app-desktop/tools/notarizeMacApp.js
|
packages/app-desktop/tools/notarizeMacApp.js
|
||||||
|
packages/app-desktop/tools/renameReleaseAssets.js
|
||||||
packages/app-desktop/utils/checkForUpdatesUtils.test.js
|
packages/app-desktop/utils/checkForUpdatesUtils.test.js
|
||||||
packages/app-desktop/utils/checkForUpdatesUtils.js
|
packages/app-desktop/utils/checkForUpdatesUtils.js
|
||||||
packages/app-desktop/utils/checkForUpdatesUtilsTestData.js
|
packages/app-desktop/utils/checkForUpdatesUtilsTestData.js
|
||||||
|
5
.github/workflows/build-macos-m1.yml
vendored
5
.github/workflows/build-macos-m1.yml
vendored
@ -41,7 +41,8 @@ jobs:
|
|||||||
APPLE_APP_SPECIFIC_PASSWORD: ${{ secrets.APPLE_APP_SPECIFIC_PASSWORD }}
|
APPLE_APP_SPECIFIC_PASSWORD: ${{ secrets.APPLE_APP_SPECIFIC_PASSWORD }}
|
||||||
CSC_KEY_PASSWORD: ${{ secrets.APPLE_CSC_KEY_PASSWORD }}
|
CSC_KEY_PASSWORD: ${{ secrets.APPLE_CSC_KEY_PASSWORD }}
|
||||||
CSC_LINK: ${{ secrets.APPLE_CSC_LINK }}
|
CSC_LINK: ${{ secrets.APPLE_CSC_LINK }}
|
||||||
GH_TOKEN: ${{ secrets.GH_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
GH_REPO: ${{ github.repository }}
|
||||||
IS_CONTINUOUS_INTEGRATION: 1
|
IS_CONTINUOUS_INTEGRATION: 1
|
||||||
BUILD_SEQUENCIAL: 1
|
BUILD_SEQUENCIAL: 1
|
||||||
run: |
|
run: |
|
||||||
@ -56,6 +57,8 @@ jobs:
|
|||||||
if [[ $GIT_TAG_NAME = v* ]]; then
|
if [[ $GIT_TAG_NAME = v* ]]; then
|
||||||
echo "Building and publishing desktop application..."
|
echo "Building and publishing desktop application..."
|
||||||
PYTHON_PATH=$(which python) USE_HARD_LINKS=false yarn run dist --mac --arm64
|
PYTHON_PATH=$(which python) USE_HARD_LINKS=false yarn run dist --mac --arm64
|
||||||
|
|
||||||
|
yarn renameReleaseAssets --repo="$GH_REPO" --tag="$GIT_TAG_NAME" --token="$GITHUB_TOKEN"
|
||||||
else
|
else
|
||||||
echo "Building but *not* publishing desktop application..."
|
echo "Building but *not* publishing desktop application..."
|
||||||
|
|
||||||
|
1
.gitignore
vendored
1
.gitignore
vendored
@ -379,6 +379,7 @@ packages/app-desktop/services/sortOrder/notesSortOrderUtils.test.js
|
|||||||
packages/app-desktop/services/sortOrder/notesSortOrderUtils.js
|
packages/app-desktop/services/sortOrder/notesSortOrderUtils.js
|
||||||
packages/app-desktop/services/spellChecker/SpellCheckerServiceDriverNative.js
|
packages/app-desktop/services/spellChecker/SpellCheckerServiceDriverNative.js
|
||||||
packages/app-desktop/tools/notarizeMacApp.js
|
packages/app-desktop/tools/notarizeMacApp.js
|
||||||
|
packages/app-desktop/tools/renameReleaseAssets.js
|
||||||
packages/app-desktop/utils/checkForUpdatesUtils.test.js
|
packages/app-desktop/utils/checkForUpdatesUtils.test.js
|
||||||
packages/app-desktop/utils/checkForUpdatesUtils.js
|
packages/app-desktop/utils/checkForUpdatesUtils.js
|
||||||
packages/app-desktop/utils/checkForUpdatesUtilsTestData.js
|
packages/app-desktop/utils/checkForUpdatesUtilsTestData.js
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@joplin/app-desktop",
|
"name": "@joplin/app-desktop",
|
||||||
"version": "2.12.14",
|
"version": "2.12.15",
|
||||||
"description": "Joplin for Desktop",
|
"description": "Joplin for Desktop",
|
||||||
"main": "main.js",
|
"main": "main.js",
|
||||||
"private": true,
|
"private": true,
|
||||||
@ -14,7 +14,8 @@
|
|||||||
"watch": "tsc --watch --preserveWatchOutput --project tsconfig.json",
|
"watch": "tsc --watch --preserveWatchOutput --project tsconfig.json",
|
||||||
"start": "gulp build && electron . --env dev --log-level debug --open-dev-tools",
|
"start": "gulp build && electron . --env dev --log-level debug --open-dev-tools",
|
||||||
"test": "jest",
|
"test": "jest",
|
||||||
"test-ci": "yarn test"
|
"test-ci": "yarn test",
|
||||||
|
"renameReleaseAssets": "node tools/renameReleaseAssets.js"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
|
109
packages/app-desktop/tools/renameReleaseAssets.ts
Normal file
109
packages/app-desktop/tools/renameReleaseAssets.ts
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
import { parseArgs } from 'util';
|
||||||
|
|
||||||
|
interface Context {
|
||||||
|
repo: string; // {owner}/{repo}
|
||||||
|
githubToken: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const apiBaseUrl = 'https://api.github.com/repos/';
|
||||||
|
const defaultApiHeaders = (context: Context) => ({
|
||||||
|
'Authorization': `token ${context.githubToken}`,
|
||||||
|
'X-GitHub-Api-Version': '2022-11-28',
|
||||||
|
'Accept': 'application/vnd.github+json',
|
||||||
|
});
|
||||||
|
|
||||||
|
const getTargetRelease = async (context: Context, targetTag: string) => {
|
||||||
|
console.log('Fetching releases...');
|
||||||
|
|
||||||
|
// Note: We need to fetch all releases, not just /releases/tag/tag-name-here.
|
||||||
|
// The latter doesn't include draft releases.
|
||||||
|
|
||||||
|
const result = await fetch(`${apiBaseUrl}${context.repo}/releases`, {
|
||||||
|
method: 'GET',
|
||||||
|
headers: defaultApiHeaders(context),
|
||||||
|
});
|
||||||
|
|
||||||
|
const releases = await result.json();
|
||||||
|
if (!result.ok) {
|
||||||
|
throw new Error(`Error fetching release: ${JSON.stringify(releases)}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const release of releases) {
|
||||||
|
if (release.tag_name === targetTag) {
|
||||||
|
return release;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new Error(`No release with tag ${targetTag} found!`);
|
||||||
|
};
|
||||||
|
|
||||||
|
const updateReleaseAsset = async (context: Context, assetUrl: string, newName: string) => {
|
||||||
|
console.log('Updating asset with URL', assetUrl, 'to have name, ', newName);
|
||||||
|
|
||||||
|
// See https://docs.github.com/en/rest/releases/assets?apiVersion=2022-11-28#update-a-release-asset
|
||||||
|
const result = await fetch(assetUrl, {
|
||||||
|
method: 'PATCH',
|
||||||
|
headers: defaultApiHeaders(context),
|
||||||
|
body: JSON.stringify({
|
||||||
|
name: newName,
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!result.ok) {
|
||||||
|
throw new Error(`Unable to update release asset: ${await result.text()}`);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Renames release assets in Joplin Desktop releases
|
||||||
|
const renameReleaseAssets = async () => {
|
||||||
|
const args = parseArgs({
|
||||||
|
options: {
|
||||||
|
tag: { type: 'string' },
|
||||||
|
token: { type: 'string' },
|
||||||
|
repo: { type: 'string' },
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!args.values.tag || !args.values.token || !args.values.repo) {
|
||||||
|
throw new Error([
|
||||||
|
'Required arguments: --tag, --token, --repo',
|
||||||
|
' --tag should be a git tag with an associated release (e.g. v12.12.12)',
|
||||||
|
' --token should be a GitHub API token',
|
||||||
|
' --repo should be a string in the form user/reponame (e.g. laurent22/joplin)',
|
||||||
|
].join('\n'));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const context: Context = {
|
||||||
|
repo: args.values.repo,
|
||||||
|
githubToken: args.values.token,
|
||||||
|
};
|
||||||
|
|
||||||
|
console.log('Renaming release assets for tag', args.values.tag, context.repo);
|
||||||
|
|
||||||
|
const release = await getTargetRelease(context, args.values.tag);
|
||||||
|
|
||||||
|
if (!release.assets) {
|
||||||
|
console.log(release);
|
||||||
|
throw new Error(`Release ${release.name} missing assets!`);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Patterns used to rename releases
|
||||||
|
const renamePatterns = [
|
||||||
|
[/-arm64\.dmg$/, '-arm64.DMG'],
|
||||||
|
];
|
||||||
|
|
||||||
|
for (const asset of release.assets) {
|
||||||
|
for (const [pattern, replacement] of renamePatterns) {
|
||||||
|
if (asset.name.match(pattern)) {
|
||||||
|
const newName = asset.name.replace(pattern, replacement);
|
||||||
|
await updateReleaseAsset(context, asset.url, newName);
|
||||||
|
|
||||||
|
// Only rename a release once.
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
void renameReleaseAssets();
|
@ -1,4 +1,4 @@
|
|||||||
import { extractVersionInfo, Release, Platform, Architecture } from './checkForUpdatesUtils';
|
import { extractVersionInfo, Release, Platform, Architecture, GitHubRelease } from './checkForUpdatesUtils';
|
||||||
import { releases1, releases2 } from './checkForUpdatesUtilsTestData';
|
import { releases1, releases2 } from './checkForUpdatesUtilsTestData';
|
||||||
|
|
||||||
describe('checkForUpdates', () => {
|
describe('checkForUpdates', () => {
|
||||||
@ -104,4 +104,47 @@ describe('checkForUpdates', () => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('macOS should match both .DMG and .dmg extensions', () => {
|
||||||
|
// A .DMG may be used to prevent older versions of Joplin from downloading an incompatible
|
||||||
|
// release. Ensure that newer versions of Joplin can download these releases.
|
||||||
|
const releaseDataWithExtension = (extension: string) => {
|
||||||
|
const downloadURL = `https://github.com/laurent22/joplin/releases/download/v2.12.4/Joplin-2.12.4${extension}`;
|
||||||
|
const releaseData: GitHubRelease = {
|
||||||
|
prerelease: false,
|
||||||
|
body: 'this is a test',
|
||||||
|
tag_name: 'v2.12.4',
|
||||||
|
assets: [
|
||||||
|
{
|
||||||
|
name: `Joplin-2.12.4${extension}`,
|
||||||
|
browser_download_url: downloadURL,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
html_url: 'https://github.com/laurent22/joplin/releases/tag/v2.12.4',
|
||||||
|
};
|
||||||
|
|
||||||
|
return releaseData;
|
||||||
|
};
|
||||||
|
|
||||||
|
const releaseData = releaseDataWithExtension('-arm64.DMG');
|
||||||
|
const releaseInfo = extractVersionInfo([releaseData], 'darwin', 'arm64', false, { });
|
||||||
|
|
||||||
|
// Should match, with uppercase .DMG
|
||||||
|
expect(releaseInfo).toMatchObject({
|
||||||
|
version: '2.12.4',
|
||||||
|
downloadUrl: 'https://objects.joplinusercontent.com/v2.12.4/Joplin-2.12.4-arm64.DMG',
|
||||||
|
pageUrl: releaseData.html_url,
|
||||||
|
prerelease: releaseData.prerelease,
|
||||||
|
});
|
||||||
|
|
||||||
|
// Should not match when the extension is invalid
|
||||||
|
expect(
|
||||||
|
extractVersionInfo([releaseDataWithExtension('-arm64.dmG')], 'darwin', 'arm64', false, { }),
|
||||||
|
).toMatchObject({
|
||||||
|
version: '2.12.4',
|
||||||
|
downloadUrl: null,
|
||||||
|
pageUrl: releaseData.html_url,
|
||||||
|
prerelease: releaseData.prerelease,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
@ -86,18 +86,18 @@ export const extractVersionInfo = (releases: GitHubRelease[], platform: Platform
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const arm64DMGPattern = /arm64\.(dmg|DMG)$/;
|
||||||
if (platform === 'darwin' && arch === 'arm64') {
|
if (platform === 'darwin' && arch === 'arm64') {
|
||||||
foundAsset = release.assets.find(asset => {
|
foundAsset = release.assets.find(asset => {
|
||||||
return asset.name.endsWith('arm64.dmg');
|
return asset.name.match(arm64DMGPattern);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!foundAsset && platform === 'darwin') {
|
if (!foundAsset && platform === 'darwin') {
|
||||||
foundAsset = release.assets.find(asset => {
|
foundAsset = release.assets.find(asset => {
|
||||||
return fileExtension(asset.name) === 'dmg' && !asset.name.endsWith('arm64.dmg');
|
return fileExtension(asset.name) === 'dmg' && !asset.name.match(arm64DMGPattern);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (platform === 'linux') {
|
if (platform === 'linux') {
|
||||||
foundAsset = release.assets.find(asset => {
|
foundAsset = release.assets.find(asset => {
|
||||||
return fileExtension(asset.name) === 'AppImage';
|
return fileExtension(asset.name) === 'AppImage';
|
||||||
|
Loading…
x
Reference in New Issue
Block a user