From a55f9e86ebfecadd50b52c3986d1a82aaee0ee35 Mon Sep 17 00:00:00 2001 From: Joseph Garrone Date: Thu, 14 May 2020 00:47:15 +0200 Subject: [PATCH] update --- .github/workflows/ci.yaml | 75 ++++++++++++++++ .github/workflows/publish.yaml | 85 +++++++++++++++++++ .../workflows/template_initialization.yaml | 57 +++++++++++++ .gitignore | 43 ++++++++++ README.md | 43 +++++++++- TEMPLATE_README.md | 15 ++++ package.json | 34 ++++++++ src/index.ts | 3 + src/myFunction.ts | 2 + src/myObject.ts | 4 + src/test/index.ts | 49 +++++++++++ src/test/myFunction.ts | 20 +++++ src/test/myObject.ts | 17 ++++ src/tools/toUpperCase.ts | 4 + 14 files changed, 449 insertions(+), 2 deletions(-) create mode 100644 .github/workflows/ci.yaml create mode 100644 .github/workflows/publish.yaml create mode 100644 .github/workflows/template_initialization.yaml create mode 100644 .gitignore create mode 100644 TEMPLATE_README.md create mode 100755 package.json create mode 100644 src/index.ts create mode 100644 src/myFunction.ts create mode 100644 src/myObject.ts create mode 100644 src/test/index.ts create mode 100644 src/test/myFunction.ts create mode 100644 src/test/myObject.ts create mode 100644 src/tools/toUpperCase.ts diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml new file mode 100644 index 0000000..c338a66 --- /dev/null +++ b/.github/workflows/ci.yaml @@ -0,0 +1,75 @@ +name: ci +on: + push: + branches: + - dev + pull_request: + branches: + - dev + +jobs: + + test_node: + runs-on: ubuntu-latest + if: ${{ !github.event.created }} + strategy: + matrix: + node: [ '13', '12', '11', '10', '8' ] + name: Test with Node v${{ matrix.node }} + steps: + + - uses: actions/checkout@v2 + - uses: actions/setup-node@v1 + with: + node-version: ${{ matrix.node }} + - run: npm install + - run: npm run build + - run: npm run test:node + + + trigger_publish: + name: Trigger publish.yaml workflow if package.json version updated ( and secrets.PAT is set ). + runs-on: ubuntu-latest + env: + PAT: ${{secrets.PAT}} + if: github.event_name == 'push' && github.event.head_commit.author.name != 'denoify_ci' + needs: test_node + steps: + + - name: Get version on branch 'latest' + id: v_latest + uses: garronej/github_actions_toolkit@master + with: + action_name: get_package_json_version + owner: ${{github.repository_owner}} + repo: ${{github.event.repository.name}} + branch: latest + + - name: Get version on master + id: v_master + uses: garronej/github_actions_toolkit@master + with: + action_name: get_package_json_version + owner: ${{github.repository_owner}} + repo: ${{github.event.repository.name}} + branch: ${{ github.sha }} + + - name: 'Trigger the ''publish'' workflow' + if: ${{ !!env.PAT && steps.v_latest.outputs.version != steps.v_master.outputs.version && steps.v_master.outputs.version != '0.0.0' }} + uses: garronej/github_actions_toolkit@master + env: + GITHUB_TOKEN: ${{ secrets.PAT }} + with: + action_name: dispatch_event + owner: ${{github.repository_owner}} + repo: ${{github.event.repository.name}} + event_type: publish + client_payload_json: | + ${{ + format( + '{{"from_version":"{0}","to_version":"{1}","repo":"{2}"}}', + steps.v_latest.outputs.version, + steps.v_master.outputs.version, + github.event.repository.name + ) + }} diff --git a/.github/workflows/publish.yaml b/.github/workflows/publish.yaml new file mode 100644 index 0000000..b470310 --- /dev/null +++ b/.github/workflows/publish.yaml @@ -0,0 +1,85 @@ +on: + repository_dispatch: + types: publish + +jobs: + update_changelog_and_sync_package_lock_version: + name: Update CHANGELOG.md and make sure package.json and package-lock.json versions matches. + runs-on: ubuntu-latest + steps: + - name: Synchronize package.json and package-lock.json version if needed. + uses: garronej/github_actions_toolkit@master + env: + GITHUB_TOKEN: ${{ secrets.PAT }} + with: + action_name: sync_package_and_package_lock_version + owner: ${{github.repository_owner}} + repo: ${{github.event.client_payload.repo}} + branch: master + commit_author_email: ts_ci@github.com + - name: Update CHANGELOG.md + if: ${{ !!github.event.client_payload.from_version }} + uses: garronej/github_actions_toolkit@master + env: + GITHUB_TOKEN: ${{ secrets.PAT }} + with: + action_name: update_changelog + owner: ${{github.repository_owner}} + repo: ${{github.event.client_payload.repo}} + branch_behind: latest + branch_ahead: master + commit_author_email: ts_ci@github.com + exclude_commit_from_author_names_json: '["ts_ci"]' + + publish_npm: + runs-on: ubuntu-latest + needs: update_changelog_and_sync_package_lock_version + steps: + + - name: Remove branch 'latest' + continue-on-error: true + run: git push origin :latest + - name: Create the new 'latest' branch + run: | + git branch latest + git checkout latest + git push origin latest + - uses: actions/setup-node@v1 + - run: npm install + + - run: npm run enable_short_import_path:npm + env: + DRY_RUN: "0" + - name: (DEBUG) Show how the files have been moved to enable short import + run: ls -lR + - name: Publishing on NPM + run: | + if [ "$NODE_AUTH_TOKEN" = "" ]; then + echo "Can't publish on NPM, You must first create a secret called NODE_AUTH_TOKEN that contains your NPM auth token. https://help.github.com/en/actions/automating-your-workflow-with-github-actions/creating-and-using-encrypted-secrets" + false + fi + npm publish + env: + NODE_AUTH_TOKEN: ${{ secrets.NODE_AUTH_TOKEN }} + + - name: Commit changes + run: | + git config --local user.email "ts_ci@github.com" + git config --local user.name "ts_ci" + git add -A + git commit -am "Automatic structural changes" + - name: Push changes + uses: ad-m/github-push-action@v0.5.0 + with: + github_token: ${{ secrets.PAT }} + branch: latest + - name: Create Release + uses: garronej/create-release@master + env: + GITHUB_TOKEN: ${{ secrets.PAT }} + with: + tag_name: ${{ github.event.client_payload.to_version }} + release_name: Release ${{ github.event.client_payload.to_version }} + branch: latest + draft: false + prerelease: false diff --git a/.github/workflows/template_initialization.yaml b/.github/workflows/template_initialization.yaml new file mode 100644 index 0000000..0bbbf1e --- /dev/null +++ b/.github/workflows/template_initialization.yaml @@ -0,0 +1,57 @@ +on: create + +jobs: + template_initialization: + runs-on: ubuntu-latest + steps: + + - name: Checking availability for module name ${{github.event.repository.name}} on NPM. + id: id1 + uses: garronej/github_actions_toolkit@master + with: + action_name: is_well_formed_and_available_module_name + module_name: ${{github.event.repository.name}} + + - name: Checks results + run: | + if [ "$IS_VALID_NODE_MODULE_NAME" = "false" ]; then + echo $MODULE_NAME" is not a valid node module name" + false + fi + if [ "$IS_AVAILABLE_ON_NPM" = "false" ]; then + echo "WARNING: There is already a NPM module named "$MODULE_NAME", if you are not the owner consider picking another name" + fi + true + env: + MODULE_NAME: ${{github.event.repository.name}} + IS_VALID_NODE_MODULE_NAME: ${{steps.id1.outputs.is_valid_node_module_name}} + IS_AVAILABLE_ON_NPM: ${{steps.id1.outputs.is_available_on_npm}} + + - uses: actions/checkout@v2 + - name: Replace tokens in README.MD and package.json + uses: cschleiden/replace-tokens@v1 + with: + files: '["README.md","package.json"]' + env: + REPO_NAME: ${{ github.event.repository.name }} + USER_OR_ORG: ${{ github.repository_owner }} + DESC: ${{ github.event.repository.description }} + - uses: actions/setup-node@v1 + - name: Update pre-configured dev dependencies + run: | + npm install --save-dev denoify + npm install --save-dev typescript + npm install --save-dev evt + rm package-lock.json + - name: Remove this workflow, it only needs to be run once. + run: rm .github/workflows/template_initialization.yaml + - name: Commit files + run: | + git config --local user.email "ts_ci@github.com" + git config --local user.name "ts_ci" + git commit -am "Replacing the template's placeholders" + - name: Push changes + uses: ad-m/github-push-action@v0.5.0 + with: + github_token: ${{ secrets.PAT || secrets.GITHUB_TOKEN }} + branch: dev diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..998f7b6 --- /dev/null +++ b/.gitignore @@ -0,0 +1,43 @@ +# Logs +logs +*.log +npm-debug.log* + +# Runtime data +pids +*.pid +*.seed + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage + +# nyc test coverage +.nyc_output + +# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (http://nodejs.org/api/addons.html) +build/Release + +# Dependency directories +node_modules +jspm_packages + +# Optional npm cache directory +.npm + +# Optional REPL history +.node_repl_history + +.vscode + +.DS_Store + +/dist diff --git a/README.md b/README.md index 08fa0a4..4f3e452 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,41 @@ -# ts_ci -Continus integration setup for TypeScript projects via GitHub Actions + +

+ +

+

+ #{DESC}# +
+
+ + + +

+

+ Home + - + Documentation + - + Chat +

+ +--- + +# Install / Import + +```bash +> npm install --save #{REPO_NAME}# +``` +```typescript +import { myFunction, myObject } from '#{REPO_NAME}#'; +//OR to import a specific file: +import { myFunction } from '#{REPO_NAME}#/myFunction' +import { myObject } from '#{REPO_NAME}#/myObject' +``` + +## CI + +This repository has has continus integration and automatic publishing implemented via GitHub Action. + +Refer to [TEMPLATE_README.md](https://github.com/#{USER_OR_ORG}#/#{REPO_NAME}#/blob/dev/TEMPLATE_README.md) for instructions. + + diff --git a/TEMPLATE_README.md b/TEMPLATE_README.md new file mode 100644 index 0000000..a2b99d5 --- /dev/null +++ b/TEMPLATE_README.md @@ -0,0 +1,15 @@ + +# GitHub Repo Secrets to set: + +The following Secrets need to be set to be able to publish. + +- ``PAT``: GitHub Personal access token. +- ``NODE_AUTH_TOKEN``: NPM Authorization token. + + +[ts-ci](https://github.com/garronej/ts_ci) is a template that: +- Automatically fills the paperwork for you: Fills the package.json and README.md +- Automate testing: Every commit pushed will be automatically tested on docker containers against many Node and Deno version ( ``npm test`` ), if everything passes you'll get a green label on the readme. +- Publish for you on NPM: Each time you'll change the version number in ``package.json`` a workflow that publishes for NPM and [deno.land](https://deno.land/x/) will trigger. The CHANGELOG.md will be automatically updated based on commit messages since last release. +- Enable you to only track sources on the main branch: With this template you won't have to track ``dist/`` on your main branch. +- Enable short import path: No more ``import 'my_module/dist/theFileNeeded'`` your users will be able to ``import 'my_module/theFileNeeded'``. diff --git a/package.json b/package.json new file mode 100755 index 0000000..19c9d5e --- /dev/null +++ b/package.json @@ -0,0 +1,34 @@ +{ + "name": "#{REPO_NAME}#", + "version": "0.0.0", + "description": "#{DESC}#", + "repository": { + "type": "git", + "url": "git://github.com/#{USER_OR_ORG}#/#{REPO_NAME}#.git" + }, + "main": "./dist/index.js", + "types": "./dist/index.d.ts", + "scripts": { + "tsc": "npx tsc", + "build": "npm run tsc && npm run denoify", + "test:node": "node ./dist/test", + "test:deno": "deno ./deno_dist/test/deno_index.ts", + "test": "npm run test:node && npm run test:deno", + "enable_short_import_path:npm": "npm run build && npx denoify_enable_short_npm_import_path", + "clean": "rm -rf node_modules dist" + }, + "author": "u/#{USER_OR_ORG}#", + "license": "MIT", + "files": [ + "/dist/*.{d.ts,js,js.map}", + "/dist/tools/*.{d.ts,js,js.map}" + ], + "keywords": [], + "homepage": "https://github.com/#{USER_OR_ORG}#/#{REPO_NAME}#", + "devDependencies": { + "typescript": "^3.9.0", + "@types/node": "^10.0.0", + "denoify": "github:garronej/denoify", + "evt": "^1.6.8" + } +} diff --git a/src/index.ts b/src/index.ts new file mode 100644 index 0000000..d643e47 --- /dev/null +++ b/src/index.ts @@ -0,0 +1,3 @@ + +export { myFunction } from "./myFunction"; +export { myObject } from "./myObject"; diff --git a/src/myFunction.ts b/src/myFunction.ts new file mode 100644 index 0000000..3be9536 --- /dev/null +++ b/src/myFunction.ts @@ -0,0 +1,2 @@ + +export const myFunction = ()=> Promise.resolve(["a", "b", "c"]); \ No newline at end of file diff --git a/src/myObject.ts b/src/myObject.ts new file mode 100644 index 0000000..2eb25e9 --- /dev/null +++ b/src/myObject.ts @@ -0,0 +1,4 @@ + +import { toUpperCase } from "./tools/toUpperCase"; + +export const myObject= { "p": toUpperCase("foo") }; \ No newline at end of file diff --git a/src/test/index.ts b/src/test/index.ts new file mode 100644 index 0000000..54e53be --- /dev/null +++ b/src/test/index.ts @@ -0,0 +1,49 @@ + +//This will not run on deno, we need a separate index to run our tests. + +import * as child_process from "child_process"; +import * as path from "path"; +import { Deferred } from "evt/dist/tools/Deferred"; + +(async () => { + + if (!!process.env.FORK) { + + process.once("unhandledRejection", error => { throw error; }); + + require(process.env.FORK); + + return; + + } + + for (const name of [ + "myFunction", + "myObject" + ]) { + + console.log(`Running: ${name}`); + + const dExitCode = new Deferred(); + + child_process.fork( + __filename, + undefined, + { "env": { "FORK": path.join(__dirname, name) } } + ) + .on("message", console.log) + .once("exit", code => dExitCode.resolve(code)) + ; + + const exitCode = await dExitCode.pr; + + if (exitCode !== 0) { + console.log(`${name} exited with error code: ${exitCode}`); + process.exit(exitCode); + } + + console.log("\n"); + + } + +})(); diff --git a/src/test/myFunction.ts b/src/test/myFunction.ts new file mode 100644 index 0000000..186cb9a --- /dev/null +++ b/src/test/myFunction.ts @@ -0,0 +1,20 @@ + +import { myFunction } from ".."; + +import { getPromiseAssertionApi } from "evt/dist/tools/testing/getPromiseAssertionApi"; + +const { mustResolve } = getPromiseAssertionApi({ "takeIntoAccountArraysOrdering": true}); + +(async () => { + + await mustResolve({ + "promise": myFunction(), + "expectedData": ["a", "b", "c"], + "delay": 0 + }); + + console.log("PASS"); + +})(); + + diff --git a/src/test/myObject.ts b/src/test/myObject.ts new file mode 100644 index 0000000..9b1e3d6 --- /dev/null +++ b/src/test/myObject.ts @@ -0,0 +1,17 @@ + + +import { assert } from "evt/dist/tools/typeSafety"; +import * as inDepth from "evt/dist/tools/inDepth"; +import { myObject } from ".."; + +assert( + inDepth.same( + myObject, + { "p": "FOO" } + ) +); + +console.log("PASS"); + + + diff --git a/src/tools/toUpperCase.ts b/src/tools/toUpperCase.ts new file mode 100644 index 0000000..1eb60b8 --- /dev/null +++ b/src/tools/toUpperCase.ts @@ -0,0 +1,4 @@ + +export function toUpperCase(str: string): string{ + return str.toUpperCase(); +} \ No newline at end of file