|
| 1 | +# Development |
| 2 | + |
| 3 | +We don't accept PRs from outside Nubank (yet). |
| 4 | + |
| 5 | + |
| 6 | +## Setup |
| 7 | + |
| 8 | +### aws-api |
| 9 | + |
| 10 | +``` |
| 11 | +git clone git@github.com:cognitect-labs/aws-api.git |
| 12 | +cd aws-api |
| 13 | +clj -Sdeps |
| 14 | +``` |
| 15 | + |
| 16 | + |
| 17 | +## Run tests |
| 18 | + |
| 19 | +We need the dependencies in the `:dev` alias and the test runner in the `:test` or `:test-integration` |
| 20 | +aliases in order to run the tests. |
| 21 | + |
| 22 | +To run the integration tests, you'll need to bind the AWS_PROFILE env var to a profile named |
| 23 | +`aws-api-test`, which should be configured to access a development account in order to avoid running |
| 24 | +destructive operations in a prod account. |
| 25 | + |
| 26 | +```shell |
| 27 | +;; unit tests |
| 28 | +clj -M:dev:test |
| 29 | + |
| 30 | +;; integration tests |
| 31 | +AWS_PROFILE=aws-api-test clj -M:dev:test-integration |
| 32 | +``` |
| 33 | + |
| 34 | +### Add new tests |
| 35 | + |
| 36 | +Tests live in `test/src`. Unit tests should be in a parallel path to the namespace you want to test, |
| 37 | +adding `_test` in the end of the filename. For example, |
| 38 | +`test/src/cognitect/aws/credentials_test.clj` contains tests for `src/cognitect/aws/credentials.clj` |
| 39 | + |
| 40 | +Integration tests go in `test/src/cognitect/aws/integration/`. When creating integration tests, |
| 41 | +please add `^:integration` in `deftest`. Example: |
| 42 | + |
| 43 | +```clj |
| 44 | +(deftest ^:integration do-something-with-a-real-aws-service |
| 45 | + ...) |
| 46 | +``` |
| 47 | + |
| 48 | +It is also important to ensure that the `AWS_PROFILE` env var is the test profile `aws-api-test`. To |
| 49 | +do this add this at the beginning of your integration test namespace: |
| 50 | + |
| 51 | +```clj |
| 52 | +(ns cognitect.aws.integration.s3-test |
| 53 | + (:require [clojure.test :refer [use-fixtures]] |
| 54 | + [cognitect.aws.integration.fixtures :as fixtures])) |
| 55 | + |
| 56 | +(use-fixtures :once fixtures/ensure-test-profile) |
| 57 | +``` |
| 58 | + |
| 59 | +## Build |
| 60 | + |
| 61 | +### Build and install in your local ~/.m2 (or wherever you store maven repos) |
| 62 | + |
| 63 | +```shell |
| 64 | +build/package |
| 65 | +``` |
| 66 | + |
| 67 | +## CI/CD |
| 68 | + |
| 69 | +This repo relies on GitHub Actions for CI/CD. See the `.github/workflows/` directory. |
| 70 | + |
| 71 | +### Secrets |
| 72 | + |
| 73 | +The integration tests require an AWS access key and secret key pair to run. The `Run integration |
| 74 | +tests` step in the `test.yml` file has an `env` which refers to these two secrets, whose values are |
| 75 | +stored as GitHub repository secrets. |
| 76 | + |
| 77 | + |
| 78 | +## Release |
| 79 | + |
| 80 | +The release is automated via a GitHub workflow (`.github/workflows/release.yml`). The workflow can |
| 81 | +be triggered on demand by an authorized user. |
| 82 | + |
| 83 | +The release workflow makes use of the `build/release` script. |
| 84 | + |
| 85 | +```shell |
| 86 | +build/release |
| 87 | +``` |
| 88 | + |
| 89 | +In summary, the release process: |
| 90 | + |
| 91 | +* Releases are done from the `main` branch of the repository. |
| 92 | +* The release artifacts are built, signed and deployed to Maven central. |
| 93 | +* The git repository is tagged with a release tag. |
| 94 | +* Updates `CHANGES.md`, `README.md`, `latest-releases.edn` |
| 95 | +* Updates the API documentation in the `gh-pages` branch |
| 96 | + |
| 97 | +### pre-release checklist |
| 98 | + |
| 99 | +* Ensure the `CHANGES.md` file (and, optionally, the `UPGRADE.md` file) contains the expected latest |
| 100 | + unreleased changes, under a heading of `## DEV` near the top of the file just below `# aws-api` |
| 101 | + header. During the release, the version updater will replace the `DEV` with the proper release |
| 102 | + number and release date. |
| 103 | +* (Optional) If releasing a beta release, create a file named `VERSION_SUFFIX` at the root of the |
| 104 | + project, containing a beta release suffix such as `-beta01` (with hyphen). |
| 105 | + |
| 106 | +### post-release checklist |
| 107 | + |
| 108 | +* When successful, the released artifacts will appear in [Maven |
| 109 | + Central](https://repo.maven.apache.org/maven2/com/cognitect/aws/api/) possibly after a few minutes |
| 110 | + delay. |
| 111 | +* Make release announcements. |
| 112 | +* (Optional) close any open issues that are fixed by the release. |
| 113 | + |
| 114 | + |
| 115 | +### release announcements |
| 116 | + |
| 117 | +An aws-api release should be announced in the following places: |
| 118 | + |
| 119 | +* [Clojure google group](https://groups.google.com/g/clojure) |
| 120 | +* Clojurians Slack, `#releases`, `#announcements`, and `#aws` channels |
| 121 | + * Post first in `#releases` |
| 122 | + * Cross-post to the other two channels (linking to the `#releases` post) |
| 123 | + |
| 124 | +To craft the release verbiage, look at previous announcements, or use the following example. Include |
| 125 | +hyperlinks of the issue numbers to the GitHub issues. |
| 126 | + |
| 127 | +Subject: `[ANN] Nubank's aws-api 0.8.666` |
| 128 | + |
| 129 | +Body: |
| 130 | + |
| 131 | +``` |
| 132 | +Nubank's aws-api 0.8.666 is now available! |
| 133 | +
|
| 134 | +0.8.666 / 2023-04-27 |
| 135 | + * 301 gets cognitect.anomalies/incorrect instead of cognitect.anomalies/fault #237 |
| 136 | +0.8.664 / 2023-04-26 |
| 137 | + * Safely return byte arrays from ByteBuffers, honoring the position and remaining attributes, copying the underlying byte array when necessary. #238 |
| 138 | + * Upgrade to com.cognitect/http-client "1.0.123", which includes status and headers in anomalies. |
| 139 | + * Fixes #171 |
| 140 | + * Improves #15 |
| 141 | +
|
| 142 | +Obs: the anomaly fix provides users the opportunity to detect 301s and programmatically recover when the "x-amz-bucket-region" header is present. |
| 143 | +
|
| 144 | +README: https://github.com/cognitect-labs/aws-api/ |
| 145 | +API: https://cognitect-labs.github.io/aws-api/ |
| 146 | +Changelog: https://github.com/cognitect-labs/aws-api/blob/master/CHANGES.md |
| 147 | +Upgrade Notes: https://github.com/cognitect-labs/aws-api/blob/master/UPGRADE.md |
| 148 | +Latest Releases of api, endpoints, and all services: https://github.com/cognitect-labs/aws-api/blob/master/latest-releases.edn |
| 149 | +``` |
| 150 | + |
| 151 | +Note: there should be a public GitHub issue for any significant fix or change. Create a public issue |
| 152 | +if necessary. |
| 153 | + |
| 154 | +#### implementation details |
| 155 | + |
| 156 | +A few words about some lower-level implementation details which the release script makes use of. |
| 157 | + |
| 158 | +* The `build/revision` script calculates the release version (see `doc/versioning.md` for more |
| 159 | + details). |
| 160 | +* The `version_updater.clj` tool is responsible for updating four files with the release version: |
| 161 | + `README.md`, `CHANGES.md`, `UPGRADE.md`, and `latest-releases.edn`. It makes use of the |
| 162 | + `build/revision` script. Note the `deps.edn` alias `update-versions` which the release script uses |
| 163 | + to invoke this tool. |
| 164 | + |
| 165 | + |
| 166 | +## REPL |
| 167 | + |
| 168 | +There are various options for opening a REPL. |
| 169 | + |
| 170 | +### cider-nrepl |
| 171 | + |
| 172 | +1. `M-x cider-jack-in` |
| 173 | + |
| 174 | +CIDER jack-in is a convenient way to start up an nrepl without having to manually configure the |
| 175 | +nrepl and cider-nrepl dependencies. However, if you wish to use additional deps.edn aliases (e.g. |
| 176 | +`dev`, `examples`), you will have to tweak CIDER's default jack-in command. There are a couple ways |
| 177 | +to do this: |
| 178 | + |
| 179 | + * Set `cider-clojure-cli-global-options` to e.g. "-M:dev" (global setting for all projects). |
| 180 | + * Set `cider-clojure-cli-aliases` to e.g. ":dev:examples" |
| 181 | + * Set either of the two aforementioned settings locally via `.dir-locals.el`, e.g. |
| 182 | + |
| 183 | + ``` emacs-lisp |
| 184 | + ((nil . ((cider-clojure-cli-aliases . ":dev:examples")))) |
| 185 | + ``` |
| 186 | + * Prefix (`C-u`) the `M-x cider-jack-in` command, which allows you to edit the default jack-in |
| 187 | + command before it runs. |
| 188 | + |
| 189 | +2. `M-x cider-connect` |
| 190 | + |
| 191 | + * Manually start an nrepl via CLI, then connect to it using CIDER. One option is to define a |
| 192 | +`cider/nrepl` alias. Add to e.g. `~/.clojure/deps.edn`: |
| 193 | + |
| 194 | +``` clojure |
| 195 | + :aliases {:cider/nrepl {:extra-deps {nrepl/nrepl {:mvn/version "x.y.z"} |
| 196 | + cider/cider-nrepl {:mvn/version "a.b.c"}} |
| 197 | + :main-opts ["-m" "nrepl.cmdline" "--middleware" "[cider.nrepl/cider-middleware]"]}} |
| 198 | +``` |
| 199 | + |
| 200 | + * From the project root, start nrepl |
| 201 | + |
| 202 | +``` shell |
| 203 | +clj -M:dev:cider/nrepl |
| 204 | +``` |
| 205 | + |
| 206 | + * Connect to nrepl from CIDER (`C-c M-c`) using indicated host and port. |
| 207 | + |
| 208 | +### IntelliJ IDEA / Cursive |
| 209 | + |
| 210 | +1. Configure a REPL Run Configuration ("Run"->"Edit Configurations"). |
| 211 | +1. Click plus "+" to "Add new Configuration". |
| 212 | +1. Select "Clojure REPL, Local". |
| 213 | +1. In the configuration window |
| 214 | + * Give it a display name |
| 215 | + * Select "nREPL" for type of REPL to run |
| 216 | + * Select "Run with Deps" for "How to run it". Add any additional desired aliases as a |
| 217 | + comma-delimited string, e.g. `dev:examples`. |
| 218 | + |
| 219 | +Now the configured REPL can be launched (run or debug) via "Run" top-level menu or Run |
| 220 | +Configurations dropdown. |
| 221 | + |
| 222 | + |
| 223 | +Implementation Notes |
| 224 | +==================== |
| 225 | + |
| 226 | +## http client |
| 227 | + |
| 228 | +This library makes uses of an underlying http client object to aid in http request/response. |
| 229 | +Originally that client has been the `com.cognitect/http-client` library. More recently, we've |
| 230 | +developed a newer client based on the `java.net.http` package which is present in JDK 11 and up. |
| 231 | + |
| 232 | +What follows is notes on http clients. |
| 233 | + |
| 234 | +### timeouts |
| 235 | + |
| 236 | +In the context of http clients and connections, "timeout" may refer to one of (at least) three values: |
| 237 | + |
| 238 | +* name resolution timeout aka resolve timeout |
| 239 | +* connect timeout |
| 240 | +* read response timeout aka idle timeout |
| 241 | + |
| 242 | +For the cognitect client (which is based on an underlying Jetty http client): |
| 243 | + |
| 244 | +* resolve timeout defaults to 5 seconds |
| 245 | +* connect timeout defaults to 5 seconds |
| 246 | +* idle timeout is unspecified, which means unbounded |
| 247 | + |
| 248 | +For the java.net.http client, there is no distinct "resolve timeout", therefore we have set the |
| 249 | +"connect timeout" to be 10 seconds, encompassing the sum of the previous client's resolve and |
| 250 | +connect timeout defaults. |
| 251 | + |
| 252 | +* resolve timeout (not applicable) |
| 253 | +* connect timeout defaults to 10 seconds |
| 254 | +* idle timeout is unspecified, which means unbounded |
| 255 | + |
| 256 | +### restricted headers |
| 257 | + |
| 258 | +Potentially confusing because "restricted headers" may be referring to one of two separate topics: |
| 259 | + |
| 260 | +* The headers which are disallowed by the java.net.HttpClient implementation, because the |
| 261 | + implementation will provide its own values for these headers |
| 262 | + ([doc](https://docs.oracle.com/en/java/javase/21/docs/api/java.net.http/module-summary.html)). |
| 263 | +* The headers which are forbidden by the Fetch API spec which runs in browsers |
| 264 | + ([doc](https://developer.mozilla.org/en-US/docs/Glossary/Forbidden_header_name)) |
| 265 | + |
| 266 | +aws-api is concerned with only the first topic. |
0 commit comments