{"id":19782439,"url":"https://github.com/steadylearner/travis-ci","last_synced_at":"2026-06-08T18:32:38.624Z","repository":{"id":44049964,"uuid":"218817314","full_name":"steadylearner/travis-ci","owner":"steadylearner","description":"Use this to set up Node Express development environment with Travis CI","archived":false,"fork":false,"pushed_at":"2023-01-24T00:43:53.000Z","size":526,"stargazers_count":0,"open_issues_count":17,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-02-28T12:57:19.947Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://www.steadylearner.com/blog","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/steadylearner.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-10-31T17:03:04.000Z","updated_at":"2019-11-01T13:54:21.000Z","dependencies_parsed_at":"2023-02-13T06:15:45.057Z","dependency_job_id":null,"html_url":"https://github.com/steadylearner/travis-ci","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/steadylearner/travis-ci","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/steadylearner%2Ftravis-ci","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/steadylearner%2Ftravis-ci/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/steadylearner%2Ftravis-ci/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/steadylearner%2Ftravis-ci/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/steadylearner","download_url":"https://codeload.github.com/steadylearner/travis-ci/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/steadylearner%2Ftravis-ci/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34075956,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-08T02:00:07.615Z","response_time":111,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-12T06:05:09.096Z","updated_at":"2026-06-08T18:32:38.605Z","avatar_url":"https://github.com/steadylearner.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![Build Status](https://travis-ci.org/steadylearner/travis-ci.svg?branch=master)](https://travis-ci.org/steadylearner/travis-ci)\n\n\u003c!--\n    Post{\n        subtitle: \"Learn how to use Docker and upload its images to DockerHub\"\n        image: \"code/Express.png\",\n        image_decription: \"Image from the official website\",\n        tags: \"How use Docker code\",\n    }\n--\u003e\n\n\u003c!-- Link --\u003e\n\n[Steadylearner]: https://www.steadylearner.com\n[Docker Website]: https://docs.docker.com/get-started\n[How to install Docker]: https://www.google.com/search?q=how+to+install+docker\n[How to deploy a container with Docker]: https://thenewstack.io/how-to-deploy-a-container-with-docker/\n[Docker Curriculum]: https://docker-curriculum.com/\n[Docker Hub]: https://hub.docker.com/\n[Docker lifecycle]: (https://medium.com/@nagarwal/lifecycle-of-docker-container-d2da9f85959).\n[AWS]: https://aws.amazon.com\n[Elastic Beanstalk]: https://aws.amazon.com/pt/elasticbeanstalk/\n[ECS]: https://aws.amazon.com/ecs/\n[Cloud​Formation]: https://aws.amazon.com/pt/cloudformation/\n[Node]: https://nodejs.org/en/\n[NPM]: https://www.npmjs.com/\n[Yarn]: https://yarnpkg.com/lang/en/\n[Express]: https://expressjs.com/\n[ESLint]: https://eslint.org/\n[Jest]: https://jestjs.io/\n[Tape]: https://github.com/substack/tape\n[Supertest]: https://github.com/visionmedia/supertest\n[Travis CI]: https://travis-ci.org/\n[node-postgres]: https://node-postgres.com/\n[gRPC Node]: https://github.com/grpc/grpc-node\n[travis-ci]: https://github.com/steadylearner/travis-ci\n\n[chalk]: [https://github.com/chalk/chalk]\n\n\u003c!-- / --\u003e\n\n\u003c!-- Steadylearner Post --\u003e\n\n[Steadylearner Blog]: https://www.steadylearner.com/blog\n[How to make es5 JavaScript code from es6+ with Babel]: https://www.steadylearner.com/blog/read/How-to-make-es5-JavaScript-code-from-es6+-with-Babel\n[How to use Docker commands]: https://www.steadylearner.com/blog/read/How-to-use-Docker-commands\n[How to automatically commit files to GitHub with Python]: https://www.steadylearner.com/blog/read/How-to-automatically-commit-files-to-GitHub-with-Python\n\n\u003c!-- / --\u003e\n\n\u003c!-- Steadylearner Twitter and LinkedIn  --\u003e\n\n[Twitter]: https://twitter.com/steadylearner_p\n[LinkedIn]: https://www.linkedin.com/in/steady-learner-3151b7164/\n\n\u003c!--  --\u003e\n\nIn this post, we will learn how to set up Node [Express] development environment.  We will start with the route that returns \"Hello, World\" to simplify the process.\n\nYou will have the Express project with [ESLint], [Jest], [Tape], [Supertest], [Travis CI] etc after you read this post.\n\nIn the following [Steadylearner Blog] posts, we will improve it to make [gRPC Node] micro services with [Postgresql][node-postgres]. Then, we will learn how to deploy it to [Elastic Beanstalk], [ECS], [Cloud​Formation] etc from [AWS].\n\nThe purpose of this post is to make their starting point you can easily refer to later.\n\nWe won't include [How to make es5 JavaScript code from es6+ with Babel]. You can use bundlers or read the post and combine it with the code from this post if you want es6+ features.\n\n\u003cbr /\u003e\n\n\u003ch2 class=\"red-white\"\u003e[Prerequisite]\u003c/h2\u003e\n\n1. [Node], [NPM], [Yarn]\n2. [How to use Docker commands]\n3. [Express]\n\n---\n\nI hope you have already used [Node], [NPM] and [Yarn] before and installed them in your machine. This is the following post of [How to use Docker commands]. It will help you to install [Node], [NPM] also if you haven't yet.\n\nIf you haven't used the [Express] before, read the documentation of it and spend a few hours.\n\n\u003cbr /\u003e\n\n\u003ch2 class=\"blue\"\u003eTable of Contents\u003c/h2\u003e\n\n1. Make Express \"Hello, World\" app\n2. Supertest and Tape to test the end point\n3. Organize the project with ESLint\n4. Jest\n5. Travis CI\n6. Commit.py to automate the GitHub commit process\n7. **Conclusion**\n\n---\n\n\u003cbr /\u003e\n\n## 1. Make Express \"Hello, World\" app\n\nWe will start by making a simple Express \"Hello, World\" app. Make a directory first.\n\n```console\n$mkdir travis-ci\n```\n\nOur project will be integrated with [Travis CI] at the end of this post. Therefore, use **travis-ci** for the directory name to find it easy later. [Travis CI] requires you to make a GitHub repository first. You can make a [travis-ci] or eles first if you save your time later.\n\nThen, we will install the dependencies with Yarn. Save the [package.json](https://github.com/steadylearner/travis-ci/blob/master/package.json) in your folder and **yarn** to install it.\n\n```json\n{\n  \"name\": \"express-example-with-travis-ci\",\n  \"version\": \"1.0.0\",\n  \"main\": \"index.js\",\n  \"license\": \"MIT\",\n  \"dependencies\": {\n    \"body-parser\": \"^1.19.0\",\n    \"chalk\": \"^2.4.2\",\n    \"dotenv\": \"^8.1.0\",\n    \"express\": \"^4.17.1\"\n  },\n  \"devDependencies\": {\n    \"eslint\": \"^6.5.1\",\n    \"eslint-plugin-jest\": \"^22.17.0\",\n    \"eslint-plugin-node\": \"^10.0.0\",\n    \"jest\": \"^24.9.0\",\n    \"supertest\": \"^4.0.2\",\n    \"tape\": \"^4.11.0\"\n  },\n  \"scripts\": {\n    \"serve\": \"node index.js\",\n    \"eslint-init\": \"node_modules/.bin/eslint --init\",\n    \"pretest\": \"eslint .\",\n    \"fix\": \"yarn pretest --fix\",\n    \"test\": \"jest\",\n    \"test:watch\": \"yarn test --watch\",\n    \"test:tape\": \"node tests/index.js\"\n  }\n}\n```\n\nWe will write a few files to return \"Hello, World\" at **/hello** route. Start with **index.js** that will be the entry point of your project to start your app.\n\n```js\nconst chalk = require(\"chalk\");\nconst app = require(\"./server\");\n\nconst port = 3000;\n\napp.listen(port, () =\u003e {\n  const blue = chalk.blue;\n  const target = blue(`http://localhost:${port}`);\n  console.log(`🚀 Server ready at ${target}`);\n});\n```\n\nWe use chalk and separate **const target = blue(`http://localhost:${port}`);** to decorate the server log. You can test it later with **$yarn serve**.\n\n\nThen, we will build **server.js** used in the **index.js** we made.\n\n```js\n// https://www.freecodecamp.org/news/how-to-write-a-production-ready-node-and-express-app-f214f0b17d8c/\nconst express = require(\"express\");\nconst bodyParser = require(\"body-parser\");\n\nconst app = express();\n\nconst { hello } = require(\"./routes\");\n\napp.use(bodyParser.urlencoded({ extended: true }));\napp.use(bodyParser.json());\n\n// https://expressjs.com/en/guide/routing.html\napp.use(\"/hello\", hello);\n\nmodule.exports = app;\n```\n\nMost of your important Express codes will be here. I hope you read [Express] documentation for them and search on your own. Then, what left will be just include more routes similar to **app.use(\"/hello\", hello);**.\n\nYou can see **hello route** is imported with **const { hello } = require(\"./routes\");**. We will build routes directory first following [the instruction for the routes](https://expressjs.com/en/guide/routing.html).\n\n```console\n$mkdir routes\n```\n\nThen, make **hello.js** to return \"hello\" response for /hello route and **index.js** to export it.\n\n```js\nconst express = require(\"express\");\nconst router = express.Router();\n\nrouter.get(\"/\", async (req, res) =\u003e {\n  console.log(\"Get request to /hello\");\n  console.log(req.headers);\n\n  res.send(\"hello\");\n});\n\nmodule.exports = router;\n```\n\n\u003cbr /\u003e\n\n```js\n// index.js\nconst hello = require(\"./hello\");\n\nmodule.exports = {\n  hello,\n};\n```\n\n**hello.js** for **hello route** an\n\nEverything is read for your **Express** app to work. **yarn serve** and you will see **Server ready at http://localhost:3000**.\n\nUse CURL or browser to manually test http://localhost:3000/hello route work or not.\n\n```console\n$curl http://localhost:3000/hello\n// hello\n```\n\nI hope you could make it. You could use monolithic index.js or server.js instead. But, having this structure will help you test and organize your project better.\n\n\u003cbr /\u003e\n\n## 2. Include Supertest and Tape to test the end point\n\nWe made a very simple Express app before. We will include [Tape] and [Supertest] relevant codes to test the **/hello** end point.\n\nStart by making **tests** folder with **$mkdir tests**. Then, make **index.js** similar to this.\n\n```js\nconst test = require(\"tape\");\nconst supertest = require(\"supertest\");\n\nconst app = require(\"../server\");\nconst request = supertest(app);\n\nconst assert = require('assert');\nconst chalk = require(\"chalk\");\n\ntest(\"GET /hello with promise\", done =\u003e {\n  request\n    .get('/hello')\n    .expect(200)\n    .then(response =\u003e {\n      const blue = chalk.blue;\n      const msg = blue(\"Should return 200 OK with 'hello'\");\n\n      try {\n        assert.strictEqual(response.text, \"hello\");\n      } catch (e) {\n        console.log(e);\n        done.fail(msg);\n      }\n\n      done.pass(msg);\n      done.end();\n    });\n});\n\ntest(\"GET /hello with async\", async done =\u003e {\n\n  const blue = chalk.blue;\n  const msg = blue(\"Should return 200 OK with 'hello'\");\n\n  try {\n    const req = await request\n      .get('/hello')\n      .expect(200);\n    assert.strictEqual(req.text, \"hello\");\n  } catch(e) {\n    console.log(e);\n    done.fail(msg);\n  }\n\n  done.pass(msg);\n  done.end();\n});\n```\n\nI hope you already read the documenation for [Test] and [Supertest]. The important parts here will be **.get**, **expect** and **assert.strictEqual** relevant codes. We convert what we did at the end of the previous part to the JavaScript code here with them.\n\nYou can also verify that we can use either **Promise** or **async await** syntax with them. The first example I could find was with Promise. I made **async await** example also for this post. It won't take more than a minute to convert code between them. \n\nUse what you want.\n\nThen, test it with **yarn test:tape** and it will show the message similar to this.\n\n```console\n# [GET] /hello with promise\nok 1 Should return 200 OK with 'hello'\n# [GET] /hello with async\nok 2 Should return 200 OK with 'hello'\n```\n\n\u003cbr /\u003e\n\n## 3. Organize the project with ESLint\n\nWe made a few JavaScript files and verified them work. We will include [ESLint] to find some potential bugs and organize code better.\n\nMake a **.eslintrc.json** similar to this.\n\n```json\n{\n    \"env\": {\n        \"browser\": true,\n        \"commonjs\": true,\n        \"es6\": true,\n        \"jest/globals\": true\n    },\n    \"extends\": [\n        \"eslint:recommended\",\n        \"plugin:node/recommended\",\n        \"plugin:jest/recommended\"\n    ],\n    \"plugins\": [\n        \"jest\"\n    ],\n    \"globals\": {\n        \"Atomics\": \"readonly\",\n        \"SharedArrayBuffer\": \"readonly\"\n    },\n    \"parserOptions\": {\n        \"ecmaVersion\": 2020\n    },\n    \"rules\": {\n        \"indent\": [\n            \"error\",\n            \"tab\"\n        ],\n        \"semi\": [\n            \"error\",\n            \"always\"\n        ],\n        \"node/exports-style\": [\n            \"error\",\n            \"module.exports\"\n        ],\n        \"node/file-extension-in-import\": [\n            \"error\",\n            \"always\"\n        ],\n        \"node/prefer-global/buffer\": [\n            \"error\",\n            \"always\"\n        ],\n        \"node/prefer-global/console\": [\n            \"error\",\n            \"always\"\n        ],\n        \"node/prefer-global/process\": [\n            \"error\",\n            \"always\"\n        ],\n        \"node/prefer-global/url-search-params\": [\n            \"error\",\n            \"always\"\n        ],\n        \"node/prefer-global/url\": [\n            \"error\",\n            \"always\"\n        ],\n        \"node/no-unpublished-require\": [\n            \"error\",\n            {\n                \"allowModules\": [\n                    \"tape\",\n                    \"supertest\"\n                ]\n            }\n        ],\n        \"node/prefer-promises/dns\": \"error\",\n        \"node/prefer-promises/fs\": \"error\",\n        \"jest/no-disabled-tests\": \"warn\",\n        \"jest/no-focused-tests\": \"error\",\n        \"jest/no-identical-title\": \"error\",\n        \"jest/prefer-to-have-length\": \"warn\",\n        \"jest/valid-expect\": \"error\"\n    }\n}\n```\n\nMost of them are from their relevant official documenations. We used Node, Tape and Supertest and will include Jest. Refer to it and include more with [ESLint] if you want.\n\nYou can see this part in **package.json** relevant to ESLint.\n\n```json\n  \"scripts\": {\n    \"eslint-init\": \"node_modules/.bin/eslint --init\",\n    \"pretest\": \"eslint .\",\n    \"fix\": \"yarn pretest --fix\",\n    \"test\": \"jest\",\n  }\n```\n\n**pretest** will be used before **test** to lint files before you test them. You will mostly want to use **$yarn fix** if you want to ESLint automatically fix your codes.\n\nYou can also make [.eslintignore](https://eslint.org/docs/user-guide/configuring#eslintignore) files if you want to exclude some files from it. Test **$yarn fix** in your CLI and lint your project.\n\n\u003cbr /\u003e\n\n## 4. Jest\n\nIn the previous part for **Tape** and **Supertest** we already made code to test the end point /hello. But, what if we want to test other features? So we will include Jest for that.\n\nWe will first set up the proejct with **jest.config.js**\n\n```js\nmodule.exports = {\n  verbose: true,\n};\n```\n\nThen, build **__tests__** folder with **$mkdir __tests** and include **hello.js** to test [Jest] work.\n\n```js\ntest('Testing to see if Jest works', () =\u003e {\n\tconst message = \"Hello from www.steadylearner.com\";\n\texpect(message).toBe(message);\n});\n```\n\nUse **$yarn test** and will show the message similar to this.\n\n```console\n$eslint .\n$jest\n  __tests__/hello.js\n```\n\nWe verified **Jest** works. Make **express.js** in **__tests__ folder similar to this.\n\n```js\nconst app = require('../server');\n\nconst supertest = require('supertest');\nconst request = supertest(app);\n\ndescribe(\"Test express with jest and supertest\", () =\u003e {\n  test(\"[GET] /hello \", async done =\u003e {\n    const response = await request\n      .get('/hello');\n\n    expect(response.status).toBe(200);\n    expect(response.text).toBe('hello');\n\n    done();\n  });\n});\n```\n\nYou can compare it with the **tests/index.js** we made. Then, test Jest again with **$yarn test**. You can see that **$yarn test:tape** is faster for the same purpose to test end points. Therefore, we will let **Tape** and **Supertest** example for local testing purpose.\n\nYou can use Jest only if your machine is fast enough.\n\n\u003cbr /\u003e\n\n## 5. Travis CI\n\nFor we made a project and tested it in our local machine, we can integrate it with CI/CD softwares such as [Travis CI]\n\nIf you haven't account for it, please make it first. Then, read [its documenation for Node js](https://docs.travis-ci.com/user/languages/javascript-with-nodejs). Refer to [this blog post](https://dev.to/nedsoft/ci-cd-with-travisci-and-coveralls-in-node-express-api-2i55) also to follow the process.\n\nI hope you already made [the Github repostiroy][travis-ci] to test this and activate your repository at [Travis CI]. You can refer to these.\n\n```console\nhttps://travis-ci.org/youraccount/repository\nhttps://travis-ci.org/steadylearner/travis-ci\n```\n\nThen, make **.travis.yml** similar to this. We used yarn here so it became very simple because the author of [Travis CI] worked instead of you. I let some explicit commands here even though some of them are defaults.\n\n```yml\nlanguage: node_js\nnode_js:\n  - \"stable\"\ninstall: yarn\ncache: yarn\nscript: yarn test\n```\n\nInclude the code similar to this in your README.md and commit your GitHub project.\n\n```md\n[![Build Status](https://travis-ci.org/steadylearner/travis-ci.svg?branch=master)](https://travis-ci.org/steadylearner/travis-ci)\n```\n\nWait for a while and you can verify it becomes **passing**. [You can also verify the log similar to this at Travis CI](https://travis-ci.org/steadylearner/travis-ci/builds).\n\n```console\nworker_info\n\nWorker information\n\nsystem_info\n\nBuild system information\n\ndocker_mtu\ngit.checkout\n\nSetting up build cache\n\ncache.yarn\n\ncache.npm\n\n$yarn --version\n\n$eslint .\n\n$jest\n\nRan all test suites.\n\nThe command \"yarn test\" exited with 0.\n\nstore build cache\n\nDone. Your build exited with 0.\n```\n\nFind it tests instead of you with Docker containers and codes you left at **package.json**, .travis.yml etc.\n\n\u003cbr /\u003e\n\n## 6. Commit.py to automate the GitHub commit process\n\nIf you read the documentation of [Travis CI], you can find it is used with **GitHub** mostly. Make a file similar to **commit.py** with JavaScript, Python or others you want to commit it faster.\n\n```py\nimport subprocess as cmd\n\ncp = cmd.run(\"git add .\", check=True, shell=True)\n\nresponse = input(\"Do you want to use the default message for this commit?([y]/n)\\n\")\nmessage = \"update the repository\"\n\nif response.startswith('n'):\n    message = input(\"What message you want?\\n\")\n\ncp = cmd.run(f\"git commit -m '{message}'\", check=True, shell=True)\ncp = cmd.run(\"git push -u origin master -f\", check=True, shell=True)\n\n```\n\nUse **$python3 commit.py** in your console and you can commit your repository easily. Read [How to automatically commit files to GitHub with Python] for more information.\n\n\u003cbr /\u003e\n\n## 7. Conclusion\n\nI hope you made it all work. We could set up Node Express development environment with Travis CI. In the process, we could also include Jest, Tape, Supertest, ESLint etc.\n\nIn the later [Steadylearner Blog], we will learn how to deploy the **web app** with [Elastic Beanstalk] from [AWS] and Dockerfile.\n\nWe will also learn how to deploy gRPC Node micro services with Postgresql database to [ECS], [Cloud​Formation], **docker-compose.yml** etc.\n\nIf you want the latest contents from Steadylearner, follow me at [Twitter].\n\nDo you need **a Full Stack Developer** who can deploy the projects with Docker, AWS etc? Contact me with [LinkedIn] and I will help you.\n\n**Thanks and please share this post with others**.\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsteadylearner%2Ftravis-ci","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsteadylearner%2Ftravis-ci","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsteadylearner%2Ftravis-ci/lists"}