Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Clean /tmp and $TMPDIR in make clean #9150

Merged
merged 1 commit into from
Oct 18, 2019

Conversation

vitvly
Copy link
Contributor

@vitvly vitvly commented Oct 9, 2019

Sometimes Metro bundler cache/Yarn cache get broken and this issue manifests itself in weird errors during app startup, e.g. ReactClassInterface: You are attempting to define 'UNSAFE_componentWillReceiveProps' on your component more than once. This conflict may be due to a mixin.

The solution is to clean temp directories, on macOS at least Yarn and Metro bundler put their cache files into /tmp and $TMPDIR folders.


Changes:

  • Define TMPDIR to be /tmp/tmp-status-react-$(BUILD_TAG) where BUILD_TAG is the commit
    • In case of Jenkins BUILD_TAG is a unique build identifier
  • Add TMPDIR to _NIX_KEEP so it's passed to Nix shell and builds
  • Add _tmpdir-mk target to Makefile to be called every time make is called
  • Add _tmpdir-rm target to Makefile to be called with make clean
  • Parallelize the 2 Archive and Upload stages to shorten the builds a bit
  • Undo the use of Nix shell for s3cmd upload, since Nix isn't available on master
  • Fixed fastlane ios clean job by adding missing NIX_IGNORE_SYMLINK_STORE=1 (fix failing TestFlight clean job #9232)

@vitvly vitvly requested a review from pedropombeiro October 9, 2019 15:52
@vitvly vitvly requested a review from a team as a code owner October 9, 2019 15:52
@auto-assign auto-assign bot removed the request for review from a team October 9, 2019 15:52
@ghost
Copy link

ghost commented Oct 9, 2019

Pull Request Checklist

  • Docs: Updated the documentation, if affected
  • Docs: Added or updated inline comments explaining intention of the code
  • Tests: Ensured that all new UI elements have been assigned accessibility IDs
  • Tests: Signaled need for E2E tests with label, if applicable
  • Tests: Briefly described what was tested and what platforms were used
  • UI: In case of UI changes, ensured that UI matches Figma
  • UI: In case of UI changes, requested review from a Core UI designer
  • UI: In case of UI changes, included screenshots of implementation

@vitvly vitvly requested review from flexsurfer and a team October 9, 2019 15:52
@status-im-auto
Copy link
Member

status-im-auto commented Oct 9, 2019

Jenkins Builds

Click to see older builds (78)
Commit #️⃣ Finished (UTC) Duration Platform Result
9ff2134 #1 2019-10-09 15:53:25 ~33 sec android-e2e 📄log
9ff2134 #1 2019-10-09 15:53:27 ~33 sec android 📄log
9ff2134 #1 2019-10-09 15:53:27 ~31 sec linux 📄log
9ff2134 #1 2019-10-09 15:53:27 ~30 sec windows 📄log
✔️ 9ff2134 #1 2019-10-09 16:03:30 ~10 min ios 📦ipa 📲
✔️ 9ff2134 #1 2019-10-09 16:04:34 ~11 min macos 📦dmg
✔️ be3223f #2 2019-10-14 10:31:15 ~13 min android-e2e 📦apk 📲
✔️ be3223f #2 2019-10-14 10:31:26 ~13 min android 📦apk 📲
✔️ be3223f #2 2019-10-14 10:32:11 ~14 min linux 📦App
✔️ be3223f #2 2019-10-14 10:33:09 ~14 min windows 📦exe
✔️ be3223f #2 2019-10-14 10:35:42 ~17 min ios 📦ipa 📲
✔️ be3223f #2 2019-10-14 10:46:36 ~28 min macos 📦dmg
✔️ be3223f #3 2019-10-14 13:03:26 ~11 min android-e2e 📦apk 📲
07df0b3 #3 2019-10-14 13:38:04 ~27 sec macos 📄log
✔️ 07df0b3 #3 2019-10-14 13:48:30 ~10 min ios 📦ipa 📲
✔️ 07df0b3 #4 2019-10-14 13:48:52 ~11 min android-e2e 📦apk 📲
✔️ 07df0b3 #3 2019-10-14 13:49:02 ~11 min android 📦apk 📲
✔️ 07df0b3 #3 2019-10-14 13:51:45 ~14 min linux 📦App
✔️ 07df0b3 #3 2019-10-14 13:52:38 ~15 min windows 📦exe
✔️ 66baccc #4 2019-10-14 14:12:25 ~9 min ios 📦ipa 📲
✔️ 66baccc #4 2019-10-14 14:13:54 ~11 min android 📦apk 📲
✔️ 66baccc #5 2019-10-14 14:14:00 ~11 min android-e2e 📦apk 📲
✔️ 66baccc #4 2019-10-14 14:15:54 ~13 min macos 📦dmg
✔️ 66baccc #4 2019-10-14 14:16:34 ~13 min linux 📦App
✔️ 66baccc #4 2019-10-14 14:17:11 ~14 min windows 📦exe
748c4ed #5 2019-10-17 10:02:08 ~28 sec macos 📄log
748c4ed #5 2019-10-17 10:02:08 ~30 sec ios 📄log
✔️ 748c4ed #5 2019-10-17 10:13:06 ~11 min android 📦apk 📲
✔️ 748c4ed #6 2019-10-17 10:13:24 ~11 min android-e2e 📦apk 📲
✔️ 748c4ed #5 2019-10-17 10:16:54 ~15 min linux 📦App
✔️ 748c4ed #5 2019-10-17 10:17:12 ~15 min windows 📦exe
✔️ f3e3355 #6 2019-10-17 11:06:44 ~9 min android 📦apk 📲
✔️ f3e3355 #6 2019-10-17 11:08:05 ~10 min ios 📦ipa 📲
✔️ f3e3355 #7 2019-10-17 11:09:06 ~11 min android-e2e 📦apk 📲
f3e3355 #6 2019-10-17 11:09:34 ~12 min macos 📄log
✔️ f3e3355 #6 2019-10-17 11:12:49 ~15 min linux 📦App
✔️ f3e3355 #6 2019-10-17 11:13:10 ~15 min windows 📦exe
✔️ 3c3661f #7 2019-10-17 11:29:08 ~8 min ios 📦ipa 📲
✔️ 3c3661f #8 2019-10-17 11:30:59 ~10 min android-e2e 📦apk 📲
3c3661f #7 2019-10-17 11:31:21 ~11 min macos 📄log
✔️ 3c3661f #7 2019-10-17 11:31:33 ~11 min android 📦apk 📲
✔️ 3c3661f #7 2019-10-17 11:35:01 ~14 min linux 📦App
✔️ 3c3661f #7 2019-10-17 11:35:12 ~14 min windows 📦exe
81adcaf #9 2019-10-17 17:31:59 ~11 min android-e2e 📄log
81adcaf #8 2019-10-17 17:32:23 ~12 min android 📄log
81adcaf #8 2019-10-17 17:32:27 ~12 min ios 📄log
81adcaf #8 2019-10-17 17:34:24 ~13 min linux 📄log
81adcaf #8 2019-10-17 17:34:35 ~14 min windows 📄log
81adcaf #8 2019-10-17 17:34:50 ~14 min macos 📄log
✔️ 3bcbebd #10 2019-10-17 17:47:30 ~9 min android-e2e 📦apk 📲
✔️ 3bcbebd #9 2019-10-17 17:47:52 ~10 min android 📦apk 📲
✔️ 3bcbebd #9 2019-10-17 17:52:37 ~14 min windows 📦exe
✔️ 3bcbebd #9 2019-10-17 17:53:25 ~15 min ios 📦ipa 📲
✔️ 3bcbebd #9 2019-10-17 17:57:29 ~19 min macos 📦dmg
8e4c963 #10 2019-10-17 18:45:00 ~27 sec linux 📄log
✔️ 8e4c963 #10 2019-10-17 18:56:06 ~11 min android 📦apk 📲
✔️ 8e4c963 #10 2019-10-17 18:56:31 ~11 min ios 📦ipa 📲
✔️ 8e4c963 #11 2019-10-17 18:57:29 ~12 min android-e2e 📦apk 📲
✔️ 8e4c963 #10 2019-10-17 18:57:55 ~13 min windows 📦exe
✔️ 8e4c963 #10 2019-10-17 18:59:34 ~14 min macos 📦dmg
✔️ 6e4b6ab #11 2019-10-17 19:40:21 ~10 min ios 📦ipa 📲
✔️ 6e4b6ab #12 2019-10-17 19:40:50 ~11 min android-e2e 📦apk 📲
✔️ 6e4b6ab #11 2019-10-17 19:41:26 ~12 min android 📦apk 📲
✔️ 6e4b6ab #11 2019-10-17 19:43:55 ~14 min linux 📦App
✔️ 6e4b6ab #11 2019-10-17 19:44:22 ~14 min windows 📦exe
✔️ 6e4b6ab #11 2019-10-17 19:44:59 ~15 min macos 📦dmg
✔️ 9d73a1b #12 2019-10-17 22:07:05 ~10 min ios 📦ipa 📲
✔️ 9d73a1b #13 2019-10-17 22:09:16 ~12 min android-e2e 📦apk 📲
✔️ 9d73a1b #12 2019-10-17 22:09:40 ~13 min android 📦apk 📲
✔️ 9d73a1b #12 2019-10-17 22:10:37 ~13 min linux 📦App
✔️ 9d73a1b #12 2019-10-17 22:10:44 ~14 min windows 📦exe
✔️ 9d73a1b #12 2019-10-17 22:12:08 ~15 min macos 📦dmg
✔️ 55b5450 #13 2019-10-17 22:45:59 ~9 min android 📦apk 📲
✔️ 55b5450 #13 2019-10-17 22:46:34 ~9 min ios 📦ipa 📲
✔️ 55b5450 #14 2019-10-17 22:48:32 ~11 min android-e2e 📦apk 📲
✔️ 55b5450 #13 2019-10-17 22:50:33 ~13 min linux 📦App
✔️ 55b5450 #13 2019-10-17 22:50:55 ~14 min windows 📦exe
✔️ 55b5450 #13 2019-10-17 22:55:06 ~18 min macos 📦dmg
Commit #️⃣ Finished (UTC) Duration Platform Result
✔️ ae6fd67 #15 2019-10-17 23:02:08 ~10 min android-e2e 📦apk 📲
✔️ ae6fd67 #14 2019-10-17 23:03:05 ~11 min android 📦apk 📲
✔️ ae6fd67 #14 2019-10-17 23:05:44 ~13 min linux 📦App
✔️ ae6fd67 #14 2019-10-17 23:05:54 ~13 min windows 📦exe
✔️ ae6fd67 #14 2019-10-17 23:13:51 ~21 min ios 📦ipa 📲
✔️ ae6fd67 #14 2019-10-17 23:19:59 ~28 min macos 📦dmg
✔️ d09ed15 #16 2019-10-17 23:26:40 ~11 min android-e2e 📦apk 📲
✔️ d09ed15 #15 2019-10-17 23:28:46 ~13 min android 📦apk 📲
✔️ d09ed15 #15 2019-10-17 23:29:32 ~14 min linux 📦App
✔️ d09ed15 #15 2019-10-17 23:29:54 ~14 min windows 📦exe
✔️ d09ed15 #15 2019-10-17 23:39:35 ~24 min ios 📦ipa 📲
✔️ d09ed15 #15 2019-10-17 23:44:51 ~29 min macos 📦dmg

@vitvly vitvly self-assigned this Oct 9, 2019
@yenda yenda requested a review from jakubgs October 10, 2019 08:56
Copy link
Member

@jakubgs jakubgs left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will not work:

Cleaning Yarn/Metro caches in temp dirs ...
/bin/sh: 6: pushd: not found
/bin/sh: 9: popd: not found
/bin/sh: 6: pushd: not found
/bin/sh: 9: popd: not found
Makefile:90: recipe for target 'clean' failed
make: *** [clean] Error 127

This logic a bit clunky, there's a simpler way to do this by using a status-react-specific TMPDIR:

# We don't want to use /run/user/$UID because it runs out of space too easilly
export TMPDIR = /tmp/tmp-status-react

Then add a target that will run first on every make call to crate it:

#----------------
# Required targets
#----------------

mk-tmpdir: SHELL := /bin/sh
mk-tmpdir: ##@prepare Create a TMPDIR for temporary files
	@mkdir -p "$(TMPDIR)"

# Run these tasks every time make is called
-include mk-tmpdir

This should be above the Nix section in Makefile.
Then modify the clean target to look like this:

rm-tmpdir: SHELL := /bin/sh
rm-tmpdir: ##@prepare Remove TMPDIR
	rm -r "$(TMPDIR)"

clean: SHELL := /bin/sh
clean: _fix-node-perms rm-tmpdir ##@prepare Remove all output folders
	git clean -dxf -f

It would be also good to add both new targets at the end of .PHONY.

@vitvly
Copy link
Contributor Author

vitvly commented Oct 10, 2019

@jakubgs i tested this on macOS and it worked there, but maybe because my /bin/sh points to /bin/bash.

@vitvly
Copy link
Contributor Author

vitvly commented Oct 10, 2019

@jakubgs thanks for reviewing! A question - you suggest to use a separate $TMPDIR for status-react, but what about /tmp? These 2 folders are different, and both contain Yarn/Metro caches.

@jakubgs
Copy link
Member

jakubgs commented Oct 10, 2019

These 2 folders are different, and both contain Yarn/Metro caches.

Well, TMPDIR is a canonical unix variable: https://en.wikipedia.org/wiki/TMPDIR
It should affect where all well behaved programs store their temporary files.

But you might be right, yarn might not respect TMPDIR. Not sure about metro but Yarn has YARN_CACHE_FOLDER env variable we could set. It's worth a try.

Makefile Outdated Show resolved Hide resolved
@jakubgs
Copy link
Member

jakubgs commented Oct 14, 2019

Damn, I added some commands before make clean and it doesn't seem like either Yarn or Metro respect the set TMPDIR:

[Pipeline] { (Cleanup)
[Pipeline] sh
15:03:21  + ls -l /tmp/tmp-status-react
15:03:21  total 0
[Pipeline] sh
15:03:21  + find /tmp/tmp-status-react
15:03:21  /tmp/tmp-status-react
[Pipeline] sh
15:03:22  + make clean
15:03:22  rm -r "/tmp/tmp-status-react"
15:03:22  git clean -dxf -f

https://ci.status.im/job/status-react/job/prs/job/android-e2e/job/PR-9150/3/

@jakubgs
Copy link
Member

jakubgs commented Oct 14, 2019

@siphiuel are you referring in your description to the following files?

admin@linux-01.do-ams3.ci.misc:~ % sudo find /run/user/1001/ -name 'yarn--*' | head -n 3 
/run/user/1001/yarn--1571053553426-0.22263707960114654
/run/user/1001/yarn--1571052679528-0.7234799062122665
/run/user/1001/yarn--1571050818044-0.9092570746829618

admin@linux-01.do-ams3.ci.misc:~ % sudo find /run/user/1001/ -name '*-metro-*' | head -n 3
/run/user/1001/haste-map-metro-4-50919a9011980e131c55b2de66d3b833
/run/user/1001/haste-map-metro-4-d30b8c66ec93963468d6157fa1f0fa31
/run/user/1001/haste-map-metro-4-cbf3b0da2185ea8e534114174fb5d51f

Because if so then on CI hosts they don't end up in /tmp but in /run/user/1001, where 1001 is the UID of the jenkins user. I'd love to be able to control where they get created but it appears this is where they end up when run via Nix.

@jakubgs
Copy link
Member

jakubgs commented Oct 14, 2019

According to jest docs:

Default: "/tmp/"
The directory where Jest should store its cached dependency information.
https://jestjs.io/docs/en/configuration#cachedirectory-string

This is the part of the jest package that creates the temporary file called haste-map-metro-4-${H}:
https://github.com/facebook/jest/blob/f3dab7cd/packages/jest-haste-map/src/index.ts#L303-L318
The directory in which it locates that cache file is defined via cacheDirectory, which comes from:
https://github.com/facebook/jest/blob/f3dab7cd/packages/jest-types/src/Config.ts#L27-L32
https://github.com/facebook/jest/blob/f3dab7cd/packages/jest-cli/src/cli/args.ts#L103-L108
Is created here:
https://github.com/facebook/jest/blob/f3dab7cd/packages/jest-runtime/src/index.ts#L198
Via the createDirectory function:
https://github.com/facebook/jest/blob/f3dab7cd/packages/jest-util/src/createDirectory.ts
There is a --cacheDirectory flag which can be set when calling jest in CLI, but we don't do that.

I need to find a way to customize it, because we can't just blindly remove the cache folder, since other CI builds on the same host could be using one of the directories we would try to remove.

@jakubgs
Copy link
Member

jakubgs commented Oct 14, 2019

Ah, I see, by default if cacheDirectory is not specified it uses os.tmpdir():
https://github.com/facebook/jest/blob/f3dab7cd/packages/jest-haste-map/src/index.ts#L248
Which according to NodeJS docs:

The os.tmpdir() method returns a string specifying the operating system's default directory for temporary files.
https://nodejs.org/api/os.html#os_os_tmpdir

Now, operating system's default directory for temporary files should be controlled by TMPDIR, which clearly isn't, and my guess is because we do not include it in allowed env variables for Nix via the --keep flag. I will test this.

@jakubgs jakubgs force-pushed the fix/clean-system-tmp-dirs-in-makefile branch 2 times, most recently from 07df0b3 to 66baccc Compare October 14, 2019 14:02
@pedropombeiro
Copy link
Contributor

pedropombeiro commented Oct 14, 2019

Now, operating system's default directory for temporary files should be controlled by TMPDIR, which clearly isn't,

Yeah, it must be something like the --keep flag, because looking at the source code of node.js 10.15, it should be fetching $TMPDIR https://github.com/nodejs/node/blob/v10.15.0%5E0/lib/os.js#L131-L134.

@jakubgs jakubgs force-pushed the fix/clean-system-tmp-dirs-in-makefile branch 6 times, most recently from 3bcbebd to 8e4c963 Compare October 17, 2019 18:44
@jakubgs
Copy link
Member

jakubgs commented Oct 17, 2019

I managed to make it work. I added a find before cleaning the TMPDIR and the contents were what I expected them to be:

MacOS

21:16:28  + make clean
21:16:30  find "/tmp/tmp-status-react-6035"
21:16:30  /tmp/tmp-status-react-6035
21:16:30  /tmp/tmp-status-react-6035/jenkins-state
21:16:30  /tmp/tmp-status-react-6035/jenkins-state/pid
21:16:30  /tmp/tmp-status-react-6035/jenkins-state/sock
21:16:30  /tmp/tmp-status-react-6035/jenkins-state/log
21:16:30  /tmp/tmp-status-react-6035/yarn--1571339785740-0.7473295541979732
21:16:30  /tmp/tmp-status-react-6035/yarn--1571339785740-0.7473295541979732/yarn
21:16:30  /tmp/tmp-status-react-6035/yarn--1571339785740-0.7473295541979732/node
21:16:30  /tmp/tmp-status-react-6035/v8-compile-cache-502
21:16:30  /tmp/tmp-status-react-6035/v8-compile-cache-502/6.8.275.32-node.45
21:16:30  /tmp/tmp-status-react-6035/v8-compile-cache-502/6.8.275.32-node.45/zSoptzSnixzSstorezS2f2ipyd1c27wrpl3prgvsqc82rhhf0rw-yarn-1.13.0zSlibexeczSyarnzSbinzSyarn.js.MAP
21:16:30  /tmp/tmp-status-react-6035/v8-compile-cache-502/6.8.275.32-node.45/zSoptzSnixzSstorezS2f2ipyd1c27wrpl3prgvsqc82rhhf0rw-yarn-1.13.0zSlibexeczSyarnzSbinzSyarn.js.BLOB
21:16:30  /tmp/tmp-status-react-6035/env-vars
21:16:30  rm -fr "/tmp/tmp-status-react-6035"

Linux

21:05:27  + make clean
21:05:27  find "/tmp/tmp-status-react-6082"
21:05:27  /tmp/tmp-status-react-6082
21:05:27  /tmp/tmp-status-react-6082/jenkins-state
21:05:27  /tmp/tmp-status-react-6082/jenkins-state/log
21:05:27  /tmp/tmp-status-react-6082/jenkins-state/pid
21:05:27  /tmp/tmp-status-react-6082/jenkins-state/sock
21:05:27  /tmp/tmp-status-react-6082/env-vars
21:05:27  /tmp/tmp-status-react-6082/v8-compile-cache-1001
21:05:27  /tmp/tmp-status-react-6082/v8-compile-cache-1001/6.8.275.32-node.45
21:05:27  /tmp/tmp-status-react-6082/v8-compile-cache-1001/6.8.275.32-node.45/zSnixzSstorezSm6xj5bd7ssjhpnl6sm62i3fqxdd19a5s-yarn-1.13.0zSlibexeczSyarnzSbinzSyarn.js.MAP
21:05:27  /tmp/tmp-status-react-6082/v8-compile-cache-1001/6.8.275.32-node.45/zSnixzSstorezSm6xj5bd7ssjhpnl6sm62i3fqxdd19a5s-yarn-1.13.0zSlibexeczSyarnzSbinzSyarn.js.BLOB
21:05:27  /tmp/tmp-status-react-6082/yarn--1571339124002-0.15680803455239944
21:05:27  /tmp/tmp-status-react-6082/yarn--1571339124002-0.15680803455239944/node
21:05:27  /tmp/tmp-status-react-6082/yarn--1571339124002-0.15680803455239944/yarn
21:05:27  rm -fr "/tmp/tmp-status-react-6082"

Windows

21:00:43  find "/tmp/tmp-status-react-2462"
21:00:43  /tmp/tmp-status-react-2462
21:00:43  /tmp/tmp-status-react-2462/jenkins-state
21:00:43  /tmp/tmp-status-react-2462/jenkins-state/sock
21:00:43  /tmp/tmp-status-react-2462/jenkins-state/pid
21:00:43  /tmp/tmp-status-react-2462/jenkins-state/log
21:00:43  /tmp/tmp-status-react-2462/yarn--1571338839511-0.30598898209784386
21:00:43  /tmp/tmp-status-react-2462/yarn--1571338839511-0.30598898209784386/node
21:00:43  /tmp/tmp-status-react-2462/yarn--1571338839511-0.30598898209784386/yarn
21:00:43  /tmp/tmp-status-react-2462/env-vars
21:00:43  /tmp/tmp-status-react-2462/v8-compile-cache-1001
21:00:43  /tmp/tmp-status-react-2462/v8-compile-cache-1001/6.8.275.32-node.45
21:00:43  /tmp/tmp-status-react-2462/v8-compile-cache-1001/6.8.275.32-node.45/zSnixzSstorezSm6xj5bd7ssjhpnl6sm62i3fqxdd19a5s-yarn-1.13.0zSlibexeczSyarnzSbinzSyarn.js.BLOB
21:00:43  /tmp/tmp-status-react-2462/v8-compile-cache-1001/6.8.275.32-node.45/zSnixzSstorezSm6xj5bd7ssjhpnl6sm62i3fqxdd19a5s-yarn-1.13.0zSlibexeczSyarnzSbinzSyarn.js.MAP
21:00:43  rm -fr "/tmp/tmp-status-react-2462"

Android & iOS

It appears mobile platforms do not create any of those yarn temporary files. I assume that's due to more extensive use of Nix with tools like yarn2nix.

@jakubgs jakubgs force-pushed the fix/clean-system-tmp-dirs-in-makefile branch 4 times, most recently from 55b5450 to ae6fd67 Compare October 17, 2019 22:51
@jakubgs jakubgs force-pushed the fix/clean-system-tmp-dirs-in-makefile branch from ae6fd67 to d09ed15 Compare October 17, 2019 23:15
@jakubgs jakubgs requested a review from pedropombeiro October 17, 2019 23:38
Also:
- parallelize upload and achive stages
- fix s3cmd uploads for combined Jenkinsfile
- fix failing TestFlight clean job

Signed-off-by: Jakub Sokołowski <jakub@status.im>
@jakubgs jakubgs force-pushed the fix/clean-system-tmp-dirs-in-makefile branch from d09ed15 to f28fd8f Compare October 18, 2019 07:42
@jakubgs jakubgs merged commit f28fd8f into develop Oct 18, 2019
@delete-merged-branch delete-merged-branch bot deleted the fix/clean-system-tmp-dirs-in-makefile branch October 18, 2019 07:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
No open projects
Archived in project
Development

Successfully merging this pull request may close these issues.

5 participants