diff --git a/CHANGELOG.md b/CHANGELOG.md
index 6b2b2bb..811ed1a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,6 +5,13 @@ All notable changes to this project will be documented in this file.
 The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this
 project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
 
+## Unreleased
+
+### Fixed
+
+- In `set_key`, add missing newline character before new entry if necessary. (#361 by
+  [@bbc2])
+
 ## [0.19.1] - 2021-08-09
 
 ### Added
diff --git a/src/dotenv/main.py b/src/dotenv/main.py
index b8d0a4e..d867f02 100644
--- a/src/dotenv/main.py
+++ b/src/dotenv/main.py
@@ -167,13 +167,17 @@ def set_key(
 
     with rewrite(dotenv_path) as (source, dest):
         replaced = False
+        missing_newline = False
         for mapping in with_warn_for_invalid_lines(parse_stream(source)):
             if mapping.key == key_to_set:
                 dest.write(line_out)
                 replaced = True
             else:
                 dest.write(mapping.original.string)
+                missing_newline = not mapping.original.string.endswith("\n")
         if not replaced:
+            if missing_newline:
+                dest.write("\n")
             dest.write(line_out)
 
     return True, key_to_set, value_to_set

diff --git a/tests/test_main.py b/tests/test_main.py
index 13e2791..541ac5e 100644
--- a/tests/test_main.py
+++ b/tests/test_main.py
@@ -37,6 +37,7 @@ def test_set_key_no_file(tmp_path):
         ("a=b\nc=d", "a", "e", (True, "a", "e"), "a='e'\nc=d"),
         ("a=b\nc=d\ne=f", "c", "g", (True, "c", "g"), "a=b\nc='g'\ne=f"),
         ("a=b\n", "c", "d", (True, "c", "d"), "a=b\nc='d'\n"),
+        ("a=b", "c", "d", (True, "c", "d"), "a=b\nc='d'\n"),
     ],
 )
 def test_set_key(dotenv_file, before, key, value, expected, after):

set_key does not check if there is a carriage return before inserting new key
Example script :
```
import os
import dotenv

DOTENV_FILE = os.path.join(os.path.dirname(__file__), ".env")

def init_dotenv():
    with open(DOTENV_FILE, "w") as fp:
        fp.write("TEST=ABCD") 


def print_dotenv():
    with open(DOTENV_FILE) as fp:
        content = fp.read()
    print("-" * 30, "DOTENV", "-" * 30)
    print(content)
    print()

init_dotenv()
print_dotenv()
dotenv.set_key(DOTENV_FILE, "FOO", "1234")
print_dotenv()
```
Output
```
------------------------------ DOTENV ------------------------------
TEST=ABCD

------------------------------ DOTENV ------------------------------
TEST=ABCDFOO='1234'


```

Is this something you want to fix ?
tests/test_main.py::test_set_key[a=b-c-d-expected12-a=b\nc='d'\n]
tests/test_main.py::test_set_key_no_file tests/test_main.py::test_set_key[-a--expected0-a=''\n] tests/test_main.py::test_set_key[-a-b-expected1-a='b'\n] tests/test_main.py::test_set_key[-a-'b'-expected2-a='\\'b\\''\n] tests/test_main.py::test_set_key[-a-"b"-expected3-a='"b"'\n] tests/test_main.py::test_set_key[-a-b'c-expected4-a='b\\'c'\n] tests/test_main.py::test_set_key[-a-b"c-expected5-a='b"c'\n] tests/test_main.py::test_set_key[a=b-a-c-expected6-a='c'\n] tests/test_main.py::test_set_key[a=b\n-a-c-expected7-a='c'\n] tests/test_main.py::test_set_key[a=b\n\n-a-c-expected8-a='c'\n\n] tests/test_main.py::test_set_key[a=b\nc=d-a-e-expected9-a='e'\nc=d] tests/test_main.py::test_set_key[a=b\nc=d\ne=f-c-g-expected10-a=b\nc='g'\ne=f] tests/test_main.py::test_set_key[a=b\n-c-d-expected11-a=b\nc='d'\n] tests/test_main.py::test_get_key_no_file tests/test_main.py::test_get_key_not_found tests/test_main.py::test_get_key_ok tests/test_main.py::test_get_key_none tests/test_main.py::test_unset_with_value tests/test_main.py::test_unset_no_value tests/test_main.py::test_unset_non_existent_file tests/test_main.py::test_find_dotenv_no_file_raise tests/test_main.py::test_find_dotenv_no_file_no_raise tests/test_main.py::test_find_dotenv_found tests/test_main.py::test_load_dotenv_existing_file tests/test_main.py::test_load_dotenv_no_file_verbose tests/test_main.py::test_load_dotenv_existing_variable_no_override tests/test_main.py::test_load_dotenv_existing_variable_override tests/test_main.py::test_load_dotenv_redefine_var_used_in_file_no_override tests/test_main.py::test_load_dotenv_redefine_var_used_in_file_with_override tests/test_main.py::test_load_dotenv_string_io_utf_8 tests/test_main.py::test_load_dotenv_file_stream tests/test_main.py::test_load_dotenv_in_current_dir tests/test_main.py::test_dotenv_values_file tests/test_main.py::test_dotenv_values_string_io[env0-a=$b-False-expected0] tests/test_main.py::test_dotenv_values_string_io[env1-a=$b-True-expected1] tests/test_main.py::test_dotenv_values_string_io[env2-a=${b}-False-expected2] tests/test_main.py::test_dotenv_values_string_io[env3-a=${b}-True-expected3] tests/test_main.py::test_dotenv_values_string_io[env4-a=${b:-d}-False-expected4] tests/test_main.py::test_dotenv_values_string_io[env5-a=${b:-d}-True-expected5] tests/test_main.py::test_dotenv_values_string_io[env6-b=c\na=${b}-True-expected6] tests/test_main.py::test_dotenv_values_string_io[env7-a=${b}-True-expected7] tests/test_main.py::test_dotenv_values_string_io[env8-a=${b:-d}-True-expected8] tests/test_main.py::test_dotenv_values_string_io[env9-a="${b}"-True-expected9] tests/test_main.py::test_dotenv_values_string_io[env10-a='${b}'-True-expected10] tests/test_main.py::test_dotenv_values_string_io[env11-a=x${b}y-True-expected11] tests/test_main.py::test_dotenv_values_string_io[env12-a=${a}-True-expected12] tests/test_main.py::test_dotenv_values_string_io[env13-a=${a}-True-expected13] tests/test_main.py::test_dotenv_values_string_io[env14-a=${a:-c}-True-expected14] tests/test_main.py::test_dotenv_values_string_io[env15-a=${a:-c}-True-expected15] tests/test_main.py::test_dotenv_values_string_io[env16-a=${b}${b}-True-expected16] tests/test_main.py::test_dotenv_values_string_io[env17-b=d\na=${b}-True-expected17] tests/test_main.py::test_dotenv_values_string_io[env18-a=b\na=c\nd=${a}-True-expected18] tests/test_main.py::test_dotenv_values_string_io[env19-a=b\nc=${a}\nd=e\nc=${d}-True-expected19] tests/test_main.py::test_dotenv_values_file_stream