ipfsUpload.js 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. // Copyright 2017-2020 @polkadot/apps authors & contributors
  2. // This software may be modified and distributed under the terms
  3. // of the Apache-2.0 license. See the LICENSE file for details.
  4. const fs = require('fs');
  5. const pinataSDK = require('@pinata/sdk');
  6. const cloudflare = require('dnslink-cloudflare');
  7. const execSync = require('@polkadot/dev/scripts/execSync');
  8. const lernaInfo = require('../lerna.json');
  9. // https://gateway.pinata.cloud/ipfs/
  10. const GATEWAY = 'https://ipfs.io/ipfs/';
  11. const DOMAIN = 'dotapps.io';
  12. const DST = 'packages/apps/build';
  13. const SRC = 'packages/apps/public';
  14. const WOPTS = { encoding: 'utf8', flag: 'w' };
  15. const repo = `https://${process.env.GH_PAT}@github.com/${process.env.GITHUB_REPOSITORY}.git`;
  16. const pinata = pinataSDK(process.env.PINATA_API_KEY, process.env.PINATA_SECRET_KEY);
  17. function writeFiles (name, content) {
  18. [DST, SRC].forEach((root) =>
  19. fs.writeFileSync(`${root}/ipfs/${name}`, content, WOPTS)
  20. );
  21. }
  22. function updateGh (hash) {
  23. execSync('git add --all .');
  24. execSync(`git commit --no-status --quiet -m "[CI Skip] publish/ipfs ${hash}
  25. skip-checks: true"`);
  26. execSync(`git push ${repo} HEAD:${process.env.GITHUB_REF}`, true);
  27. }
  28. async function pin () {
  29. const result = await pinata.pinFromFS(DST);
  30. const url = `${GATEWAY}${result.IpfsHash}/`;
  31. const html = `<!DOCTYPE html>
  32. <html>
  33. <head>
  34. <title>Redirecting to ipfs gateway</title>
  35. <meta http-equiv="refresh" content="0; url=${url}" />
  36. <style>
  37. body { font-family: sans-serif; line-height: 1.5rem; padding: 2rem; text-align: center }
  38. p { margin: 0 }
  39. </style>
  40. </head>
  41. <body>
  42. <p>Redirecting to</p>
  43. <p><a href="${url}">${url}</a></p>
  44. </body>
  45. </html>`;
  46. writeFiles('index.html', html);
  47. writeFiles('pin.json', JSON.stringify(result));
  48. updateGh(result.IpfsHash);
  49. console.log(`Pinned ${result.IpfsHash}`);
  50. return result.IpfsHash;
  51. }
  52. async function unpin (exclude) {
  53. const result = await pinata.pinList({ status: 'pinned' });
  54. if (result.count > 1) {
  55. const filtered = result.rows
  56. .map(({ ipfs_pin_hash: hash }) => hash)
  57. .filter((hash) => hash !== exclude);
  58. if (filtered.length) {
  59. await Promise.all(
  60. filtered.map((hash) =>
  61. pinata
  62. .unpin(hash)
  63. .then(() => console.log(`Unpinned ${hash}`))
  64. .catch(console.error)
  65. )
  66. );
  67. }
  68. }
  69. }
  70. async function dnslink (hash) {
  71. await cloudflare(
  72. { token: process.env.CF_API_TOKEN },
  73. { link: `/ipfs/${hash}`, record: `_dnslink.${DOMAIN}`, zone: DOMAIN }
  74. );
  75. console.log(`Dnslink ${hash}`);
  76. }
  77. async function main () {
  78. // only run on non-beta versions
  79. if (!lernaInfo.version.includes('-beta.')) {
  80. const hash = await pin();
  81. await dnslink(hash);
  82. await unpin(hash);
  83. }
  84. }
  85. main()
  86. .catch(console.error)
  87. .finally(() => process.exit());