Просмотр исходного кода

Merge branch 'master' into dev/7.0.x

Yuki Takei 2 лет назад
Родитель
Сommit
5dc643d13b

+ 0 - 7
.github/release-drafter-dev-7.0.x.yml

@@ -1,7 +0,0 @@
-_extends: growi:.github/release-drafter.yml
-
-prerelease: true
-
-# Filter previous releases to consider only those with the tags starts with 'v6.2'
-include-pre-releases: true
-tag-prefix: v7.0

+ 0 - 7
.github/release-drafter-master.yml

@@ -1,7 +0,0 @@
-_extends: growi:.github/release-drafter.yml
-
-prerelease: true
-
-# Filter previous releases to consider only those with the master branch
-include-pre-releases: true
-filter-by-commitish: true

+ 6 - 0
.github/release-drafter.yml

@@ -1,3 +1,9 @@
+prerelease: true
+
+# Filter previous releases to consider target_commitish
+include-pre-releases: true
+filter-by-commitish: true
+
 categories:
   - title: 'BREAKING CHANGES'
     labels:

+ 2 - 9
.github/workflows/draft-release.yml

@@ -29,17 +29,10 @@ jobs:
         uses: myrotvorets/info-from-package-json-action@1.2.0
         id: package-json
 
-      - name: Determine config file
-        id: determine-config-name
-        run: |
-          BRANCH_NAME="${{ github.ref_name }}"
-          BRANCH_NAME_REPLACED=${BRANCH_NAME/\//-}
-          echo "value=release-drafter-$BRANCH_NAME_REPLACED.yml" >> $GITHUB_OUTPUT
-
       - uses: release-drafter/release-drafter@v5
         id: release-drafter
         with:
-          config-name: ${{ steps.determine-config-name.outputs.value }}
+          config-name: release-drafter.yml
           name: v${{ steps.package-json.outputs.packageVersion }}
           tag: v${{ steps.package-json.outputs.packageVersion }}
           version: ${{ steps.package-json.outputs.packageVersion }}
@@ -68,7 +61,7 @@ jobs:
         uses: bakunyo/git-pr-release-action@master
         env:
           GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
-          GIT_PR_RELEASE_BRANCH_PRODUCTION: release/current
+          GIT_PR_RELEASE_BRANCH_PRODUCTION: release/${{ github.ref_name == 'master' && 'current' || steps.release-version.outputs.RELEASE_VERSION }}
           GIT_PR_RELEASE_BRANCH_STAGING: ${{ github.ref_name }}
           GIT_PR_RELEASE_TEMPLATE: .github/git-pr-release-template.erb
           GIT_PR_RELEASE_TITLE: Release v${{ steps.release-version.outputs.RELEASE_VERSION }}

+ 4 - 4
.github/workflows/release.yml

@@ -63,11 +63,11 @@ jobs:
         commit_message: Release v${{ steps.package-json.outputs.packageVersion }}
         tagging_message: v${{ steps.package-json.outputs.packageVersion }}
 
-    - uses: ncipollo/release-action@v1
+    - uses: softprops/action-gh-release@v1
       with:
         body: ${{ github.event.pull_request.body }}
-        tag: v${{ steps.package-json.outputs.packageVersion }}
-        token: ${{ secrets.GITHUB_TOKEN }}
+        tag_name: v${{ steps.package-json.outputs.packageVersion }}
+        target_commitish: ${{ github.head_ref }}
 
     - name: Delete drafts
       uses: hugo19941994/delete-draft-releases@v1.0.1
@@ -118,7 +118,7 @@ jobs:
       uses: repo-sync/pull-request@v2
       with:
         source_branch: support/prepare-v${{ steps.package-json.outputs.packageVersion }}
-        destination_branch: master
+        destination_branch: ${{ github.head_ref }}
         pr_title: Prepare v${{ steps.package-json.outputs.packageVersion }}
         pr_label: flag/exclude-from-changelog,type/prepare-next-version
         pr_body: "[skip ci] An automated PR generated by create-pr-for-next-rc"

+ 8 - 1
CHANGELOG.md

@@ -1,9 +1,16 @@
 # Changelog
 
-## [Unreleased](https://github.com/weseek/growi/compare/v6.1.11...HEAD)
+## [Unreleased](https://github.com/weseek/growi/compare/v6.1.12...HEAD)
 
 *Please do not manually update this file. We've automated the process.*
 
+## [v6.1.12](https://github.com/weseek/growi/compare/v6.1.11...v6.1.12) - 2023-08-14
+
+### 🐛 Bug Fixes
+
+- fix: Consider an empty page when renaming and duplicating (v6.1.x) (#7980) @yuki-takei
+- fix: Do not work image tag properties (#7977) @jam411
+
 ## [v6.1.11](https://github.com/weseek/growi/compare/v6.1.10...v6.1.11) - 2023-08-07
 
 ### 🐛 Bug Fixes

+ 2 - 2
apps/app/src/server/routes/apiv3/pages.js

@@ -529,7 +529,7 @@ module.exports = (crowi) => {
     // check whether path starts slash
     newPagePath = addHeadingSlash(newPagePath);
 
-    const isExist = await Page.count({ path: newPagePath }) > 0;
+    const isExist = await Page.exists({ path: newPagePath, isEmpty: false });
     if (isExist) {
       // if page found, cannot rename to that path
       return res.apiv3Err(new ErrorV3(`${newPagePath} already exists`, 'already_exists'), 409);
@@ -757,7 +757,7 @@ module.exports = (crowi) => {
       }
 
       // check page existence
-      const isExist = (await Page.count({ path: newPagePath })) > 0;
+      const isExist = (await Page.exists({ path: newPagePath, isEmpty: false }));
       if (isExist) {
         return res.apiv3Err(new ErrorV3(`Page exists '${newPagePath})'`, 'already_exists'), 409);
       }

+ 1 - 1
apps/app/src/server/service/page.ts

@@ -375,7 +375,7 @@ class PageService {
 
     const activity = await this.crowi.activityService.createActivity(parameters);
 
-    const isExist = await Page.exists({ path: newPagePath });
+    const isExist = await Page.exists({ path: newPagePath, isEmpty: false });
     if (isExist) {
       throw Error(`Page already exists at ${newPagePath}`);
     }

+ 8 - 1
apps/app/test/cypress/e2e/22-sharelink/22-sharelink--access-to-sharelink.cy.ts

@@ -31,7 +31,14 @@ context('Access to sharelink by guest', () => {
 
     // create share link
     cy.getByTestid('share-link-management').within(() => {
-      cy.getByTestid('btn-sharelink-toggleform').should('be.visible').click();
+      // open form
+      cy.waitUntil(() => {
+        // do
+        cy.getByTestid('btn-sharelink-toggleform').click();
+        // wait until
+        return cy.getByTestid('btn-sharelink-issue').then($elem => $elem.is(':visible'))
+      });
+
       cy.getByTestid('btn-sharelink-issue').should('be.visible').click();
 
       cy.get('tbody')

+ 75 - 10
apps/app/test/integration/service/v5.public-page.test.ts

@@ -135,9 +135,13 @@ describe('PageService page operations with only public pages', () => {
     const pageIdForRename9 = new mongoose.Types.ObjectId();
     const pageIdForRename10 = new mongoose.Types.ObjectId();
     const pageIdForRename11 = new mongoose.Types.ObjectId();
-    const pageIdForRename12 = new mongoose.Types.ObjectId();
-    const pageIdForRename13 = new mongoose.Types.ObjectId();
-    const pageIdForRename14 = new mongoose.Types.ObjectId();
+
+    const childPageIdForRename1 = new mongoose.Types.ObjectId();
+    const childPageIdForRename2 = new mongoose.Types.ObjectId();
+    const childPageIdForRename3 = new mongoose.Types.ObjectId();
+    const childPageIdForRename4 = new mongoose.Types.ObjectId();
+    const childPageIdForRename5 = new mongoose.Types.ObjectId();
+    const childPageIdForRename7 = new mongoose.Types.ObjectId();
 
     const pageIdForRename16 = new mongoose.Types.ObjectId();
 
@@ -235,7 +239,7 @@ describe('PageService page operations with only public pages', () => {
       },
       {
         _id: pageIdForRename10,
-        path: '/v5_ChildForRename1',
+        path: '/v5_ParentForRename10',
         grant: Page.GRANT_PUBLIC,
         creator: dummyUser1,
         lastUpdateUser: dummyUser1._id,
@@ -243,6 +247,23 @@ describe('PageService page operations with only public pages', () => {
       },
       {
         _id: pageIdForRename11,
+        path: '/v5_ParentForRename11',
+        grant: Page.GRANT_PUBLIC,
+        creator: dummyUser1,
+        lastUpdateUser: dummyUser1._id,
+        parent: rootPage._id,
+        isEmpty: true,
+      },
+      {
+        _id: childPageIdForRename1,
+        path: '/v5_ChildForRename1',
+        grant: Page.GRANT_PUBLIC,
+        creator: dummyUser1,
+        lastUpdateUser: dummyUser1._id,
+        parent: rootPage._id,
+      },
+      {
+        _id: childPageIdForRename2,
         path: '/v5_ChildForRename2',
         grant: Page.GRANT_PUBLIC,
         creator: dummyUser1,
@@ -250,7 +271,7 @@ describe('PageService page operations with only public pages', () => {
         parent: rootPage._id,
       },
       {
-        _id: pageIdForRename12,
+        _id: childPageIdForRename3,
         path: '/v5_ChildForRename3',
         grant: Page.GRANT_PUBLIC,
         creator: dummyUser1,
@@ -259,7 +280,7 @@ describe('PageService page operations with only public pages', () => {
         updatedAt: new Date('2021'),
       },
       {
-        _id: pageIdForRename13,
+        _id: childPageIdForRename4,
         path: '/v5_ChildForRename4',
         grant: Page.GRANT_PUBLIC,
         creator: dummyUser1,
@@ -267,7 +288,7 @@ describe('PageService page operations with only public pages', () => {
         parent: rootPage._id,
       },
       {
-        _id: pageIdForRename14,
+        _id: childPageIdForRename5,
         path: '/v5_ChildForRename5',
         grant: Page.GRANT_PUBLIC,
         creator: dummyUser1,
@@ -275,7 +296,7 @@ describe('PageService page operations with only public pages', () => {
         parent: rootPage._id,
       },
       {
-        _id: pageIdForRename16,
+        _id: childPageIdForRename7,
         path: '/v5_ChildForRename7',
         grant: Page.GRANT_PUBLIC,
         parent: rootPage._id,
@@ -286,7 +307,7 @@ describe('PageService page operations with only public pages', () => {
         grant: Page.GRANT_PUBLIC,
         creator: dummyUser1,
         lastUpdateUser: dummyUser1._id,
-        parent: pageIdForRename14,
+        parent: childPageIdForRename5,
         updatedAt: new Date('2021'),
       },
       {
@@ -294,7 +315,7 @@ describe('PageService page operations with only public pages', () => {
         grant: Page.GRANT_PUBLIC,
         creator: dummyUser1,
         lastUpdateUser: dummyUser1._id,
-        parent: pageIdForRename16,
+        parent: childPageIdForRename7,
       },
       {
         _id: pageIdForRename17,
@@ -470,6 +491,7 @@ describe('PageService page operations with only public pages', () => {
     const pageIdForDuplicate13 = new mongoose.Types.ObjectId();
     const pageIdForDuplicate14 = new mongoose.Types.ObjectId();
     const pageIdForDuplicate15 = new mongoose.Types.ObjectId();
+    const pageIdForDuplicate16 = new mongoose.Types.ObjectId();
 
     // revision ids
     const revisionIdForDuplicate1 = new mongoose.Types.ObjectId();
@@ -606,6 +628,13 @@ describe('PageService page operations with only public pages', () => {
         parent: pageIdForDuplicate14,
         revision: revisionIdForDuplicate12,
       },
+      {
+        _id: pageIdForDuplicate16,
+        path: '/v5_PageForDuplicate16',
+        grant: Page.GRANT_PUBLIC,
+        parent: rootPage._id,
+        isEmpty: true,
+      },
     ]);
 
     await Revision.insertMany([
@@ -1370,6 +1399,24 @@ describe('PageService page operations with only public pages', () => {
 
       expect(isThrown).toBe(true);
     });
+    test('Should rename/move to the path that exists as an empty page', async() => {
+      const page = await Page.findOne({ path: '/v5_ParentForRename10' });
+      const pageDistination = await Page.findOne({ path: '/v5_ParentForRename11', isEmpty: true });
+      expect(page).toBeTruthy();
+      expect(pageDistination).toBeTruthy();
+      expect(pageDistination.isEmpty).toBe(true);
+
+      const newPath = '/v5_ParentForRename11';
+      const renamedPage = await renamePage(page, newPath, dummyUser1, {}, {
+        ip: '::ffff:127.0.0.1',
+        endpoint: '/_api/v3/pages/rename',
+      });
+
+      expect(xssSpy).toHaveBeenCalled();
+      expect(renamedPage.path).toBe(newPath);
+      expect(renamedPage.isEmpty).toBe(false);
+      expect(renamedPage._id).toStrictEqual(page._id);
+    });
     test('Rename non-empty page path to its descendant non-empty page path', async() => {
       const initialPathForPage1 = '/v5_pageForRename17';
       const initialPathForPage2 = '/v5_pageForRename17/v5_pageForRename18';
@@ -1696,6 +1743,24 @@ describe('PageService page operations with only public pages', () => {
       expect(isThrown).toBe(true);
     });
 
+    test('Should duplicate to the path that exists as an empty page', async() => {
+      const page = await Page.findOne({ path: '/v5_PageForDuplicate1' });
+      expect(page).toBeTruthy();
+
+      const newPagePath = '/v5_PageForDuplicate16';
+      const duplicatedPage = await duplicate(page, newPagePath, dummyUser1, false);
+
+      const duplicatedRevision = await Revision.findOne({ pageId: duplicatedPage._id });
+      const baseRevision = await Revision.findOne({ pageId: page._id });
+
+      // new path
+      expect(xssSpy).toHaveBeenCalled();
+      expect(duplicatedPage.path).toBe(newPagePath);
+      expect(duplicatedPage._id).not.toStrictEqual(page._id);
+      expect(duplicatedPage.revision).toStrictEqual(duplicatedRevision._id);
+      expect(duplicatedRevision.body).toEqual(baseRevision.body);
+    });
+
     test('Should duplicate multiple pages', async() => {
       const basePage = await Page.findOne({ path: '/v5_PageForDuplicate3' });
       const revision = await Revision.findOne({ pageId: basePage._id });