Skip to content

Commit 46570df

Browse files
authored
development doc (#285)
Add documentation for developers
1 parent dd379ee commit 46570df

File tree

1 file changed

+266
-0
lines changed

1 file changed

+266
-0
lines changed

doc/development.md

Lines changed: 266 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,266 @@
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

Comments
 (0)