|
@ -1,5 +0,0 @@
|
|||
/node_modules
|
||||
/static/feeds/*
|
||||
!/static/feeds/.gitkeep
|
||||
/static/alternate/*
|
||||
!/static/alternate/.gitkeep
|
|
@ -1,16 +1,140 @@
|
|||
on: push
|
||||
jobs:
|
||||
main:
|
||||
insiders-build:
|
||||
strategy:
|
||||
matrix:
|
||||
os: [windows, macos, ubuntu]
|
||||
include:
|
||||
- os: windows
|
||||
build: npx caxa --directory . --command "{{caxa}}/node_modules/.bin/node" "{{caxa}}/lib/index.js" --output "CourseLore--windows--${{ github.sha }}.exe"
|
||||
artifact: CourseLore--windows--${{ github.sha }}.exe
|
||||
- os: macos
|
||||
build: |
|
||||
npx caxa --directory . --command "{{caxa}}/node_modules/.bin/node" "{{caxa}}/lib/index.js" --output "CourseLore.app"
|
||||
tar -czf "CourseLore--macos--${{ github.sha }}.app.tgz" "CourseLore.app"
|
||||
artifact: CourseLore--macos--${{ github.sha }}.app.tgz
|
||||
- os: ubuntu
|
||||
build: |
|
||||
npx caxa --directory . --command "{{caxa}}/node_modules/.bin/node" "{{caxa}}/lib/index.js" --output "courselore"
|
||||
tar -czf "courselore--linux--${{ github.sha }}.tgz" "courselore"
|
||||
artifact: courselore--linux--${{ github.sha }}.tgz
|
||||
runs-on: ${{ matrix.os }}-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: 15
|
||||
- run: |
|
||||
npm ci
|
||||
${{ matrix.build }}
|
||||
- uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: ${{ matrix.artifact }}
|
||||
path: ${{ matrix.artifact }}
|
||||
|
||||
test:
|
||||
strategy:
|
||||
matrix:
|
||||
os: [windows, macos, ubuntu]
|
||||
runs-on: ${{ matrix.os }}-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: 15
|
||||
- run: npm install-ci-test
|
||||
|
||||
deploy:
|
||||
if: github.ref == 'refs/heads/master'
|
||||
needs: [insiders-build, test]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: webfactory/ssh-agent@v0.5.0
|
||||
with:
|
||||
ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY }}
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/download-artifact@v2
|
||||
with:
|
||||
name: courselore--linux--${{ github.sha }}.tgz
|
||||
- run: |
|
||||
tar -xzf courselore--linux--${{ github.sha }}.tgz
|
||||
|
||||
cat >> ~/.ssh/known_hosts << "EOF"
|
||||
courselore.org ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDWOjzHPP1v+6gEeRAVzEB7l/RH+mt31heowjiUVNjgTnpT1FDL/T4yqmztwPrzhXUdBAy7M16H+88Padxm+/rJ5qfbw2dH7KtOA4RALYy9ruBl6HFdCf59eh01A97Py/AmxlpXysGAVcdcVjLsr0PvfoEGOqMlohc0sBjCjhoFcqkP9P57Q4Q3gcqgwjNYaZ1BSbI2G6J6kihjN7+b8pFCHCw8fqs7xo+7pDUv/rvqfBTUAFV7sovwQU0bZK6Z8gWXYFGG0NpKVojsKOHCrZpM8pBBDmleisrJhXmnKQ+Lj/JvYuaEM6cHZh6+RH7ua6S9eqlL8EErXf7GZ4SPuTo1ghNJ5H9cR3k8Px4Op5bDIIdPP767jwGHabZJ5Z8l9QnQajq85gcE7E3vZ1yT2BDKQsIDJeNpg1etTgw6hSUlBQsKx8TNaI9nROSnKwKbSI+sGmZlwrx11XimEkvaMaFmSZfpN+ne/2kmjc81Pr0WKb82sIPf3X2KzmWeChkZus8=
|
||||
courselore.org ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBOIhUnh2H/733XnnD4mvaEqKbxbEc9ov3UhlbG7gkQS7vM5TaSSuknZLOGUIx2VWB681y4jn4vG3Wsja9JYPCB0=
|
||||
courselore.org ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBCGyIA9/oiJt/qrQNeNoIRNKA8CFc/ppPMnrtw2NW+7
|
||||
EOF
|
||||
|
||||
ssh root@courselore.org "mkdir -p courselore"
|
||||
rsync -a courselore root@courselore.org:courselore/courselore
|
||||
rsync -a --delete customization-example/ root@courselore.org:courselore/customization/
|
||||
rsync -a deployment-example/configuration.js root@courselore.org:courselore/configuration.js
|
||||
rsync -a deployment-example/courselore.service root@courselore.org:/etc/systemd/system/courselore.service
|
||||
|
||||
ssh root@courselore.org << "EOF"
|
||||
systemctl daemon-reload
|
||||
systemctl enable courselore
|
||||
systemctl restart courselore
|
||||
EOF
|
||||
|
||||
npm-publish:
|
||||
if: startsWith(github.ref, 'refs/tags/v')
|
||||
needs: test
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: webfactory/ssh-agent@v0.4.1
|
||||
if: github.ref == 'refs/heads/master'
|
||||
with:
|
||||
ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY }}
|
||||
- uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: 14
|
||||
- run: npm install-ci-test
|
||||
- run: npm run deploy
|
||||
if: github.ref == 'refs/heads/master'
|
||||
node-version: 15
|
||||
registry-url: https://registry.npmjs.org/
|
||||
- run: npm ci && npm publish
|
||||
env:
|
||||
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||
|
||||
release:
|
||||
if: startsWith(github.ref, 'refs/tags/v')
|
||||
needs: [insiders-build, test]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/download-artifact@v2
|
||||
with:
|
||||
name: CourseLore--windows--${{ github.sha }}.exe
|
||||
- uses: actions/download-artifact@v2
|
||||
with:
|
||||
name: CourseLore--macos--${{ github.sha }}.app.tgz
|
||||
- uses: actions/download-artifact@v2
|
||||
with:
|
||||
name: courselore--linux--${{ github.sha }}.tgz
|
||||
- run: echo "::set-output name=tag::${GITHUB_REF#refs/tags/}"
|
||||
id: tag
|
||||
- uses: actions/create-release@v1
|
||||
id: create-release
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
tag_name: ${{ steps.tag.outputs.tag }}
|
||||
release_name: Release ${{ steps.tag.outputs.tag }}
|
||||
- uses: actions/upload-release-asset@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
upload_url: ${{ steps.create-release.outputs.upload_url }}
|
||||
asset_path: CourseLore--windows--${{ github.sha }}.exe
|
||||
asset_name: CourseLore--windows--${{ steps.tag.outputs.tag }}.exe
|
||||
asset_content_type: application/vnd.microsoft.portable-executable
|
||||
- uses: actions/upload-release-asset@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
upload_url: ${{ steps.create-release.outputs.upload_url }}
|
||||
asset_path: CourseLore--macos--${{ github.sha }}.app.tgz
|
||||
asset_name: CourseLore--macos--${{ steps.tag.outputs.tag }}.app.tgz
|
||||
asset_content_type: application/gzip
|
||||
- uses: actions/upload-release-asset@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
upload_url: ${{ steps.create-release.outputs.upload_url }}
|
||||
asset_path: courselore--linux--${{ github.sha }}.tgz
|
||||
asset_name: courselore--linux--${{ steps.tag.outputs.tag }}.tgz
|
||||
asset_content_type: application/gzip
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
/node_modules/
|
||||
/static/feeds/*
|
||||
!/static/feeds/.gitkeep
|
||||
/static/alternate/*
|
||||
!/static/alternate/.gitkeep
|
||||
/lib/
|
||||
/kill-the-newsletter.db
|
||||
|
|
|
@ -1,2 +0,0 @@
|
|||
/static/typeface-pt-sans/
|
||||
/static/typeface-pt-mono/
|
|
@ -1,7 +0,0 @@
|
|||
kill-the-newsletter.com {
|
||||
reverse_proxy localhost:8000
|
||||
}
|
||||
|
||||
www.kill-the-newsletter.com {
|
||||
redir https://kill-the-newsletter.com{uri}
|
||||
}
|
21
Dockerfile
|
@ -1,21 +0,0 @@
|
|||
FROM node:latest
|
||||
|
||||
WORKDIR /kill-the-newsletter
|
||||
|
||||
COPY package*.json ./
|
||||
RUN npm ci --production
|
||||
COPY . .
|
||||
|
||||
VOLUME /kill-the-newsletter/static/feeds/
|
||||
VOLUME /kill-the-newsletter/static/alternate/
|
||||
|
||||
ENV WEB_PORT=8000
|
||||
ENV EMAIL_PORT=2525
|
||||
ENV BASE_URL=http://localhost:8000
|
||||
ENV EMAIL_DOMAIN=localhost
|
||||
ENV ISSUE_REPORT=mailto:kill-the-newsletter@leafac.com
|
||||
|
||||
EXPOSE 8000
|
||||
EXPOSE 2525
|
||||
|
||||
CMD npm start
|
107
package.json
|
@ -1,81 +1,56 @@
|
|||
{
|
||||
"name": "kill-the-newsletter",
|
||||
"version": "0.0.0",
|
||||
"description": "Convert email newsletters into Atom feeds",
|
||||
"main": "lib/index.js",
|
||||
"types": "lib/index.d.ts",
|
||||
"bin": "lib/index.js",
|
||||
"repository": "leafac/kill-the-newsletter",
|
||||
"keywords": [
|
||||
"newsletter",
|
||||
"atom feeds",
|
||||
"news"
|
||||
],
|
||||
"author": "Leandro Facchinetti <kill-the-newsletter@leafac.com> (https://leafac.com)",
|
||||
"license": "MIT",
|
||||
"bugs": "https://github.com/leafac/kill-the-newsletter/issues",
|
||||
"homepage": "https://github.com/leafac/kill-the-newsletter#readme",
|
||||
"scripts": {
|
||||
"start": "ts-node .",
|
||||
"develop": "nodemon --ext ts --exec \"ts-node .\"",
|
||||
"test": "prettier --check \"**/*.{ts,css}\" --end-of-line auto && jest",
|
||||
"deploy": "pm2 deploy package.json production",
|
||||
"deploy:setup": "pm2 deploy package.json production setup"
|
||||
"start": "ts-node-dev --poll src/index.ts",
|
||||
"test": "prettier --check \"src/**/*\" --end-of-line auto && jest",
|
||||
"prepare": "tsc"
|
||||
},
|
||||
"dependencies": {
|
||||
"@types/express": "^4.17.3",
|
||||
"@types/jsdom": "^16.2.1",
|
||||
"@types/mailparser": "^2.7.2",
|
||||
"@types/node": "^13.9.8",
|
||||
"@types/smtp-server": "^3.5.4",
|
||||
"@types/write-file-atomic": "^3.0.0",
|
||||
"caddy-npm": "^2.1.1",
|
||||
"crypto-random-string": "^3.2.0",
|
||||
"entities": "^2.0.0",
|
||||
"@leafac/css": "^0.0.1",
|
||||
"@leafac/html": "^1.3.0",
|
||||
"@leafac/sqlite": "^1.1.2",
|
||||
"@leafac/sqlite-migration": "^1.0.3",
|
||||
"crypto-random-string": "^3.3.1",
|
||||
"escape-string-regexp": "^4.0.0",
|
||||
"express": "^4.17.1",
|
||||
"jsdom": "^16.2.2",
|
||||
"mailparser": "^2.7.7",
|
||||
"pm2": "^4.2.3",
|
||||
"sanitize-xml-string": "^1.1.0",
|
||||
"smtp-server": "^3.6.0",
|
||||
"tagged-template-noop": "^2.1.1",
|
||||
"ts-node": "^8.10.1",
|
||||
"typescript": "^3.8.3",
|
||||
"write-file-atomic": "^3.0.3"
|
||||
"mailparser": "^3.1.0",
|
||||
"smtp-server": "^3.8.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/jest": "^25.1.4",
|
||||
"@types/express": "^4.17.11",
|
||||
"@types/jest": "^26.0.20",
|
||||
"@types/mailparser": "^3.0.2",
|
||||
"@types/node": "^14.14.33",
|
||||
"@types/nodemailer": "^6.4.0",
|
||||
"@types/qs": "^6.9.1",
|
||||
"axios": "^0.21.1",
|
||||
"jest": "^25.2.4",
|
||||
"nodemailer": "^6.4.6",
|
||||
"nodemon": "^2.0.2",
|
||||
"prettier": "^2.0.2",
|
||||
"qs": "^6.9.3",
|
||||
"ts-jest": "^25.5.0"
|
||||
"@types/smtp-server": "^3.5.6",
|
||||
"caxa": "^1.0.0",
|
||||
"got": "^11.8.2",
|
||||
"jest": "^26.6.3",
|
||||
"nodemailer": "^6.4.18",
|
||||
"prettier": "^2.2.1",
|
||||
"ts-jest": "^26.5.3",
|
||||
"ts-node": "^9.1.1",
|
||||
"ts-node-dev": "^1.1.6",
|
||||
"typescript": "^4.2.3"
|
||||
},
|
||||
"jest": {
|
||||
"rootDir": "src",
|
||||
"preset": "ts-jest",
|
||||
"testEnvironment": "node"
|
||||
},
|
||||
"apps": [
|
||||
{
|
||||
"name": "kill-the-newsletter",
|
||||
"script": "npm start",
|
||||
"env": {
|
||||
"NODE_ENV": "production",
|
||||
"WEB_PORT": "8000",
|
||||
"EMAIL_PORT": "25",
|
||||
"BASE_URL": "https://kill-the-newsletter.com",
|
||||
"EMAIL_DOMAIN": "kill-the-newsletter.com",
|
||||
"ISSUE_REPORT": "mailto:kill-the-newsletter@leafac.com"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "caddy",
|
||||
"script": "caddy run"
|
||||
}
|
||||
],
|
||||
"deploy": {
|
||||
"production": {
|
||||
"user": "root",
|
||||
"host": "kill-the-newsletter.com",
|
||||
"ref": "origin/master",
|
||||
"repo": "git@github.com:leafac/kill-the-newsletter.com.git",
|
||||
"path": "/root/kill-the-newsletter.com",
|
||||
"pre-setup": "(curl -sL https://deb.nodesource.com/setup_14.x | bash -) && apt install -y nodejs build-essential && (ssh -o StrictHostKeyChecking=no git@github.com || true)",
|
||||
"post-setup": "npm ci --production && npx pm2 startup",
|
||||
"post-deploy": "npm ci --production && npx pm2 startOrRestart package.json && npx pm2 save",
|
||||
"ssh_options": [
|
||||
"ForwardAgent=yes",
|
||||
"StrictHostKeyChecking=no"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Before Width: | Height: | Size: 427 B After Width: | Height: | Size: 427 B |
Before Width: | Height: | Size: 985 B After Width: | Height: | Size: 985 B |
Before Width: | Height: | Size: 5.3 KiB After Width: | Height: | Size: 5.3 KiB |
Before Width: | Height: | Size: 5.8 KiB After Width: | Height: | Size: 5.8 KiB |
Before Width: | Height: | Size: 5.8 KiB After Width: | Height: | Size: 5.8 KiB |
Before Width: | Height: | Size: 5.2 KiB After Width: | Height: | Size: 5.2 KiB |
|
@ -1,8 +1,16 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"rootDir": "src",
|
||||
"outDir": "lib",
|
||||
|
||||
"target": "ES2019",
|
||||
"module": "commonjs",
|
||||
"strict": true,
|
||||
"esModuleInterop": true
|
||||
"esModuleInterop": true,
|
||||
|
||||
"declaration": true,
|
||||
"declarationMap": true,
|
||||
"sourceMap": true,
|
||||
|
||||
"strict": true
|
||||
}
|
||||
}
|
||||
|
|