diff --git a/.github/workflows/ecr_api.yml b/.github/workflows/ecr_api.yml index ded0c53e..13c0049f 100644 --- a/.github/workflows/ecr_api.yml +++ b/.github/workflows/ecr_api.yml @@ -16,7 +16,7 @@ jobs: runs-on: ubuntu-latest if: github.event.pull_request.draft == false steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 with: ref: ${{ github.event.pull_request.head.sha || github.sha }} @@ -24,7 +24,7 @@ jobs: run: docker build -t api api/ - name: Configure AWS Credentials - uses: aws-actions/configure-aws-credentials@v1 + uses: aws-actions/configure-aws-credentials@v4 with: aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} @@ -32,7 +32,7 @@ jobs: - name: Login to Amazon ECR id: login-ecr - uses: aws-actions/amazon-ecr-login@v1 + uses: aws-actions/amazon-ecr-login@v2 - name: Docker Tag API run: docker tag api ${{secrets.AWS_ACCOUNT_ID}}.dkr.ecr.us-east-1.amazonaws.com/batch:api-${{ github.event.pull_request.head.sha || github.sha }} diff --git a/.github/workflows/ecr_task.yml b/.github/workflows/ecr_task.yml index 78fc10e1..b8136bb3 100644 --- a/.github/workflows/ecr_task.yml +++ b/.github/workflows/ecr_task.yml @@ -17,13 +17,13 @@ jobs: if: github.event.pull_request.draft == false steps: - name: Configure AWS Credentials - uses: aws-actions/configure-aws-credentials@v1 + uses: aws-actions/configure-aws-credentials@v4 with: aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} aws-region: ${{ secrets.AWS_REGION }} - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 with: ref: ${{ github.event.pull_request.head.sha || github.sha }} @@ -33,7 +33,7 @@ jobs: - name: Login to Amazon ECR id: login-ecr - uses: aws-actions/amazon-ecr-login@v1 + uses: aws-actions/amazon-ecr-login@v2 - name: Docker Build Task run: docker build -t task task/ diff --git a/eslint.config.js b/eslint.config.js index d85f4a42..b9fb073f 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -1,38 +1,36 @@ -import js from "@eslint/js"; -import nodePlugin from "eslint-plugin-n"; +import nodePlugin from 'eslint-plugin-n'; export default [ - js.configs.recommended, - nodePlugin.configs["flat/recommended-module"], + nodePlugin.configs['flat/recommended-module'], { - "rules": { - "no-console": 0, - "arrow-parens": [ "error", "always" ], - "no-var": "error", - "prefer-const": "error", - "array-bracket-spacing": [ "error", "never" ], - "comma-dangle": [ "error", "never" ], - "computed-property-spacing": [ "error", "never" ], - "eol-last": "error", - "eqeqeq": [ "error", "smart" ], - "indent": [ "error", 4, { "SwitchCase": 1 } ], - "no-confusing-arrow": [ "error", { "allowParens": false } ], - "no-extend-native": "error", - "no-mixed-spaces-and-tabs": "error", - "func-call-spacing": [ "error", "never" ], - "no-trailing-spaces": "error", - "no-unused-vars": "error", - "no-use-before-define": [ "error", "nofunc" ], - "object-curly-spacing": [ "error", "always" ], - "prefer-arrow-callback": "error", - "quotes": [ "error", "single", "avoid-escape" ], - "semi": [ "error", "always" ], - "space-infix-ops": "error", - "spaced-comment": [ "error", "always" ], - "keyword-spacing": [ "error", { "before": true, "after": true } ], - "template-curly-spacing": [ "error", "never" ], - "semi-spacing": "error", - "strict": "error", + 'rules': { + 'no-console': 0, + 'arrow-parens': ['error', 'always'], + 'no-var': 'error', + 'prefer-const': 'error', + 'array-bracket-spacing': ['error', 'never'], + 'comma-dangle': ['error', 'never'], + 'computed-property-spacing': ['error', 'never'], + 'eol-last': 'error', + 'eqeqeq': ['error', 'smart'], + 'indent': ['error', 4, { 'SwitchCase': 1 }], + 'no-confusing-arrow': ['error', { 'allowParens': false }], + 'no-extend-native': 'error', + 'no-mixed-spaces-and-tabs': 'error', + 'func-call-spacing': ['error', 'never'], + 'no-trailing-spaces': 'error', + 'no-unused-vars': 'error', + 'no-use-before-define': ['error', 'nofunc'], + 'object-curly-spacing': ['error', 'always'], + 'prefer-arrow-callback': 'error', + 'quotes': ['error', 'single', 'avoid-escape'], + 'semi': ['error', 'always'], + 'space-infix-ops': 'error', + 'spaced-comment': ['error', 'always'], + 'keyword-spacing': ['error', { 'before': true, 'after': true }], + 'template-curly-spacing': ['error', 'never'], + 'semi-spacing': 'error', + 'strict': 'error' } } -] +]; diff --git a/package-lock.json b/package-lock.json index 49309b57..fb0b2920 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,6 +14,9 @@ "devDependencies": { "eslint": "^9.0.0", "eslint-plugin-n": "^17.10.2" + }, + "engines": { + "node": ">=22.0.0" } }, "node_modules/@ampproject/remapping": { diff --git a/package.json b/package.json index 6ff60efe..a85ec59d 100644 --- a/package.json +++ b/package.json @@ -7,6 +7,9 @@ "repository": "git@github.com:openaddresses/batch", "author": "ingalls ", "private": false, + "engines": { + "node": ">=22.0.0" + }, "scripts": { "test": "echo 'no tests'", "lint": "eslint cloudformation/" diff --git a/task/Dockerfile b/task/Dockerfile index a0e774cd..4457c2c5 100644 --- a/task/Dockerfile +++ b/task/Dockerfile @@ -1,4 +1,4 @@ -FROM node:18-alpine3.17 AS node +FROM node:22-alpine3.19 AS node FROM 847904970422.dkr.ecr.us-east-1.amazonaws.com/batch-machine:9.3.0 COPY --from=node /usr/lib /usr/lib diff --git a/task/collect.js b/task/collect.js index ea8ffdc2..53fb7ee5 100755 --- a/task/collect.js +++ b/task/collect.js @@ -1,5 +1,3 @@ -#!/usr/bin/env node - // Does not need to mark instance // as protected as it runs on a managed queue import { interactive } from './lib/pre.js'; @@ -66,7 +64,7 @@ async function cli() { tmp = path.resolve(DRIVE, Math.random().toString(36).substring(2, 15)); } catch (err) { - console.error(`ok - could not find ${DRIVE}`); + console.error(`ok - could not find ${DRIVE}: ${err}`); } fs.mkdirSync(tmp); @@ -87,7 +85,7 @@ async function cli() { } } catch (err) { console.error(err); - process.exit(1); + throw err; } } @@ -171,7 +169,7 @@ async function get_source(oa, tmp, data, stats) { Bucket: process.env.Bucket, Key: `${process.env.StackName}/job/${data.job}/source.geojson.gz` }))).Body, - Unzip(), + new Unzip(), split(), new Transform({ objectMode: true, diff --git a/task/eslint.config.js b/task/eslint.config.js index d85f4a42..b9fb073f 100644 --- a/task/eslint.config.js +++ b/task/eslint.config.js @@ -1,38 +1,36 @@ -import js from "@eslint/js"; -import nodePlugin from "eslint-plugin-n"; +import nodePlugin from 'eslint-plugin-n'; export default [ - js.configs.recommended, - nodePlugin.configs["flat/recommended-module"], + nodePlugin.configs['flat/recommended-module'], { - "rules": { - "no-console": 0, - "arrow-parens": [ "error", "always" ], - "no-var": "error", - "prefer-const": "error", - "array-bracket-spacing": [ "error", "never" ], - "comma-dangle": [ "error", "never" ], - "computed-property-spacing": [ "error", "never" ], - "eol-last": "error", - "eqeqeq": [ "error", "smart" ], - "indent": [ "error", 4, { "SwitchCase": 1 } ], - "no-confusing-arrow": [ "error", { "allowParens": false } ], - "no-extend-native": "error", - "no-mixed-spaces-and-tabs": "error", - "func-call-spacing": [ "error", "never" ], - "no-trailing-spaces": "error", - "no-unused-vars": "error", - "no-use-before-define": [ "error", "nofunc" ], - "object-curly-spacing": [ "error", "always" ], - "prefer-arrow-callback": "error", - "quotes": [ "error", "single", "avoid-escape" ], - "semi": [ "error", "always" ], - "space-infix-ops": "error", - "spaced-comment": [ "error", "always" ], - "keyword-spacing": [ "error", { "before": true, "after": true } ], - "template-curly-spacing": [ "error", "never" ], - "semi-spacing": "error", - "strict": "error", + 'rules': { + 'no-console': 0, + 'arrow-parens': ['error', 'always'], + 'no-var': 'error', + 'prefer-const': 'error', + 'array-bracket-spacing': ['error', 'never'], + 'comma-dangle': ['error', 'never'], + 'computed-property-spacing': ['error', 'never'], + 'eol-last': 'error', + 'eqeqeq': ['error', 'smart'], + 'indent': ['error', 4, { 'SwitchCase': 1 }], + 'no-confusing-arrow': ['error', { 'allowParens': false }], + 'no-extend-native': 'error', + 'no-mixed-spaces-and-tabs': 'error', + 'func-call-spacing': ['error', 'never'], + 'no-trailing-spaces': 'error', + 'no-unused-vars': 'error', + 'no-use-before-define': ['error', 'nofunc'], + 'object-curly-spacing': ['error', 'always'], + 'prefer-arrow-callback': 'error', + 'quotes': ['error', 'single', 'avoid-escape'], + 'semi': ['error', 'always'], + 'space-infix-ops': 'error', + 'spaced-comment': ['error', 'always'], + 'keyword-spacing': ['error', { 'before': true, 'after': true }], + 'template-curly-spacing': ['error', 'never'], + 'semi-spacing': 'error', + 'strict': 'error' } } -] +]; diff --git a/task/export.js b/task/export.js index a2e9a055..d6e979f5 100755 --- a/task/export.js +++ b/task/export.js @@ -1,4 +1,3 @@ -#!/usr/bin/env node import { interactive } from './lib/pre.js'; import Meta from './lib/meta.js'; @@ -151,6 +150,7 @@ async function cli() { }); } finally { await meta.protection(false); + // eslint-disable-next-line n/no-process-exit process.exit(1); } } @@ -247,7 +247,7 @@ async function get_source(tmp, jobid) { Bucket: process.env.Bucket, Key: `${process.env.StackName}/job/${jobid}/source.geojson.gz` }))).Body, - Unzip(), + new Unzip(), fs.createWriteStream(path.resolve(tmp, 'source.geojson')) ); diff --git a/task/fabric.js b/task/fabric.js index 09c43139..e93fd4c9 100755 --- a/task/fabric.js +++ b/task/fabric.js @@ -1,5 +1,3 @@ -#!/usr/bin/env node - // Does not need to mark instance // as protected as it runs on a managed queue import { interactive } from './lib/pre.js'; @@ -183,7 +181,7 @@ async function cli() { } catch (err) { await meta.protection(false); console.error(err); - process.exit(); + throw err; } } @@ -195,7 +193,7 @@ async function get_source(out, data) { Bucket: process.env.Bucket, Key: `${process.env.StackName}/job/${data.job}/source.geojson.gz` }))).Body, - Unzip(), + new Unzip(), fs.createWriteStream(path.resolve(DRIVE, `${data.layer}.geojson`), { flags: 'a' }) ); } diff --git a/task/lib/tippecanoe.js b/task/lib/tippecanoe.js index fe7374b0..dbe66f1f 100644 --- a/task/lib/tippecanoe.js +++ b/task/lib/tippecanoe.js @@ -12,7 +12,7 @@ export default class Tippecanoe { CP.execSync('tippecanoe --version 2>&1'); CP.execSync('which tile-join'); } catch (err) { - throw new Error('tippecanoe not installed'); + throw new Error('tippecanoe not installed', err); } } diff --git a/task/package-lock.json b/task/package-lock.json index 8c5e7e7b..05565bd0 100644 --- a/task/package-lock.json +++ b/task/package-lock.json @@ -41,6 +41,9 @@ "eslint-plugin-n": "^17.10.2", "sinon": "^19.0.0", "tape": "^5.0.0" + }, + "engines": { + "node": ">=22.0.0" } }, "node_modules/@ampproject/remapping": { diff --git a/task/package.json b/task/package.json index e76c0077..66c5547d 100644 --- a/task/package.json +++ b/task/package.json @@ -5,6 +5,9 @@ "main": "index.js", "license": "MIT", "private": true, + "engines": { + "node": ">=22.0.0" + }, "scripts": { "test": "tape test/**.test.js", "lint": "eslint *.js lib/ test/" diff --git a/task/sources.js b/task/sources.js index b2f1fedf..f125ea2d 100755 --- a/task/sources.js +++ b/task/sources.js @@ -1,5 +1,3 @@ -#!/usr/bin/env node - import { interactive } from './lib/pre.js'; import Meta from './lib/meta.js'; @@ -93,7 +91,7 @@ async function cli() { } catch (err) { console.error(err); await meta.protection(false); - process.exit(1); + throw err; } } diff --git a/task/task.js b/task/task.js index 377870b6..9ae918d1 100755 --- a/task/task.js +++ b/task/task.js @@ -1,4 +1,3 @@ -#!/usr/bin/env node import { interactive } from './lib/pre.js'; import Job from './lib/job.js'; @@ -55,7 +54,7 @@ async function cli() { flow(job).catch((err) => { console.error(err); - process.exit(1); + throw err; }); } @@ -134,6 +133,7 @@ async function flow(job) { console.error(err); } finally { await meta.protection(false); + // eslint-disable-next-line n/no-process-exit process.exit(1); } }