Simple Release Script: Sequence, Class, And Flow Diagrams

by Alex Johnson 58 views

In the realm of software development, efficient release management is crucial. This article delves into the inner workings of a simple release script designed for lightweight, in-between releases. We'll explore its sequence diagram, class diagram, and flow diagram to provide a comprehensive understanding of its functionality and structure. The script aims to streamline the release process by automating version updates, publishing packages, and handling potential errors, all while maintaining a clean and organized workflow.

Sequence Diagram for Running the Simple Release Script

The sequence diagram illustrates the interaction between different actors and components during the execution of the simple release script. It provides a chronological view of the steps involved, making it easier to understand the flow of data and control.

sequenceDiagram
  actor Maintainer
  participant Shell
  participant SimpleReleaseScript
  participant GitRepo
  participant NpmRegistry

  Maintainer->>Shell: Run npm run release:simple
  Shell->>SimpleReleaseScript: Execute scripts/simple-release.ts version npm_token tag

  SimpleReleaseScript->>SimpleReleaseScript: parseArgs(version,npmToken,tag)
  SimpleReleaseScript->>GitRepo: Read packages/*/package.json
  GitRepo-->>SimpleReleaseScript: PackageJson content per active package

  SimpleReleaseScript->>SimpleReleaseScript: updatePackageVersions(packages,version)
  SimpleReleaseScript->>GitRepo: Write updated package.json files

  loop For each active package
    SimpleReleaseScript->>NpmRegistry: npm publish --tag=tag with NPM_TOKEN
    NpmRegistry-->>SimpleReleaseScript: Publish result
  end

  alt Any publish fails
    SimpleReleaseScript->>GitRepo: git checkout -- packages/*/package.json
    SimpleReleaseScript-->>Maintainer: Print release failed
  else All publishes succeed
    SimpleReleaseScript->>GitRepo: git checkout -- packages/*/package.json
    SimpleReleaseScript-->>Maintainer: Print release completed successfully
  end

The sequence starts with a maintainer initiating the release process by running the npm run release:simple command in the shell. The shell then executes the scripts/simple-release.ts script, passing the version, npm token, and tag as arguments. The script begins by parsing these arguments to ensure they are valid and in the correct format. Next, the script interacts with the Git repository to read the package.json files for each active package. This involves retrieving the content of these files to gather information about the package, such as its name, version, and dependencies. The script then updates the package versions in memory. These updated package.json files are then written back to the Git repository, effectively modifying the version information for each active package. Subsequently, the script iterates through each active package and attempts to publish it to the npm registry using the provided npm token and tag. The npm registry responds with a publish result, indicating whether the publication was successful or not.

Finally, the script evaluates whether all publishes were successful. If any publish fails, the script reverts the changes made to the package.json files by using git checkout and informs the maintainer that the release failed. Conversely, if all publishes succeed, the script still reverts the changes to the package.json files to maintain a clean state, but informs the maintainer that the release completed successfully. This sequence diagram provides a clear and concise representation of the steps involved in the simple release script, highlighting the interactions between the maintainer, shell, script, Git repository, and npm registry.

Class Diagram for Simple-Release Script Structure

The class diagram provides a static view of the structure of the simple-release script. It defines the classes, their attributes, and the relationships between them. This diagram helps to understand the design and organization of the script's code.

classDiagram
  class SimpleReleaseScript {
    +ACTIVE_PACKAGES string[]
    +main() Promise~void~
    +parseArgs() Args
    +readPackageJson(packagePath string) PackageJson
    +writePackageJson(packagePath string, packageJson PackageJson) void
    +updateDependencyVersion(deps Record~string,string~, newVersion string) Record~string,string~
    +updatePackageVersions(packages PackageInfo[], newVersion string) void
    +publishPackages(packages PackageInfo[], npmToken string, tag string) void
    +revertChanges() void
  }

  class PackageJson {
    +name string
    +version string
    +dependencies Record~string,string~
    +devDependencies Record~string,string~
  }

  class PackageInfo {
    +name string
    +path string
    +oldVersion string
    +packageJson PackageJson
  }

  class Args {
    +version string
    +npmToken string
    +tag string
  }

  SimpleReleaseScript --> PackageJson : reads/writes
  SimpleReleaseScript --> PackageInfo : manages
  SimpleReleaseScript --> Args : uses

  class ExamplesRunnerScript {
    +pkg string
    +__dirname string
  }

  SimpleReleaseScript <.. ExamplesRunnerScript : both use ESM compatible file resolution

The central class is SimpleReleaseScript, which orchestrates the entire release process. It contains several methods, including main() which is the entry point of the script, parseArgs() which parses the command-line arguments, readPackageJson() and writePackageJson() which handle reading and writing package.json files, updatePackageVersions() which updates the versions of the packages, publishPackages() which publishes the packages to the npm registry, and revertChanges() which reverts any changes made to the package.json files in case of failure. The SimpleReleaseScript class relies on several other classes to perform its functions. The PackageJson class represents the structure of a package.json file, containing attributes such as name, version, dependencies, and devDependencies. The PackageInfo class encapsulates information about a package, including its name, path, oldVersion, and the packageJson object. The Args class represents the command-line arguments passed to the script, including the version, npmToken, and tag. The SimpleReleaseScript class reads and writes PackageJson objects, manages PackageInfo objects, and uses Args objects. It also shares a dependency on ESM compatible file resolution with the ExamplesRunnerScript class.

Flow Diagram for Simple In-Between Release Script

The flow diagram illustrates the step-by-step process of the simple in-between release script. It provides a visual representation of the control flow, decision points, and actions performed by the script. This diagram helps to understand the overall logic and execution of the script.

flowchart TD
  A[Start simple release
  tsx scripts/simple-release.ts
  or npm run release:simple] --> B[Parse arguments
  version, npm_token, tag]
  B --> C{Arguments valid?}
  C -- No --> Z[Print usage and exit 1]
  C -- Yes --> D[Resolve rootPath and packagesPath]
  D --> E[Build ACTIVE_PACKAGES list]
  E --> F[For each active package
  read package_json
  collect name, path, oldVersion]
  F --> G[Print current package versions]
  G --> H[updatePackageVersions
  set version
  update @ethereumjs/* deps and devDeps
  write package_json]
  H --> I[publishPackages
  for each package
  npm publish --tag=tag
  with NPM_TOKEN]
  I --> J{Publish succeeded for all?}
  J -- No --> K[Log failure
  attempt revertChanges
  git checkout -- packages/*/package.json
  exit 1]
  J -- Yes --> L[revertChanges
  git checkout -- packages/*/package.json]
  L --> M[Print success message]
  M --> N[End]

  subgraph Environment
    D
    E
    F
  end

  subgraph Version_update
    H
  end

  subgraph Publishing
    I
  end

  subgraph Cleanup_and_error_handling
    J
    K
    L
    M
  end

The process begins with the start of the simple release script, initiated either by running tsx scripts/simple-release.ts or npm run release:simple. The script then parses the arguments passed to it, including the version, npm token, and tag. If the arguments are invalid, the script prints the usage instructions and exits with an error code. If the arguments are valid, the script resolves the root path and packages path, and builds a list of active packages. For each active package, the script reads the package.json file and collects the name, path, and old version. The current package versions are then printed for informational purposes. The script updates the package versions by setting the new version and updating the @ethereumjs/* dependencies and devDependencies. The updated package.json files are then written back to disk. The script then publishes each package to the npm registry using the provided npm token and tag. If the publish succeeds for all packages, the script reverts the changes made to the package.json files and prints a success message. If the publish fails for any package, the script logs the failure, attempts to revert the changes, and exits with an error code. This flow diagram provides a clear and concise overview of the steps involved in the simple in-between release script, highlighting the decision points and actions performed by the script.

File-Level Changes

The changes introduced by this script are organized into several file-level modifications, each addressing specific aspects of the release process. These changes collectively enhance the efficiency and maintainability of the release workflow.

Change Details Files
Introduce a simple scripted workflow for lightweight in-between (nightly/alpha) releases and wire it into npm scripts.
  • Add scripts/simple-release.ts to batch-update active package versions, publish them with a custom npm dist-tag using an NPM token, and then revert local version changes via git checkout.
  • Define ACTIVE_PACKAGES list and implement helpers to read/write package.json files and update internal @ethereumjs/* dependency versions while preserving semver prefixes.
  • Implement CLI argument parsing, logging, and error handling for the simple release flow, including reverting changes on failure.
  • Add scripts/package.json with module type configuration to support ES module imports in scripts.
  • Expose the script through a new npm script release:simple in the root package.json.
scripts/simple-release.ts
scripts/package.json
package.json
Document the new simple release flow for developers.
  • Extend DEVELOPER.md with an "In-between Releases" section explaining the purpose of lightweight releases and providing usage and example commands for scripts/simple-release.ts.
DEVELOPER.md
Fix the examples runner script to work correctly under ES modules.
  • Use fileURLToPath and dirname(import.meta.url) to reconstruct __dirname and make path resolution work in scripts/examples-runner.ts.
scripts/examples-runner.ts
Remove obsolete end-to-end Hardhat-related scripts and helpers.
  • Delete legacy e2e hardhat shell and Node scripts that are no longer used for the current release/testing flows.
scripts/e2e-hardhat.sh
scripts/e2e-inject-resolutions.js
scripts/e2e-publish.sh
scripts/e2e-resolutions.js

Conclusion

The simple release script provides a streamlined and automated approach to managing in-between releases. By understanding its sequence diagram, class diagram, and flow diagram, developers can gain valuable insights into its functionality and structure. This knowledge empowers them to effectively utilize the script, troubleshoot any issues, and contribute to its improvement.

For more information on release management best practices, visit the Atlassian's Release Management Guide.