{"id":20951373,"url":"https://github.com/lgug2z/story","last_synced_at":"2025-05-14T03:33:03.352Z","repository":{"id":64302974,"uuid":"135195613","full_name":"LGUG2Z/story","owner":"LGUG2Z","description":"Workflow tool for implementing stories across multiple inter-dependent node projects in a meta-repo","archived":false,"fork":false,"pushed_at":"2019-07-24T09:00:41.000Z","size":170,"stargazers_count":15,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2024-06-20T15:58:44.455Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Go","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/LGUG2Z.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":"2018-05-28T18:25:01.000Z","updated_at":"2023-07-25T14:17:25.000Z","dependencies_parsed_at":"2023-01-15T09:45:46.404Z","dependency_job_id":null,"html_url":"https://github.com/LGUG2Z/story","commit_stats":null,"previous_names":[],"tags_count":17,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LGUG2Z%2Fstory","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LGUG2Z%2Fstory/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LGUG2Z%2Fstory/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LGUG2Z%2Fstory/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/LGUG2Z","download_url":"https://codeload.github.com/LGUG2Z/story/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":225275675,"owners_count":17448389,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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-19T00:58:37.319Z","updated_at":"2024-11-19T00:58:37.909Z","avatar_url":"https://github.com/LGUG2Z.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# story\n[![Go Report Card](https://goreportcard.com/badge/github.com/lgug2z/story)](https://goreportcard.com/report/github.com/lgug2z/story)\n[![Maintainability](https://api.codeclimate.com/v1/badges/ed8cb042219f695c8436/maintainability)](https://codeclimate.com/github/LGUG2Z/story/maintainability)\n[![Test Coverage](https://api.codeclimate.com/v1/badges/ed8cb042219f695c8436/test_coverage)](https://codeclimate.com/github/LGUG2Z/story/test_coverage)\n[![Build Status](https://travis-ci.org/LGUG2Z/story.svg?branch=master)](https://travis-ci.org/LGUG2Z/story)\n\n`story` works as a layer on top of [meta](https://github.com/mateodelnorte/meta) to aid development, continuous integration,\ntesting, container building and deployments when working with meta-repos containing a large number of inter-dependent\n`node` projects.\n\n- [Installation](#installation)\n  * [Go Get](#go-get)\n  * [Homebrew](#homebrew)\n  * [Bash Completion](#bash-completion)\n- [The .meta File](#the-meta-file)\n  * [The trunk `.meta` file](#the-trunk--meta--file)\n  * [The `story` `.meta` file](#the--story---meta--file)\n  * [`.storyignore`](#-storyignore-)\n- [Commands](#commands)\n- [Workflow Examples](#workflow-examples)\n  * [Starting a New Story](#starting-a-new-story)\n  * [Updating From Trunk Branches](#updating-from-trunk-branches)\n  * [Migrating Existing Branches to a New Story](#migrating-existing-branches-to-a-new-story)\n  * [Switching Stories](#switching-stories)\n  * [Merging Completed Stories](#merging-completed-stories)\n    + [Using the GitHub PR Merge API](#using-the-github-pr-merge-api)\n    + [Using Plain Git](#using-plain-git)\n\n# Installation\n## Go Get\n```bash\ngo get -u github.com/LGUG2Z/story\ncd $GOPATH/src/github.com/LGUG2Z/story\nmake install\n```\n\n## Homebrew\n```bash\nbrew tap LGUG2Z/tap\nbrew install LGUG2Z/tap/story\n```\n\n## Bash Completion\nAdd the following to your `.bashrc` or `.zshrc`\n```bash\nPROG=story source /usr/local/etc/bash_completion.d/story\n```\n\n# The .meta File\n## The trunk `.meta` file\nThere are two types of `.meta` files used by `story`, which are both supersets of the `.meta` file used by\n [meta](https://github.com/mateodelnorte/meta):\n\nThe `.meta` file for the overall meta-repo includes two extra keys, `artifacts` and `organisation`:\n\n```json\n{\n  \"artifacts\": {\n    \"api\": false,\n    \"app\": false\n  },\n  \"organisation\": \"SecretOrg\",\n  \"projects\": {\n    \"api\": \"git@github.com:SecretOrg/api.git\",\n    \"app\": \"git@github.com:SecretOrg/app.git\",\n    \"lib-1\": \"git@github.com:SecretOrg/lib-1.git\",\n    \"lib-2\": \"git@github.com:SecretOrg/lib-2.git\"\n  }\n}\n```\n\n`artifacts` refers to projects that can be built and deployed, and should be set to `false` in the `.meta` file for a meta-repo.\n\n`organisation` refers to the name of the organisation on GitHub where private repositories are hosted.\n\nA JSONSchema for the trunk `.meta` file is available [here](meta.json).\n\n## The `story` `.meta` file\nThe `.meta` file for stories includes a number of extra keys on top of those introduced above:\n```json\n{\n  \"story\": \"story/auth-endpoint\",\n  \"organisation\": \"SecretOrg\",\n  \"projects\": {\n    \"api\": \"git@github.com:SecretOrg/api.git\",\n    \"lib-2\": \"git@github.com:SecretOrg/lib-2.git\"\n  },\n  \"hashes\": {\n    \"api\": \"c917d416366a04f2ec62c2e8aaee5bc740d8c6aa\",\n    \"lib-2\": \"6bbe39ebe169c46eee7b2a6bc392e0b37e397a0e\"\n  },\n  \"blastRadius\": {\n    \"api\": null,\n    \"lib-2\": [\"api\", \"app\"]\n  },\n  \"artifacts\": {\n    \"api\": true,\n    \"app\": true\n  },\n  \"allProjects\": {\n    \"api\": \"git@github.com:SecretOrg/api.git\",\n    \"app\": \"git@github.com:SecretOrg/app.git\",\n    \"lib-1\": \"git@github.com:SecretOrg/lib-1.git\",\n    \"lib-2\": \"git@github.com:SecretOrg/lib-2.git\"\n  }\n}\n```\n`story` refers to the name of the branch that will be checked out on any projects added to a story.\n\n`projects` refers to the subset of projects that the story requires work to be done on.\n\n`hashes` refers to the current commit hashes of each project at the time of a commit to the meta-repo.\n\n`blastRadius` refers to projects in the meta-repo that can be impacted by made changes in the scope of the current story.\n\n`allProjects` refers to the complete list of projects in the meta-repo.\n\nThis latter file is automatically generated and maintained by `story` commands. For example, adding or removing a project\nto a story will update the `projects`, `hashes`, `blastRadius` and `artifacts` keys accordingly, and making a commit\nacross the meta-repo will update the `hashes` key before making a final commit to the meta-repo.\n\nA JSONSchema for the `story` `.meta` file is available [here](story.json).\n\n## `.storyignore`\nOptionally, a `.storyignore` file can be committed to the root of the metarepo containing the names of repositories\nin which the `package.json` files should never be modified by `story`. Repo names should be separated by new lines.\nGlob and regex patterns are not supported. The state of these repositories will still be tracked by the `.story` `.meta`\nfile.\n\n```\n# .storyignore\nlib-3\nlegacy-app\n```\n\n# Commands\n```\nNAME:\n   story - A workflow tool for implementing stories across a node meta-repo\n\nUSAGE:\n   story [global options] command [command options] [arguments...]\n\nVERSION:\n   0.3.4\n\nAUTHOR:\n   J. Iqbal \u003cjade@beamery.com\u003e\n\nCOMMANDS:\n     create       Creates a new story\n     load         Loads an existing story\n     reset        Resets all story branches to trunk branches\n     add          Adds a project to the current story\n     remove       Removes a project from the current story\n     list         Shows a list of projects added to the current story\n     blastradius  Shows a list of current story's blast radius\n     artifacts    Shows a list of artifacts to be built and deployed for the current story\n     commit       Commits code across the current story\n     push         Pushes commits across the current story\n     unpin        Unpins code in the current story\n     pin          Pins code in the current story\n     prepare      Prepares a story for merges to trunk\n     update       Updates code from the upstream master branch across the current story\n     merge        Merges prepared code to master branches across the current story\n     pr           Opens pull requests for the current story\n     help, h      Shows a list of commands or help for one command\n\nGLOBAL OPTIONS:\n   --trunk value  (default: \"master\") [$STORY_TRUNK]\n   --help, -h     show help\n   --version, -v  print the version\n```\n\n# Workflow Examples\n## Starting a New Story\n```bash\n# navigate to your metarepo\ncd ~/metarepo\n\n# create the story\nstory create story/sso-login\n\n# add the repoos you will be working on\nstory add login-service marketing-app\n\n# stage the changes made by creating and adding to the story\nmeta git add -p\n\n# make an initial commit across all the repos\nstory commit -m \"add login-service and marketing-app, update package.json files\"\n\n# push branches in all story repos\nstory push\n\n# open PRs linked to a central issue\nstory pr --issue https://github.com/SecretOrg/tracking-board/issues/9\n```\n\n## Updating From Trunk Branches\n```bash\n# load the story\nstory load story/email-login\n\n# merge in changes from trunk on every repo in the story\nstory update\n```\n\n## Migrating Existing Branches to a New Story\n```bash\n# create a new story\nstory new story/otp-login\n\n# merge in changes from other existing on every repo in the story\nstory update --from-branch feature/otp-login\n```\n\n## Switching Stories\n```bash\n# reset to the trunk branches\nstory reset\n\n# load another story\nstory load story/sso-acl\n```\n\n## Merging Completed Stories\n### Using the GitHub PR Merge API\n```bash\n# load the story\nstory load story/sso-login\n\n# make sure we have the latest from master\nstory update\n\n##########\n# EITHER #\n##########\n# reset the package.json dependencies to point to master\nstory unpin\n\n##########\n# OR     #\n##########\n# pin the package.json dependencies to a specific commit hash\nstory pin\n\n# archive the story manifest and reset the .meta file for merge\nstory prepare\n\n# push final changes to the story branches\n# still on branch story/sso-login at this point\nstory push --from-manifest story/sso-login --story-branch\n\n# merge using the github pr merge api\nstory merge --github\n```\n\n### Using Plain Git\n```bash\n# load the story\nstory load story/sso-login\n\n# make sure we have the latest from master\nstory update\n\n##########\n# EITHER #\n##########\n# reset the package.json dependencies to point to master\nstory unpin\n\n##########\n# OR     #\n##########\n# pin the package.json dependencies to a specific commit hash\nstory pin\n\n# archive the story manifest and reset the .meta file for merge\nstory prepare\n\n# push final changes to the story branches\n# still on branch story/sso-login at this point\nstory push --from-manifest story/sso-login --story-branch\n\n# merge the story to the trunk branch across all story repos\nstory merge\n\n# push just the repos that were changed in the story post-merge\n# on master branch at this point\nstory push --from-manifest story/sso-login\n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flgug2z%2Fstory","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flgug2z%2Fstory","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flgug2z%2Fstory/lists"}